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
8 This file is part of SXEmacs
10 SXEmacs is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 SXEmacs is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 /* Synched up with: Not in FSF. */
26 /* Original author: Jamie Zawinski for 19.8
27 font-truename stuff added by Jamie Zawinski for 19.10
28 subwindow support added by Chuck Thompson
29 additional XPM support added by Chuck Thompson
30 initial X-Face support added by Stig
31 rewritten/restructured by Ben Wing for 19.12/19.13
32 GIF/JPEG support added by Ben Wing for 19.14
33 PNG support added by Bill Perry for 19.14
34 Improved GIF/JPEG support added by Bill Perry for 19.14
35 Cleanup/simplification of error handling by Ben Wing for 19.14
36 Pointer/icon overhaul, more restructuring by Ben Wing for 19.14
37 GIF support changed to external Gifreader lib by Jareth Hein for 21.0
38 Many changes for color work and optimizations by Jareth Hein for 21.0
39 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
40 TIFF code by Jareth Hein for 21.0
41 Generalization for ms-windows by Andy Piper for 21.0
43 Convert images.el to C and stick it in here?
62 #if defined WITH_PNG && defined HAVE_PNG
74 #include "mule/file-coding.h"
82 DEFINE_IMAGE_INSTANTIATOR_FORMAT(tiff);
87 DEFINE_IMAGE_INSTANTIATOR_FORMAT(jpeg);
92 DEFINE_IMAGE_INSTANTIATOR_FORMAT(gif);
96 #if defined WITH_PNG && defined HAVE_PNG
97 DEFINE_IMAGE_INSTANTIATOR_FORMAT(png);
102 DEFINE_IMAGE_INSTANTIATOR_FORMAT(rawrgb);
105 DEFINE_IMAGE_INSTANTIATOR_FORMAT(rawrgba);
106 Lisp_Object Qrawrgba;
111 /**********************************************************************
113 **********************************************************************/
123 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/
124 static void jpeg_validate(Lisp_Object instantiator)
126 file_or_data_must_be_present(instantiator);
130 jpeg_normalize(Lisp_Object inst, Lisp_Object console_type,
131 Lisp_Object dest_mask)
133 return simple_image_type_normalize(inst, console_type, Qjpeg);
136 static int jpeg_possible_dest_types(void)
138 return IMAGE_COLOR_PIXMAP_MASK;
141 /* To survive the otherwise baffling complexity of making sure
142 everything gets cleaned up in the presence of an error, we
143 use an unwind_protect(). */
145 struct jpeg_unwind_data {
146 /* Stream that we need to close */
148 /* Object that holds state info for JPEG decoding */
149 struct jpeg_decompress_struct *cinfo_ptr;
151 unsigned char *eimage;
154 static Lisp_Object jpeg_instantiate_unwind(Lisp_Object unwind_obj)
156 struct jpeg_unwind_data *data =
157 (struct jpeg_unwind_data *)get_opaque_ptr(unwind_obj);
159 free_opaque_ptr(unwind_obj);
161 jpeg_destroy_decompress(data->cinfo_ptr);
164 fclose(data->instream);
175 * The JPEG library's standard error handler (jerror.c) is divided into
176 * several "methods" which you can override individually. This lets you
177 * adjust the behavior without duplicating a lot of code, which you might
178 * have to update with each future release.
180 * Our example here shows how to override the "error_exit" method so that
181 * control is returned to the library's caller when a fatal error occurs,
182 * rather than calling exit() as the standard error_exit method does.
184 * We use C's setjmp/longjmp facility to return control. This means that the
185 * routine which calls the JPEG library must first execute a setjmp() call to
186 * establish the return point. We want the replacement error_exit to do a
187 * longjmp(). But we need to make the setjmp buffer accessible to the
188 * error_exit routine. To do this, we make a private extension of the
189 * standard JPEG error handler object. (If we were using C++, we'd say we
190 * were making a subclass of the regular error handler.)
192 * Here's the extended error handler struct:
195 struct my_jpeg_error_mgr {
196 struct jpeg_error_mgr pub; /* "public" fields */
197 jmp_buf setjmp_buffer; /* for return to caller */
200 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
205 our_init_source(j_decompress_ptr cinfo)
209 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
214 our_fill_input_buffer(j_decompress_ptr cinfo)
216 /* Insert a fake EOI marker */
217 struct jpeg_source_mgr *src = cinfo->src;
218 static JOCTET buffer[2];
220 buffer[0] = (JOCTET) 0xFF;
221 buffer[1] = (JOCTET) JPEG_EOI;
223 src->next_input_byte = buffer;
224 src->bytes_in_buffer = 2;
228 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
233 our_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
235 struct jpeg_source_mgr *src = NULL;
237 src = (struct jpeg_source_mgr *)cinfo->src;
241 } else if (num_bytes > (long)src->bytes_in_buffer) {
242 ERREXIT(cinfo, JERR_INPUT_EOF);
245 src->bytes_in_buffer -= num_bytes;
246 src->next_input_byte += num_bytes;
249 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
254 our_term_source(j_decompress_ptr cinfo)
259 struct jpeg_source_mgr pub;
260 } our_jpeg_source_mgr;
263 jpeg_memory_src(j_decompress_ptr cinfo, const JOCTET *data, size_t len)
265 struct jpeg_source_mgr *src;
267 if (cinfo->src == NULL) { /* first time for this JPEG object? */
268 cinfo->src = (struct jpeg_source_mgr *)
269 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
271 sizeof(our_jpeg_source_mgr));
272 src = (struct jpeg_source_mgr *)cinfo->src;
273 src->next_input_byte = data;
275 src = (struct jpeg_source_mgr *)cinfo->src;
276 src->init_source = our_init_source;
277 src->fill_input_buffer = our_fill_input_buffer;
278 src->skip_input_data = our_skip_input_data;
279 /* use default method */
280 src->resync_to_restart = jpeg_resync_to_restart;
281 src->term_source = our_term_source;
282 src->bytes_in_buffer = len;
283 src->next_input_byte = data;
287 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
292 my_jpeg_error_exit(j_common_ptr cinfo)
294 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
295 struct my_jpeg_error_mgr *myerr =
296 (struct my_jpeg_error_mgr *)cinfo->err;
298 /* Return control to the setjmp point */
299 longjmp(myerr->setjmp_buffer, 1);
302 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
307 my_jpeg_output_message(j_common_ptr cinfo)
309 char buffer[JMSG_LENGTH_MAX];
311 /* Create the message */
312 (*cinfo->err->format_message) (cinfo, buffer);
313 warn_when_safe(Qjpeg, Qinfo, "%s", buffer);
316 /* The code in this routine is based on example.c from the JPEG library
317 source code and from gif_instantiate() */
319 jpeg_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
320 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
321 int dest_mask, Lisp_Object domain)
323 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
324 /* It is OK for the unwind data to be local to this function,
325 because the unwind-protect is always executed when this
326 stack frame is still valid. */
327 struct jpeg_unwind_data unwind;
328 int speccount = specpdl_depth();
330 /* This struct contains the JPEG decompression parameters and pointers to
331 * working space (which is allocated as needed by the JPEG library).
333 struct jpeg_decompress_struct cinfo;
334 /* We use our private extension JPEG error handler.
335 * Note that this struct must live as long as the main JPEG parameter
336 * struct, to avoid dangling-pointer problems.
338 struct my_jpeg_error_mgr jerr;
340 /* Step -1: First record our unwind-protect, which will clean up after
341 any exit, normal or not */
344 record_unwind_protect(jpeg_instantiate_unwind,
345 make_opaque_ptr(&unwind));
347 /* Step 1: allocate and initialize JPEG decompression object */
349 /* We set up the normal JPEG error routines, then override error_exit. */
350 cinfo.err = jpeg_std_error(&jerr.pub);
351 jerr.pub.error_exit = my_jpeg_error_exit;
352 jerr.pub.output_message = my_jpeg_output_message;
354 /* Establish the setjmp return context for my_error_exit to use. */
355 if (setjmp(jerr.setjmp_buffer)) {
356 /* If we get here, the JPEG code has signaled an error.
357 * We need to clean up the JPEG object, close the input file, and return.
361 Lisp_Object errstring;
362 char buffer[JMSG_LENGTH_MAX];
364 /* Create the message */
365 (*cinfo.err->format_message) ((j_common_ptr) & cinfo,
367 errstring = build_string(buffer);
369 signal_image_error_2("JPEG decoding error",
370 errstring, instantiator);
374 /* Now we can initialize the JPEG decompression object. */
375 jpeg_create_decompress(&cinfo);
376 unwind.cinfo_ptr = &cinfo;
378 /* Step 2: specify data source (eg, a file) */
381 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
382 const Extbyte *bytes;
387 bytes = XEFFIO(data)->fostorage;
388 len = XEFFIO(data)->storage_size;
390 #endif /* HAVE_FFI */
391 /* #### This is a definite problem under Mule due to the amount of
392 stack data it might allocate. Need to be able to convert and
393 write out to a file. */
394 TO_EXTERNAL_FORMAT(LISP_STRING, data, ALLOCA, (bytes, len),
396 jpeg_memory_src(&cinfo, (const JOCTET*)bytes, len);
399 /* Step 3: read file parameters with jpeg_read_header() */
401 jpeg_read_header(&cinfo, TRUE);
402 /* We can ignore the return value from jpeg_read_header since
403 * (a) suspension is not possible with the stdio data source, and
404 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
405 * See libjpeg.doc for more info.
409 int jpeg_gray = 0; /* if we're dealing with a grayscale */
410 /* Step 4: set parameters for decompression. */
412 /* Now that we're using EImages, send all data as 24bit color.
413 The backend routine will take care of any necessary reductions.
414 We do have to handle the grayscale case ourselves, however. */
415 if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
416 cinfo.out_color_space = JCS_GRAYSCALE;
419 /* we're relying on the jpeg driver to do any other conversions,
420 or signal an error if the conversion isn't supported. */
421 cinfo.out_color_space = JCS_RGB;
424 /* Step 5: Start decompressor */
425 jpeg_start_decompress(&cinfo);
427 /* Step 6: Read in the data and put into EImage format (8bit RGB
429 unwind.eimage = xmalloc_atomic(cinfo.output_width *
430 cinfo.output_height * 3);
431 if (!unwind.eimage) {
433 ("Unable to allocate enough memory for image",
438 JSAMPARRAY row_buffer; /* Output row buffer */
440 int row_stride; /* physical row width in output buffer */
441 unsigned char *op = unwind.eimage;
443 /* We may need to do some setup of our own at this point
444 * before reading the data. After
445 * jpeg_start_decompress() we have the correct scaled
446 * output image dimensions available
447 * We need to make an output work buffer of the right
449 /* JSAMPLEs per row in output buffer. */
450 row_stride = cinfo.output_width *
451 cinfo.output_components;
452 /* Make a one-row-high sample array that will go away
453 * when done with image */
454 row_buffer = ((*cinfo.mem->alloc_sarray)
455 ((j_common_ptr) & cinfo, JPOOL_IMAGE,
458 /* Here we use the library's state variable
459 * cinfo.output_scanline as the loop counter, so that
460 * we don't have to keep track ourselves. */
461 while (cinfo.output_scanline < cinfo.output_height) {
464 /* jpeg_read_scanlines expects an array of
465 * pointers to scanlines.
466 * Here the array is only one element long,
467 * but you could ask for more than one
468 * scanline at a time if that's more
470 (void)jpeg_read_scanlines(&cinfo, row_buffer,
473 for (i = 0; i < cinfo.output_width; i++) {
477 #if (BITS_IN_JSAMPLE == 8)
478 val = (unsigned char)*jp++;
479 #else /* other option is 12 */
481 (unsigned char)(*jp++ >> 4);
483 /* copy the same value
485 for (clr = 0; clr < 3; clr++) {
489 for (clr = 0; clr < 3; clr++) {
490 #if (BITS_IN_JSAMPLE == 8)
491 *op++ = (unsigned char)
493 #else /* other option is 12 */
494 *op++ = (unsigned char)
504 /* Step 6.5: Create the pixmap and set up the image instance */
505 /* now instantiate */
506 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
507 init_image_instance_from_eimage,
508 (ii, cinfo.output_width, cinfo.output_height, 1,
509 unwind.eimage, dest_mask, instantiator, domain));
511 /* Step 7: Finish decompression */
513 jpeg_finish_decompress(&cinfo);
514 /* We can ignore the return value since suspension is not possible
515 * with the stdio data source.
518 /* And we're done! */
519 /* This will clean up everything else. */
520 unbind_to(speccount, Qnil);
523 #endif /* HAVE_JPEG */
526 /**********************************************************************
528 **********************************************************************/
532 static void gif_validate(Lisp_Object instantiator)
534 file_or_data_must_be_present(instantiator);
538 gif_normalize(Lisp_Object inst, Lisp_Object console_type, Lisp_Object dest_mask)
540 return simple_image_type_normalize(inst, console_type, Qgif);
543 static int gif_possible_dest_types(void)
545 return IMAGE_COLOR_PIXMAP_MASK;
548 /* To survive the otherwise baffling complexity of making sure
549 everything gets cleaned up in the presence of an error, we
550 use an unwind_protect(). */
552 struct gif_unwind_data {
553 unsigned char *eimage;
554 /* Object that holds the decoded data from a GIF file */
555 GifFileType *giffile;
558 static Lisp_Object gif_instantiate_unwind(Lisp_Object unwind_obj)
560 struct gif_unwind_data *data =
561 (struct gif_unwind_data *)get_opaque_ptr(unwind_obj);
563 free_opaque_ptr(unwind_obj);
565 DGifCloseFile(data->giffile);
566 GifFree(data->giffile);
574 typedef struct gif_memory_storage {
575 Extbyte *bytes; /* The data */
576 Extcount len; /* How big is it? */
577 int index; /* Where are we? */
578 } gif_memory_storage;
580 static size_t gif_read_from_memory(GifByteType * buf, size_t size, VoidPtr data)
582 gif_memory_storage *mem = (gif_memory_storage *) data;
584 if ((ssize_t) size > (mem->len - mem->index))
586 memcpy(buf, mem->bytes + mem->index, size);
587 mem->index = mem->index + size;
591 static int gif_memory_close(VoidPtr data)
596 struct gif_error_struct {
597 const char *err_str; /* return the error string */
598 jmp_buf setjmp_buffer; /* for return to caller */
601 static void gif_error_func(const char *err_str, VoidPtr error_ptr)
603 struct gif_error_struct *error_data =
604 (struct gif_error_struct *)error_ptr;
606 /* return to setjmp point */
607 error_data->err_str = err_str;
608 longjmp(error_data->setjmp_buffer, 1);
612 gif_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
613 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
614 int dest_mask, Lisp_Object domain)
616 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
617 /* It is OK for the unwind data to be local to this function,
618 because the unwind-protect is always executed when this
619 stack frame is still valid. */
620 struct gif_unwind_data unwind;
621 int speccount = specpdl_depth();
622 gif_memory_storage mem_struct;
623 struct gif_error_struct gif_err;
630 record_unwind_protect(gif_instantiate_unwind, make_opaque_ptr(&unwind));
632 /* 1. Now decode the data. */
635 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
639 if (!(unwind.giffile = GifSetup()))
641 ("Insufficient memory to instantiate GIF image",
644 /* set up error facilities */
645 if (setjmp(gif_err.setjmp_buffer)) {
646 /* An error was signaled. No clean up is needed, as unwind handles that
647 for us. Just pass the error along. */
648 Lisp_Object errstring;
649 errstring = build_string(gif_err.err_str);
650 signal_image_error_2("GIF decoding error", errstring,
653 GifSetErrorFunc(unwind.giffile, (Gif_error_func) gif_error_func,
654 (VoidPtr) & gif_err);
658 bytes = XEFFIO(data)->fostorage;
659 len = XEFFIO(data)->storage_size;
661 #endif /* HAVE_FFI */
662 TO_EXTERNAL_FORMAT(LISP_STRING, data, ALLOCA, (bytes, len),
664 mem_struct.bytes = bytes;
665 mem_struct.len = len;
666 mem_struct.index = 0;
667 GifSetReadFunc(unwind.giffile, gif_read_from_memory,
668 (VoidPtr) & mem_struct);
669 GifSetCloseFunc(unwind.giffile, gif_memory_close,
670 (VoidPtr) & mem_struct);
671 DGifInitRead(unwind.giffile);
673 /* Then slurp the image into memory, decoding along the way.
674 The result is the image in a simple one-byte-per-pixel
675 format (#### the GIF routines only support 8-bit GIFs,
677 DGifSlurp(unwind.giffile);
680 /* 3. Now create the EImage(s) */
682 ColorMapObject *cmo = unwind.giffile->SColorMap;
683 int i, j, row, pass, interlace, slice;
685 /* interlaced gifs have rows in this order:
686 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
687 static int InterlacedOffset[] = { 0, 4, 2, 1 };
688 static int InterlacedJumps[] = { 8, 8, 4, 2 };
690 height = unwind.giffile->SHeight;
691 width = unwind.giffile->SWidth;
692 unwind.eimage = xmalloc_atomic(width * height * 3 *
693 unwind.giffile->ImageCount);
694 if (!unwind.eimage) {
696 ("Unable to allocate enough memory for image",
700 /* write the data in EImage format (8bit RGB triples) */
701 for (slice = 0; slice < unwind.giffile->ImageCount; slice++) {
702 /* We check here that the current image covers the full
704 if (unwind.giffile->SavedImages[slice].ImageDesc.
706 || unwind.giffile->SavedImages[slice].ImageDesc.
708 || unwind.giffile->SavedImages[slice].ImageDesc.
710 || unwind.giffile->SavedImages[slice].ImageDesc.
713 ("Image in GIF file is not full size",
717 unwind.giffile->SavedImages[slice].ImageDesc.
720 row = interlace ? InterlacedOffset[pass] : 0;
721 eip = unwind.eimage + (width * height * 3 * slice);
722 for (i = 0; i < height; i++) {
725 row = InterlacedOffset[++pass];
726 while (row >= height)
733 (width * height * 3 * slice) +
735 for (j = 0; j < width; j++) {
736 unsigned char pixel =
737 unwind.giffile->SavedImages[slice].
738 RasterBits[(i * width) + j];
739 *eip++ = cmo->Colors[pixel].Red;
740 *eip++ = cmo->Colors[pixel].Green;
741 *eip++ = cmo->Colors[pixel].Blue;
743 row += interlace ? InterlacedJumps[pass] : 1;
747 /* now instantiate */
748 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
749 init_image_instance_from_eimage,
750 (ii, width, height, unwind.giffile->ImageCount,
751 unwind.eimage, dest_mask, instantiator, domain));
754 /* We read the gif successfully. If we have more than one slice then
756 if (unwind.giffile->ImageCount > 1) {
757 /* See if there is a timeout value. In theory there could be one
758 for every image - but that makes the implementation way to
759 complicated for now so we just take the first. */
760 unsigned short timeout = 0;
763 if (unwind.giffile->SavedImages[0].Function ==
764 GRAPHICS_EXT_FUNC_CODE
765 && unwind.giffile->SavedImages[0].ExtensionBlockCount) {
766 timeout = (unsigned short)
767 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].
769 unwind.giffile->SavedImages[0].ExtensionBlocks[0].
773 /* Too short a timeout will crucify us performance-wise. */
775 add_glyph_animated_timeout(timeout > 10 ? timeout : 10,
779 IMAGE_INSTANCE_PIXMAP_TIMEOUT(ii) = XINT(tid);
782 unbind_to(speccount, Qnil);
785 #endif /* HAVE_GIF */
787 #if defined WITH_PNG && defined HAVE_PNG
789 /**********************************************************************
791 **********************************************************************/
792 static void png_validate(Lisp_Object instantiator)
794 file_or_data_must_be_present(instantiator);
798 png_normalize(Lisp_Object inst, Lisp_Object console_type, Lisp_Object dest_mask)
800 return simple_image_type_normalize(inst, console_type, Qpng);
803 static int png_possible_dest_types(void)
805 return IMAGE_COLOR_PIXMAP_MASK;
808 struct png_memory_storage {
809 const Extbyte *bytes; /* The data */
810 Extcount len; /* How big is it? */
811 int index; /* Where are we? */
815 png_read_from_memory(png_structp png_ptr, png_bytep data, png_size_t length)
817 struct png_memory_storage *tbr =
818 (struct png_memory_storage *)png_get_io_ptr(png_ptr);
820 if ((ssize_t) length > (tbr->len - tbr->index))
821 png_error(png_ptr, (png_const_charp) "Read Error");
822 memcpy(data, tbr->bytes + tbr->index, length);
823 tbr->index = tbr->index + length;
826 struct png_error_struct {
828 jmp_buf setjmp_buffer; /* for return to caller */
831 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
832 structure, and there are cases where the size can be different from
833 between inside the library, and inside the code! To do an end run
834 around this, use our own error functions, and don't rely on things
835 passed in the png_ptr to them. This is an ugly hack and must
836 go away when the lisp engine is threaded! */
837 static struct png_error_struct png_err_stct;
839 static void png_error_func(png_structp png_ptr, png_const_charp msg)
841 png_err_stct.err_str = msg;
842 longjmp(png_err_stct.setjmp_buffer, 1);
845 static void png_warning_func(png_structp png_ptr, png_const_charp msg)
847 warn_when_safe(Qpng, Qinfo, "%s", msg);
850 struct png_unwind_data {
852 unsigned char *eimage;
857 static Lisp_Object png_instantiate_unwind(Lisp_Object unwind_obj)
859 struct png_unwind_data *data =
860 (struct png_unwind_data *)get_opaque_ptr(unwind_obj);
862 free_opaque_ptr(unwind_obj);
864 png_destroy_read_struct(&(data->png_ptr), &(data->info_ptr),
867 fclose(data->instream);
876 png_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
877 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
878 int dest_mask, Lisp_Object domain)
880 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
881 struct png_unwind_data unwind;
882 int speccount = specpdl_depth();
884 struct png_memory_storage tbr; /* Data to be read */
890 /* Initialize all PNG structures */
892 png_create_read_struct(PNG_LIBPNG_VER_STRING, (void *)&png_err_stct,
893 png_error_func, png_warning_func);
895 signal_image_error("Error obtaining memory for png_read",
897 info_ptr = png_create_info_struct(png_ptr);
899 png_destroy_read_struct(&png_ptr, (png_infopp) NULL,
901 signal_image_error("Error obtaining memory for png_read",
906 unwind.png_ptr = png_ptr;
907 unwind.info_ptr = info_ptr;
909 record_unwind_protect(png_instantiate_unwind, make_opaque_ptr(&unwind));
911 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
912 this file, example.c from the libpng 0.81 distribution, and the
913 pngtopnm sources. -WMP-
915 /* It has been further modified to handle the API changes for 0.96,
916 and is no longer usable for previous versions. jh
919 /* Set the jmp_buf return context for png_error ... if this returns !0, then
920 we ran into a problem somewhere, and need to clean up after ourselves. */
921 if (setjmp(png_err_stct.setjmp_buffer)) {
922 /* Something blew up: just display the error (cleanup happens in the unwind) */
923 signal_image_error_2("Error decoding PNG",
924 build_string(png_err_stct.err_str),
928 /* Initialize the IO layer and read in header information */
930 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
931 const Extbyte *bytes;
938 bytes = XEFFIO(data)->fostorage;
939 len = XEFFIO(data)->storage_size;
941 #endif /* HAVE_FFI */
942 /* #### This is a definite problem under Mule due to the amount of
943 stack data it might allocate. Need to think about using Lstreams */
944 TO_EXTERNAL_FORMAT(LISP_STRING, data, ALLOCA, (bytes, len),
949 png_set_read_fn(png_ptr, (void *)&tbr, png_read_from_memory);
952 png_read_info(png_ptr, info_ptr);
956 unsigned char **row_pointers;
957 height = info_ptr->height;
958 width = info_ptr->width;
960 /* Wow, allocate all the memory. Truly, exciting. */
961 unwind.eimage = xmalloc_atomic(width * height * 3);
962 /* libpng expects that the image buffer passed in contains a
963 picture to draw on top of if the png has any transparencies.
964 This could be a good place to pass that in... */
965 row_pointers = xnew_array(png_byte *, height);
967 for (y = 0; y < height; y++) {
968 row_pointers[y] = unwind.eimage + (width * 3 * y);
971 /* if the png specifies a background chunk, go ahead and
972 * use it, else use what we can get
973 * from the default face. */
974 png_color_16 my_background, *image_background;
975 Lisp_Object bkgd = Qnil;
977 my_background.red = 0x7fff;
978 my_background.green = 0x7fff;
979 my_background.blue = 0x7fff;
980 bkgd = FACE_BACKGROUND(Vdefault_face, domain);
981 if (!COLOR_INSTANCEP(bkgd)) {
982 warn_when_safe(Qpng, Qinfo,
983 "Couldn't get background color!");
985 Lisp_Color_Instance *c;
988 c = XCOLOR_INSTANCE(bkgd);
989 rgblist = MAYBE_LISP_DEVMETH(XDEVICE(c->device),
990 color_instance_rgb_components,
993 (unsigned short)XINT(XCAR(rgblist));
994 my_background.green =
995 (unsigned short)XINT(XCAR(XCDR(rgblist)));
998 XINT(XCAR(XCDR(XCDR(rgblist))));
1001 if (png_get_bKGD(png_ptr, info_ptr, &image_background))
1002 png_set_background(png_ptr, image_background,
1003 PNG_BACKGROUND_GAMMA_FILE, 1,
1006 png_set_background(png_ptr, &my_background,
1007 PNG_BACKGROUND_GAMMA_SCREEN,
1011 /* Now that we're using EImage, ask for 8bit RGB triples for any type
1013 /* convert palette images to full RGB */
1014 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1015 png_set_expand(png_ptr);
1016 /* send grayscale images to RGB too */
1017 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
1018 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1019 png_set_gray_to_rgb(png_ptr);
1020 /* we can't handle alpha values
1021 * Actually, mostly, we can. There's just a problem
1022 * with FACE_BACKGROUND_PIXMAP. Don't set a
1023 * background pixmap and you're fine. --SY.
1024 * if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
1025 * png_set_strip_alpha(png_ptr);
1027 /* tell libpng to strip 16 bit depth files down to 8 bits */
1028 if (info_ptr->bit_depth == 16)
1029 png_set_strip_16(png_ptr);
1030 /* if the image is < 8 bits, pad it out */
1031 if (info_ptr->bit_depth < 8) {
1032 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1033 png_set_expand(png_ptr);
1035 png_set_packing(png_ptr);
1038 png_read_image(png_ptr, row_pointers);
1039 png_read_end(png_ptr, info_ptr);
1041 #ifdef PNG_SHOW_COMMENTS
1043 * I turn this off by default now, because the !%^@#!% comments
1044 * show up every time the image is instantiated, which can get
1045 * really really annoying. There should be some way to pass this
1046 * type of data down into the glyph code, where you can get to it
1047 * from lisp anyway. - WMP
1052 for (i = 0; i < info_ptr->num_text; i++) {
1053 /* How paranoid do I have to be about no trailing NULLs, and
1054 using (int)info_ptr->text[i].text_length, and strncpy and a temp
1055 string somewhere? */
1057 warn_when_safe(Qpng, Qinfo, "%s - %s",
1058 info_ptr->text[i].key,
1059 info_ptr->text[i].text);
1064 xfree(row_pointers);
1067 /* now instantiate */
1068 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1069 init_image_instance_from_eimage,
1070 (ii, width, height, 1, unwind.eimage, dest_mask,
1071 instantiator, domain));
1073 /* This will clean up everything else. */
1074 unbind_to(speccount, Qnil);
1077 #endif /* HAVE_PNG */
1082 /**********************************************************************
1084 **********************************************************************/
1085 static void tiff_validate(Lisp_Object instantiator)
1087 file_or_data_must_be_present(instantiator);
1091 tiff_normalize(Lisp_Object inst, Lisp_Object console_type,
1092 Lisp_Object dest_mask)
1094 return simple_image_type_normalize(inst, console_type, Qtiff);
1097 static int tiff_possible_dest_types(void)
1099 return IMAGE_COLOR_PIXMAP_MASK;
1102 struct tiff_unwind_data {
1103 unsigned char *eimage;
1104 /* Object that holds the decoded data from a TIFF file */
1108 static Lisp_Object tiff_instantiate_unwind(Lisp_Object unwind_obj)
1110 struct tiff_unwind_data *data =
1111 (struct tiff_unwind_data *)get_opaque_ptr(unwind_obj);
1113 free_opaque_ptr(unwind_obj);
1115 TIFFClose(data->tiff);
1118 xfree(data->eimage);
1123 typedef struct tiff_memory_storage {
1124 Extbyte *bytes; /* The data */
1125 Extcount len; /* How big is it? */
1126 int index; /* Where are we? */
1127 } tiff_memory_storage;
1129 static size_t tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1131 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1133 if (size > (mem->len - mem->index))
1134 return (size_t) - 1;
1135 memcpy(buf, mem->bytes + mem->index, size);
1136 mem->index = mem->index + size;
1140 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1143 return 0; /* Shut up warnings. */
1146 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1148 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1155 newidx = mem->len + off;
1158 newidx = mem->index + off;
1161 fprintf(stderr, "Eh? invalid seek mode in tiff_memory_seek\n");
1162 return (toff_t) - 1;
1165 if ((newidx > mem->len) || (newidx < 0))
1166 return (toff_t) - 1;
1168 mem->index = newidx;
1172 static int tiff_memory_close(thandle_t data)
1177 static int tiff_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1182 static void tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1187 static toff_t tiff_memory_size(thandle_t data)
1189 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1193 struct tiff_error_struct {
1194 #ifdef HAVE_VSNPRINTF
1197 char err_str[1024]; /* return the error string */
1199 jmp_buf setjmp_buffer; /* for return to caller */
1202 /* jh 98/03/12 - ###This struct for passing data to the error functions
1203 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1204 have any place to store error func data. This should be rectified
1205 before SXEmacs gets threads! */
1206 static struct tiff_error_struct tiff_err_data;
1208 static void tiff_error_func(const char *module, const char *fmt, ...)
1212 va_start(vargs, fmt);
1213 #ifdef HAVE_VSNPRINTF
1214 vsnprintf(tiff_err_data.err_str, 255, fmt, vargs);
1216 /* pray this doesn't overflow... */
1217 vsprintf(tiff_err_data.err_str, fmt, vargs);
1220 /* return to setjmp point */
1221 longjmp(tiff_err_data.setjmp_buffer, 1);
1224 static void tiff_warning_func(const char *module, const char *fmt, ...)
1227 #ifdef HAVE_VSNPRINTF
1230 char warn_str[1024];
1233 va_start(vargs, fmt);
1234 #ifdef HAVE_VSNPRINTF
1235 vsnprintf(warn_str, 255, fmt, vargs);
1237 vsprintf(warn_str, fmt, vargs);
1240 warn_when_safe(Qtiff, Qinfo, "%s - %s", module, warn_str);
1244 tiff_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1245 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1246 int dest_mask, Lisp_Object domain)
1248 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1249 tiff_memory_storage mem_struct;
1250 /* It is OK for the unwind data to be local to this function,
1251 because the unwind-protect is always executed when this
1252 stack frame is still valid. */
1253 struct tiff_unwind_data unwind;
1254 int speccount = specpdl_depth();
1255 uint32 width, height;
1258 record_unwind_protect(tiff_instantiate_unwind,
1259 make_opaque_ptr(&unwind));
1261 /* set up error facilities */
1262 if (setjmp(tiff_err_data.setjmp_buffer)) {
1263 /* An error was signaled. No clean up is needed, as unwind handles that
1264 for us. Just pass the error along. */
1265 signal_image_error_2("TIFF decoding error",
1266 build_string(tiff_err_data.err_str),
1269 TIFFSetErrorHandler((TIFFErrorHandler) tiff_error_func);
1270 TIFFSetWarningHandler((TIFFErrorHandler) tiff_warning_func);
1272 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1279 assert(!NILP(data));
1283 bytes = XEFFIO(data)->fostorage;
1284 len = XEFFIO(data)->storage_size;
1286 #endif /* HAVE_FFI */
1287 /* #### This is a definite problem under Mule due to the amount of
1288 stack data it might allocate. Think about Lstreams... */
1289 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1290 ALLOCA, (bytes, len), Qbinary);
1291 mem_struct.bytes = bytes;
1292 mem_struct.len = len;
1293 mem_struct.index = 0;
1296 TIFFClientOpen("memfile", "r", (thandle_t) & mem_struct,
1297 (TIFFReadWriteProc) tiff_memory_read,
1298 (TIFFReadWriteProc) tiff_memory_write,
1299 tiff_memory_seek, tiff_memory_close,
1300 tiff_memory_size, tiff_map_noop,
1304 ("Insufficient memory to instantiate TIFF image",
1307 TIFFGetField(unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1308 TIFFGetField(unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1309 unwind.eimage = xmalloc_atomic(width * height * 3);
1311 /* #### This is little more than proof-of-concept/function testing.
1312 It needs to be reimplemented via scanline reads for both memory
1315 (uint32 *) _TIFFmalloc(width * height * sizeof(uint32));
1316 if (raster != NULL) {
1321 if (TIFFReadRGBAImage
1322 (unwind.tiff, width, height, raster, 0)) {
1323 for (i = height - 1; i >= 0; i--) {
1324 /* This is to get around weirdness in the libtiff library where properly
1325 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1326 rp = raster + (i * width);
1327 for (j = 0; (uint32) j < width; j++) {
1344 ("Unable to allocate memory for TIFFReadRGBA",
1349 /* now instantiate */
1350 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1351 init_image_instance_from_eimage,
1352 (ii, width, height, 1, unwind.eimage, dest_mask,
1353 instantiator, domain));
1355 unbind_to(speccount, Qnil);
1358 #endif /* HAVE_TIFF */
1361 /**********************************************************************
1363 **********************************************************************/
1364 static void rawrgb_validate(Lisp_Object instantiator)
1366 data_must_be_present(instantiator);
1367 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1368 signal_simple_error("Must supply :pixel-width",
1370 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1371 signal_simple_error("Must supply :pixel-height",
1374 static void rawrgba_validate(Lisp_Object instantiator)
1376 file_or_data_must_be_present(instantiator);
1377 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1378 signal_simple_error("Must supply :pixel-width",
1380 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1381 signal_simple_error("Must supply :pixel-height",
1386 rawrgb_normalize(Lisp_Object inst, Lisp_Object console_type,
1387 Lisp_Object dest_mask)
1389 return simple_image_type_normalize(inst, console_type, Qrawrgb);
1392 rawrgba_normalize(Lisp_Object inst, Lisp_Object console_type,
1393 Lisp_Object dest_mask)
1395 return simple_image_type_normalize(inst, console_type, Qrawrgba);
1398 static int rawrgb_possible_dest_types(void)
1400 return IMAGE_COLOR_PIXMAP_MASK;
1402 static int rawrgba_possible_dest_types(void)
1404 return IMAGE_COLOR_PIXMAP_MASK;
1407 struct rawrgb_unwind_data {
1408 unsigned char *eimage;
1410 struct rawrgba_unwind_data {
1411 unsigned char *eimage;
1414 static Lisp_Object rawrgb_instantiate_unwind(Lisp_Object unwind_obj)
1416 struct rawrgb_unwind_data *data =
1417 (struct rawrgb_unwind_data *)get_opaque_ptr(unwind_obj);
1419 free_opaque_ptr(unwind_obj);
1421 xfree(data->eimage);
1425 static Lisp_Object rawrgba_instantiate_unwind(Lisp_Object unwind_obj)
1427 struct rawrgba_unwind_data *data =
1428 (struct rawrgba_unwind_data *)get_opaque_ptr(unwind_obj);
1430 free_opaque_ptr(unwind_obj);
1432 xfree(data->eimage);
1437 typedef struct rawrgb_memory_storage {
1438 Extbyte *bytes; /* The data */
1439 Extcount len; /* How big is it? */
1440 int index; /* Where are we? */
1441 } rawrgb_memory_storage;
1442 typedef struct rawrgba_memory_storage {
1443 Extbyte *bytes; /* The data */
1444 Extcount len; /* How big is it? */
1445 int index; /* Where are we? */
1446 } rawrgba_memory_storage;
1449 static size_t rawrgb_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1451 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1453 if (size > (mem->len - mem->index))
1454 return (size_t) - 1;
1455 memcpy(buf, mem->bytes + mem->index, size);
1456 mem->index = mem->index + size;
1459 static size_t rawrgba_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1461 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1463 if (size > (mem->len - mem->index))
1464 return (size_t) - 1;
1465 memcpy(buf, mem->bytes + mem->index, size);
1466 mem->index = mem->index + size;
1470 static size_t rawrgb_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1473 return 0; /* Shut up warnings. */
1475 static size_t rawrgba_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1478 return 0; /* Shut up warnings. */
1481 static toff_t rawrgb_memory_seek(thandle_t data, toff_t off, int whence)
1483 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1490 newidx = mem->len + off;
1493 newidx = mem->index + off;
1497 "Eh? invalid seek mode in rawrgb_memory_seek\n");
1498 return (toff_t) - 1;
1501 if ((newidx > mem->len) || (newidx < 0))
1502 return (toff_t) - 1;
1504 mem->index = newidx;
1507 static toff_t rawrgba_memory_seek(thandle_t data, toff_t off, int whence)
1509 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1516 newidx = mem->len + off;
1519 newidx = mem->index + off;
1523 "Eh? invalid seek mode in rawrgba_memory_seek\n");
1524 return (toff_t) - 1;
1527 if ((newidx > mem->len) || (newidx < 0))
1528 return (toff_t) - 1;
1530 mem->index = newidx;
1534 static int rawrgb_memory_close(thandle_t data)
1538 static int rawrgba_memory_close(thandle_t data)
1543 static int rawrgb_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1547 static int rawrgba_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1552 static void rawrgb_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1556 static void rawrgba_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1561 static toff_t rawrgb_memory_size(thandle_t data)
1563 rawrgb_memory_storage *mem = (rawrgb_memory_storage *) data;
1566 static toff_t rawrgba_memory_size(thandle_t data)
1568 rawrgba_memory_storage *mem = (rawrgba_memory_storage *) data;
1574 rawrgb_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1575 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1576 int dest_mask, Lisp_Object domain)
1578 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1579 rawrgb_memory_storage mem_struct;
1580 /* It is OK for the unwind data to be local to this function,
1581 because the unwind-protect is always executed when this
1582 stack frame is still valid. */
1583 struct rawrgb_unwind_data unwind;
1584 int speccount = specpdl_depth();
1585 unsigned long width, height;
1588 record_unwind_protect(rawrgb_instantiate_unwind,
1589 make_opaque_ptr(&unwind));
1592 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1593 Lisp_Object rows = find_keyword_in_vector(instantiator,
1595 Lisp_Object cols = find_keyword_in_vector(instantiator,
1603 assert(!NILP(data));
1607 bytes = XEFFIO(data)->fostorage;
1608 len = XEFFIO(data)->storage_size;
1610 #endif /* HAVE_FFI */
1611 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1612 ALLOCA, (bytes, len), Qbinary);
1613 mem_struct.bytes = bytes;
1614 mem_struct.len = len;
1615 mem_struct.index = 0;
1618 height = XINT(rows);
1620 unwind.eimage = xmalloc_atomic(len);
1622 dp = (unsigned char*)bytes;
1623 for ( ; dp < (unsigned char*)bytes+len; ep++, dp++)
1627 /* now instantiate */
1628 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1629 init_image_instance_from_eimage,
1630 (ii, width, height, 1, unwind.eimage, dest_mask,
1631 instantiator, domain));
1633 unbind_to(speccount, Qnil);
1636 rawrgba_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1637 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1638 int dest_mask, Lisp_Object domain)
1640 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1641 rawrgba_memory_storage mem_struct;
1642 /* It is OK for the unwind data to be local to this function,
1643 because the unwind-protect is always executed when this
1644 stack frame is still valid. */
1645 struct rawrgba_unwind_data unwind;
1646 int speccount = specpdl_depth();
1647 unsigned long width, height;
1650 record_unwind_protect(rawrgba_instantiate_unwind,
1651 make_opaque_ptr(&unwind));
1654 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1655 Lisp_Object rows = find_keyword_in_vector(instantiator,
1657 Lisp_Object cols = find_keyword_in_vector(instantiator,
1665 assert(!NILP(data));
1669 bytes = XEFFIO(data)->fostorage;
1670 len = XEFFIO(data)->storage_size;
1672 #endif /* HAVE_FFI */
1673 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1674 ALLOCA, (bytes, len), Qbinary);
1675 mem_struct.bytes = bytes;
1676 mem_struct.len = len;
1677 mem_struct.index = 0;
1680 height = XINT(rows);
1682 unwind.eimage = xmalloc_atomic(len);
1683 for (ep = unwind.eimage, dp = (unsigned char*)bytes;
1684 dp < (unsigned char*)bytes+len; ep++, dp++) {
1689 /* now instantiate */
1690 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1691 init_image_instance_from_eimage,
1692 (ii, width, height, 1, unwind.eimage, dest_mask,
1693 instantiator, domain));
1695 unbind_to(speccount, Qnil);
1699 /************************************************************************/
1700 /* initialization */
1701 /************************************************************************/
1703 void syms_of_glyphs_eimage(void)
1707 static void check_valid_ffio_or_string(Lisp_Object data)
1710 if (!EFFIOP(data) && !STRINGP(data))
1711 dead_wrong_type_argument(Qstringp, data);
1714 #endif /* HAVE_FFI */
1717 void image_instantiator_format_create_glyphs_eimage(void)
1719 /* image-instantiator types */
1721 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(jpeg, "jpeg");
1723 IIFORMAT_HAS_METHOD(jpeg, validate);
1724 IIFORMAT_HAS_METHOD(jpeg, normalize);
1725 IIFORMAT_HAS_METHOD(jpeg, possible_dest_types);
1726 IIFORMAT_HAS_METHOD(jpeg, instantiate);
1728 IIFORMAT_VALID_KEYWORD(jpeg, Q_data, check_valid_ffio_or_string);
1729 IIFORMAT_VALID_KEYWORD(jpeg, Q_file, check_valid_string);
1733 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(gif, "gif");
1735 IIFORMAT_HAS_METHOD(gif, validate);
1736 IIFORMAT_HAS_METHOD(gif, normalize);
1737 IIFORMAT_HAS_METHOD(gif, possible_dest_types);
1738 IIFORMAT_HAS_METHOD(gif, instantiate);
1740 IIFORMAT_VALID_KEYWORD(gif, Q_data, check_valid_ffio_or_string);
1741 IIFORMAT_VALID_KEYWORD(gif, Q_file, check_valid_string);
1744 #if defined WITH_PNG && defined HAVE_PNG
1745 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(png, "png");
1747 IIFORMAT_HAS_METHOD(png, validate);
1748 IIFORMAT_HAS_METHOD(png, normalize);
1749 IIFORMAT_HAS_METHOD(png, possible_dest_types);
1750 IIFORMAT_HAS_METHOD(png, instantiate);
1752 IIFORMAT_VALID_KEYWORD(png, Q_data, check_valid_ffio_or_string);
1753 IIFORMAT_VALID_KEYWORD(png, Q_file, check_valid_string);
1757 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(tiff, "tiff");
1759 IIFORMAT_HAS_METHOD(tiff, validate);
1760 IIFORMAT_HAS_METHOD(tiff, normalize);
1761 IIFORMAT_HAS_METHOD(tiff, possible_dest_types);
1762 IIFORMAT_HAS_METHOD(tiff, instantiate);
1764 IIFORMAT_VALID_KEYWORD(tiff, Q_data, check_valid_ffio_or_string);
1765 IIFORMAT_VALID_KEYWORD(tiff, Q_file, check_valid_string);
1769 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgb, "rawrgb");
1770 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgba, "rawrgba");
1772 IIFORMAT_HAS_METHOD(rawrgb, validate);
1773 IIFORMAT_HAS_METHOD(rawrgb, normalize);
1774 IIFORMAT_HAS_METHOD(rawrgb, possible_dest_types);
1775 IIFORMAT_HAS_METHOD(rawrgb, instantiate);
1777 IIFORMAT_HAS_METHOD(rawrgba, validate);
1778 IIFORMAT_HAS_METHOD(rawrgba, normalize);
1779 IIFORMAT_HAS_METHOD(rawrgba, possible_dest_types);
1780 IIFORMAT_HAS_METHOD(rawrgba, instantiate);
1782 IIFORMAT_VALID_KEYWORD(rawrgb, Q_data, check_valid_ffio_or_string);
1783 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_width, check_valid_int);
1784 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_height, check_valid_int);
1786 IIFORMAT_VALID_KEYWORD(rawrgba, Q_data, check_valid_ffio_or_string);
1787 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_width, check_valid_int);
1788 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_height, check_valid_int);
1792 void vars_of_glyphs_eimage(void)
1802 #if defined WITH_PNG && defined HAVE_PNG