diff options
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/src/image.c b/src/image.c index 4cdd7f2bbab..e16b63ae0f4 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1049,10 +1049,6 @@ free_image (struct frame *f, struct image *img) | |||
| 1049 | /* Free resources, then free IMG. */ | 1049 | /* Free resources, then free IMG. */ |
| 1050 | img->type->free (f, img); | 1050 | img->type->free (f, img); |
| 1051 | xfree (img); | 1051 | xfree (img); |
| 1052 | |||
| 1053 | /* As display glyphs may still be referring to the image ID, we | ||
| 1054 | must garbage the frame (Bug#6426). */ | ||
| 1055 | SET_FRAME_GARBAGED (f); | ||
| 1056 | } | 1052 | } |
| 1057 | } | 1053 | } |
| 1058 | 1054 | ||
| @@ -1471,7 +1467,12 @@ uncache_image (struct frame *f, Lisp_Object spec) | |||
| 1471 | { | 1467 | { |
| 1472 | struct image *img = search_image_cache (f, spec, sxhash (spec, 0)); | 1468 | struct image *img = search_image_cache (f, spec, sxhash (spec, 0)); |
| 1473 | if (img) | 1469 | if (img) |
| 1474 | free_image (f, img); | 1470 | { |
| 1471 | free_image (f, img); | ||
| 1472 | /* As display glyphs may still be referring to the image ID, we | ||
| 1473 | must garbage the frame (Bug#6426). */ | ||
| 1474 | SET_FRAME_GARBAGED (f); | ||
| 1475 | } | ||
| 1475 | } | 1476 | } |
| 1476 | 1477 | ||
| 1477 | 1478 | ||
| @@ -7096,12 +7097,15 @@ gif_read_from_memory (GifFileType *file, GifByteType *buf, int len) | |||
| 7096 | static const int interlace_start[] = {0, 4, 2, 1}; | 7097 | static const int interlace_start[] = {0, 4, 2, 1}; |
| 7097 | static const int interlace_increment[] = {8, 8, 4, 2}; | 7098 | static const int interlace_increment[] = {8, 8, 4, 2}; |
| 7098 | 7099 | ||
| 7100 | #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249 | ||
| 7101 | |||
| 7099 | static int | 7102 | static int |
| 7100 | gif_load (struct frame *f, struct image *img) | 7103 | gif_load (struct frame *f, struct image *img) |
| 7101 | { | 7104 | { |
| 7102 | Lisp_Object file, specified_file; | 7105 | Lisp_Object file, specified_file; |
| 7103 | Lisp_Object specified_data; | 7106 | Lisp_Object specified_data; |
| 7104 | int rc, width, height, x, y, i; | 7107 | int rc, width, height, x, y, i; |
| 7108 | boolean transparent_p; | ||
| 7105 | XImagePtr ximg; | 7109 | XImagePtr ximg; |
| 7106 | ColorMapObject *gif_color_map; | 7110 | ColorMapObject *gif_color_map; |
| 7107 | unsigned long pixel_colors[256]; | 7111 | unsigned long pixel_colors[256]; |
| @@ -7110,6 +7114,7 @@ gif_load (struct frame *f, struct image *img) | |||
| 7110 | int ino, image_height, image_width; | 7114 | int ino, image_height, image_width; |
| 7111 | gif_memory_source memsrc; | 7115 | gif_memory_source memsrc; |
| 7112 | unsigned char *raster; | 7116 | unsigned char *raster; |
| 7117 | unsigned int transparency_color_index; | ||
| 7113 | 7118 | ||
| 7114 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 7119 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 7115 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 7120 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| @@ -7182,6 +7187,18 @@ gif_load (struct frame *f, struct image *img) | |||
| 7182 | return 0; | 7187 | return 0; |
| 7183 | } | 7188 | } |
| 7184 | 7189 | ||
| 7190 | for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++) | ||
| 7191 | if ((gif->SavedImages[ino].ExtensionBlocks[i].Function | ||
| 7192 | == GIF_LOCAL_DESCRIPTOR_EXTENSION) | ||
| 7193 | && gif->SavedImages[ino].ExtensionBlocks[i].ByteCount == 4 | ||
| 7194 | /* Transparency enabled? */ | ||
| 7195 | && gif->SavedImages[ino].ExtensionBlocks[i].Bytes[0] & 1) | ||
| 7196 | { | ||
| 7197 | transparent_p = 1; | ||
| 7198 | transparency_color_index | ||
| 7199 | = (unsigned char) gif->SavedImages[ino].ExtensionBlocks[i].Bytes[3]; | ||
| 7200 | } | ||
| 7201 | |||
| 7185 | img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top; | 7202 | img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top; |
| 7186 | img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left; | 7203 | img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left; |
| 7187 | image_height = gif->SavedImages[ino].ImageDesc.Height; | 7204 | image_height = gif->SavedImages[ino].ImageDesc.Height; |
| @@ -7220,10 +7237,22 @@ gif_load (struct frame *f, struct image *img) | |||
| 7220 | if (gif_color_map) | 7237 | if (gif_color_map) |
| 7221 | for (i = 0; i < gif_color_map->ColorCount; ++i) | 7238 | for (i = 0; i < gif_color_map->ColorCount; ++i) |
| 7222 | { | 7239 | { |
| 7223 | int r = gif_color_map->Colors[i].Red << 8; | 7240 | if (transparent_p && transparency_color_index == i) |
| 7224 | int g = gif_color_map->Colors[i].Green << 8; | 7241 | { |
| 7225 | int b = gif_color_map->Colors[i].Blue << 8; | 7242 | Lisp_Object specified_bg |
| 7226 | pixel_colors[i] = lookup_rgb_color (f, r, g, b); | 7243 | = image_spec_value (img->spec, QCbackground, NULL); |
| 7244 | pixel_colors[i] = STRINGP (specified_bg) | ||
| 7245 | ? x_alloc_image_color (f, img, specified_bg, | ||
| 7246 | FRAME_BACKGROUND_PIXEL (f)) | ||
| 7247 | : FRAME_BACKGROUND_PIXEL (f); | ||
| 7248 | } | ||
| 7249 | else | ||
| 7250 | { | ||
| 7251 | int r = gif_color_map->Colors[i].Red << 8; | ||
| 7252 | int g = gif_color_map->Colors[i].Green << 8; | ||
| 7253 | int b = gif_color_map->Colors[i].Blue << 8; | ||
| 7254 | pixel_colors[i] = lookup_rgb_color (f, r, g, b); | ||
| 7255 | } | ||
| 7227 | } | 7256 | } |
| 7228 | 7257 | ||
| 7229 | #ifdef COLOR_TABLE_SUPPORT | 7258 | #ifdef COLOR_TABLE_SUPPORT |