This commit was generated by cvs2svn to compensate for changes in r31, which
[chise/xemacs-chise.git.1] / src / glyphs-eimage.c
1 /* EImage-specific Lisp objects.
2    Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc.
3    Copyright (C) 1995 Board of Trustees, University of Illinois.
4    Copyright (C) 1995 Tinker Systems
5    Copyright (C) 1995, 1996 Ben Wing
6    Copyright (C) 1995 Sun Microsystems
7
8 This file is part of XEmacs.
9
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
13 later version.
14
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING.  If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.  */
24
25 /* Synched up with: Not in FSF. */
26
27 /* Original author: Jamie Zawinski for 19.8
28    font-truename stuff added by Jamie Zawinski for 19.10
29    subwindow support added by Chuck Thompson
30    additional XPM support added by Chuck Thompson
31    initial X-Face support added by Stig
32    rewritten/restructured by Ben Wing for 19.12/19.13
33    GIF/JPEG support added by Ben Wing for 19.14
34    PNG support added by Bill Perry for 19.14
35    Improved GIF/JPEG support added by Bill Perry for 19.14
36    Cleanup/simplification of error handling by Ben Wing for 19.14
37    Pointer/icon overhaul, more restructuring by Ben Wing for 19.14
38    GIF support changed to external Gifreader lib by Jareth Hein for 21.0
39    Many changes for color work and optimizations by Jareth Hein for 21.0
40    Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
41    TIFF code by Jareth Hein for 21.0
42    Generalization for ms-windows by Andy Piper for 21.0
43    TODO:
44    Convert images.el to C and stick it in here?
45  */
46
47 #include <config.h>
48 #include "lisp.h"
49 #include "lstream.h"
50 #include "console.h"
51 #include "device.h"
52 #include "glyphs.h"
53 #include "objects.h"
54
55 #include "buffer.h"
56 #include "frame.h"
57 #include "insdel.h"
58 #include "opaque.h"
59
60 #include "imgproc.h"
61 #include "sysfile.h"
62
63 #ifdef HAVE_PNG
64 #ifdef __cplusplus
65 extern "C" {
66 #endif
67 #include <png.h>
68 #ifdef __cplusplus
69 }
70 #endif
71 #else
72 #include <setjmp.h>
73 #endif
74 #ifdef FILE_CODING
75 #include "file-coding.h"
76 #endif
77
78 #if INTBITS == 32
79 # define FOUR_BYTE_TYPE unsigned int
80 #elif LONGBITS == 32
81 # define FOUR_BYTE_TYPE unsigned long
82 #elif SHORTBITS == 32
83 # define FOUR_BYTE_TYPE unsigned short
84 #else
85 #error What kind of strange-ass system are we running on?
86 #endif
87
88 #ifdef HAVE_TIFF
89 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
90 Lisp_Object Qtiff;
91 #endif
92
93 #ifdef HAVE_JPEG
94 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
95 Lisp_Object Qjpeg;
96 #endif
97
98 #ifdef HAVE_GIF
99 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif);
100 Lisp_Object Qgif;
101 #endif
102
103 #ifdef HAVE_PNG
104 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png);
105 Lisp_Object Qpng;
106 #endif
107
108 \f
109 #ifdef HAVE_JPEG
110
111 /**********************************************************************
112  *                             JPEG                                   *
113  **********************************************************************/
114
115 #ifdef __cplusplus
116 extern "C" {
117 #endif
118 #include <jpeglib.h>
119 #include <jerror.h>
120 #ifdef __cplusplus
121 }
122 #endif
123
124 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/
125 static void
126 jpeg_validate (Lisp_Object instantiator)
127 {
128   file_or_data_must_be_present (instantiator);
129 }
130
131 static Lisp_Object
132 jpeg_normalize (Lisp_Object inst, Lisp_Object console_type)
133 {
134   return simple_image_type_normalize (inst, console_type, Qjpeg);
135 }
136
137 static int
138 jpeg_possible_dest_types (void)
139 {
140   return IMAGE_COLOR_PIXMAP_MASK;
141 }
142
143 /* To survive the otherwise baffling complexity of making sure
144    everything gets cleaned up in the presence of an error, we
145    use an unwind_protect(). */
146
147 struct jpeg_unwind_data
148 {
149   /* Stream that we need to close */
150   FILE *instream;
151   /* Object that holds state info for JPEG decoding */
152   struct jpeg_decompress_struct *cinfo_ptr;
153   /* EImage data */
154   unsigned char *eimage;
155 };
156
157 static Lisp_Object
158 jpeg_instantiate_unwind (Lisp_Object unwind_obj)
159 {
160   struct jpeg_unwind_data *data =
161     (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj);
162
163   free_opaque_ptr (unwind_obj);
164   if (data->cinfo_ptr)
165     jpeg_destroy_decompress (data->cinfo_ptr);
166
167   if (data->instream)
168     fclose (data->instream);
169
170   if (data->eimage) xfree (data->eimage);
171
172   return Qnil;
173 }
174
175 /*
176  * ERROR HANDLING:
177  *
178  * The JPEG library's standard error handler (jerror.c) is divided into
179  * several "methods" which you can override individually.  This lets you
180  * adjust the behavior without duplicating a lot of code, which you might
181  * have to update with each future release.
182  *
183  * Our example here shows how to override the "error_exit" method so that
184  * control is returned to the library's caller when a fatal error occurs,
185  * rather than calling exit() as the standard error_exit method does.
186  *
187  * We use C's setjmp/longjmp facility to return control.  This means that the
188  * routine which calls the JPEG library must first execute a setjmp() call to
189  * establish the return point.  We want the replacement error_exit to do a
190  * longjmp().  But we need to make the setjmp buffer accessible to the
191  * error_exit routine.  To do this, we make a private extension of the
192  * standard JPEG error handler object.  (If we were using C++, we'd say we
193  * were making a subclass of the regular error handler.)
194  *
195  * Here's the extended error handler struct:
196  */
197
198 struct my_jpeg_error_mgr
199 {
200   struct jpeg_error_mgr pub;    /* "public" fields */
201   jmp_buf setjmp_buffer;        /* for return to caller */
202 };
203
204 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
205 METHODDEF(void)
206 #else
207 METHODDEF void
208 #endif
209 our_init_source (j_decompress_ptr cinfo)
210 {
211 }
212
213 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
214 METHODDEF(boolean)
215 #else
216 METHODDEF boolean
217 #endif
218 our_fill_input_buffer (j_decompress_ptr cinfo)
219 {
220   /* Insert a fake EOI marker */
221   struct jpeg_source_mgr *src = cinfo->src;
222   static JOCTET buffer[2];
223
224   buffer[0] = (JOCTET) 0xFF;
225   buffer[1] = (JOCTET) JPEG_EOI;
226
227   src->next_input_byte = buffer;
228   src->bytes_in_buffer = 2;
229   return TRUE;
230 }
231
232 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
233 METHODDEF(void)
234 #else
235 METHODDEF void
236 #endif
237 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
238 {
239   struct jpeg_source_mgr *src = NULL;
240
241   src = (struct jpeg_source_mgr *) cinfo->src;
242
243   if (!src)
244     {
245       return;
246     } else if (num_bytes > src->bytes_in_buffer)
247       {
248         ERREXIT(cinfo, JERR_INPUT_EOF);
249         /*NOTREACHED*/
250       }
251
252   src->bytes_in_buffer -= num_bytes;
253   src->next_input_byte += num_bytes;
254 }
255
256 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
257 METHODDEF(void)
258 #else
259 METHODDEF void
260 #endif
261 our_term_source (j_decompress_ptr cinfo)
262 {
263 }
264
265 typedef struct
266 {
267   struct jpeg_source_mgr pub;
268 } our_jpeg_source_mgr;
269
270 static void
271 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
272 {
273   struct jpeg_source_mgr *src;
274
275   if (cinfo->src == NULL)
276     {   /* first time for this JPEG object? */
277       cinfo->src = (struct jpeg_source_mgr *)
278         (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
279                                     sizeof(our_jpeg_source_mgr));
280       src = (struct jpeg_source_mgr *) cinfo->src;
281       src->next_input_byte = data;
282     }
283   src = (struct jpeg_source_mgr *) cinfo->src;
284   src->init_source = our_init_source;
285   src->fill_input_buffer = our_fill_input_buffer;
286   src->skip_input_data = our_skip_input_data;
287   src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
288   src->term_source = our_term_source;
289   src->bytes_in_buffer = len;
290   src->next_input_byte = data;
291 }
292
293 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
294 METHODDEF(void)
295 #else
296 METHODDEF void
297 #endif
298 my_jpeg_error_exit (j_common_ptr cinfo)
299 {
300   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
301   struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err;
302
303   /* Return control to the setjmp point */
304   longjmp (myerr->setjmp_buffer, 1);
305 }
306
307 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
308 METHODDEF(void)
309 #else
310 METHODDEF void
311 #endif
312 my_jpeg_output_message (j_common_ptr cinfo)
313 {
314   char buffer[JMSG_LENGTH_MAX];
315
316   /* Create the message */
317   (*cinfo->err->format_message) (cinfo, buffer);
318   warn_when_safe (Qjpeg, Qinfo, "%s", buffer);
319 }
320
321 /* The code in this routine is based on example.c from the JPEG library
322    source code and from gif_instantiate() */
323 static void
324 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
325                   Lisp_Object pointer_fg, Lisp_Object pointer_bg,
326                   int dest_mask, Lisp_Object domain)
327 {
328   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
329   /* It is OK for the unwind data to be local to this function,
330      because the unwind-protect is always executed when this
331      stack frame is still valid. */
332   struct jpeg_unwind_data unwind;
333   int speccount = specpdl_depth ();
334
335   /* This struct contains the JPEG decompression parameters and pointers to
336    * working space (which is allocated as needed by the JPEG library).
337    */
338   struct jpeg_decompress_struct cinfo;
339   /* We use our private extension JPEG error handler.
340    * Note that this struct must live as long as the main JPEG parameter
341    * struct, to avoid dangling-pointer problems.
342    */
343   struct my_jpeg_error_mgr jerr;
344
345   /* Step -1: First record our unwind-protect, which will clean up after
346      any exit, normal or not */
347
348   xzero (unwind);
349   record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind));
350
351   /* Step 1: allocate and initialize JPEG decompression object */
352
353   /* We set up the normal JPEG error routines, then override error_exit. */
354   cinfo.err = jpeg_std_error (&jerr.pub);
355   jerr.pub.error_exit = my_jpeg_error_exit;
356   jerr.pub.output_message = my_jpeg_output_message;
357
358   /* Establish the setjmp return context for my_error_exit to use. */
359   if (setjmp (jerr.setjmp_buffer))
360     {
361       /* If we get here, the JPEG code has signaled an error.
362        * We need to clean up the JPEG object, close the input file, and return.
363        */
364
365       {
366         Lisp_Object errstring;
367         char buffer[JMSG_LENGTH_MAX];
368
369         /* Create the message */
370         (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer);
371         errstring = build_string (buffer);
372
373         signal_image_error_2 ("JPEG decoding error",
374                               errstring, instantiator);
375       }
376     }
377
378   /* Now we can initialize the JPEG decompression object. */
379   jpeg_create_decompress (&cinfo);
380   unwind.cinfo_ptr = &cinfo;
381
382   /* Step 2: specify data source (eg, a file) */
383
384   {
385     Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
386     CONST Extbyte *bytes;
387     Extcount len;
388
389     /* #### This is a definite problem under Mule due to the amount of
390        stack data it might allocate.  Need to be able to convert and
391        write out to a file. */
392     GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
393     jpeg_memory_src (&cinfo, (JOCTET *) bytes, len);
394   }
395
396   /* Step 3: read file parameters with jpeg_read_header() */
397
398   jpeg_read_header (&cinfo, TRUE);
399   /* We can ignore the return value from jpeg_read_header since
400    *   (a) suspension is not possible with the stdio data source, and
401    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
402    * See libjpeg.doc for more info.
403    */
404
405   {
406     int jpeg_gray = 0;          /* if we're dealing with a grayscale */
407     /* Step 4: set parameters for decompression.   */
408
409     /* Now that we're using EImages, send all data as 24bit color.
410        The backend routine will take care of any necessary reductions.
411        We do have to handle the grayscale case ourselves, however. */
412     if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
413       {
414         cinfo.out_color_space = JCS_GRAYSCALE;
415         jpeg_gray = 1;
416       }
417     else
418       {
419         /* we're relying on the jpeg driver to do any other conversions,
420            or signal an error if the conversion isn't supported. */
421         cinfo.out_color_space = JCS_RGB;        
422       }
423
424     /* Step 5: Start decompressor */
425     jpeg_start_decompress (&cinfo);
426
427     /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
428
429     unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3);
430     if (!unwind.eimage)
431       signal_image_error("Unable to allocate enough memory for image", instantiator);
432
433     {
434       JSAMPARRAY row_buffer;    /* Output row buffer */
435       JSAMPLE *jp;
436       int row_stride;           /* physical row width in output buffer */
437       unsigned char *op = unwind.eimage;
438
439       /* We may need to do some setup of our own at this point before reading
440        * the data.  After jpeg_start_decompress() we have the correct scaled
441        * output image dimensions available
442        * We need to make an output work buffer of the right size.
443        */
444       /* JSAMPLEs per row in output buffer. */
445       row_stride = cinfo.output_width * cinfo.output_components;
446       /* Make a one-row-high sample array that will go away when done
447          with image */
448       row_buffer = ((*cinfo.mem->alloc_sarray)
449                     ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1));
450
451       /* Here we use the library's state variable cinfo.output_scanline as the
452        * loop counter, so that we don't have to keep track ourselves.
453        */
454       while (cinfo.output_scanline < cinfo.output_height)
455         {
456           int i;
457
458           /* jpeg_read_scanlines expects an array of pointers to scanlines.
459            * Here the array is only one element long, but you could ask for
460            * more than one scanline at a time if that's more convenient.
461            */
462           (void) jpeg_read_scanlines (&cinfo, row_buffer, 1);
463           jp = row_buffer[0];
464           for (i = 0; i < cinfo.output_width; i++)
465             {
466               int clr;
467               if (jpeg_gray) 
468                 {
469                   unsigned char val;
470 #if (BITS_IN_JSAMPLE == 8)
471                   val = (unsigned char)*jp++;
472 #else /* other option is 12 */
473                   val = (unsigned char)(*jp++ >> 4);
474 #endif
475                   for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */
476                       *op++ = val;
477                 }
478               else
479                 {
480                   for (clr = 0; clr < 3; clr++)
481 #if (BITS_IN_JSAMPLE == 8)
482                     *op++ = (unsigned char)*jp++;
483 #else /* other option is 12 */
484                     *op++ = (unsigned char)(*jp++ >> 4);
485 #endif
486                 }
487             }
488         }
489     }
490   }
491
492   /* Step 6.5: Create the pixmap and set up the image instance */
493   /* now instantiate */
494   MAYBE_DEVMETH (XDEVICE (ii->device), 
495                  init_image_instance_from_eimage,
496                  (ii, cinfo.output_width, cinfo.output_height, 
497                   unwind.eimage, dest_mask, 
498                   instantiator, domain));
499
500   /* Step 7: Finish decompression */
501
502   jpeg_finish_decompress (&cinfo);
503   /* We can ignore the return value since suspension is not possible
504    * with the stdio data source.
505    */
506
507   /* And we're done! */
508   /* This will clean up everything else. */
509   unbind_to (speccount, Qnil);
510 }
511
512 #endif /* HAVE_JPEG */
513 \f
514 #ifdef HAVE_GIF
515 /**********************************************************************
516  *                               GIF                                  *
517  **********************************************************************/
518
519 #include <gifrlib.h>
520
521 static void
522 gif_validate (Lisp_Object instantiator)
523 {
524   file_or_data_must_be_present (instantiator);
525 }
526
527 static Lisp_Object
528 gif_normalize (Lisp_Object inst, Lisp_Object console_type)
529 {
530   return simple_image_type_normalize (inst, console_type, Qgif);
531 }
532
533 static int
534 gif_possible_dest_types (void)
535 {
536   return IMAGE_COLOR_PIXMAP_MASK;
537 }
538
539 /* To survive the otherwise baffling complexity of making sure
540    everything gets cleaned up in the presence of an error, we
541    use an unwind_protect(). */
542
543 struct gif_unwind_data
544 {
545   unsigned char *eimage;
546   /* Object that holds the decoded data from a GIF file */
547   GifFileType *giffile;
548 };
549
550 static Lisp_Object
551 gif_instantiate_unwind (Lisp_Object unwind_obj)
552 {
553   struct gif_unwind_data *data =
554     (struct gif_unwind_data *) get_opaque_ptr (unwind_obj);
555
556   free_opaque_ptr (unwind_obj);
557   if (data->giffile)
558     {
559       DGifCloseFile (data->giffile);
560       GifFree(data->giffile);
561     }
562   if (data->eimage) xfree(data->eimage);
563
564   return Qnil;
565 }
566
567 typedef struct gif_memory_storage
568 {
569   Extbyte *bytes;               /* The data       */
570   Extcount len;                 /* How big is it? */
571   int index;                    /* Where are we?  */
572 } gif_memory_storage;
573
574 static size_t
575 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
576 {
577   gif_memory_storage *mem = (gif_memory_storage*)data;
578   
579   if (size > (mem->len - mem->index))
580     return -1;
581   memcpy(buf, mem->bytes + mem->index, size);
582   mem->index = mem->index + size;
583   return size;
584 }
585
586 static int
587 gif_memory_close(VoidPtr data)
588 {
589   return 0;
590 }
591
592 struct gif_error_struct
593 {
594   CONST char *err_str;          /* return the error string */
595   jmp_buf setjmp_buffer;        /* for return to caller */
596 };
597
598 static void
599 gif_error_func(CONST char *err_str, VoidPtr error_ptr)
600 {
601   struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr;
602
603   /* return to setjmp point */
604   error_data->err_str = err_str;
605   longjmp (error_data->setjmp_buffer, 1);
606 }
607
608 static void
609 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
610                  Lisp_Object pointer_fg, Lisp_Object pointer_bg,
611                  int dest_mask, Lisp_Object domain)
612 {
613   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
614   /* It is OK for the unwind data to be local to this function,
615      because the unwind-protect is always executed when this
616      stack frame is still valid. */
617   struct gif_unwind_data unwind;
618   int speccount = specpdl_depth ();
619   gif_memory_storage mem_struct;
620   struct gif_error_struct gif_err;
621   Extbyte *bytes;
622   Extcount len;
623   int height = 0;
624   int width = 0;
625   
626   xzero (unwind);
627   record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
628   
629   /* 1. Now decode the data. */
630   
631   {
632     Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
633     
634     assert (!NILP (data));
635     
636     if (!(unwind.giffile = GifSetup()))
637       signal_image_error ("Insufficent memory to instantiate GIF image", instantiator);
638     
639     /* set up error facilities */
640     if (setjmp(gif_err.setjmp_buffer))
641       {
642         /* An error was signaled. No clean up is needed, as unwind handles that
643            for us.  Just pass the error along. */
644         Lisp_Object errstring;
645         errstring = build_string (gif_err.err_str);
646         signal_image_error_2 ("GIF decoding error", errstring, instantiator);
647       }
648     GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
649     
650     GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
651     mem_struct.bytes = bytes;
652     mem_struct.len = len;
653     mem_struct.index = 0;
654     GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
655     GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
656     DGifInitRead(unwind.giffile);
657     
658     /* Then slurp the image into memory, decoding along the way.
659        The result is the image in a simple one-byte-per-pixel
660        format (#### the GIF routines only support 8-bit GIFs,
661        it appears). */
662     DGifSlurp (unwind.giffile);
663   }
664   
665   /* 3. Now create the EImage */
666   {
667     ColorMapObject *cmo = unwind.giffile->SColorMap;
668     int i, j, row, pass, interlace;
669     unsigned char *eip;
670     /* interlaced gifs have rows in this order:
671        0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ...  */
672     static int InterlacedOffset[] = { 0, 4, 2, 1 };
673     static int InterlacedJumps[] = { 8, 8, 4, 2 };
674     
675     height = unwind.giffile->SHeight;
676     width = unwind.giffile->SWidth;
677     unwind.eimage = (unsigned char*) xmalloc (width * height * 3);
678     if (!unwind.eimage)
679       signal_image_error("Unable to allocate enough memory for image", instantiator);
680     
681     /* write the data in EImage format (8bit RGB triples) */
682     
683     /* Note: We just use the first image in the file and ignore the rest.
684        We check here that that image covers the full "screen" size.
685        I don't know whether that's always the case.
686        -dkindred@cs.cmu.edu  */
687     if (unwind.giffile->SavedImages[0].ImageDesc.Height != height
688         || unwind.giffile->SavedImages[0].ImageDesc.Width != width
689         || unwind.giffile->SavedImages[0].ImageDesc.Left != 0
690         || unwind.giffile->SavedImages[0].ImageDesc.Top != 0)
691       signal_image_error ("First image in GIF file is not full size",
692                           instantiator);
693     
694     interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace;
695     pass = 0;
696     row = interlace ? InterlacedOffset[pass] : 0;
697     eip = unwind.eimage;
698     for (i = 0; i < height; i++)
699       {
700         if (interlace && row >= height)
701           row = InterlacedOffset[++pass];
702         eip = unwind.eimage + (row * width * 3);
703         for (j = 0; j < width; j++)
704           {
705             unsigned char pixel = unwind.giffile->SavedImages[0].RasterBits[(i * width) + j];
706             *eip++ = cmo->Colors[pixel].Red;
707             *eip++ = cmo->Colors[pixel].Green;
708             *eip++ = cmo->Colors[pixel].Blue;
709           }
710         row += interlace ? InterlacedJumps[pass] : 1;
711       }
712   }
713   /* now instantiate */
714   MAYBE_DEVMETH (XDEVICE (ii->device), 
715                  init_image_instance_from_eimage,
716                  (ii, width, height, unwind.eimage, dest_mask, 
717                   instantiator, domain));
718   
719   unbind_to (speccount, Qnil);
720 }
721
722 #endif /* HAVE_GIF */
723
724 \f
725 #ifdef HAVE_PNG
726
727 /**********************************************************************
728  *                             PNG                                    *
729  **********************************************************************/
730 static void
731 png_validate (Lisp_Object instantiator)
732 {
733   file_or_data_must_be_present (instantiator);
734 }
735
736 static Lisp_Object
737 png_normalize (Lisp_Object inst, Lisp_Object console_type)
738 {
739   return simple_image_type_normalize (inst, console_type, Qpng);
740 }
741
742 static int
743 png_possible_dest_types (void)
744 {
745   return IMAGE_COLOR_PIXMAP_MASK;
746 }
747
748 struct png_memory_storage
749 {
750   CONST Extbyte *bytes;         /* The data       */
751   Extcount len;                 /* How big is it? */
752   int index;                    /* Where are we?  */
753 };
754
755 static void
756 png_read_from_memory(png_structp png_ptr, png_bytep data,
757                      png_size_t length)
758 {
759    struct png_memory_storage *tbr =
760      (struct png_memory_storage *) png_get_io_ptr (png_ptr);
761
762    if (length > (tbr->len - tbr->index))
763      png_error (png_ptr, (png_const_charp) "Read Error");
764    memcpy (data,tbr->bytes + tbr->index,length);
765    tbr->index = tbr->index + length;
766 }
767
768 struct png_error_struct
769 {
770   CONST char *err_str;
771   jmp_buf setjmp_buffer;        /* for return to caller */
772 };
773
774 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
775    structure, and there are cases where the size can be different from
776    between inside the libarary, and inside the code!  To do an end run
777    around this, use our own error functions, and don't rely on things
778    passed in the png_ptr to them.  This is an ugly hack and must
779    go away when the lisp engine is threaded! */
780 static struct png_error_struct png_err_stct;
781
782 static void
783 png_error_func (png_structp png_ptr, png_const_charp msg)
784 {
785   png_err_stct.err_str = msg;
786   longjmp (png_err_stct.setjmp_buffer, 1);
787 }
788
789 static void
790 png_warning_func (png_structp png_ptr, png_const_charp msg)
791 {
792   warn_when_safe (Qpng, Qinfo, "%s", msg);
793 }
794
795 struct png_unwind_data
796 {
797   FILE *instream;
798   unsigned char *eimage;
799   png_structp png_ptr;
800   png_infop info_ptr;
801 };
802
803 static Lisp_Object
804 png_instantiate_unwind (Lisp_Object unwind_obj)
805 {
806   struct png_unwind_data *data =
807     (struct png_unwind_data *) get_opaque_ptr (unwind_obj);
808
809   free_opaque_ptr (unwind_obj);
810   if (data->png_ptr)
811     png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
812   if (data->instream)
813     fclose (data->instream);
814
815   return Qnil;
816 }
817
818 static void
819 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
820                  Lisp_Object pointer_fg, Lisp_Object pointer_bg,
821                  int dest_mask, Lisp_Object domain)
822 {
823   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
824   struct png_unwind_data unwind;
825   int speccount = specpdl_depth ();
826   int height, width;
827   struct png_memory_storage tbr;  /* Data to be read */
828
829   /* PNG variables */
830   png_structp png_ptr;
831   png_infop info_ptr;
832
833   /* Initialize all PNG structures */
834   png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct,
835                                     png_error_func, png_warning_func);
836   if (!png_ptr)
837     signal_image_error ("Error obtaining memory for png_read", instantiator);
838   info_ptr = png_create_info_struct (png_ptr);
839   if (!info_ptr)
840     {
841       png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
842       signal_image_error ("Error obtaining memory for png_read", instantiator);
843     }
844   
845   xzero (unwind);
846   unwind.png_ptr = png_ptr;
847   unwind.info_ptr = info_ptr;
848
849   record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
850
851   /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
852      this file, example.c from the libpng 0.81 distribution, and the
853      pngtopnm sources. -WMP-
854      */
855   /* It has been further modified to handle the API changes for 0.96,
856      and is no longer usable for previous versions. jh
857   */
858
859   /* Set the jmp_buf reurn context for png_error ... if this returns !0, then
860      we ran into a problem somewhere, and need to clean up after ourselves. */
861   if (setjmp (png_err_stct.setjmp_buffer))
862     {
863       /* Something blew up: just display the error (cleanup happens in the unwind) */
864       signal_image_error_2 ("Error decoding PNG",
865                              build_string(png_err_stct.err_str),
866                              instantiator);
867     }
868
869   /* Initialize the IO layer and read in header information */
870   {
871     Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
872     CONST Extbyte *bytes;
873     Extcount len;
874
875     assert (!NILP (data));
876
877     /* #### This is a definite problem under Mule due to the amount of
878        stack data it might allocate.  Need to think about using Lstreams */
879     GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
880     tbr.bytes = bytes;
881     tbr.len = len;
882     tbr.index = 0;
883     png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory);
884   }
885
886   png_read_info (png_ptr, info_ptr);
887
888   {
889     int y;
890     unsigned char **row_pointers;
891     height = info_ptr->height;
892     width = info_ptr->width;
893
894     /* Wow, allocate all the memory.  Truly, exciting. */
895     unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3);
896     /* libpng expects that the image buffer passed in contains a
897        picture to draw on top of if the png has any transparencies.
898        This could be a good place to pass that in... */
899     
900     row_pointers  = xnew_array (png_byte *, height);
901
902     for (y = 0; y < height; y++)
903       row_pointers[y] = unwind.eimage + (width * 3 * y);
904
905     /* Now that we're using EImage, ask for 8bit RGB triples for any type
906        of image*/
907     /* convert palatte images to full RGB */
908     if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
909       png_set_expand (png_ptr);
910     /* send grayscale images to RGB too */
911     if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
912         info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
913       png_set_gray_to_rgb (png_ptr);
914     /* we can't handle alpha values */
915     if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
916       png_set_strip_alpha (png_ptr);
917     /* rip out any transparancy layers/colors */
918     if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
919       {
920         png_set_expand (png_ptr);
921         png_set_strip_alpha (png_ptr);
922       }
923     /* tell libpng to strip 16 bit depth files down to 8 bits */
924     if (info_ptr->bit_depth == 16)
925       png_set_strip_16 (png_ptr);
926     /* if the image is < 8 bits, pad it out */
927     if (info_ptr->bit_depth < 8)
928       {
929         if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
930           png_set_expand (png_ptr);
931         else
932           png_set_packing (png_ptr);
933       }
934
935 #if 1 /* tests? or permanent? */
936     {
937       /* if the png specifies a background chunk, go ahead and
938          use it */
939       png_color_16 my_background, *image_background;
940     
941       /* ### how do I get the background of the current frame? */
942       my_background.red   = 0x7fff;
943       my_background.green = 0x7fff;
944       my_background.blue  = 0x7fff;
945
946       if (png_get_bKGD (png_ptr, info_ptr, &image_background))
947         png_set_background (png_ptr, image_background,
948                             PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
949       else 
950         png_set_background (png_ptr, &my_background,
951                             PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
952     }
953 #endif
954     png_read_image (png_ptr, row_pointers);
955     png_read_end (png_ptr, info_ptr);
956     
957 #ifdef PNG_SHOW_COMMENTS
958     /* ####
959      * I turn this off by default now, because the !%^@#!% comments
960      * show up every time the image is instantiated, which can get
961      * really really annoying.  There should be some way to pass this
962      * type of data down into the glyph code, where you can get to it
963      * from lisp anyway. - WMP
964      */
965     {
966       int i;
967
968       for (i = 0 ; i < info_ptr->num_text ; i++)
969         {
970           /* How paranoid do I have to be about no trailing NULLs, and
971              using (int)info_ptr->text[i].text_length, and strncpy and a temp
972              string somewhere? */
973
974           warn_when_safe (Qpng, Qinfo, "%s - %s",
975                           info_ptr->text[i].key,
976                           info_ptr->text[i].text);
977         }
978     }
979 #endif
980
981     xfree (row_pointers);
982   }
983
984   /* now instantiate */
985   MAYBE_DEVMETH (XDEVICE (ii->device), 
986                  init_image_instance_from_eimage,
987                  (ii, width, height, unwind.eimage, dest_mask, 
988                   instantiator, domain));
989
990   /* This will clean up everything else. */
991   unbind_to (speccount, Qnil);
992 }
993
994 #endif /* HAVE_PNG */
995
996 \f
997 #ifdef HAVE_TIFF
998 #include "tiffio.h"
999
1000 /**********************************************************************
1001  *                             TIFF                                   *
1002  **********************************************************************/
1003 static void
1004 tiff_validate (Lisp_Object instantiator)
1005 {
1006   file_or_data_must_be_present (instantiator);
1007 }
1008
1009 static Lisp_Object
1010 tiff_normalize (Lisp_Object inst, Lisp_Object console_type)
1011 {
1012   return simple_image_type_normalize (inst, console_type, Qtiff);
1013 }
1014
1015 static int
1016 tiff_possible_dest_types (void)
1017 {
1018   return IMAGE_COLOR_PIXMAP_MASK;
1019 }
1020
1021 struct tiff_unwind_data
1022 {
1023   unsigned char *eimage;
1024   /* Object that holds the decoded data from a TIFF file */
1025   TIFF *tiff;
1026 };
1027
1028 static Lisp_Object
1029 tiff_instantiate_unwind (Lisp_Object unwind_obj)
1030 {
1031   struct tiff_unwind_data *data =
1032     (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj);
1033
1034   free_opaque_ptr (unwind_obj);
1035   if (data->tiff)
1036     {
1037       TIFFClose(data->tiff);
1038     }
1039   if (data->eimage)
1040     xfree (data->eimage);
1041
1042   return Qnil;
1043 }
1044
1045 typedef struct tiff_memory_storage
1046 {
1047   Extbyte *bytes;               /* The data       */
1048   Extcount len;                 /* How big is it? */
1049   int index;                    /* Where are we?  */
1050 } tiff_memory_storage;
1051
1052 static size_t
1053 tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1054 {
1055   tiff_memory_storage *mem = (tiff_memory_storage*)data;
1056
1057   if (size > (mem->len - mem->index))
1058     return (size_t) -1;
1059   memcpy(buf, mem->bytes + mem->index, size);
1060   mem->index = mem->index + size;
1061   return size;
1062 }
1063
1064 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1065 {
1066   abort();
1067   return 0;                     /* Shut up warnings. */
1068 }
1069
1070 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1071 {
1072   tiff_memory_storage *mem = (tiff_memory_storage*)data;
1073   int newidx;
1074   switch(whence) {
1075   case SEEK_SET:
1076     newidx = off;
1077     break;
1078   case SEEK_END:
1079     newidx = mem->len + off;
1080     break;
1081   case SEEK_CUR:
1082     newidx = mem->index + off;
1083     break;
1084   default:
1085     fprintf(stderr,"Eh? invalid seek mode in tiff_memory_seek\n");
1086     return -1;
1087   }
1088
1089   if ((newidx > mem->len) || (newidx < 0))
1090     return -1;
1091   
1092   mem->index = newidx;
1093   return newidx;
1094 }
1095
1096 static int
1097 tiff_memory_close(thandle_t data)
1098 {
1099   return 0;
1100 }
1101
1102 static int
1103 tiff_map_noop(thandle_t data, tdata_t* pbase, toff_t* psize)
1104 {
1105   return 0;
1106 }
1107
1108 static void
1109 tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1110 {
1111   return;
1112 }
1113
1114 static toff_t
1115 tiff_memory_size(thandle_t data)
1116 {
1117   tiff_memory_storage *mem = (tiff_memory_storage*)data;
1118   return mem->len;
1119 }
1120
1121 struct tiff_error_struct
1122 {
1123 #if HAVE_VSNPRINTF
1124   char err_str[256];
1125 #else
1126   char err_str[1024];           /* return the error string */
1127 #endif
1128   jmp_buf setjmp_buffer;        /* for return to caller */
1129 };
1130
1131 /* jh 98/03/12 - ###This struct for passing data to the error functions
1132    is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1133    have any place to store error func data.  This should be rectified
1134    before XEmacs gets threads! */
1135 static struct tiff_error_struct tiff_err_data;
1136
1137 static void
1138 tiff_error_func(CONST char *module, CONST char *fmt, ...)
1139 {
1140   va_list vargs;
1141
1142   va_start (vargs, fmt);
1143 #if HAVE_VSNPRINTF
1144   vsnprintf (tiff_err_data.err_str, 255, fmt, vargs);
1145 #else
1146   /* pray this doesn't overflow... */
1147   vsprintf (tiff_err_data.err_str, fmt, vargs);
1148 #endif
1149   va_end (vargs);
1150   /* return to setjmp point */
1151   longjmp (tiff_err_data.setjmp_buffer, 1);
1152 }
1153
1154 static void
1155 tiff_warning_func(CONST char *module, CONST char *fmt, ...)
1156 {
1157   va_list vargs;
1158 #if HAVE_VSNPRINTF
1159   char warn_str[256];
1160 #else
1161   char warn_str[1024];
1162 #endif
1163
1164   va_start (vargs, fmt);
1165 #if HAVE_VSNPRINTF
1166   vsnprintf (warn_str, 255, fmt, vargs);
1167 #else
1168   vsprintf (warn_str, fmt, vargs);
1169 #endif
1170   va_end (vargs);
1171   warn_when_safe (Qtiff, Qinfo, "%s - %s",
1172                   module, warn_str);
1173 }
1174
1175 static void
1176 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1177                   Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1178                   int dest_mask, Lisp_Object domain)
1179 {
1180   struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1181   tiff_memory_storage mem_struct;
1182   /* It is OK for the unwind data to be local to this function,
1183      because the unwind-protect is always executed when this
1184      stack frame is still valid. */
1185   struct tiff_unwind_data unwind;
1186   int speccount = specpdl_depth ();
1187   uint32 width, height;
1188
1189   xzero (unwind);
1190   record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
1191   
1192   /* set up error facilities */
1193   if (setjmp (tiff_err_data.setjmp_buffer))
1194     {
1195       /* An error was signaled. No clean up is needed, as unwind handles that
1196          for us.  Just pass the error along. */
1197       signal_image_error_2 ("TIFF decoding error",
1198                             build_string(tiff_err_data.err_str),
1199                             instantiator);
1200     }
1201   TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func);
1202   TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func);
1203   {
1204     Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1205     Extbyte *bytes;
1206     Extcount len;
1207
1208     uint32 *raster;
1209     unsigned char *ep;
1210
1211     assert (!NILP (data));
1212
1213     /* #### This is a definite problem under Mule due to the amount of
1214        stack data it might allocate.  Think about Lstreams... */
1215     GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
1216     mem_struct.bytes = bytes;
1217     mem_struct.len = len;
1218     mem_struct.index = 0;
1219
1220     unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct,
1221                                   (TIFFReadWriteProc)tiff_memory_read,
1222                                   (TIFFReadWriteProc)tiff_memory_write,
1223                                   tiff_memory_seek, tiff_memory_close, tiff_memory_size,
1224                                   tiff_map_noop, tiff_unmap_noop);
1225     if (!unwind.tiff)
1226       signal_image_error ("Insufficent memory to instantiate TIFF image", instantiator);
1227
1228     TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1229     TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1230     unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
1231
1232     /* ### This is little more than proof-of-concept/function testing.
1233        It needs to be reimplimented via scanline reads for both memory
1234        compactness. */
1235     raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1236     if (raster != NULL)
1237       {
1238         int i,j;
1239         uint32 *rp;
1240         ep = unwind.eimage;
1241         rp = raster;
1242         if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0))
1243           {
1244             for (i = height - 1;  i >= 0; i--)
1245               {
1246                 /* This is to get around weirdness in the libtiff library where properly
1247                    made TIFFs will come out upside down.  libtiff bug or jhod-brainlock? */
1248                 rp = raster + (i * width);
1249                 for (j = 0; j < width; j++)
1250                   {
1251                     *ep++ = (unsigned char)TIFFGetR(*rp);
1252                     *ep++ = (unsigned char)TIFFGetG(*rp);
1253                     *ep++ = (unsigned char)TIFFGetB(*rp);
1254                     rp++;
1255                   }
1256               }
1257           }
1258         _TIFFfree (raster);
1259       } else
1260         signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator);
1261
1262   }
1263
1264   /* now instantiate */
1265   MAYBE_DEVMETH (XDEVICE (ii->device), 
1266                  init_image_instance_from_eimage,
1267                  (ii, width, height, unwind.eimage, dest_mask, 
1268                   instantiator, domain));
1269
1270   unbind_to (speccount, Qnil);
1271 }
1272
1273 #endif /* HAVE_TIFF */
1274
1275 \f
1276 /************************************************************************/
1277 /*                            initialization                            */
1278 /************************************************************************/
1279
1280 void
1281 syms_of_glyphs_eimage (void)
1282 {
1283 }
1284
1285 void
1286 image_instantiator_format_create_glyphs_eimage (void)
1287 {
1288   /* image-instantiator types */
1289 #ifdef HAVE_JPEG
1290   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg");
1291
1292   IIFORMAT_HAS_METHOD (jpeg, validate);
1293   IIFORMAT_HAS_METHOD (jpeg, normalize);
1294   IIFORMAT_HAS_METHOD (jpeg, possible_dest_types);
1295   IIFORMAT_HAS_METHOD (jpeg, instantiate);
1296
1297   IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string);
1298   IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string);
1299 #endif
1300
1301 #ifdef HAVE_GIF
1302   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif");
1303
1304   IIFORMAT_HAS_METHOD (gif, validate);
1305   IIFORMAT_HAS_METHOD (gif, normalize);
1306   IIFORMAT_HAS_METHOD (gif, possible_dest_types);
1307   IIFORMAT_HAS_METHOD (gif, instantiate);
1308
1309   IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string);
1310   IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string);
1311 #endif
1312
1313 #ifdef HAVE_PNG
1314   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png");
1315
1316   IIFORMAT_HAS_METHOD (png, validate);
1317   IIFORMAT_HAS_METHOD (png, normalize);
1318   IIFORMAT_HAS_METHOD (png, possible_dest_types);
1319   IIFORMAT_HAS_METHOD (png, instantiate);
1320
1321   IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string);
1322   IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string);
1323 #endif
1324
1325 #ifdef HAVE_TIFF
1326   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff");
1327
1328   IIFORMAT_HAS_METHOD (tiff, validate);
1329   IIFORMAT_HAS_METHOD (tiff, normalize);
1330   IIFORMAT_HAS_METHOD (tiff, possible_dest_types);
1331   IIFORMAT_HAS_METHOD (tiff, instantiate);
1332
1333   IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string);
1334   IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string);
1335 #endif
1336
1337 }
1338
1339 void
1340 vars_of_glyphs_eimage (void)
1341 {
1342 #ifdef HAVE_JPEG
1343   Fprovide (Qjpeg);
1344 #endif
1345
1346 #ifdef HAVE_GIF
1347   Fprovide (Qgif);
1348 #endif
1349
1350 #ifdef HAVE_PNG
1351   Fprovide (Qpng);
1352 #endif
1353
1354 #ifdef HAVE_TIFF
1355   Fprovide (Qtiff);
1356 #endif
1357
1358 }