# HG changeset patch # User Chong Yidong # Date 1288814928 14400 # Node ID 230a50b33a46a95ab4a4a989b414f5d36951a918 # Parent a2ba77c845e92c2a00c30b3faebca7c0ba726b92 Support for gif transparency. * image.c (gif_load): Add support for transparency and specified :background. diff -r a2ba77c845e9 -r 230a50b33a46 src/ChangeLog --- a/src/ChangeLog Wed Nov 03 15:53:47 2010 -0400 +++ b/src/ChangeLog Wed Nov 03 16:08:48 2010 -0400 @@ -1,3 +1,8 @@ +2010-11-03 Julien Danjou + + * image.c (gif_load): Add support for transparency and specified + :background. + 2010-11-01 Kenichi Handa * dispextern.h (lookup_glyphless_char_display): Extern it. diff -r a2ba77c845e9 -r 230a50b33a46 src/image.c --- a/src/image.c Wed Nov 03 15:53:47 2010 -0400 +++ b/src/image.c Wed Nov 03 16:08:48 2010 -0400 @@ -7096,12 +7096,15 @@ static const int interlace_start[] = {0, 4, 2, 1}; static const int interlace_increment[] = {8, 8, 4, 2}; +#define GIF_LOCAL_DESCRIPTOR_EXTENSION 249 + static int gif_load (struct frame *f, struct image *img) { Lisp_Object file, specified_file; Lisp_Object specified_data; int rc, width, height, x, y, i; + boolean transparent_p; XImagePtr ximg; ColorMapObject *gif_color_map; unsigned long pixel_colors[256]; @@ -7110,6 +7113,7 @@ int ino, image_height, image_width; gif_memory_source memsrc; unsigned char *raster; + unsigned int transparency_color_index; specified_file = image_spec_value (img->spec, QCfile, NULL); specified_data = image_spec_value (img->spec, QCdata, NULL); @@ -7182,6 +7186,18 @@ return 0; } + for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++) + if ((gif->SavedImages[ino].ExtensionBlocks[i].Function + == GIF_LOCAL_DESCRIPTOR_EXTENSION) + && gif->SavedImages[ino].ExtensionBlocks[i].ByteCount == 4 + /* Transparency enabled? */ + && gif->SavedImages[ino].ExtensionBlocks[i].Bytes[0] & 1) + { + transparent_p = 1; + transparency_color_index + = (unsigned char) gif->SavedImages[ino].ExtensionBlocks[i].Bytes[3]; + } + img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top; img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left; image_height = gif->SavedImages[ino].ImageDesc.Height; @@ -7220,10 +7236,22 @@ if (gif_color_map) for (i = 0; i < gif_color_map->ColorCount; ++i) { - int r = gif_color_map->Colors[i].Red << 8; - int g = gif_color_map->Colors[i].Green << 8; - int b = gif_color_map->Colors[i].Blue << 8; - pixel_colors[i] = lookup_rgb_color (f, r, g, b); + if (transparent_p && transparency_color_index == i) + { + Lisp_Object specified_bg + = image_spec_value (img->spec, QCbackground, NULL); + pixel_colors[i] = STRINGP (specified_bg) + ? x_alloc_image_color (f, img, specified_bg, + FRAME_BACKGROUND_PIXEL (f)) + : FRAME_BACKGROUND_PIXEL (f); + } + else + { + int r = gif_color_map->Colors[i].Red << 8; + int g = gif_color_map->Colors[i].Green << 8; + int b = gif_color_map->Colors[i].Blue << 8; + pixel_colors[i] = lookup_rgb_color (f, r, g, b); + } } #ifdef COLOR_TABLE_SUPPORT