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

source code of poppler/glib/poppler-movie.cc