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