This commit was generated by cvs2svn to compensate for changes in r5670,
[chise/xemacs-chise.git.1] / src / glyphs-eimage.c
index 7e58f9c..c4daa12 100644 (file)
@@ -49,14 +49,15 @@ Boston, MA 02111-1307, USA.  */
 #include "lstream.h"
 #include "console.h"
 #include "device.h"
-#include "faces.h"
 #include "glyphs.h"
 #include "objects.h"
 
 #include "buffer.h"
 #include "frame.h"
+#include "insdel.h"
 #include "opaque.h"
 
+#include "imgproc.h"
 #include "sysfile.h"
 
 #ifdef HAVE_PNG
@@ -74,6 +75,16 @@ extern "C" {
 #include "file-coding.h"
 #endif
 
+#if INTBITS == 32
+# define FOUR_BYTE_TYPE unsigned int
+#elif LONGBITS == 32
+# define FOUR_BYTE_TYPE unsigned long
+#elif SHORTBITS == 32
+# define FOUR_BYTE_TYPE unsigned short
+#else
+#error What kind of strange-ass system are we running on?
+#endif
+
 #ifdef HAVE_TIFF
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
 Lisp_Object Qtiff;
@@ -407,7 +418,7 @@ jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
       {
        /* we're relying on the jpeg driver to do any other conversions,
           or signal an error if the conversion isn't supported. */
-       cinfo.out_color_space = JCS_RGB;
+       cinfo.out_color_space = JCS_RGB;        
       }
 
     /* Step 5: Start decompressor */
@@ -453,7 +464,7 @@ jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
          for (i = 0; i < cinfo.output_width; i++)
            {
              int clr;
-             if (jpeg_gray)
+             if (jpeg_gray) 
                {
                  unsigned char val;
 #if (BITS_IN_JSAMPLE == 8)
@@ -480,10 +491,10 @@ jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 
   /* Step 6.5: Create the pixmap and set up the image instance */
   /* now instantiate */
-  MAYBE_DEVMETH (XDEVICE (ii->device),
+  MAYBE_DEVMETH (XDEVICE (ii->device), 
                 init_image_instance_from_eimage,
-                (ii, cinfo.output_width, cinfo.output_height,
-                 unwind.eimage, dest_mask,
+                (ii, cinfo.output_width, cinfo.output_height, 
+                 unwind.eimage, dest_mask, 
                  instantiator, domain));
 
   /* Step 7: Finish decompression */
@@ -505,7 +516,7 @@ jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
  *                               GIF                                  *
  **********************************************************************/
 
-#include "gifrlib.h"
+#include <gifrlib.h>
 
 static void
 gif_validate (Lisp_Object instantiator)
@@ -564,9 +575,9 @@ static size_t
 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
 {
   gif_memory_storage *mem = (gif_memory_storage*)data;
-
+  
   if (size > (mem->len - mem->index))
-    return (size_t) -1;
+    return -1;
   memcpy(buf, mem->bytes + mem->index, size);
   mem->index = mem->index + size;
   return size;
@@ -611,20 +622,20 @@ gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
   Extcount len;
   int height = 0;
   int width = 0;
-
+  
   xzero (unwind);
   record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
-
+  
   /* 1. Now decode the data. */
-
+  
   {
     Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
-
+    
     assert (!NILP (data));
-
+    
     if (!(unwind.giffile = GifSetup()))
       signal_image_error ("Insufficent memory to instantiate GIF image", instantiator);
-
+    
     /* set up error facilities */
     if (setjmp(gif_err.setjmp_buffer))
       {
@@ -635,7 +646,7 @@ gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
        signal_image_error_2 ("GIF decoding error", errstring, instantiator);
       }
     GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
-
+    
     GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
     mem_struct.bytes = bytes;
     mem_struct.len = len;
@@ -643,14 +654,14 @@ gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
     GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
     GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
     DGifInitRead(unwind.giffile);
-
+    
     /* Then slurp the image into memory, decoding along the way.
        The result is the image in a simple one-byte-per-pixel
        format (#### the GIF routines only support 8-bit GIFs,
        it appears). */
     DGifSlurp (unwind.giffile);
   }
-
+  
   /* 3. Now create the EImage */
   {
     ColorMapObject *cmo = unwind.giffile->SColorMap;
@@ -660,15 +671,15 @@ gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
        0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ...  */
     static int InterlacedOffset[] = { 0, 4, 2, 1 };
     static int InterlacedJumps[] = { 8, 8, 4, 2 };
-
+    
     height = unwind.giffile->SHeight;
     width = unwind.giffile->SWidth;
     unwind.eimage = (unsigned char*) xmalloc (width * height * 3);
     if (!unwind.eimage)
       signal_image_error("Unable to allocate enough memory for image", instantiator);
-
+    
     /* write the data in EImage format (8bit RGB triples) */
-
+    
     /* Note: We just use the first image in the file and ignore the rest.
        We check here that that image covers the full "screen" size.
        I don't know whether that's always the case.
@@ -679,19 +690,15 @@ gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
        || unwind.giffile->SavedImages[0].ImageDesc.Top != 0)
       signal_image_error ("First image in GIF file is not full size",
                          instantiator);
-
+    
     interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace;
     pass = 0;
     row = interlace ? InterlacedOffset[pass] : 0;
     eip = unwind.eimage;
     for (i = 0; i < height; i++)
       {
-       if (interlace)
-         if (row >= height) {
-           row = InterlacedOffset[++pass];
-           while (row > height)
-             row = InterlacedOffset[++pass];
-         }
+       if (interlace && row >= height)
+         row = InterlacedOffset[++pass];
        eip = unwind.eimage + (row * width * 3);
        for (j = 0; j < width; j++)
          {
@@ -704,11 +711,11 @@ gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
       }
   }
   /* now instantiate */
-  MAYBE_DEVMETH (XDEVICE (ii->device),
+  MAYBE_DEVMETH (XDEVICE (ii->device), 
                 init_image_instance_from_eimage,
-                (ii, width, height, unwind.eimage, dest_mask,
+                (ii, width, height, unwind.eimage, dest_mask, 
                  instantiator, domain));
-
+  
   unbind_to (speccount, Qnil);
 }
 
@@ -766,7 +773,7 @@ struct png_error_struct
 
 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
    structure, and there are cases where the size can be different from
-   between inside the library, and inside the code!  To do an end run
+   between inside the libarary, and inside the code!  To do an end run
    around this, use our own error functions, and don't rely on things
    passed in the png_ptr to them.  This is an ugly hack and must
    go away when the lisp engine is threaded! */
@@ -805,8 +812,6 @@ png_instantiate_unwind (Lisp_Object unwind_obj)
   if (data->instream)
     fclose (data->instream);
 
-  if (data->eimage) xfree(data->eimage);
-
   return Qnil;
 }
 
@@ -836,7 +841,7 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
       png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
       signal_image_error ("Error obtaining memory for png_read", instantiator);
     }
-
+  
   xzero (unwind);
   unwind.png_ptr = png_ptr;
   unwind.info_ptr = info_ptr;
@@ -851,7 +856,7 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
      and is no longer usable for previous versions. jh
   */
 
-  /* Set the jmp_buf return context for png_error ... if this returns !0, then
+  /* Set the jmp_buf reurn context for png_error ... if this returns !0, then
      we ran into a problem somewhere, and need to clean up after ourselves. */
   if (setjmp (png_err_stct.setjmp_buffer))
     {
@@ -891,51 +896,15 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
     /* libpng expects that the image buffer passed in contains a
        picture to draw on top of if the png has any transparencies.
        This could be a good place to pass that in... */
-
+    
     row_pointers  = xnew_array (png_byte *, height);
 
     for (y = 0; y < height; y++)
       row_pointers[y] = unwind.eimage + (width * 3 * y);
 
-    {
-      /* if the png specifies a background chunk, go ahead and
-        use it, else use what we can get from the default face. */
-      png_color_16 my_background, *image_background;
-      Lisp_Object bkgd = Qnil;
-
-      my_background.red   = 0x7fff;
-      my_background.green = 0x7fff;
-      my_background.blue  = 0x7fff;
-      bkgd = FACE_BACKGROUND (Vdefault_face, domain);
-      if (!COLOR_INSTANCEP (bkgd))
-       {
-         warn_when_safe (Qpng, Qinfo, "Couldn't get background color!");
-       }
-      else
-       {
-         struct Lisp_Color_Instance *c;
-         Lisp_Object rgblist;
-
-         c = XCOLOR_INSTANCE (bkgd);
-         rgblist = MAYBE_LISP_DEVMETH (XDEVICE (c->device),
-                                       color_instance_rgb_components,
-                                       (c));
-         my_background.red = XINT (XCAR (rgblist));
-         my_background.green = XINT (XCAR (XCDR (rgblist)));
-         my_background.blue = XINT (XCAR (XCDR (XCDR (rgblist))));
-       }
-
-      if (png_get_bKGD (png_ptr, info_ptr, &image_background))
-       png_set_background (png_ptr, image_background,
-                           PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
-      else
-       png_set_background (png_ptr, &my_background,
-                           PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
-    }
-
     /* Now that we're using EImage, ask for 8bit RGB triples for any type
        of image*/
-    /* convert palette images to full RGB */
+    /* convert palatte images to full RGB */
     if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
       png_set_expand (png_ptr);
     /* send grayscale images to RGB too */
@@ -945,6 +914,12 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
     /* we can't handle alpha values */
     if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
       png_set_strip_alpha (png_ptr);
+    /* rip out any transparancy layers/colors */
+    if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
+      {
+        png_set_expand (png_ptr);
+       png_set_strip_alpha (png_ptr);
+      }
     /* tell libpng to strip 16 bit depth files down to 8 bits */
     if (info_ptr->bit_depth == 16)
       png_set_strip_16 (png_ptr);
@@ -957,9 +932,28 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
          png_set_packing (png_ptr);
       }
 
+#if 1 /* tests? or permanent? */
+    {
+      /* if the png specifies a background chunk, go ahead and
+        use it */
+      png_color_16 my_background, *image_background;
+    
+      /* ### how do I get the background of the current frame? */
+      my_background.red   = 0x7fff;
+      my_background.green = 0x7fff;
+      my_background.blue  = 0x7fff;
+
+      if (png_get_bKGD (png_ptr, info_ptr, &image_background))
+       png_set_background (png_ptr, image_background,
+                           PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+      else 
+       png_set_background (png_ptr, &my_background,
+                           PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+    }
+#endif
     png_read_image (png_ptr, row_pointers);
     png_read_end (png_ptr, info_ptr);
-
+    
 #ifdef PNG_SHOW_COMMENTS
     /* ####
      * I turn this off by default now, because the !%^@#!% comments
@@ -988,9 +982,9 @@ png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
   }
 
   /* now instantiate */
-  MAYBE_DEVMETH (XDEVICE (ii->device),
+  MAYBE_DEVMETH (XDEVICE (ii->device), 
                 init_image_instance_from_eimage,
-                (ii, width, height, unwind.eimage, dest_mask,
+                (ii, width, height, unwind.eimage, dest_mask, 
                  instantiator, domain));
 
   /* This will clean up everything else. */
@@ -1094,7 +1088,7 @@ static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
 
   if ((newidx > mem->len) || (newidx < 0))
     return -1;
-
+  
   mem->index = newidx;
   return newidx;
 }
@@ -1194,7 +1188,7 @@ tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
 
   xzero (unwind);
   record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
-
+  
   /* set up error facilities */
   if (setjmp (tiff_err_data.setjmp_buffer))
     {
@@ -1236,7 +1230,7 @@ tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
     unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
 
     /* ### This is little more than proof-of-concept/function testing.
-       It needs to be reimplemented via scanline reads for both memory
+       It needs to be reimplimented via scanline reads for both memory
        compactness. */
     raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
     if (raster != NULL)
@@ -1268,9 +1262,9 @@ tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
   }
 
   /* now instantiate */
-  MAYBE_DEVMETH (XDEVICE (ii->device),
+  MAYBE_DEVMETH (XDEVICE (ii->device), 
                 init_image_instance_from_eimage,
-                (ii, width, height, unwind.eimage, dest_mask,
+                (ii, width, height, unwind.eimage, dest_mask, 
                  instantiator, domain));
 
   unbind_to (speccount, Qnil);