diff options
author | Matthias Clasen <matthias@localhost.localdomain> | 2003-06-22 18:08:33 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2003-06-22 18:08:33 +0000 |
commit | a378391aaa4b7e422a96ae42477f080cc90989a8 (patch) | |
tree | 03b0530fac034f3fd0e504013e948f4aeaee752f /gdk-pixbuf/io-gif-animation.c | |
parent | 1a3ba4fde060cc90cac32a6affce028cfdd672f9 (diff) | |
download | gdk-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.c | 141 |
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; } |