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:
Matthias Clasen
2003-06-22 18:08:33 +00:00
committed by Matthias Clasen
parent 1a3ba4fde0
commit a378391aaa
3 changed files with 167 additions and 138 deletions

View File

@ -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;
}