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