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