changeset 111393:230a50b33a46

Support for gif transparency. * image.c (gif_load): Add support for transparency and specified :background.
author Chong Yidong <cyd@stupidchicken.com>
date Wed, 03 Nov 2010 16:08:48 -0400
parents a2ba77c845e9
children 72d2a83a2641
files src/ChangeLog src/image.c
diffstat 2 files changed, 37 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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  <julien@danjou.info>
+
+	* image.c (gif_load): Add support for transparency and specified
+	:background.
+
 2010-11-01  Kenichi Handa  <handa@m17n.org>
 
 	* dispextern.h (lookup_glyphless_char_display): Extern it.
--- 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