summaryrefslogtreecommitdiff
path: root/gdk-pixbuf/io-gif-animation.c
diff options
context:
space:
mode:
authorMatthias Clasen <matthias@localhost.localdomain>2003-06-22 18:08:33 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2003-06-22 18:08:33 +0000
commita378391aaa4b7e422a96ae42477f080cc90989a8 (patch)
tree03b0530fac034f3fd0e504013e948f4aeaee752f /gdk-pixbuf/io-gif-animation.c
parent1a3ba4fde060cc90cac32a6affce028cfdd672f9 (diff)
downloadgdk-pixbuf-a378391aaa4b7e422a96ae42477f080cc90989a8.tar.gz
Reset block_count to 0 for all application extensions, otherwise the data
2003-06-22 Matthias Clasen <matthias@localhost.localdomain> * io-gif.c (gif_get_extension): Reset block_count to 0 for all application extensions, otherwise the data blocks of unknown extensions are not propertly skipped. Second half of the fix for #106962, handle frames extending beyond the logical screen: * io-gif.c (clip_frame): New helper function to clip a rectangle to the logical screen size of the gif. (maybe_update): New helper function to call update_func only if the rectangle is not completely off-bounds. (gif_get_lzw): Read frames extending outside the logical screen size, but be careful clip to the logical screen size when operating on the composite pixbuf and when calling update_func. (gif_init): Set the animation size to the logical screen size. (gif_get_frame_info): Don't refuse to load images with frames extending beyond the logical screen size. * io-gif-animation.c (gdk_pixbuf_gif_anim_frame_composite): Be careful to clip all rectangles to the logical screen size, also handle the fact that frames may be completely off-bounds.
Diffstat (limited to 'gdk-pixbuf/io-gif-animation.c')
-rw-r--r--gdk-pixbuf/io-gif-animation.c141
1 files changed, 71 insertions, 70 deletions
diff --git a/gdk-pixbuf/io-gif-animation.c b/gdk-pixbuf/io-gif-animation.c
index 97062ba9c..bf50a9363 100644
--- a/gdk-pixbuf/io-gif-animation.c
+++ b/gdk-pixbuf/io-gif-animation.c
@@ -391,7 +391,9 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
while (tmp != NULL) {
GdkPixbufFrame *f = tmp->data;
-
+ gint clipped_width = MIN (gif_anim->width - f->x_offset, gdk_pixbuf_get_width (f->pixbuf));
+ gint clipped_height = MIN (gif_anim->height - f->y_offset, gdk_pixbuf_get_height (f->pixbuf));
+
if (f->need_recomposite) {
if (f->composited) {
g_object_unref (f->composited);
@@ -419,26 +421,17 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
(gif_anim->bg_green << 16) |
(gif_anim->bg_blue << 8));
- gdk_pixbuf_composite (f->pixbuf,
- f->composited,
- f->x_offset,
- f->y_offset,
- gdk_pixbuf_get_width (f->pixbuf),
- gdk_pixbuf_get_height (f->pixbuf),
- f->x_offset, f->y_offset,
- 1.0, 1.0,
- GDK_INTERP_BILINEAR,
- 255);
-#if 0
- gdk_pixbuf_copy_area (f->pixbuf,
- 0, 0,
- gdk_pixbuf_get_width (f->pixbuf),
- gdk_pixbuf_get_height (f->pixbuf),
- f->composited,
- f->x_offset,
- f->y_offset);
-
-#endif
+ if (clipped_width > 0 && clipped_height > 0)
+ gdk_pixbuf_composite (f->pixbuf,
+ f->composited,
+ f->x_offset,
+ f->y_offset,
+ clipped_width,
+ clipped_height,
+ f->x_offset, f->y_offset,
+ 1.0, 1.0,
+ GDK_INTERP_BILINEAR,
+ 255);
if (f->action == GDK_PIXBUF_FRAME_REVERT)
g_warning ("First frame of GIF has bad dispose mode, GIF loader should not have loaded this image");
@@ -449,6 +442,9 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
prev_frame = tmp->prev->data;
+ gint prev_clipped_width = MIN (gif_anim->width - prev_frame->x_offset, gdk_pixbuf_get_width (prev_frame->pixbuf));
+ gint prev_clipped_height = MIN (gif_anim->height - prev_frame->y_offset, gdk_pixbuf_get_height (prev_frame->pixbuf));
+
/* Init f->composited with what we should have after the previous
* frame
*/
@@ -457,66 +453,71 @@ gdk_pixbuf_gif_anim_frame_composite (GdkPixbufGifAnim *gif_anim,
f->composited = gdk_pixbuf_copy (prev_frame->composited);
} else if (prev_frame->action == GDK_PIXBUF_FRAME_DISPOSE) {
- GdkPixbuf *area;
-
f->composited = gdk_pixbuf_copy (prev_frame->composited);
-
- /* Clear area of previous frame to background */
- area = gdk_pixbuf_new_subpixbuf (f->composited,
- prev_frame->x_offset,
- prev_frame->y_offset,
- gdk_pixbuf_get_width (prev_frame->pixbuf),
- gdk_pixbuf_get_height (prev_frame->pixbuf));
-
- gdk_pixbuf_fill (area,
- (gif_anim->bg_red << 24) |
- (gif_anim->bg_green << 16) |
- (gif_anim->bg_blue << 8));
-
- g_object_unref (area);
-
+ if (prev_clipped_width > 0 && prev_clipped_height > 0) {
+ /* Clear area of previous frame to background */
+ GdkPixbuf *area;
+
+ area = gdk_pixbuf_new_subpixbuf (f->composited,
+ prev_frame->x_offset,
+ prev_frame->y_offset,
+ prev_clipped_width,
+ prev_clipped_height);
+
+ gdk_pixbuf_fill (area,
+ (gif_anim->bg_red << 24) |
+ (gif_anim->bg_green << 16) |
+ (gif_anim->bg_blue << 8));
+
+ g_object_unref (area);
+ }
} else if (prev_frame->action == GDK_PIXBUF_FRAME_REVERT) {
f->composited = gdk_pixbuf_copy (prev_frame->composited);
-
- /* Copy in the revert frame */
- gdk_pixbuf_copy_area (prev_frame->revert,
- 0, 0,
- gdk_pixbuf_get_width (prev_frame->revert),
- gdk_pixbuf_get_height (prev_frame->revert),
- f->composited,
- prev_frame->x_offset,
- prev_frame->y_offset);
+ if (prev_clipped_width > 0 && prev_clipped_height > 0) {
+ /* Copy in the revert frame */
+ gdk_pixbuf_copy_area (prev_frame->revert,
+ 0, 0,
+ gdk_pixbuf_get_width (prev_frame->revert),
+ gdk_pixbuf_get_height (prev_frame->revert),
+ f->composited,
+ prev_frame->x_offset,
+ prev_frame->y_offset);
+ }
} else {
g_warning ("Unknown revert action for GIF frame");
}
if (f->revert == NULL &&
f->action == GDK_PIXBUF_FRAME_REVERT) {
- /* We need to save the contents before compositing */
- GdkPixbuf *area;
-
- area = gdk_pixbuf_new_subpixbuf (f->composited,
- f->x_offset,
- f->y_offset,
- gdk_pixbuf_get_width (f->pixbuf),
- gdk_pixbuf_get_height (f->pixbuf));
-
- f->revert = gdk_pixbuf_copy (area);
-
- g_object_unref (area);
+ if (clipped_width > 0 && clipped_height > 0) {
+ /* We need to save the contents before compositing */
+ GdkPixbuf *area;
+
+ area = gdk_pixbuf_new_subpixbuf (f->composited,
+ f->x_offset,
+ f->y_offset,
+ clipped_width,
+ clipped_height);
+
+ f->revert = gdk_pixbuf_copy (area);
+
+ g_object_unref (area);
+ }
}
- /* Put current frame onto f->composited */
- gdk_pixbuf_composite (f->pixbuf,
- f->composited,
- f->x_offset,
- f->y_offset,
- gdk_pixbuf_get_width (f->pixbuf),
- gdk_pixbuf_get_height (f->pixbuf),
- f->x_offset, f->y_offset,
- 1.0, 1.0,
- GDK_INTERP_NEAREST,
- 255);
+ if (clipped_width > 0 && clipped_height > 0) {
+ /* Put current frame onto f->composited */
+ gdk_pixbuf_composite (f->pixbuf,
+ f->composited,
+ f->x_offset,
+ f->y_offset,
+ clipped_width,
+ clipped_height,
+ f->x_offset, f->y_offset,
+ 1.0, 1.0,
+ GDK_INTERP_NEAREST,
+ 255);
+ }
f->need_recomposite = FALSE;
}