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();
883 struct png_memory_storage tbr; /* Data to be read */
888 png_uint_32 height, width;
889 int bit_depth, color_type, interlace_type;
891 /* Initialize all PNG structures */
893 png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp *)&png_err_stct,
894 png_error_func, png_warning_func);
896 signal_image_error("Error obtaining memory for png_read",
898 info_ptr = png_create_info_struct(png_ptr);
900 png_destroy_read_struct(&png_ptr, (png_infopp) NULL,
902 signal_image_error("Error obtaining memory for png_read",
907 unwind.png_ptr = png_ptr;
908 unwind.info_ptr = info_ptr;
910 record_unwind_protect(png_instantiate_unwind, make_opaque_ptr(&unwind));
912 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
913 this file, example.c from the libpng 0.81 distribution, and the
914 pngtopnm sources. -WMP-
916 /* It has been further modified to handle the API changes for 0.96,
917 and is no longer usable for previous versions. jh
919 /* It has been further modified to handle libpng 1.5.x --SY */
921 /* Set the jmp_buf return context for png_error ... if this returns !0, then
922 we ran into a problem somewhere, and need to clean up after ourselves. */
923 if (setjmp(png_err_stct.setjmp_buffer)) {
924 /* Something blew up: just display the error (cleanup
925 * happens in the unwind) */
926 signal_image_error_2("Error decoding PNG",
927 build_string(png_err_stct.err_str),
931 /* Initialize the IO layer and read in header information */
933 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
934 const Extbyte *bytes;
941 bytes = XEFFIO(data)->fostorage;
942 len = XEFFIO(data)->storage_size;
944 #endif /* HAVE_FFI */
945 /* #### This is a definite problem under Mule due to the amount of
946 stack data it might allocate. Need to think about using Lstreams */
947 TO_EXTERNAL_FORMAT(LISP_STRING, data, ALLOCA, (bytes, len),
952 png_set_read_fn(png_ptr, (void *)&tbr, png_read_from_memory);
955 png_read_info(png_ptr, info_ptr);
956 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
957 &interlace_type, NULL, NULL);
963 png_bytep row_pointers[height];
965 /* Wow, allocate all the memory. Truly, exciting. */
966 unwind.eimage = xmalloc_atomic(width * height * 3);
967 /* libpng expects that the image buffer passed in contains a
968 picture to draw on top of if the png has any transparencies.
969 This could be a good place to pass that in... */
970 for (y = 0; y < height; y++) {
971 row_pointers[y] = NULL;
974 for (y = 0; y < height; y++) {
975 row_pointers[y] = unwind.eimage + (width * 3 * y);
979 /* if the png specifies a background chunk, go ahead and
980 * use it, else use what we can get
981 * from the default face. */
982 png_color_16 my_background, *image_background;
983 Lisp_Object bkgd = Qnil;
985 my_background.red = 0x7fff;
986 my_background.green = 0x7fff;
987 my_background.blue = 0x7fff;
988 bkgd = FACE_BACKGROUND(Vdefault_face, domain);
989 if (!COLOR_INSTANCEP(bkgd)) {
990 warn_when_safe(Qpng, Qinfo,
991 "Couldn't get background color!");
993 Lisp_Color_Instance *c;
996 c = XCOLOR_INSTANCE(bkgd);
997 rgblist = MAYBE_LISP_DEVMETH(XDEVICE(c->device),
998 color_instance_rgb_components,
1001 (unsigned short)XINT(XCAR(rgblist));
1002 my_background.green =
1003 (unsigned short)XINT(XCAR(XCDR(rgblist)));
1004 my_background.blue =
1006 XINT(XCAR(XCDR(XCDR(rgblist))));
1009 if (png_get_bKGD(png_ptr, info_ptr, &image_background))
1010 png_set_background(png_ptr, image_background,
1011 PNG_BACKGROUND_GAMMA_FILE, 1,
1014 png_set_background(png_ptr, &my_background,
1015 PNG_BACKGROUND_GAMMA_SCREEN,
1019 /* Now that we're using EImage, ask for 8bit RGB triples for any type
1022 /* tell libpng to strip 16 bit depth files down to 8 bits */
1023 if (bit_depth == 16)
1024 png_set_strip_16(png_ptr);
1025 /* if the image is < 8 bits, pad it out */
1026 if (bit_depth < 8) {
1027 if (color_type == PNG_COLOR_TYPE_GRAY)
1028 png_set_expand_gray_1_2_4_to_8(png_ptr);
1030 png_set_packing(png_ptr);
1032 /* convert palette images to full RGB */
1033 if (color_type == PNG_COLOR_TYPE_PALETTE)
1034 png_set_palette_to_rgb(png_ptr);
1035 /* send grayscale images to RGB too */
1036 if (color_type == PNG_COLOR_TYPE_GRAY ||
1037 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1038 png_set_gray_to_rgb(png_ptr);
1040 * Expand paletted or RGB images with transparency to
1041 * full alpha channels so the data will be available
1042 * as RGBA quartets. We don't actually take advantage
1043 * of this yet, but it's not going to hurt, and you
1044 * never know... one of these days... --SY.
1046 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
1047 png_set_tRNS_to_alpha(png_ptr);
1048 /* Turn on interlace handling */
1049 if (interlace_type == PNG_INTERLACE_ADAM7)
1050 passes = png_set_interlace_handling(png_ptr);
1052 /* Update the data */
1053 png_read_update_info(png_ptr, info_ptr);
1055 /* read in the image row by row if interlaced, */
1056 if (interlace_type == PNG_INTERLACE_ADAM7) {
1057 for (pass = 0; pass < passes; pass++) {
1058 for (y = 0; y < height; y++) {
1059 png_read_rows(png_ptr,
1064 } else { /* the whole thing in 1 hit for non-interlaced */
1065 png_read_image(png_ptr, row_pointers);
1067 png_read_end(png_ptr, info_ptr);
1070 /* now instantiate */
1071 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1072 init_image_instance_from_eimage,
1073 (ii, width, height, 1, unwind.eimage, dest_mask,
1074 instantiator, domain));
1076 /* This will clean up everything else. */
1077 unbind_to(speccount, Qnil);
1080 #endif /* HAVE_PNG */
1085 /**********************************************************************
1087 **********************************************************************/
1088 static void tiff_validate(Lisp_Object instantiator)
1090 file_or_data_must_be_present(instantiator);
1094 tiff_normalize(Lisp_Object inst, Lisp_Object console_type,
1095 Lisp_Object dest_mask)
1097 return simple_image_type_normalize(inst, console_type, Qtiff);
1100 static int tiff_possible_dest_types(void)
1102 return IMAGE_COLOR_PIXMAP_MASK;
1105 struct tiff_unwind_data {
1106 unsigned char *eimage;
1107 /* Object that holds the decoded data from a TIFF file */
1111 static Lisp_Object tiff_instantiate_unwind(Lisp_Object unwind_obj)
1113 struct tiff_unwind_data *data =
1114 (struct tiff_unwind_data *)get_opaque_ptr(unwind_obj);
1116 free_opaque_ptr(unwind_obj);
1118 TIFFClose(data->tiff);
1121 xfree(data->eimage);
1126 typedef struct tiff_memory_storage {
1127 Extbyte *bytes; /* The data */
1128 Extcount len; /* How big is it? */
1129 int index; /* Where are we? */
1130 } tiff_memory_storage;
1132 static size_t tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1134 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1136 if (size > (mem->len - mem->index))
1137 return (size_t) - 1;
1138 memcpy(buf, mem->bytes + mem->index, size);
1139 mem->index = mem->index + size;
1143 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1146 return 0; /* Shut up warnings. */
1149 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1151 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1158 newidx = mem->len + off;
1161 newidx = mem->index + off;
1164 fprintf(stderr, "Eh? invalid seek mode in tiff_memory_seek\n");
1165 return (toff_t) - 1;
1168 if ((newidx > mem->len) || (newidx < 0))
1169 return (toff_t) - 1;
1171 mem->index = newidx;
1175 static int tiff_memory_close(thandle_t data)
1180 static int tiff_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1185 static void tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1190 static toff_t tiff_memory_size(thandle_t data)
1192 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1196 struct tiff_error_struct {
1198 jmp_buf setjmp_buffer; /* for return to caller */
1201 /* jh 98/03/12 - ###This struct for passing data to the error functions
1202 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1203 have any place to store error func data. This should be rectified
1204 before SXEmacs gets threads! */
1205 static struct tiff_error_struct tiff_err_data;
1207 static void tiff_error_func(const char *module, const char *fmt, ...)
1212 va_start(vargs, fmt);
1214 n = vsnprintf(tiff_err_data.err_str, sizeof(tiff_err_data.err_str), fmt, vargs);
1215 assert(n>=0 && (size_t)n < sizeof(tiff_err_data.err_str));
1218 /* return to setjmp point */
1219 longjmp(tiff_err_data.setjmp_buffer, 1);
1222 static void tiff_warning_func(const char *module, const char *fmt, ...)
1228 va_start(vargs, fmt);
1230 n = vsnprintf(warn_str, sizeof(warn_str), fmt, vargs);
1231 assert(n>=0 && (size_t)n < sizeof(warn_str));
1233 warn_when_safe(Qtiff, Qinfo, "%s - %s", module, warn_str);
1237 tiff_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1238 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1239 int dest_mask, Lisp_Object domain)
1241 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1242 tiff_memory_storage mem_struct;
1243 /* It is OK for the unwind data to be local to this function,
1244 because the unwind-protect is always executed when this
1245 stack frame is still valid. */
1246 struct tiff_unwind_data unwind;
1247 int speccount = specpdl_depth();
1248 uint32 width, height;
1251 record_unwind_protect(tiff_instantiate_unwind,
1252 make_opaque_ptr(&unwind));
1254 /* set up error facilities */
1255 if (setjmp(tiff_err_data.setjmp_buffer)) {
1256 /* An error was signaled. No clean up is needed, as unwind handles that
1257 for us. Just pass the error along. */
1258 signal_image_error_2("TIFF decoding error",
1259 build_string(tiff_err_data.err_str),
1262 TIFFSetErrorHandler((TIFFErrorHandler) tiff_error_func);
1263 TIFFSetWarningHandler((TIFFErrorHandler) tiff_warning_func);
1265 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1272 assert(!NILP(data));
1276 bytes = XEFFIO(data)->fostorage;
1277 len = XEFFIO(data)->storage_size;
1279 #endif /* HAVE_FFI */
1280 /* #### This is a definite problem under Mule due to the amount of
1281 stack data it might allocate. Think about Lstreams... */
1282 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1283 ALLOCA, (bytes, len), Qbinary);
1284 mem_struct.bytes = bytes;
1285 mem_struct.len = len;
1286 mem_struct.index = 0;
1289 TIFFClientOpen("memfile", "r", (thandle_t) & mem_struct,
1290 (TIFFReadWriteProc) tiff_memory_read,
1291 (TIFFReadWriteProc) tiff_memory_write,
1292 tiff_memory_seek, tiff_memory_close,
1293 tiff_memory_size, tiff_map_noop,
1297 ("Insufficient memory to instantiate TIFF image",
1300 TIFFGetField(unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1301 TIFFGetField(unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1302 unwind.eimage = xmalloc_atomic(width * height * 3);
1304 /* #### This is little more than proof-of-concept/function testing.
1305 It needs to be reimplemented via scanline reads for both memory
1308 (uint32 *) _TIFFmalloc(width * height * sizeof(uint32));
1309 if (raster != NULL) {
1314 if (TIFFReadRGBAImage
1315 (unwind.tiff, width, height, raster, 0)) {
1316 for (i = height - 1; i >= 0; i--) {
1317 /* This is to get around weirdness in the libtiff library where properly
1318 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1319 rp = raster + (i * width);
1320 for (j = 0; (uint32) j < width; j++) {
1337 ("Unable to allocate memory for TIFFReadRGBA",
1342 /* now instantiate */
1343 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1344 init_image_instance_from_eimage,
1345 (ii, width, height, 1, unwind.eimage, dest_mask,
1346 instantiator, domain));
1348 unbind_to(speccount, Qnil);
1351 #endif /* HAVE_TIFF */
1354 /**********************************************************************
1356 **********************************************************************/
1357 static void rawrgb_validate(Lisp_Object instantiator)
1359 data_must_be_present(instantiator);
1360 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1361 signal_simple_error("Must supply :pixel-width",
1363 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1364 signal_simple_error("Must supply :pixel-height",
1367 static void rawrgba_validate(Lisp_Object instantiator)
1369 file_or_data_must_be_present(instantiator);
1370 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1371 signal_simple_error("Must supply :pixel-width",
1373 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1374 signal_simple_error("Must supply :pixel-height",
1379 rawrgb_normalize(Lisp_Object inst, Lisp_Object console_type,
1380 Lisp_Object dest_mask)
1382 return simple_image_type_normalize(inst, console_type, Qrawrgb);
1385 rawrgba_normalize(Lisp_Object inst, Lisp_Object console_type,
1386 Lisp_Object dest_mask)
1388 return simple_image_type_normalize(inst, console_type, Qrawrgba);
1391 static int rawrgb_possible_dest_types(void)
1393 return IMAGE_COLOR_PIXMAP_MASK;
1395 static int rawrgba_possible_dest_types(void)
1397 return IMAGE_COLOR_PIXMAP_MASK;
1400 struct rawrgb_unwind_data {
1401 unsigned char *eimage;
1403 struct rawrgba_unwind_data {
1404 unsigned char *eimage;
1407 static Lisp_Object rawrgb_instantiate_unwind(Lisp_Object unwind_obj)
1409 struct rawrgb_unwind_data *data =
1410 (struct rawrgb_unwind_data *)get_opaque_ptr(unwind_obj);
1412 free_opaque_ptr(unwind_obj);
1414 xfree(data->eimage);
1418 static Lisp_Object rawrgba_instantiate_unwind(Lisp_Object unwind_obj)
1420 struct rawrgba_unwind_data *data =
1421 (struct rawrgba_unwind_data *)get_opaque_ptr(unwind_obj);
1423 free_opaque_ptr(unwind_obj);
1425 xfree(data->eimage);
1430 typedef struct rawrgb_memory_storage {
1431 Extbyte *bytes; /* The data */
1432 Extcount len; /* How big is it? */
1433 int index; /* Where are we? */
1434 } rawrgb_memory_storage;
1435 typedef struct rawrgba_memory_storage {
1436 Extbyte *bytes; /* The data */
1437 Extcount len; /* How big is it? */
1438 int index; /* Where are we? */
1439 } rawrgba_memory_storage;
1442 static size_t rawrgb_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1444 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1446 if (size > (mem->len - mem->index))
1447 return (size_t) - 1;
1448 memcpy(buf, mem->bytes + mem->index, size);
1449 mem->index = mem->index + size;
1452 static size_t rawrgba_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1454 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1456 if (size > (mem->len - mem->index))
1457 return (size_t) - 1;
1458 memcpy(buf, mem->bytes + mem->index, size);
1459 mem->index = mem->index + size;
1463 static size_t rawrgb_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1466 return 0; /* Shut up warnings. */
1468 static size_t rawrgba_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1471 return 0; /* Shut up warnings. */
1474 static toff_t rawrgb_memory_seek(thandle_t data, toff_t off, int whence)
1476 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1483 newidx = mem->len + off;
1486 newidx = mem->index + off;
1490 "Eh? invalid seek mode in rawrgb_memory_seek\n");
1491 return (toff_t) - 1;
1494 if ((newidx > mem->len) || (newidx < 0))
1495 return (toff_t) - 1;
1497 mem->index = newidx;
1500 static toff_t rawrgba_memory_seek(thandle_t data, toff_t off, int whence)
1502 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1509 newidx = mem->len + off;
1512 newidx = mem->index + off;
1516 "Eh? invalid seek mode in rawrgba_memory_seek\n");
1517 return (toff_t) - 1;
1520 if ((newidx > mem->len) || (newidx < 0))
1521 return (toff_t) - 1;
1523 mem->index = newidx;
1527 static int rawrgb_memory_close(thandle_t data)
1531 static int rawrgba_memory_close(thandle_t data)
1536 static int rawrgb_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1540 static int rawrgba_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1545 static void rawrgb_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1549 static void rawrgba_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1554 static toff_t rawrgb_memory_size(thandle_t data)
1556 rawrgb_memory_storage *mem = (rawrgb_memory_storage *) data;
1559 static toff_t rawrgba_memory_size(thandle_t data)
1561 rawrgba_memory_storage *mem = (rawrgba_memory_storage *) data;
1567 rawrgb_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1568 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1569 int dest_mask, Lisp_Object domain)
1571 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1572 rawrgb_memory_storage mem_struct;
1573 /* It is OK for the unwind data to be local to this function,
1574 because the unwind-protect is always executed when this
1575 stack frame is still valid. */
1576 struct rawrgb_unwind_data unwind;
1577 int speccount = specpdl_depth();
1578 unsigned long width, height;
1581 record_unwind_protect(rawrgb_instantiate_unwind,
1582 make_opaque_ptr(&unwind));
1585 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1586 Lisp_Object rows = find_keyword_in_vector(instantiator,
1588 Lisp_Object cols = find_keyword_in_vector(instantiator,
1596 assert(!NILP(data));
1600 bytes = XEFFIO(data)->fostorage;
1601 len = XEFFIO(data)->storage_size;
1603 #endif /* HAVE_FFI */
1604 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1605 ALLOCA, (bytes, len), Qbinary);
1606 mem_struct.bytes = bytes;
1607 mem_struct.len = len;
1608 mem_struct.index = 0;
1611 height = XINT(rows);
1613 unwind.eimage = xmalloc_atomic(len);
1615 dp = (unsigned char*)bytes;
1616 for ( ; dp < (unsigned char*)bytes+len; ep++, dp++)
1620 /* now instantiate */
1621 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1622 init_image_instance_from_eimage,
1623 (ii, width, height, 1, unwind.eimage, dest_mask,
1624 instantiator, domain));
1626 unbind_to(speccount, Qnil);
1629 rawrgba_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1630 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1631 int dest_mask, Lisp_Object domain)
1633 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1634 rawrgba_memory_storage mem_struct;
1635 /* It is OK for the unwind data to be local to this function,
1636 because the unwind-protect is always executed when this
1637 stack frame is still valid. */
1638 struct rawrgba_unwind_data unwind;
1639 int speccount = specpdl_depth();
1640 unsigned long width, height;
1643 record_unwind_protect(rawrgba_instantiate_unwind,
1644 make_opaque_ptr(&unwind));
1647 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1648 Lisp_Object rows = find_keyword_in_vector(instantiator,
1650 Lisp_Object cols = find_keyword_in_vector(instantiator,
1658 assert(!NILP(data));
1662 bytes = XEFFIO(data)->fostorage;
1663 len = XEFFIO(data)->storage_size;
1665 #endif /* HAVE_FFI */
1666 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1667 ALLOCA, (bytes, len), Qbinary);
1668 mem_struct.bytes = bytes;
1669 mem_struct.len = len;
1670 mem_struct.index = 0;
1673 height = XINT(rows);
1675 unwind.eimage = xmalloc_atomic(len);
1676 for (ep = unwind.eimage, dp = (unsigned char*)bytes;
1677 dp < (unsigned char*)bytes+len; ep++, dp++) {
1682 /* now instantiate */
1683 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1684 init_image_instance_from_eimage,
1685 (ii, width, height, 1, unwind.eimage, dest_mask,
1686 instantiator, domain));
1688 unbind_to(speccount, Qnil);
1692 /************************************************************************/
1693 /* initialization */
1694 /************************************************************************/
1696 void syms_of_glyphs_eimage(void)
1700 static void check_valid_ffio_or_string(Lisp_Object data)
1703 if (!EFFIOP(data) && !STRINGP(data))
1704 dead_wrong_type_argument(Qstringp, data);
1707 #endif /* HAVE_FFI */
1710 void image_instantiator_format_create_glyphs_eimage(void)
1712 /* image-instantiator types */
1714 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(jpeg, "jpeg");
1716 IIFORMAT_HAS_METHOD(jpeg, validate);
1717 IIFORMAT_HAS_METHOD(jpeg, normalize);
1718 IIFORMAT_HAS_METHOD(jpeg, possible_dest_types);
1719 IIFORMAT_HAS_METHOD(jpeg, instantiate);
1721 IIFORMAT_VALID_KEYWORD(jpeg, Q_data, check_valid_ffio_or_string);
1722 IIFORMAT_VALID_KEYWORD(jpeg, Q_file, check_valid_string);
1726 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(gif, "gif");
1728 IIFORMAT_HAS_METHOD(gif, validate);
1729 IIFORMAT_HAS_METHOD(gif, normalize);
1730 IIFORMAT_HAS_METHOD(gif, possible_dest_types);
1731 IIFORMAT_HAS_METHOD(gif, instantiate);
1733 IIFORMAT_VALID_KEYWORD(gif, Q_data, check_valid_ffio_or_string);
1734 IIFORMAT_VALID_KEYWORD(gif, Q_file, check_valid_string);
1737 #if defined WITH_PNG && defined HAVE_PNG
1738 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(png, "png");
1740 IIFORMAT_HAS_METHOD(png, validate);
1741 IIFORMAT_HAS_METHOD(png, normalize);
1742 IIFORMAT_HAS_METHOD(png, possible_dest_types);
1743 IIFORMAT_HAS_METHOD(png, instantiate);
1745 IIFORMAT_VALID_KEYWORD(png, Q_data, check_valid_ffio_or_string);
1746 IIFORMAT_VALID_KEYWORD(png, Q_file, check_valid_string);
1750 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(tiff, "tiff");
1752 IIFORMAT_HAS_METHOD(tiff, validate);
1753 IIFORMAT_HAS_METHOD(tiff, normalize);
1754 IIFORMAT_HAS_METHOD(tiff, possible_dest_types);
1755 IIFORMAT_HAS_METHOD(tiff, instantiate);
1757 IIFORMAT_VALID_KEYWORD(tiff, Q_data, check_valid_ffio_or_string);
1758 IIFORMAT_VALID_KEYWORD(tiff, Q_file, check_valid_string);
1762 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgb, "rawrgb");
1763 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgba, "rawrgba");
1765 IIFORMAT_HAS_METHOD(rawrgb, validate);
1766 IIFORMAT_HAS_METHOD(rawrgb, normalize);
1767 IIFORMAT_HAS_METHOD(rawrgb, possible_dest_types);
1768 IIFORMAT_HAS_METHOD(rawrgb, instantiate);
1770 IIFORMAT_HAS_METHOD(rawrgba, validate);
1771 IIFORMAT_HAS_METHOD(rawrgba, normalize);
1772 IIFORMAT_HAS_METHOD(rawrgba, possible_dest_types);
1773 IIFORMAT_HAS_METHOD(rawrgba, instantiate);
1775 IIFORMAT_VALID_KEYWORD(rawrgb, Q_data, check_valid_ffio_or_string);
1776 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_width, check_valid_int);
1777 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_height, check_valid_int);
1779 IIFORMAT_VALID_KEYWORD(rawrgba, Q_data, check_valid_ffio_or_string);
1780 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_width, check_valid_int);
1781 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_height, check_valid_int);
1785 void vars_of_glyphs_eimage(void)
1795 #if defined WITH_PNG && defined HAVE_PNG