Coverage Report

Created: 2025-12-31 07:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/glib/poppler-movie.cc
Line
Count
Source
1
/* poppler-movie.cc: glib interface to Movie
2
 *
3
 * Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
4
 * Copyright (C) 2008 Hugo Mercier <hmercier31[@]gmail.com>
5
 * Copyright (C) 2017 Francesco Poli <invernomuto@paranoici.org>
6
 * Copyright (C) 2025 Albert Astals Cid <aacid@kde.org>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2, or (at your option)
11
 * any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
21
 */
22
23
#include "poppler-movie.h"
24
#include "poppler-private.h"
25
26
/**
27
 * SECTION: poppler-movie
28
 * @short_description: Movies
29
 * @title: PopplerMovie
30
 */
31
32
typedef struct _PopplerMovieClass PopplerMovieClass;
33
34
struct _PopplerMovie
35
{
36
    GObject parent_instance;
37
38
    gchar *filename;
39
    gboolean need_poster;
40
    gboolean show_controls;
41
    PopplerMoviePlayMode mode;
42
    gboolean synchronous_play;
43
    gdouble volume;
44
    gdouble rate;
45
    guint64 start;
46
    guint64 duration;
47
    gushort rotation_angle;
48
    gint width;
49
    gint height;
50
};
51
52
struct _PopplerMovieClass
53
{
54
    GObjectClass parent_class;
55
};
56
57
0
G_DEFINE_TYPE(PopplerMovie, poppler_movie, G_TYPE_OBJECT)
58
0
59
0
static void poppler_movie_finalize(GObject *object)
60
0
{
61
0
    PopplerMovie *movie = POPPLER_MOVIE(object);
62
63
0
    if (movie->filename) {
64
0
        g_free(movie->filename);
65
0
        movie->filename = nullptr;
66
0
    }
67
68
0
    G_OBJECT_CLASS(poppler_movie_parent_class)->finalize(object);
69
0
}
70
71
static void poppler_movie_class_init(PopplerMovieClass *klass)
72
0
{
73
0
    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
74
75
0
    gobject_class->finalize = poppler_movie_finalize;
76
0
}
77
78
0
static void poppler_movie_init(PopplerMovie * /*movie*/) { }
79
80
PopplerMovie *_poppler_movie_new(const Movie *poppler_movie)
81
0
{
82
0
    PopplerMovie *movie;
83
84
0
    g_assert(poppler_movie != nullptr);
85
86
0
    movie = POPPLER_MOVIE(g_object_new(POPPLER_TYPE_MOVIE, nullptr));
87
88
0
    movie->filename = g_strdup(poppler_movie->getFileName()->c_str());
89
0
    if (poppler_movie->getShowPoster()) {
90
0
        Object tmp = poppler_movie->getPoster();
91
0
        movie->need_poster = (!tmp.isRef() && !tmp.isStream());
92
0
    }
93
94
0
    movie->show_controls = poppler_movie->getActivationParameters()->showControls;
95
96
0
    switch (poppler_movie->getActivationParameters()->repeatMode) {
97
0
    case MovieActivationParameters::repeatModeOnce:
98
0
        movie->mode = POPPLER_MOVIE_PLAY_MODE_ONCE;
99
0
        break;
100
0
    case MovieActivationParameters::repeatModeOpen:
101
0
        movie->mode = POPPLER_MOVIE_PLAY_MODE_OPEN;
102
0
        break;
103
0
    case MovieActivationParameters::repeatModeRepeat:
104
0
        movie->mode = POPPLER_MOVIE_PLAY_MODE_REPEAT;
105
0
        break;
106
0
    case MovieActivationParameters::repeatModePalindrome:
107
0
        movie->mode = POPPLER_MOVIE_PLAY_MODE_PALINDROME;
108
0
        break;
109
0
    }
110
111
0
    movie->synchronous_play = poppler_movie->getActivationParameters()->synchronousPlay;
112
113
    // map 0 - 100 to 0.0 - 1.0
114
0
    movie->volume = poppler_movie->getActivationParameters()->volume / 100.0;
115
116
0
    movie->rate = poppler_movie->getActivationParameters()->rate;
117
118
0
    if (poppler_movie->getActivationParameters()->start.units_per_second > 0 && poppler_movie->getActivationParameters()->start.units <= G_MAXUINT64 / 1000000000) {
119
0
        movie->start = 1000000000L * poppler_movie->getActivationParameters()->start.units / poppler_movie->getActivationParameters()->start.units_per_second;
120
0
    } else {
121
0
        movie->start = 0L;
122
0
    }
123
124
0
    if (poppler_movie->getActivationParameters()->duration.units_per_second > 0 && poppler_movie->getActivationParameters()->duration.units <= G_MAXUINT64 / 1000000000) {
125
0
        movie->duration = 1000000000L * poppler_movie->getActivationParameters()->duration.units / poppler_movie->getActivationParameters()->duration.units_per_second;
126
0
    } else {
127
0
        movie->duration = 0L;
128
0
    }
129
130
0
    movie->rotation_angle = poppler_movie->getRotationAngle();
131
132
0
    poppler_movie->getAspect(&movie->width, &movie->height);
133
134
0
    return movie;
135
0
}
136
137
/**
138
 * poppler_movie_get_filename:
139
 * @poppler_movie: a #PopplerMovie
140
 *
141
 * Returns the local filename identifying a self-describing movie file
142
 *
143
 * Return value: a local filename, return value is owned by #PopplerMovie and
144
 *               should not be freed
145
 *
146
 * Since: 0.14
147
 */
148
const gchar *poppler_movie_get_filename(PopplerMovie *poppler_movie)
149
0
{
150
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), NULL);
151
152
0
    return poppler_movie->filename;
153
0
}
154
155
/**
156
 * poppler_movie_need_poster:
157
 * @poppler_movie: a #PopplerMovie
158
 *
159
 * Returns whether a poster image representing the Movie
160
 * shall be displayed. The poster image must be retrieved
161
 * from the movie file.
162
 *
163
 * Return value: %TRUE if move needs a poster image, %FALSE otherwise
164
 *
165
 * Since: 0.14
166
 */
167
gboolean poppler_movie_need_poster(PopplerMovie *poppler_movie)
168
0
{
169
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), FALSE);
170
171
0
    return poppler_movie->need_poster;
172
0
}
173
174
/**
175
 * poppler_movie_show_controls:
176
 * @poppler_movie: a #PopplerMovie
177
 *
178
 * Returns whether to display a movie controller bar while playing the movie
179
 *
180
 * Return value: %TRUE if controller bar should be displayed, %FALSE otherwise
181
 *
182
 * Since: 0.14
183
 */
184
gboolean poppler_movie_show_controls(PopplerMovie *poppler_movie)
185
0
{
186
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), FALSE);
187
188
0
    return poppler_movie->show_controls;
189
0
}
190
191
/**
192
 * poppler_movie_get_play_mode:
193
 * @poppler_movie: a #PopplerMovie
194
 *
195
 * Returns the play mode of @poppler_movie.
196
 *
197
 * Return value: a #PopplerMoviePlayMode.
198
 *
199
 * Since: 0.54
200
 */
201
PopplerMoviePlayMode poppler_movie_get_play_mode(PopplerMovie *poppler_movie)
202
0
{
203
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), POPPLER_MOVIE_PLAY_MODE_ONCE);
204
205
0
    return poppler_movie->mode;
206
0
}
207
208
/**
209
 * poppler_movie_is_synchronous:
210
 * @poppler_movie: a #PopplerMovie
211
 *
212
 * Returns whether the user must wait for the movie to be finished before
213
 * the PDF viewer accepts any interactive action
214
 *
215
 * Return value: %TRUE if yes, %FALSE otherwise
216
 *
217
 * Since: 0.80
218
 */
219
gboolean poppler_movie_is_synchronous(PopplerMovie *poppler_movie)
220
0
{
221
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), FALSE);
222
223
0
    return poppler_movie->synchronous_play;
224
0
}
225
226
/**
227
 * poppler_movie_get_volume:
228
 * @poppler_movie: a #PopplerMovie
229
 *
230
 * Returns the playback audio volume
231
 *
232
 * Return value: volume setting for the movie (0.0 - 1.0)
233
 *
234
 * Since: 0.80
235
 */
236
gdouble poppler_movie_get_volume(PopplerMovie *poppler_movie)
237
0
{
238
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), 0);
239
240
0
    return poppler_movie->volume;
241
0
}
242
243
/**
244
 * poppler_movie_get_rate:
245
 * @poppler_movie: a #PopplerMovie
246
 *
247
 * Returns the relative speed of the movie
248
 *
249
 * Return value: the relative speed of the movie (1 means no change)
250
 *
251
 * Since: 0.80
252
 */
253
gdouble poppler_movie_get_rate(PopplerMovie *poppler_movie)
254
0
{
255
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), 0);
256
257
0
    return poppler_movie->rate;
258
0
}
259
260
/**
261
 * poppler_movie_get_rotation_angle:
262
 * @poppler_movie: a #PopplerMovie
263
 *
264
 * Returns the rotation angle
265
 *
266
 * Return value: the number of degrees the movie should be rotated (positive,
267
 * multiples of 90: 0, 90, 180, 270)
268
 *
269
 * Since: 0.80
270
 */
271
gushort poppler_movie_get_rotation_angle(PopplerMovie *poppler_movie)
272
0
{
273
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), 0);
274
275
0
    return poppler_movie->rotation_angle;
276
0
}
277
278
/**
279
 * poppler_movie_get_start:
280
 * @poppler_movie: a #PopplerMovie
281
 *
282
 * Returns the start position of the movie playback
283
 *
284
 * Return value: the start position of the movie playback (in ns)
285
 *
286
 * Since: 0.80
287
 */
288
guint64 poppler_movie_get_start(PopplerMovie *poppler_movie)
289
0
{
290
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), 0L);
291
292
0
    return poppler_movie->start;
293
0
}
294
295
/**
296
 * poppler_movie_get_duration:
297
 * @poppler_movie: a #PopplerMovie
298
 *
299
 * Returns the duration of the movie playback
300
 *
301
 * Return value: the duration of the movie playback (in ns)
302
 *
303
 * Since: 0.80
304
 */
305
guint64 poppler_movie_get_duration(PopplerMovie *poppler_movie)
306
0
{
307
0
    g_return_val_if_fail(POPPLER_IS_MOVIE(poppler_movie), 0L);
308
309
0
    return poppler_movie->duration;
310
0
}
311
312
/**
313
 * poppler_movie_get_aspect:
314
 * @poppler_movie: a #PopplerMovie
315
 * @width: width of the movie's bounding box
316
 * @height: height of the movie's bounding box
317
 *
318
 * Returns the dimensions of the movie's bounding box (in pixels).
319
 * The respective PDF movie dictionary entry is optional; if missing,
320
 * -1x-1 will be returned.
321
 *
322
 * Since: 0.89
323
 */
324
void poppler_movie_get_aspect(PopplerMovie *poppler_movie, gint *width, gint *height)
325
0
{
326
0
    g_return_if_fail(POPPLER_IS_MOVIE(poppler_movie));
327
328
0
    *width = poppler_movie->width;
329
0
    *height = poppler_movie->height;
330
0
}