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 = NULL;
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 if ( bytes != NULL ) {
397 jpeg_memory_src(&cinfo, (const JOCTET*)bytes, len);
400 ("Unable to transcode image source",
405 /* Step 3: read file parameters with jpeg_read_header() */
407 jpeg_read_header(&cinfo, TRUE);
408 /* We can ignore the return value from jpeg_read_header since
409 * (a) suspension is not possible with the stdio data source, and
410 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
411 * See libjpeg.doc for more info.
415 int jpeg_gray = 0; /* if we're dealing with a grayscale */
416 /* Step 4: set parameters for decompression. */
418 /* Now that we're using EImages, send all data as 24bit color.
419 The backend routine will take care of any necessary reductions.
420 We do have to handle the grayscale case ourselves, however. */
421 if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
422 cinfo.out_color_space = JCS_GRAYSCALE;
425 /* we're relying on the jpeg driver to do any other conversions,
426 or signal an error if the conversion isn't supported. */
427 cinfo.out_color_space = JCS_RGB;
430 /* Step 5: Start decompressor */
431 jpeg_start_decompress(&cinfo);
433 /* Step 6: Read in the data and put into EImage format (8bit RGB
435 unwind.eimage = xmalloc_atomic(cinfo.output_width *
436 cinfo.output_height * 3);
437 if (!unwind.eimage) {
439 ("Unable to allocate enough memory for image",
444 JSAMPARRAY row_buffer; /* Output row buffer */
446 int row_stride; /* physical row width in output buffer */
447 unsigned char *op = unwind.eimage;
449 /* We may need to do some setup of our own at this point
450 * before reading the data. After
451 * jpeg_start_decompress() we have the correct scaled
452 * output image dimensions available
453 * We need to make an output work buffer of the right
455 /* JSAMPLEs per row in output buffer. */
456 row_stride = cinfo.output_width *
457 cinfo.output_components;
458 /* Make a one-row-high sample array that will go away
459 * when done with image */
460 row_buffer = ((*cinfo.mem->alloc_sarray)
461 ((j_common_ptr) & cinfo, JPOOL_IMAGE,
464 /* Here we use the library's state variable
465 * cinfo.output_scanline as the loop counter, so that
466 * we don't have to keep track ourselves. */
467 while (cinfo.output_scanline < cinfo.output_height) {
470 /* jpeg_read_scanlines expects an array of
471 * pointers to scanlines.
472 * Here the array is only one element long,
473 * but you could ask for more than one
474 * scanline at a time if that's more
476 (void)jpeg_read_scanlines(&cinfo, row_buffer,
479 for (i = 0; i < cinfo.output_width; i++) {
483 #if (BITS_IN_JSAMPLE == 8)
484 val = (unsigned char)*jp++;
485 #else /* other option is 12 */
487 (unsigned char)(*jp++ >> 4);
489 /* copy the same value
491 for (clr = 0; clr < 3; clr++) {
495 for (clr = 0; clr < 3; clr++) {
496 #if (BITS_IN_JSAMPLE == 8)
497 *op++ = (unsigned char)
499 #else /* other option is 12 */
500 *op++ = (unsigned char)
510 /* Step 6.5: Create the pixmap and set up the image instance */
511 /* now instantiate */
512 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
513 init_image_instance_from_eimage,
514 (ii, cinfo.output_width, cinfo.output_height, 1,
515 unwind.eimage, dest_mask, instantiator, domain));
517 /* Step 7: Finish decompression */
519 jpeg_finish_decompress(&cinfo);
520 /* We can ignore the return value since suspension is not possible
521 * with the stdio data source.
524 /* And we're done! */
525 /* This will clean up everything else. */
526 unbind_to(speccount, Qnil);
529 #endif /* HAVE_JPEG */
532 /**********************************************************************
534 **********************************************************************/
538 static void gif_validate(Lisp_Object instantiator)
540 file_or_data_must_be_present(instantiator);
544 gif_normalize(Lisp_Object inst, Lisp_Object console_type, Lisp_Object dest_mask)
546 return simple_image_type_normalize(inst, console_type, Qgif);
549 static int gif_possible_dest_types(void)
551 return IMAGE_COLOR_PIXMAP_MASK;
554 /* To survive the otherwise baffling complexity of making sure
555 everything gets cleaned up in the presence of an error, we
556 use an unwind_protect(). */
558 struct gif_unwind_data {
559 unsigned char *eimage;
560 /* Object that holds the decoded data from a GIF file */
561 GifFileType *giffile;
564 static Lisp_Object gif_instantiate_unwind(Lisp_Object unwind_obj)
566 struct gif_unwind_data *data =
567 (struct gif_unwind_data *)get_opaque_ptr(unwind_obj);
569 free_opaque_ptr(unwind_obj);
571 DGifCloseFile(data->giffile);
572 GifFree(data->giffile);
580 typedef struct gif_memory_storage {
581 Extbyte *bytes; /* The data */
582 Extcount len; /* How big is it? */
583 int index; /* Where are we? */
584 } gif_memory_storage;
586 static size_t gif_read_from_memory(GifByteType * buf, size_t size, VoidPtr data)
588 gif_memory_storage *mem = (gif_memory_storage *) data;
590 if ((ssize_t) size > (mem->len - mem->index))
592 memcpy(buf, mem->bytes + mem->index, size);
593 mem->index = mem->index + size;
597 static int gif_memory_close(VoidPtr data)
602 struct gif_error_struct {
603 const char *err_str; /* return the error string */
604 jmp_buf setjmp_buffer; /* for return to caller */
607 static void gif_error_func(const char *err_str, VoidPtr error_ptr)
609 struct gif_error_struct *error_data =
610 (struct gif_error_struct *)error_ptr;
612 /* return to setjmp point */
613 error_data->err_str = err_str;
614 longjmp(error_data->setjmp_buffer, 1);
618 gif_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
619 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
620 int dest_mask, Lisp_Object domain)
622 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
623 /* It is OK for the unwind data to be local to this function,
624 because the unwind-protect is always executed when this
625 stack frame is still valid. */
626 struct gif_unwind_data unwind;
627 int speccount = specpdl_depth();
628 gif_memory_storage mem_struct;
629 struct gif_error_struct gif_err;
630 Extbyte *bytes = NULL;
636 record_unwind_protect(gif_instantiate_unwind, make_opaque_ptr(&unwind));
638 /* 1. Now decode the data. */
641 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
645 if (!(unwind.giffile = GifSetup()))
647 ("Insufficient memory to instantiate GIF image",
650 /* set up error facilities */
651 if (setjmp(gif_err.setjmp_buffer)) {
652 /* An error was signaled. No clean up is needed, as unwind handles that
653 for us. Just pass the error along. */
654 Lisp_Object errstring;
655 errstring = build_string(gif_err.err_str);
656 signal_image_error_2("GIF decoding error", errstring,
659 GifSetErrorFunc(unwind.giffile, (Gif_error_func) gif_error_func,
660 (VoidPtr) & gif_err);
664 bytes = XEFFIO(data)->fostorage;
665 len = XEFFIO(data)->storage_size;
667 #endif /* HAVE_FFI */
668 TO_EXTERNAL_FORMAT(LISP_STRING, data, ALLOCA, (bytes, len),
670 if ( bytes == NULL ) {
672 ("Error reading GIF data",
675 mem_struct.bytes = bytes;
676 mem_struct.len = len;
677 mem_struct.index = 0;
678 GifSetReadFunc(unwind.giffile, gif_read_from_memory,
679 (VoidPtr) & mem_struct);
680 GifSetCloseFunc(unwind.giffile, gif_memory_close,
681 (VoidPtr) & mem_struct);
682 DGifInitRead(unwind.giffile);
684 /* Then slurp the image into memory, decoding
685 along the way. The result is the image in
686 a simple one-byte-per-pixel format (####
687 the GIF routines only support 8-bit GIFs,
689 DGifSlurp(unwind.giffile);
693 /* 3. Now create the EImage(s) */
695 ColorMapObject *cmo = unwind.giffile->SColorMap;
696 int i, j, row, pass, interlace, slice;
698 /* interlaced gifs have rows in this order:
699 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
700 static int InterlacedOffset[] = { 0, 4, 2, 1 };
701 static int InterlacedJumps[] = { 8, 8, 4, 2 };
703 height = unwind.giffile->SHeight;
704 width = unwind.giffile->SWidth;
705 unwind.eimage = xmalloc_atomic(width * height * 3 *
706 unwind.giffile->ImageCount);
707 if (!unwind.eimage) {
709 ("Unable to allocate enough memory for image",
713 /* write the data in EImage format (8bit RGB triples) */
714 for (slice = 0; slice < unwind.giffile->ImageCount; slice++) {
715 /* We check here that the current image covers the full
717 if (unwind.giffile->SavedImages[slice].ImageDesc.
719 || unwind.giffile->SavedImages[slice].ImageDesc.
721 || unwind.giffile->SavedImages[slice].ImageDesc.
723 || unwind.giffile->SavedImages[slice].ImageDesc.
726 ("Image in GIF file is not full size",
730 unwind.giffile->SavedImages[slice].ImageDesc.
733 row = interlace ? InterlacedOffset[pass] : 0;
734 eip = unwind.eimage + (width * height * 3 * slice);
735 for (i = 0; i < height; i++) {
738 row = InterlacedOffset[++pass];
739 while (row >= height)
746 (width * height * 3 * slice) +
748 for (j = 0; j < width; j++) {
749 unsigned char pixel =
750 unwind.giffile->SavedImages[slice].
751 RasterBits[(i * width) + j];
752 *eip++ = cmo->Colors[pixel].Red;
753 *eip++ = cmo->Colors[pixel].Green;
754 *eip++ = cmo->Colors[pixel].Blue;
756 row += interlace ? InterlacedJumps[pass] : 1;
760 /* now instantiate */
761 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
762 init_image_instance_from_eimage,
763 (ii, width, height, unwind.giffile->ImageCount,
764 unwind.eimage, dest_mask, instantiator, domain));
767 /* We read the gif successfully. If we have more than one slice then
769 if (unwind.giffile->ImageCount > 1) {
770 /* See if there is a timeout value. In theory there could be one
771 for every image - but that makes the implementation way to
772 complicated for now so we just take the first. */
773 unsigned short timeout = 0;
776 if (unwind.giffile->SavedImages[0].Function ==
777 GRAPHICS_EXT_FUNC_CODE
778 && unwind.giffile->SavedImages[0].ExtensionBlockCount) {
779 timeout = (unsigned short)
780 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].
782 unwind.giffile->SavedImages[0].ExtensionBlocks[0].
786 /* Too short a timeout will crucify us performance-wise. */
788 add_glyph_animated_timeout(timeout > 10 ? timeout : 10,
792 IMAGE_INSTANCE_PIXMAP_TIMEOUT(ii) = XINT(tid);
795 unbind_to(speccount, Qnil);
798 #endif /* HAVE_GIF */
800 #if defined WITH_PNG && defined HAVE_PNG
802 /**********************************************************************
804 **********************************************************************/
805 static void png_validate(Lisp_Object instantiator)
807 file_or_data_must_be_present(instantiator);
811 png_normalize(Lisp_Object inst, Lisp_Object console_type, Lisp_Object dest_mask)
813 return simple_image_type_normalize(inst, console_type, Qpng);
816 static int png_possible_dest_types(void)
818 return IMAGE_COLOR_PIXMAP_MASK;
821 struct png_memory_storage {
822 const Extbyte *bytes; /* The data */
823 Extcount len; /* How big is it? */
824 int index; /* Where are we? */
828 png_read_from_memory(png_structp png_ptr, png_bytep data, png_size_t length)
830 struct png_memory_storage *tbr =
831 (struct png_memory_storage *)png_get_io_ptr(png_ptr);
833 if ((ssize_t) length > (tbr->len - tbr->index))
834 png_error(png_ptr, (png_const_charp) "Read Error");
835 memcpy(data, tbr->bytes + tbr->index, length);
836 tbr->index = tbr->index + length;
839 struct png_error_struct {
841 jmp_buf setjmp_buffer; /* for return to caller */
844 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
845 structure, and there are cases where the size can be different from
846 between inside the library, and inside the code! To do an end run
847 around this, use our own error functions, and don't rely on things
848 passed in the png_ptr to them. This is an ugly hack and must
849 go away when the lisp engine is threaded! */
850 static struct png_error_struct png_err_stct;
852 static void png_error_func(png_structp png_ptr, png_const_charp msg)
854 png_err_stct.err_str = msg;
855 longjmp(png_err_stct.setjmp_buffer, 1);
858 static void png_warning_func(png_structp png_ptr, png_const_charp msg)
860 warn_when_safe(Qpng, Qinfo, "%s", msg);
863 struct png_unwind_data {
865 unsigned char *eimage;
870 static Lisp_Object png_instantiate_unwind(Lisp_Object unwind_obj)
872 struct png_unwind_data *data =
873 (struct png_unwind_data *)get_opaque_ptr(unwind_obj);
875 free_opaque_ptr(unwind_obj);
877 png_destroy_read_struct(&(data->png_ptr), &(data->info_ptr),
880 fclose(data->instream);
889 png_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
890 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
891 int dest_mask, Lisp_Object domain)
893 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
894 struct png_unwind_data unwind;
895 int speccount = specpdl_depth();
896 struct png_memory_storage tbr; /* Data to be read */
901 png_uint_32 height, width;
902 int bit_depth, color_type, interlace_type;
904 /* Initialize all PNG structures */
906 png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp *)&png_err_stct,
907 png_error_func, png_warning_func);
909 signal_image_error("Error obtaining memory for png_read",
911 info_ptr = png_create_info_struct(png_ptr);
913 png_destroy_read_struct(&png_ptr, (png_infopp) NULL,
915 signal_image_error("Error obtaining memory for png_read",
921 unwind.png_ptr = png_ptr;
922 unwind.info_ptr = info_ptr;
924 record_unwind_protect(png_instantiate_unwind, make_opaque_ptr(&unwind));
926 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
927 this file, example.c from the libpng 0.81 distribution, and the
928 pngtopnm sources. -WMP-
930 /* It has been further modified to handle the API changes for 0.96,
931 and is no longer usable for previous versions. jh
933 /* It has been further modified to handle libpng 1.5.x --SY */
935 /* Set the jmp_buf return context for png_error ... if this returns !0, then
936 we ran into a problem somewhere, and need to clean up after ourselves. */
937 if (setjmp(png_err_stct.setjmp_buffer)) {
938 /* Something blew up: just display the error (cleanup
939 * happens in the unwind) */
940 signal_image_error_2("Error decoding PNG",
941 build_string(png_err_stct.err_str),
945 /* Initialize the IO layer and read in header information */
947 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
948 const Extbyte *bytes = NULL;
955 bytes = XEFFIO(data)->fostorage;
956 len = XEFFIO(data)->storage_size;
958 #endif /* HAVE_FFI */
959 /* #### This is a definite problem under Mule due to the amount of
960 stack data it might allocate. Need to think about using Lstreams */
961 TO_EXTERNAL_FORMAT(LISP_STRING, data, ALLOCA, (bytes, len),
963 if ( bytes != NULL ) {
967 png_set_read_fn(png_ptr, (void *)&tbr, png_read_from_memory);
969 signal_image_error("Error reading PNG data", instantiator);
973 png_read_info(png_ptr, info_ptr);
974 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
975 &interlace_type, NULL, NULL);
981 png_bytep row_pointers[height];
983 /* Wow, allocate all the memory. Truly, exciting. */
984 unwind.eimage = xmalloc_atomic(width * height * 3);
985 /* libpng expects that the image buffer passed in contains a
986 picture to draw on top of if the png has any transparencies.
987 This could be a good place to pass that in... */
988 for (y = 0; y < height; y++) {
989 row_pointers[y] = NULL;
992 for (y = 0; y < height; y++) {
993 row_pointers[y] = unwind.eimage + (width * 3 * y);
997 /* if the png specifies a background chunk, go ahead and
998 * use it, else use what we can get
999 * from the default face. */
1000 png_color_16 my_background, *image_background;
1001 Lisp_Object bkgd = Qnil;
1003 my_background.red = 0x7fff;
1004 my_background.green = 0x7fff;
1005 my_background.blue = 0x7fff;
1006 bkgd = FACE_BACKGROUND(Vdefault_face, domain);
1007 if (!COLOR_INSTANCEP(bkgd)) {
1008 warn_when_safe(Qpng, Qinfo,
1009 "Couldn't get background color!");
1011 Lisp_Color_Instance *c;
1012 Lisp_Object rgblist;
1014 c = XCOLOR_INSTANCE(bkgd);
1015 rgblist = MAYBE_LISP_DEVMETH(XDEVICE(c->device),
1016 color_instance_rgb_components,
1019 (unsigned short)XINT(XCAR(rgblist));
1020 my_background.green =
1021 (unsigned short)XINT(XCAR(XCDR(rgblist)));
1022 my_background.blue =
1024 XINT(XCAR(XCDR(XCDR(rgblist))));
1027 if (png_get_bKGD(png_ptr, info_ptr, &image_background))
1028 png_set_background(png_ptr, image_background,
1029 PNG_BACKGROUND_GAMMA_FILE, 1,
1032 png_set_background(png_ptr, &my_background,
1033 PNG_BACKGROUND_GAMMA_SCREEN,
1037 /* Now that we're using EImage, ask for 8bit RGB triples for any type
1040 /* tell libpng to strip 16 bit depth files down to 8 bits */
1041 if (bit_depth == 16)
1042 png_set_strip_16(png_ptr);
1043 /* if the image is < 8 bits, pad it out */
1044 if (bit_depth < 8) {
1045 if (color_type == PNG_COLOR_TYPE_GRAY)
1046 png_set_expand_gray_1_2_4_to_8(png_ptr);
1048 png_set_packing(png_ptr);
1050 /* convert palette images to full RGB */
1051 if (color_type == PNG_COLOR_TYPE_PALETTE)
1052 png_set_palette_to_rgb(png_ptr);
1053 /* send grayscale images to RGB too */
1054 if (color_type == PNG_COLOR_TYPE_GRAY ||
1055 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1056 png_set_gray_to_rgb(png_ptr);
1058 * Expand paletted or RGB images with transparency to
1059 * full alpha channels so the data will be available
1060 * as RGBA quartets. We don't actually take advantage
1061 * of this yet, but it's not going to hurt, and you
1062 * never know... one of these days... --SY.
1064 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
1065 png_set_tRNS_to_alpha(png_ptr);
1066 /* Turn on interlace handling */
1067 if (interlace_type == PNG_INTERLACE_ADAM7)
1068 passes = png_set_interlace_handling(png_ptr);
1070 /* Update the data */
1071 png_read_update_info(png_ptr, info_ptr);
1073 /* read in the image row by row if interlaced, */
1074 if (interlace_type == PNG_INTERLACE_ADAM7) {
1075 for (pass = 0; pass < passes; pass++) {
1076 for (y = 0; y < height; y++) {
1077 png_read_rows(png_ptr,
1082 } else { /* the whole thing in 1 hit for non-interlaced */
1083 png_read_image(png_ptr, row_pointers);
1085 png_read_end(png_ptr, info_ptr);
1088 /* now instantiate */
1089 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1090 init_image_instance_from_eimage,
1091 (ii, width, height, 1, unwind.eimage, dest_mask,
1092 instantiator, domain));
1094 /* This will clean up everything else. */
1095 unbind_to(speccount, Qnil);
1098 #endif /* HAVE_PNG */
1103 /**********************************************************************
1105 **********************************************************************/
1106 static void tiff_validate(Lisp_Object instantiator)
1108 file_or_data_must_be_present(instantiator);
1112 tiff_normalize(Lisp_Object inst, Lisp_Object console_type,
1113 Lisp_Object dest_mask)
1115 return simple_image_type_normalize(inst, console_type, Qtiff);
1118 static int tiff_possible_dest_types(void)
1120 return IMAGE_COLOR_PIXMAP_MASK;
1123 struct tiff_unwind_data {
1124 unsigned char *eimage;
1125 /* Object that holds the decoded data from a TIFF file */
1129 static Lisp_Object tiff_instantiate_unwind(Lisp_Object unwind_obj)
1131 struct tiff_unwind_data *data =
1132 (struct tiff_unwind_data *)get_opaque_ptr(unwind_obj);
1134 free_opaque_ptr(unwind_obj);
1136 TIFFClose(data->tiff);
1139 xfree(data->eimage);
1144 typedef struct tiff_memory_storage {
1145 Extbyte *bytes; /* The data */
1146 Extcount len; /* How big is it? */
1147 int index; /* Where are we? */
1148 } tiff_memory_storage;
1150 static size_t tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1152 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1154 if (size > (mem->len - mem->index))
1155 return (size_t) - 1;
1156 memcpy(buf, mem->bytes + mem->index, size);
1157 mem->index = mem->index + size;
1161 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1164 return 0; /* Shut up warnings. */
1167 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1169 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1176 newidx = mem->len + off;
1179 newidx = mem->index + off;
1182 fprintf(stderr, "Eh? invalid seek mode in tiff_memory_seek\n");
1183 return (toff_t) - 1;
1186 if ((newidx > mem->len) || (newidx < 0))
1187 return (toff_t) - 1;
1189 mem->index = newidx;
1193 static int tiff_memory_close(thandle_t data)
1198 static int tiff_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1203 static void tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1208 static toff_t tiff_memory_size(thandle_t data)
1210 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1214 struct tiff_error_struct {
1216 jmp_buf setjmp_buffer; /* for return to caller */
1219 /* jh 98/03/12 - ###This struct for passing data to the error functions
1220 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1221 have any place to store error func data. This should be rectified
1222 before SXEmacs gets threads! */
1223 static struct tiff_error_struct tiff_err_data;
1225 static void tiff_error_func(const char *module, const char *fmt, ...)
1230 va_start(vargs, fmt);
1232 n = vsnprintf(tiff_err_data.err_str, sizeof(tiff_err_data.err_str), fmt, vargs);
1233 assert(n>=0 && (size_t)n < sizeof(tiff_err_data.err_str));
1236 /* return to setjmp point */
1237 longjmp(tiff_err_data.setjmp_buffer, 1);
1240 static void tiff_warning_func(const char *module, const char *fmt, ...)
1246 va_start(vargs, fmt);
1248 n = vsnprintf(warn_str, sizeof(warn_str), fmt, vargs);
1249 assert(n>=0 && (size_t)n < sizeof(warn_str));
1251 warn_when_safe(Qtiff, Qinfo, "%s - %s", module, warn_str);
1255 tiff_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1256 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1257 int dest_mask, Lisp_Object domain)
1259 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1260 tiff_memory_storage mem_struct;
1261 /* It is OK for the unwind data to be local to this function,
1262 because the unwind-protect is always executed when this
1263 stack frame is still valid. */
1264 struct tiff_unwind_data unwind;
1265 int speccount = specpdl_depth();
1266 uint32 width, height;
1269 record_unwind_protect(tiff_instantiate_unwind,
1270 make_opaque_ptr(&unwind));
1272 /* set up error facilities */
1273 if (setjmp(tiff_err_data.setjmp_buffer)) {
1274 /* An error was signaled. No clean up is needed, as unwind handles that
1275 for us. Just pass the error along. */
1276 signal_image_error_2("TIFF decoding error",
1277 build_string(tiff_err_data.err_str),
1280 TIFFSetErrorHandler((TIFFErrorHandler) tiff_error_func);
1281 TIFFSetWarningHandler((TIFFErrorHandler) tiff_warning_func);
1283 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1284 Extbyte *bytes = NULL;
1290 assert(!NILP(data));
1294 bytes = XEFFIO(data)->fostorage;
1295 len = XEFFIO(data)->storage_size;
1297 #endif /* HAVE_FFI */
1298 /* #### This is a definite problem under Mule due to the amount of
1299 stack data it might allocate. Think about Lstreams... */
1300 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1301 ALLOCA, (bytes, len), Qbinary);
1302 if ( bytes == NULL ) {
1304 ("Unable to encode filename", instantiator);
1306 mem_struct.bytes = bytes;
1307 mem_struct.len = len;
1308 mem_struct.index = 0;
1311 TIFFClientOpen("memfile", "r", (thandle_t) & mem_struct,
1312 (TIFFReadWriteProc) tiff_memory_read,
1313 (TIFFReadWriteProc) tiff_memory_write,
1314 tiff_memory_seek, tiff_memory_close,
1315 tiff_memory_size, tiff_map_noop,
1319 ("Insufficient memory to instantiate TIFF image",
1322 TIFFGetField(unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1323 TIFFGetField(unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1324 unwind.eimage = xmalloc_atomic(width * height * 3);
1326 /* #### This is little more than proof-of-concept/function testing.
1327 It needs to be reimplemented via scanline reads for both memory
1330 (uint32 *) _TIFFmalloc(width * height * sizeof(uint32));
1331 if (raster != NULL) {
1336 if (TIFFReadRGBAImage
1337 (unwind.tiff, width, height, raster, 0)) {
1338 for (i = height - 1; i >= 0; i--) {
1347 rp = raster + (i * width);
1348 for (j = 0; (uint32) j < width; j++) {
1365 ("Unable to allocate memory for TIFFReadRGBA",
1370 /* now instantiate */
1371 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1372 init_image_instance_from_eimage,
1373 (ii, width, height, 1, unwind.eimage, dest_mask,
1374 instantiator, domain));
1376 unbind_to(speccount, Qnil);
1379 #endif /* HAVE_TIFF */
1382 /**********************************************************************
1384 **********************************************************************/
1385 static void rawrgb_validate(Lisp_Object instantiator)
1387 data_must_be_present(instantiator);
1388 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1389 signal_simple_error("Must supply :pixel-width",
1391 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1392 signal_simple_error("Must supply :pixel-height",
1395 static void rawrgba_validate(Lisp_Object instantiator)
1397 file_or_data_must_be_present(instantiator);
1398 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1399 signal_simple_error("Must supply :pixel-width",
1401 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1402 signal_simple_error("Must supply :pixel-height",
1407 rawrgb_normalize(Lisp_Object inst, Lisp_Object console_type,
1408 Lisp_Object dest_mask)
1410 return simple_image_type_normalize(inst, console_type, Qrawrgb);
1413 rawrgba_normalize(Lisp_Object inst, Lisp_Object console_type,
1414 Lisp_Object dest_mask)
1416 return simple_image_type_normalize(inst, console_type, Qrawrgba);
1419 static int rawrgb_possible_dest_types(void)
1421 return IMAGE_COLOR_PIXMAP_MASK;
1423 static int rawrgba_possible_dest_types(void)
1425 return IMAGE_COLOR_PIXMAP_MASK;
1428 struct rawrgb_unwind_data {
1429 unsigned char *eimage;
1431 struct rawrgba_unwind_data {
1432 unsigned char *eimage;
1435 static Lisp_Object rawrgb_instantiate_unwind(Lisp_Object unwind_obj)
1437 struct rawrgb_unwind_data *data =
1438 (struct rawrgb_unwind_data *)get_opaque_ptr(unwind_obj);
1440 free_opaque_ptr(unwind_obj);
1442 xfree(data->eimage);
1446 static Lisp_Object rawrgba_instantiate_unwind(Lisp_Object unwind_obj)
1448 struct rawrgba_unwind_data *data =
1449 (struct rawrgba_unwind_data *)get_opaque_ptr(unwind_obj);
1451 free_opaque_ptr(unwind_obj);
1453 xfree(data->eimage);
1458 typedef struct rawrgb_memory_storage {
1459 Extbyte *bytes; /* The data */
1460 Extcount len; /* How big is it? */
1461 int index; /* Where are we? */
1462 } rawrgb_memory_storage;
1463 typedef struct rawrgba_memory_storage {
1464 Extbyte *bytes; /* The data */
1465 Extcount len; /* How big is it? */
1466 int index; /* Where are we? */
1467 } rawrgba_memory_storage;
1470 static size_t rawrgb_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1472 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1474 if (size > (mem->len - mem->index))
1475 return (size_t) - 1;
1476 memcpy(buf, mem->bytes + mem->index, size);
1477 mem->index = mem->index + size;
1480 static size_t rawrgba_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1482 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1484 if (size > (mem->len - mem->index))
1485 return (size_t) - 1;
1486 memcpy(buf, mem->bytes + mem->index, size);
1487 mem->index = mem->index + size;
1491 static size_t rawrgb_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1494 return 0; /* Shut up warnings. */
1496 static size_t rawrgba_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1499 return 0; /* Shut up warnings. */
1502 static toff_t rawrgb_memory_seek(thandle_t data, toff_t off, int whence)
1504 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1511 newidx = mem->len + off;
1514 newidx = mem->index + off;
1518 "Eh? invalid seek mode in rawrgb_memory_seek\n");
1519 return (toff_t) - 1;
1522 if ((newidx > mem->len) || (newidx < 0))
1523 return (toff_t) - 1;
1525 mem->index = newidx;
1528 static toff_t rawrgba_memory_seek(thandle_t data, toff_t off, int whence)
1530 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1537 newidx = mem->len + off;
1540 newidx = mem->index + off;
1544 "Eh? invalid seek mode in rawrgba_memory_seek\n");
1545 return (toff_t) - 1;
1548 if ((newidx > mem->len) || (newidx < 0))
1549 return (toff_t) - 1;
1551 mem->index = newidx;
1555 static int rawrgb_memory_close(thandle_t data)
1559 static int rawrgba_memory_close(thandle_t data)
1564 static int rawrgb_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1568 static int rawrgba_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1573 static void rawrgb_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1577 static void rawrgba_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1582 static toff_t rawrgb_memory_size(thandle_t data)
1584 rawrgb_memory_storage *mem = (rawrgb_memory_storage *) data;
1587 static toff_t rawrgba_memory_size(thandle_t data)
1589 rawrgba_memory_storage *mem = (rawrgba_memory_storage *) data;
1595 rawrgb_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1596 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1597 int dest_mask, Lisp_Object domain)
1599 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1600 rawrgb_memory_storage mem_struct;
1601 /* It is OK for the unwind data to be local to this function,
1602 because the unwind-protect is always executed when this
1603 stack frame is still valid. */
1604 struct rawrgb_unwind_data unwind;
1605 int speccount = specpdl_depth();
1606 unsigned long width = 0, height = 0;
1607 mem_struct.bytes = NULL;
1610 record_unwind_protect(rawrgb_instantiate_unwind,
1611 make_opaque_ptr(&unwind));
1614 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1615 Lisp_Object rows = find_keyword_in_vector(instantiator,
1617 Lisp_Object cols = find_keyword_in_vector(instantiator,
1619 Extbyte *bytes = NULL;
1625 assert(!NILP(data));
1629 bytes = XEFFIO(data)->fostorage;
1630 len = XEFFIO(data)->storage_size;
1632 #endif /* HAVE_FFI */
1633 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1634 ALLOCA, (bytes, len), Qbinary);
1635 if ( bytes != NULL ) {
1636 mem_struct.bytes = bytes;
1637 mem_struct.len = len;
1638 mem_struct.index = 0;
1641 height = XINT(rows);
1643 unwind.eimage = xmalloc_atomic(len);
1645 dp = (unsigned char*)bytes;
1646 for ( ; dp < (unsigned char*)bytes+len; ep++, dp++)
1651 if ( mem_struct.bytes != NULL ) {
1652 /* now instantiate */
1653 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1654 init_image_instance_from_eimage,
1655 (ii, width, height, 1, unwind.eimage, dest_mask,
1656 instantiator, domain));
1658 unbind_to(speccount, Qnil);
1661 rawrgba_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1662 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1663 int dest_mask, Lisp_Object domain)
1665 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1666 rawrgba_memory_storage mem_struct;
1667 /* It is OK for the unwind data to be local to this function,
1668 because the unwind-protect is always executed when this
1669 stack frame is still valid. */
1670 struct rawrgba_unwind_data unwind;
1671 int speccount = specpdl_depth();
1672 unsigned long width = 0, height = 0;
1674 mem_struct.bytes = 0;
1676 record_unwind_protect(rawrgba_instantiate_unwind,
1677 make_opaque_ptr(&unwind));
1680 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1681 Lisp_Object rows = find_keyword_in_vector(instantiator,
1683 Lisp_Object cols = find_keyword_in_vector(instantiator,
1685 Extbyte *bytes = NULL;
1691 assert(!NILP(data));
1695 bytes = XEFFIO(data)->fostorage;
1696 len = XEFFIO(data)->storage_size;
1698 #endif /* HAVE_FFI */
1699 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1700 ALLOCA, (bytes, len), Qbinary);
1701 if (bytes != NULL ) {
1702 mem_struct.bytes = bytes;
1703 mem_struct.len = len;
1704 mem_struct.index = 0;
1707 height = XINT(rows);
1709 unwind.eimage = xmalloc_atomic(len);
1710 for (ep = unwind.eimage, dp = (unsigned char*)bytes;
1711 dp < (unsigned char*)bytes+len; ep++, dp++) {
1717 if ( mem_struct.bytes != NULL) {
1718 /* now instantiate */
1719 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1720 init_image_instance_from_eimage,
1721 (ii, width, height, 1, unwind.eimage, dest_mask,
1722 instantiator, domain));
1724 unbind_to(speccount, Qnil);
1728 /************************************************************************/
1729 /* initialization */
1730 /************************************************************************/
1732 void syms_of_glyphs_eimage(void)
1736 static void check_valid_ffio_or_string(Lisp_Object data)
1739 if (!EFFIOP(data) && !STRINGP(data))
1740 dead_wrong_type_argument(Qstringp, data);
1743 #endif /* HAVE_FFI */
1746 void image_instantiator_format_create_glyphs_eimage(void)
1748 /* image-instantiator types */
1750 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(jpeg, "jpeg");
1752 IIFORMAT_HAS_METHOD(jpeg, validate);
1753 IIFORMAT_HAS_METHOD(jpeg, normalize);
1754 IIFORMAT_HAS_METHOD(jpeg, possible_dest_types);
1755 IIFORMAT_HAS_METHOD(jpeg, instantiate);
1757 IIFORMAT_VALID_KEYWORD(jpeg, Q_data, check_valid_ffio_or_string);
1758 IIFORMAT_VALID_KEYWORD(jpeg, Q_file, check_valid_string);
1762 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(gif, "gif");
1764 IIFORMAT_HAS_METHOD(gif, validate);
1765 IIFORMAT_HAS_METHOD(gif, normalize);
1766 IIFORMAT_HAS_METHOD(gif, possible_dest_types);
1767 IIFORMAT_HAS_METHOD(gif, instantiate);
1769 IIFORMAT_VALID_KEYWORD(gif, Q_data, check_valid_ffio_or_string);
1770 IIFORMAT_VALID_KEYWORD(gif, Q_file, check_valid_string);
1773 #if defined WITH_PNG && defined HAVE_PNG
1774 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(png, "png");
1776 IIFORMAT_HAS_METHOD(png, validate);
1777 IIFORMAT_HAS_METHOD(png, normalize);
1778 IIFORMAT_HAS_METHOD(png, possible_dest_types);
1779 IIFORMAT_HAS_METHOD(png, instantiate);
1781 IIFORMAT_VALID_KEYWORD(png, Q_data, check_valid_ffio_or_string);
1782 IIFORMAT_VALID_KEYWORD(png, Q_file, check_valid_string);
1786 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(tiff, "tiff");
1788 IIFORMAT_HAS_METHOD(tiff, validate);
1789 IIFORMAT_HAS_METHOD(tiff, normalize);
1790 IIFORMAT_HAS_METHOD(tiff, possible_dest_types);
1791 IIFORMAT_HAS_METHOD(tiff, instantiate);
1793 IIFORMAT_VALID_KEYWORD(tiff, Q_data, check_valid_ffio_or_string);
1794 IIFORMAT_VALID_KEYWORD(tiff, Q_file, check_valid_string);
1798 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgb, "rawrgb");
1799 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgba, "rawrgba");
1801 IIFORMAT_HAS_METHOD(rawrgb, validate);
1802 IIFORMAT_HAS_METHOD(rawrgb, normalize);
1803 IIFORMAT_HAS_METHOD(rawrgb, possible_dest_types);
1804 IIFORMAT_HAS_METHOD(rawrgb, instantiate);
1806 IIFORMAT_HAS_METHOD(rawrgba, validate);
1807 IIFORMAT_HAS_METHOD(rawrgba, normalize);
1808 IIFORMAT_HAS_METHOD(rawrgba, possible_dest_types);
1809 IIFORMAT_HAS_METHOD(rawrgba, instantiate);
1811 IIFORMAT_VALID_KEYWORD(rawrgb, Q_data, check_valid_ffio_or_string);
1812 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_width, check_valid_int);
1813 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_height, check_valid_int);
1815 IIFORMAT_VALID_KEYWORD(rawrgba, Q_data, check_valid_ffio_or_string);
1816 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_width, check_valid_int);
1817 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_height, check_valid_int);
1821 void vars_of_glyphs_eimage(void)
1831 #if defined WITH_PNG && defined HAVE_PNG