1 /* GdkPixbuf library - Simple animation support
3 * Copyright (C) 1999 The Free Software Foundation
5 * Authors: Jonathan Blandford <jrb@redhat.com>
6 * Havoc Pennington <hp@redhat.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library 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 GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
26 #include "gdk-pixbuf-io.h"
27 #include "gdk-pixbuf-private.h"
29 static void gdk_pixbuf_animation_class_init (GdkPixbufAnimationClass *klass);
30 static void gdk_pixbuf_animation_finalize (GObject *object);
34 static gpointer parent_class;
37 gdk_pixbuf_animation_get_type (void)
39 static GType object_type = 0;
42 static const GTypeInfo object_info = {
43 sizeof (GdkPixbufAnimationClass),
45 (GBaseFinalizeFunc) NULL,
46 (GClassInitFunc) gdk_pixbuf_animation_class_init,
47 NULL, /* class_finalize */
48 NULL, /* class_data */
49 sizeof (GdkPixbufAnimation),
51 (GInstanceInitFunc) NULL,
54 object_type = g_type_register_static (G_TYPE_OBJECT,
63 gdk_pixbuf_animation_class_init (GdkPixbufAnimationClass *klass)
65 GObjectClass *object_class = G_OBJECT_CLASS (klass);
67 parent_class = g_type_class_peek_parent (klass);
69 object_class->finalize = gdk_pixbuf_animation_finalize;
73 gdk_pixbuf_animation_finalize (GObject *object)
75 GdkPixbufAnimation *animation = GDK_PIXBUF_ANIMATION (object);
78 GdkPixbufFrame *frame;
80 for (l = animation->frames; l; l = l->next) {
82 gdk_pixbuf_unref (frame->pixbuf);
86 g_list_free (animation->frames);
88 G_OBJECT_CLASS (parent_class)->finalize (object);
94 * gdk_pixbuf_animation_new_from_file:
95 * @filename: Name of file to load.
96 * @error: return location for error
98 * Creates a new animation by loading it from a file. The file format is
99 * detected automatically. If the file's format does not support multi-frame
100 * images, then an animation with a single frame will be created. Possible errors
101 * are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains.
103 * Return value: A newly created animation with a reference count of 1, or NULL
104 * if any of several error conditions ocurred: the file could not be opened,
105 * there was no loader for the file's format, there was not enough memory to
106 * allocate the image buffer, or the image file contained invalid data.
109 gdk_pixbuf_animation_new_from_file (const char *filename,
112 GdkPixbufAnimation *animation;
116 GdkPixbufModule *image_module;
118 g_return_val_if_fail (filename != NULL, NULL);
120 f = fopen (filename, "rb");
124 g_file_error_from_errno (errno),
125 _("Failed to open file '%s': %s"),
126 filename, g_strerror (errno));
130 size = fread (&buffer, 1, sizeof (buffer), f);
135 GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
136 _("Image file '%s' contains no data"),
143 image_module = gdk_pixbuf_get_module (buffer, size, filename, error);
149 if (image_module->module == NULL)
150 if (!gdk_pixbuf_load_module (image_module, error)) {
155 if (image_module->load_animation == NULL) {
157 GdkPixbufFrame *frame;
159 /* Keep this logic in sync with gdk_pixbuf_new_from_file() */
161 if (image_module->load == NULL) {
164 GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
165 _("Don't know how to load the animation in file '%s'"),
171 fseek (f, 0, SEEK_SET);
172 pixbuf = (* image_module->load) (f, error);
175 if (pixbuf == NULL && error != NULL && *error == NULL) {
176 /* I don't trust these crufty longjmp()'ing image libs
177 * to maintain proper error invariants, and I don't
178 * want user code to segfault as a result. We need to maintain
179 * the invariant that error gets set if NULL is returned.
182 g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.",
183 image_module->module_name);
186 GDK_PIXBUF_ERROR_FAILED,
187 _("Failed to load image '%s': reason not known, probably a corrupt image file"),
194 frame = g_new (GdkPixbufFrame, 1);
195 frame->pixbuf = pixbuf;
198 frame->delay_time = -1;
199 frame->action = GDK_PIXBUF_FRAME_RETAIN;
201 animation = g_object_new (GDK_TYPE_PIXBUF_ANIMATION, NULL);
203 animation->n_frames = 1;
204 animation->frames = g_list_prepend (NULL, frame);
205 animation->width = gdk_pixbuf_get_width (pixbuf);
206 animation->height = gdk_pixbuf_get_height (pixbuf);
208 fseek (f, 0, SEEK_SET);
209 animation = (* image_module->load_animation) (f, error);
211 if (animation == NULL && error != NULL && *error == NULL) {
212 /* I don't trust these crufty longjmp()'ing
213 * image libs to maintain proper error
214 * invariants, and I don't want user code to
215 * segfault as a result. We need to maintain
216 * the invariant that error gets set if NULL
220 g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.",
221 image_module->module_name);
224 GDK_PIXBUF_ERROR_FAILED,
225 _("Failed to load animation '%s': reason not known, probably a corrupt animation file"),
236 * gdk_pixbuf_animation_ref:
237 * @animation: An animation.
239 * Adds a reference to an animation. Deprecated; use
240 * g_object_ref(). The reference must be released afterwards using
243 * Return value: The same as the @animation argument.
246 gdk_pixbuf_animation_ref (GdkPixbufAnimation *animation)
248 return (GdkPixbufAnimation*) g_object_ref (G_OBJECT (animation));
252 * gdk_pixbuf_animation_unref:
253 * @animation: An animation.
255 * Removes a reference from an animation. Deprecated; use g_object_unref().
258 gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation)
260 g_object_unref (G_OBJECT (animation));
264 * gdk_pixbuf_animation_get_width:
265 * @animation: An animation.
267 * Queries the width of the bounding box of a pixbuf animation.
269 * Return value: Width of the bounding box of the animation.
272 gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation)
274 g_return_val_if_fail (animation != NULL, -1);
276 return animation->width;
280 * gdk_pixbuf_animation_get_height:
281 * @animation: An animation.
283 * Queries the height of the bounding box of a pixbuf animation.
285 * Return value: Height of the bounding box of the animation.
288 gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation)
290 g_return_val_if_fail (animation != NULL, -1);
292 return animation->height;
296 * gdk_pixbuf_animation_get_num_frames:
297 * @animation: An animation.
299 * Queries the number of frames in a pixbuf animation.
301 * Return value: Number of frames in the animation.
304 gdk_pixbuf_animation_get_num_frames (GdkPixbufAnimation *animation)
306 g_return_val_if_fail (animation != NULL, -1);
308 return animation->n_frames;
312 * gdk_pixbuf_animation_get_frames:
313 * @animation: An animation.
315 * Queries the list of frames of an animation.
317 * Return value: List of frames in the animation; this is a #GList of
318 * #GdkPixbufFrame structures.
321 gdk_pixbuf_animation_get_frames (GdkPixbufAnimation *animation)
323 g_return_val_if_fail (animation != NULL, NULL);
325 return animation->frames;
331 * gdk_pixbuf_frame_get_pixbuf:
332 * @frame: A pixbuf animation frame.
334 * Queries the pixbuf of an animation frame.
336 * Return value: A pixbuf.
339 gdk_pixbuf_frame_get_pixbuf (GdkPixbufFrame *frame)
341 g_return_val_if_fail (frame != NULL, NULL);
343 return frame->pixbuf;
347 * gdk_pixbuf_frame_get_x_offset:
348 * @frame: A pixbuf animation frame.
350 * Queries the X offset of an animation frame.
352 * Return value: X offset from the top left corner of the animation.
355 gdk_pixbuf_frame_get_x_offset (GdkPixbufFrame *frame)
357 g_return_val_if_fail (frame != NULL, -1);
359 return frame->x_offset;
363 * gdk_pixbuf_frame_get_y_offset:
364 * @frame: A pixbuf animation frame.
366 * Queries the Y offset of an animation frame.
368 * Return value: Y offset from the top left corner of the animation.
371 gdk_pixbuf_frame_get_y_offset (GdkPixbufFrame *frame)
373 g_return_val_if_fail (frame != NULL, -1);
375 return frame->y_offset;
379 * gdk_pixbuf_frame_get_delay_time:
380 * @frame: A pixbuf animation frame.
382 * Queries the delay time in milliseconds of an animation frame.
384 * Return value: Delay time in milliseconds.
387 gdk_pixbuf_frame_get_delay_time (GdkPixbufFrame *frame)
389 g_return_val_if_fail (frame != NULL, -1);
391 return frame->delay_time;
395 * gdk_pixbuf_frame_get_action:
396 * @frame: A pixbuf animation frame.
398 * Queries the overlay action of an animation frame.
400 * Return value: Overlay action for this frame.
403 gdk_pixbuf_frame_get_action (GdkPixbufFrame *frame)
405 g_return_val_if_fail (frame != NULL, GDK_PIXBUF_FRAME_RETAIN);
407 return frame->action;