emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r105526: Fix animated gif segfault an


From: Chong Yidong
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r105526: Fix animated gif segfault and frame clearing bug.
Date: Sun, 21 Aug 2011 22:34:23 -0400
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 105526
fixes bug(s): http://debbugs.gnu.org/9335
committer: Chong Yidong <address@hidden>
branch nick: trunk
timestamp: Sun 2011-08-21 22:34:23 -0400
message:
  Fix animated gif segfault and frame clearing bug.
  
  * src/image.c (gif_load): Don't assume that each subimage has the same
  dimensions as the base image.  Handle disposal method that is
  "undefined" by the gif spec.
modified:
  src/ChangeLog
  src/image.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-08-20 21:22:46 +0000
+++ b/src/ChangeLog     2011-08-22 02:34:23 +0000
@@ -1,3 +1,9 @@
+2011-08-22  Chong Yidong  <address@hidden>
+
+       * image.c (gif_load): Don't assume that each subimage has the same
+       dimensions as the base image.  Handle disposal method that is
+       "undefined" by the gif spec (Bug#9335).
+
 2011-08-20  Chong Yidong  <address@hidden>
 
        * eval.c (Fsignal): Handle `debug' symbol in error handler (Bug#9329).

=== modified file 'src/image.c'
--- a/src/image.c       2011-08-04 00:58:07 +0000
+++ b/src/image.c       2011-08-22 02:34:23 +0000
@@ -7139,7 +7139,6 @@
   ColorMapObject *gif_color_map;
   unsigned long pixel_colors[256];
   GifFileType *gif;
-  int image_height, image_width;
   gif_memory_source memsrc;
   Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
   Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -7216,19 +7215,13 @@
       }
   }
 
-  img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top;
-  img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left;
-  image_height = gif->SavedImages[idx].ImageDesc.Height;
-  img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
-  image_width = gif->SavedImages[idx].ImageDesc.Width;
-  img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
+  width = img->width = gif->SWidth;
+  height = img->height = gif->SHeight;
 
-  width = img->width = max (gif->SWidth,
-                           max (gif->Image.Left + gif->Image.Width,
-                                img->corners[RIGHT_CORNER]));
-  height = img->height = max (gif->SHeight,
-                             max (gif->Image.Top + gif->Image.Height,
-                                  img->corners[BOT_CORNER]));
+  img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
+  img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
+  img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + height;
+  img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + width;
 
   if (!check_image_size (f, width, height))
     {
@@ -7283,6 +7276,10 @@
       unsigned char *raster = (unsigned char *) subimage->RasterBits;
       int transparency_color_index = -1;
       int disposal = 0;
+      int subimg_width = subimage->ImageDesc.Width;
+      int subimg_height = subimage->ImageDesc.Height;
+      int subimg_top = subimage->ImageDesc.Top;
+      int subimg_left = subimage->ImageDesc.Left;
 
       /* Find the Graphic Control Extension block for this sub-image.
         Extract the disposal method and transparency color.  */
@@ -7306,6 +7303,13 @@
       if (j == 0)
        disposal = 2;
 
+      /* For disposal == 0, the spec says "No disposal specified. The
+        decoder is not required to take any action."  In practice, it
+        seems we need to treat this like "keep in place", see e.g.
+        http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
+      if (disposal == 0)
+       disposal = 1;
+
       /* Allocate subimage colors.  */
       memset (pixel_colors, 0, sizeof pixel_colors);
       gif_color_map = subimage->ImageDesc.ColorMap;
@@ -7333,34 +7337,34 @@
          int row, pass;
 
          for (y = 0, row = interlace_start[0], pass = 0;
-              y < image_height;
+              y < subimg_height;
               y++, row += interlace_increment[pass])
            {
-             if (row >= image_height)
+             if (row >= subimg_height)
                {
                  row = interlace_start[++pass];
-                 while (row >= image_height)
+                 while (row >= subimg_height)
                    row = interlace_start[++pass];
                }
 
-             for (x = 0; x < image_width; x++)
+             for (x = 0; x < subimg_width; x++)
                {
-                 int c = raster[y * image_width + x];
+                 int c = raster[y * subimg_width + x];
                  if (transparency_color_index != c || disposal != 1)
-                   XPutPixel (ximg, x + img->corners[LEFT_CORNER],
-                              row + img->corners[TOP_CORNER], pixel_colors[c]);
+                   XPutPixel (ximg, x + subimg_left, row + subimg_top,
+                              pixel_colors[c]);
                }
            }
        }
       else
        {
-         for (y = 0; y < image_height; ++y)
-           for (x = 0; x < image_width; ++x)
+         for (y = 0; y < subimg_height; ++y)
+           for (x = 0; x < subimg_width; ++x)
              {
-               int c = raster[y * image_width + x];
+               int c = raster[y * subimg_width + x];
                if (transparency_color_index != c || disposal != 1)
-                 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
-                            y + img->corners[TOP_CORNER], pixel_colors[c]);
+                 XPutPixel (ximg, x + subimg_left, y + subimg_top,
+                            pixel_colors[c]);
              }
        }
     }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]