aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorChong Yidong2011-08-21 22:34:23 -0400
committerChong Yidong2011-08-21 22:34:23 -0400
commite013fb340c50dd99676ccc4552fd6aae2e319aa8 (patch)
treedc391443df091476c5607e196b0a1658175a3525 /src/image.c
parent138c0212ac4bc4708210ba4b3e0a4fad00a4dc5f (diff)
downloademacs-e013fb340c50dd99676ccc4552fd6aae2e319aa8.tar.gz
emacs-e013fb340c50dd99676ccc4552fd6aae2e319aa8.zip
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. Fixes: debbugs:9335
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/src/image.c b/src/image.c
index d1091aec6f3..65be22b087a 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7139,7 +7139,6 @@ gif_load (struct frame *f, struct image *img)
7139 ColorMapObject *gif_color_map; 7139 ColorMapObject *gif_color_map;
7140 unsigned long pixel_colors[256]; 7140 unsigned long pixel_colors[256];
7141 GifFileType *gif; 7141 GifFileType *gif;
7142 int image_height, image_width;
7143 gif_memory_source memsrc; 7142 gif_memory_source memsrc;
7144 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); 7143 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
7145 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); 7144 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -7216,19 +7215,13 @@ gif_load (struct frame *f, struct image *img)
7216 } 7215 }
7217 } 7216 }
7218 7217
7219 img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top; 7218 width = img->width = gif->SWidth;
7220 img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left; 7219 height = img->height = gif->SHeight;
7221 image_height = gif->SavedImages[idx].ImageDesc.Height;
7222 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
7223 image_width = gif->SavedImages[idx].ImageDesc.Width;
7224 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
7225 7220
7226 width = img->width = max (gif->SWidth, 7221 img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
7227 max (gif->Image.Left + gif->Image.Width, 7222 img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
7228 img->corners[RIGHT_CORNER])); 7223 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + height;
7229 height = img->height = max (gif->SHeight, 7224 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + width;
7230 max (gif->Image.Top + gif->Image.Height,
7231 img->corners[BOT_CORNER]));
7232 7225
7233 if (!check_image_size (f, width, height)) 7226 if (!check_image_size (f, width, height))
7234 { 7227 {
@@ -7283,6 +7276,10 @@ gif_load (struct frame *f, struct image *img)
7283 unsigned char *raster = (unsigned char *) subimage->RasterBits; 7276 unsigned char *raster = (unsigned char *) subimage->RasterBits;
7284 int transparency_color_index = -1; 7277 int transparency_color_index = -1;
7285 int disposal = 0; 7278 int disposal = 0;
7279 int subimg_width = subimage->ImageDesc.Width;
7280 int subimg_height = subimage->ImageDesc.Height;
7281 int subimg_top = subimage->ImageDesc.Top;
7282 int subimg_left = subimage->ImageDesc.Left;
7286 7283
7287 /* Find the Graphic Control Extension block for this sub-image. 7284 /* Find the Graphic Control Extension block for this sub-image.
7288 Extract the disposal method and transparency color. */ 7285 Extract the disposal method and transparency color. */
@@ -7306,6 +7303,13 @@ gif_load (struct frame *f, struct image *img)
7306 if (j == 0) 7303 if (j == 0)
7307 disposal = 2; 7304 disposal = 2;
7308 7305
7306 /* For disposal == 0, the spec says "No disposal specified. The
7307 decoder is not required to take any action." In practice, it
7308 seems we need to treat this like "keep in place", see e.g.
7309 http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
7310 if (disposal == 0)
7311 disposal = 1;
7312
7309 /* Allocate subimage colors. */ 7313 /* Allocate subimage colors. */
7310 memset (pixel_colors, 0, sizeof pixel_colors); 7314 memset (pixel_colors, 0, sizeof pixel_colors);
7311 gif_color_map = subimage->ImageDesc.ColorMap; 7315 gif_color_map = subimage->ImageDesc.ColorMap;
@@ -7333,34 +7337,34 @@ gif_load (struct frame *f, struct image *img)
7333 int row, pass; 7337 int row, pass;
7334 7338
7335 for (y = 0, row = interlace_start[0], pass = 0; 7339 for (y = 0, row = interlace_start[0], pass = 0;
7336 y < image_height; 7340 y < subimg_height;
7337 y++, row += interlace_increment[pass]) 7341 y++, row += interlace_increment[pass])
7338 { 7342 {
7339 if (row >= image_height) 7343 if (row >= subimg_height)
7340 { 7344 {
7341 row = interlace_start[++pass]; 7345 row = interlace_start[++pass];
7342 while (row >= image_height) 7346 while (row >= subimg_height)
7343 row = interlace_start[++pass]; 7347 row = interlace_start[++pass];
7344 } 7348 }
7345 7349
7346 for (x = 0; x < image_width; x++) 7350 for (x = 0; x < subimg_width; x++)
7347 { 7351 {
7348 int c = raster[y * image_width + x]; 7352 int c = raster[y * subimg_width + x];
7349 if (transparency_color_index != c || disposal != 1) 7353 if (transparency_color_index != c || disposal != 1)
7350 XPutPixel (ximg, x + img->corners[LEFT_CORNER], 7354 XPutPixel (ximg, x + subimg_left, row + subimg_top,
7351 row + img->corners[TOP_CORNER], pixel_colors[c]); 7355 pixel_colors[c]);
7352 } 7356 }
7353 } 7357 }
7354 } 7358 }
7355 else 7359 else
7356 { 7360 {
7357 for (y = 0; y < image_height; ++y) 7361 for (y = 0; y < subimg_height; ++y)
7358 for (x = 0; x < image_width; ++x) 7362 for (x = 0; x < subimg_width; ++x)
7359 { 7363 {
7360 int c = raster[y * image_width + x]; 7364 int c = raster[y * subimg_width + x];
7361 if (transparency_color_index != c || disposal != 1) 7365 if (transparency_color_index != c || disposal != 1)
7362 XPutPixel (ximg, x + img->corners[LEFT_CORNER], 7366 XPutPixel (ximg, x + subimg_left, y + subimg_top,
7363 y + img->corners[TOP_CORNER], pixel_colors[c]); 7367 pixel_colors[c]);
7364 } 7368 }
7365 } 7369 }
7366 } 7370 }