Commit 153a599e authored by Matthias Clasen's avatar Matthias Clasen

Support the Netscape application extension for gif animations (#95060):

parent 6c38cd7a
...@@ -260,6 +260,7 @@ gdk_pixbuf_gif_anim_iter_advance (GdkPixbufAnimationIter *anim_iter, ...@@ -260,6 +260,7 @@ gdk_pixbuf_gif_anim_iter_advance (GdkPixbufAnimationIter *anim_iter,
{ {
GdkPixbufGifAnimIter *iter; GdkPixbufGifAnimIter *iter;
gint elapsed; gint elapsed;
gint loop;
GList *tmp; GList *tmp;
GList *old; GList *old;
...@@ -285,12 +286,17 @@ gdk_pixbuf_gif_anim_iter_advance (GdkPixbufAnimationIter *anim_iter, ...@@ -285,12 +286,17 @@ gdk_pixbuf_gif_anim_iter_advance (GdkPixbufAnimationIter *anim_iter,
/* See how many times we've already played the full animation, /* See how many times we've already played the full animation,
* and subtract time for that. * and subtract time for that.
*/ */
loop = elapsed / iter->gif_anim->total_time;
elapsed = elapsed % iter->gif_anim->total_time; elapsed = elapsed % iter->gif_anim->total_time;
iter->position = elapsed; iter->position = elapsed;
/* Now move to the proper frame */ /* Now move to the proper frame */
tmp = iter->gif_anim->frames; if (iter->gif_anim->loop == 0 || loop < iter->gif_anim->loop)
tmp = iter->gif_anim->frames;
else
tmp = NULL;
while (tmp != NULL) { while (tmp != NULL) {
GdkPixbufFrame *frame = tmp->data; GdkPixbufFrame *frame = tmp->data;
...@@ -525,7 +531,7 @@ gdk_pixbuf_gif_anim_iter_get_pixbuf (GdkPixbufAnimationIter *anim_iter) ...@@ -525,7 +531,7 @@ gdk_pixbuf_gif_anim_iter_get_pixbuf (GdkPixbufAnimationIter *anim_iter)
iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter); iter = GDK_PIXBUF_GIF_ANIM_ITER (anim_iter);
frame = iter->current_frame ? iter->current_frame->data : NULL; frame = iter->current_frame ? iter->current_frame->data : g_list_last (iter->gif_anim->frames)->data;
#if 0 #if 0
if (FALSE && frame) if (FALSE && frame)
......
...@@ -76,6 +76,8 @@ struct _GdkPixbufGifAnim { ...@@ -76,6 +76,8 @@ struct _GdkPixbufGifAnim {
guchar bg_red; guchar bg_red;
guchar bg_green; guchar bg_green;
guchar bg_blue; guchar bg_blue;
int loop;
}; };
struct _GdkPixbufGifAnimClass { struct _GdkPixbufGifAnimClass {
......
...@@ -83,7 +83,7 @@ enum { ...@@ -83,7 +83,7 @@ enum {
GIF_GET_COLORMAP, GIF_GET_COLORMAP,
GIF_GET_NEXT_STEP, GIF_GET_NEXT_STEP,
GIF_GET_FRAME_INFO, GIF_GET_FRAME_INFO,
GIF_GET_EXTENTION, GIF_GET_EXTENSION,
GIF_GET_COLORMAP2, GIF_GET_COLORMAP2,
GIF_PREPARE_LZW, GIF_PREPARE_LZW,
GIF_LZW_FILL_BUFFER, GIF_LZW_FILL_BUFFER,
...@@ -149,6 +149,7 @@ struct _GifContext ...@@ -149,6 +149,7 @@ struct _GifContext
/* extension context */ /* extension context */
guchar extension_label; guchar extension_label;
guchar extension_flag; guchar extension_flag;
gboolean in_loop_extension;
/* get block context */ /* get block context */
guchar block_count; guchar block_count;
...@@ -353,7 +354,7 @@ get_data_block (GifContext *context, ...@@ -353,7 +354,7 @@ get_data_block (GifContext *context,
static void static void
gif_set_get_extension (GifContext *context) gif_set_get_extension (GifContext *context)
{ {
context->state = GIF_GET_EXTENTION; context->state = GIF_GET_EXTENSION;
context->extension_flag = TRUE; context->extension_flag = TRUE;
context->extension_label = 0; context->extension_label = 0;
context->block_count = 0; context->block_count = 0;
...@@ -376,8 +377,8 @@ gif_get_extension (GifContext *context) ...@@ -376,8 +377,8 @@ gif_get_extension (GifContext *context)
} }
switch (context->extension_label) { switch (context->extension_label) {
case 0xf9: /* Graphic Control Extension */ case 0xf9: /* Graphic Control Extension */
retval = get_data_block (context, (unsigned char *) context->block_buf, NULL); retval = get_data_block (context, (unsigned char *) context->block_buf, NULL);
if (retval != 0) if (retval != 0)
return retval; return retval;
...@@ -399,6 +400,36 @@ gif_get_extension (GifContext *context) ...@@ -399,6 +400,36 @@ gif_get_extension (GifContext *context)
/* Now we've successfully loaded this one, we continue on our way */ /* Now we've successfully loaded this one, we continue on our way */
context->block_count = 0; context->block_count = 0;
context->extension_flag = FALSE; context->extension_flag = FALSE;
break;
case 0xff: /* application extension */
if (!context->in_loop_extension) {
retval = get_data_block (context, (unsigned char *) context->block_buf, NULL);
if (retval != 0)
return retval;
if (!strncmp (context->block_buf, "NETSCAPE2.0", 11) ||
!strncmp (context->block_buf, "ANIMEXTS1.0", 11)) {
context->in_loop_extension = TRUE;
context->block_count = 0;
}
}
if (context->in_loop_extension) {
do {
retval = get_data_block (context, (unsigned char *) context->block_buf, &empty_block);
if (retval != 0)
return retval;
if (context->block_buf[0] == 0x01) {
context->animation->loop = context->block_buf[1] + (context->block_buf[2] << 8);
if (context->animation->loop != 0)
context->animation->loop++;
}
context->block_count = 0;
}
while (!empty_block);
context->in_loop_extension = FALSE;
context->extension_flag = FALSE;
return 0;
}
break;
default: default:
/* Unhandled extension */ /* Unhandled extension */
break; break;
...@@ -1280,7 +1311,7 @@ gif_main_loop (GifContext *context) ...@@ -1280,7 +1311,7 @@ gif_main_loop (GifContext *context)
retval = gif_get_frame_info (context); retval = gif_get_frame_info (context);
break; break;
case GIF_GET_EXTENTION: case GIF_GET_EXTENSION:
LOG("get_extension\n"); LOG("get_extension\n");
retval = gif_get_extension (context); retval = gif_get_extension (context);
if (retval == 0) if (retval == 0)
...@@ -1349,6 +1380,8 @@ new_context (void) ...@@ -1349,6 +1380,8 @@ new_context (void)
context->gif89.delay_time = -1; context->gif89.delay_time = -1;
context->gif89.input_flag = -1; context->gif89.input_flag = -1;
context->gif89.disposal = -1; context->gif89.disposal = -1;
context->animation->loop = 1;
context->in_loop_extension = FALSE;
return context; return context;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment