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 | |
31 | typedef struct _PopplerMovieClass PopplerMovieClass; |
32 | |
33 | struct _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 | |
51 | struct _PopplerMovieClass |
52 | { |
53 | GObjectClass parent_class; |
54 | }; |
55 | |
56 | G_DEFINE_TYPE(PopplerMovie, poppler_movie, G_TYPE_OBJECT) |
57 | |
58 | static 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 | |
70 | static 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 | |
77 | static void poppler_movie_init(PopplerMovie *movie) { } |
78 | |
79 | PopplerMovie *_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 | */ |
147 | const 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 | */ |
166 | gboolean 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 | */ |
183 | gboolean 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 | */ |
200 | PopplerMoviePlayMode 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 | */ |
218 | gboolean 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 | */ |
235 | gdouble 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 | */ |
252 | gdouble 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 | */ |
270 | gushort 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 | */ |
287 | guint64 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 | */ |
304 | guint64 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 | */ |
323 | void 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 | |