gif_deanimate(): Tolerate multiple image extensions in a row
authorFabian Keil <fk@fabiankeil.de>
Tue, 9 Feb 2021 19:20:34 +0000 (20:20 +0100)
committerFabian Keil <fk@fabiankeil.de>
Tue, 29 Mar 2022 14:16:08 +0000 (16:16 +0200)
This allows to deanimate all the gifs on:
https://commons.wikimedia.org/wiki/Category:Animated_smilies

Fixes SF bug #795 reported by Celejar.

deanimate.c

index a6759da..7975122 100644 (file)
@@ -328,6 +328,7 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
 {
    unsigned char c;
    struct binbuffer *image;
 {
    unsigned char c;
    struct binbuffer *image;
+   int image_buffered = 0;
 
    if (NULL == src || NULL == dst)
    {
 
    if (NULL == src || NULL == dst)
    {
@@ -398,8 +399,14 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
           * Image block: Extract to current image buffer.
           */
       case 0x2c:
           * Image block: Extract to current image buffer.
           */
       case 0x2c:
-         image->offset = 0;
+         if (image_buffered == 1)
+         {
+            /* Discard previous image. */
+            image->offset = 0;
+            image_buffered = 0;
+         }
          if (gif_extract_image(src, image)) goto failed;
          if (gif_extract_image(src, image)) goto failed;
+         image_buffered = 1;
          if (get_first_image) goto write;
          continue;
 
          if (get_first_image) goto write;
          continue;
 
@@ -410,14 +417,16 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
          switch (buf_getbyte(src, 1))
          {
             /*
          switch (buf_getbyte(src, 1))
          {
             /*
-             * Image extension: Copy extension  header and image
-             *                  to the current image buffer
+             * Image extension: Copy extension header
+             * and continue looking for new blocks.
              */
          case 0xf9:
              */
          case 0xf9:
-            image->offset = 0;
-            if (buf_copy(src, image, 8) || buf_getbyte(src, 0) != 0x2c) goto failed;
-            if (gif_extract_image(src, image)) goto failed;
-            if (get_first_image) goto write;
+            if (image_buffered == 1)
+            {
+               image->offset = 0;
+               image_buffered = 0;
+            }
+            if (buf_copy(src, image, 8)) goto failed;
             continue;
 
             /*
             continue;
 
             /*