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.
This commit is contained in:
committed by
Matthias Clasen
parent
1a3ba4fde0
commit
a378391aaa
@ -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);
|
||||
if (prev_clipped_width > 0 && prev_clipped_height > 0) {
|
||||
/* Clear area of previous frame to background */
|
||||
GdkPixbuf *area;
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user