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);
962 png_bytep row_pointers[height];
964 /* Wow, allocate all the memory. Truly, exciting. */
965 unwind.eimage = xmalloc_atomic(width * height * 3);
966 /* libpng expects that the image buffer passed in contains a
967 picture to draw on top of if the png has any transparencies.
968 This could be a good place to pass that in... */
969 for (y = 0; y < height; y++) {
970 row_pointers[y] = NULL;
973 for (y = 0; y < height; y++) {
974 row_pointers[y] = unwind.eimage + (width * 3 * y);
978 /* if the png specifies a background chunk, go ahead and
979 * use it, else use what we can get
980 * from the default face. */
981 png_color_16 my_background, *image_background;
982 Lisp_Object bkgd = Qnil;
984 my_background.red = 0x7fff;
985 my_background.green = 0x7fff;
986 my_background.blue = 0x7fff;
987 bkgd = FACE_BACKGROUND(Vdefault_face, domain);
988 if (!COLOR_INSTANCEP(bkgd)) {
989 warn_when_safe(Qpng, Qinfo,
990 "Couldn't get background color!");
992 Lisp_Color_Instance *c;
995 c = XCOLOR_INSTANCE(bkgd);
996 rgblist = MAYBE_LISP_DEVMETH(XDEVICE(c->device),
997 color_instance_rgb_components,
1000 (unsigned short)XINT(XCAR(rgblist));
1001 my_background.green =
1002 (unsigned short)XINT(XCAR(XCDR(rgblist)));
1003 my_background.blue =
1005 XINT(XCAR(XCDR(XCDR(rgblist))));
1008 if (png_get_bKGD(png_ptr, info_ptr, &image_background))
1009 png_set_background(png_ptr, image_background,
1010 PNG_BACKGROUND_GAMMA_FILE, 1,
1013 png_set_background(png_ptr, &my_background,
1014 PNG_BACKGROUND_GAMMA_SCREEN,
1018 /* Now that we're using EImage, ask for 8bit RGB triples for any type
1021 /* tell libpng to strip 16 bit depth files down to 8 bits */
1022 if (bit_depth == 16)
1023 png_set_strip_16(png_ptr);
1024 /* if the image is < 8 bits, pad it out */
1025 if (bit_depth < 8) {
1026 if (color_type == PNG_COLOR_TYPE_GRAY)
1027 png_set_expand_gray_1_2_4_to_8(png_ptr);
1029 png_set_packing(png_ptr);
1031 /* convert palette images to full RGB */
1032 if (color_type == PNG_COLOR_TYPE_PALETTE)
1033 png_set_palette_to_rgb(png_ptr);
1034 /* send grayscale images to RGB too */
1035 if (color_type == PNG_COLOR_TYPE_GRAY ||
1036 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1037 png_set_gray_to_rgb(png_ptr);
1039 * Expand paletted or RGB images with transparency to
1040 * full alpha channels so the data will be available
1041 * as RGBA quartets. We don't actually take advantage
1042 * of this yet, but it's not going to hurt, and you
1043 * never know... one of these days... --SY.
1045 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
1046 png_set_tRNS_to_alpha(png_ptr);
1047 /* Turn on interlace handling */
1048 if (interlace_type == PNG_INTERLACE_ADAM7)
1049 passes = png_set_interlace_handling(png_ptr);
1051 /* Update the data */
1052 png_read_update_info(png_ptr, info_ptr);
1054 /* read in the image row by row if interlaced, */
1055 if (interlace_type == PNG_INTERLACE_ADAM7) {
1056 for (pass = 0; pass < passes; pass++) {
1057 for (y = 0; y < height; y++) {
1058 png_read_rows(png_ptr,
1063 } else { /* the whole thing in 1 hit for non-interlaced */
1064 png_read_image(png_ptr, row_pointers);
1066 png_read_end(png_ptr, info_ptr);
1069 /* now instantiate */
1070 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1071 init_image_instance_from_eimage,
1072 (ii, width, height, 1, unwind.eimage, dest_mask,
1073 instantiator, domain));
1075 /* This will clean up everything else. */
1076 unbind_to(speccount, Qnil);
1079 #endif /* HAVE_PNG */
1084 /**********************************************************************
1086 **********************************************************************/
1087 static void tiff_validate(Lisp_Object instantiator)
1089 file_or_data_must_be_present(instantiator);
1093 tiff_normalize(Lisp_Object inst, Lisp_Object console_type,
1094 Lisp_Object dest_mask)
1096 return simple_image_type_normalize(inst, console_type, Qtiff);
1099 static int tiff_possible_dest_types(void)
1101 return IMAGE_COLOR_PIXMAP_MASK;
1104 struct tiff_unwind_data {
1105 unsigned char *eimage;
1106 /* Object that holds the decoded data from a TIFF file */
1110 static Lisp_Object tiff_instantiate_unwind(Lisp_Object unwind_obj)
1112 struct tiff_unwind_data *data =
1113 (struct tiff_unwind_data *)get_opaque_ptr(unwind_obj);
1115 free_opaque_ptr(unwind_obj);
1117 TIFFClose(data->tiff);
1120 xfree(data->eimage);
1125 typedef struct tiff_memory_storage {
1126 Extbyte *bytes; /* The data */
1127 Extcount len; /* How big is it? */
1128 int index; /* Where are we? */
1129 } tiff_memory_storage;
1131 static size_t tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1133 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1135 if (size > (mem->len - mem->index))
1136 return (size_t) - 1;
1137 memcpy(buf, mem->bytes + mem->index, size);
1138 mem->index = mem->index + size;
1142 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1145 return 0; /* Shut up warnings. */
1148 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1150 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1157 newidx = mem->len + off;
1160 newidx = mem->index + off;
1163 fprintf(stderr, "Eh? invalid seek mode in tiff_memory_seek\n");
1164 return (toff_t) - 1;
1167 if ((newidx > mem->len) || (newidx < 0))
1168 return (toff_t) - 1;
1170 mem->index = newidx;
1174 static int tiff_memory_close(thandle_t data)
1179 static int tiff_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1184 static void tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1189 static toff_t tiff_memory_size(thandle_t data)
1191 tiff_memory_storage *mem = (tiff_memory_storage *) data;
1195 struct tiff_error_struct {
1197 jmp_buf setjmp_buffer; /* for return to caller */
1200 /* jh 98/03/12 - ###This struct for passing data to the error functions
1201 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1202 have any place to store error func data. This should be rectified
1203 before SXEmacs gets threads! */
1204 static struct tiff_error_struct tiff_err_data;
1206 static void tiff_error_func(const char *module, const char *fmt, ...)
1211 va_start(vargs, fmt);
1213 n = vsnprintf(tiff_err_data.err_str, sizeof(tiff_err_data.err_str), fmt, vargs);
1214 assert(n>=0 && n < sizeof(tiff_err_data.err_str));
1217 /* return to setjmp point */
1218 longjmp(tiff_err_data.setjmp_buffer, 1);
1221 static void tiff_warning_func(const char *module, const char *fmt, ...)
1227 va_start(vargs, fmt);
1229 n = vsnprintf(warn_str, sizeof(warn_str), fmt, vargs);
1230 assert(n>=0 && n < sizeof(warn_str));
1232 warn_when_safe(Qtiff, Qinfo, "%s - %s", module, warn_str);
1236 tiff_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1237 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1238 int dest_mask, Lisp_Object domain)
1240 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1241 tiff_memory_storage mem_struct;
1242 /* It is OK for the unwind data to be local to this function,
1243 because the unwind-protect is always executed when this
1244 stack frame is still valid. */
1245 struct tiff_unwind_data unwind;
1246 int speccount = specpdl_depth();
1247 uint32 width, height;
1250 record_unwind_protect(tiff_instantiate_unwind,
1251 make_opaque_ptr(&unwind));
1253 /* set up error facilities */
1254 if (setjmp(tiff_err_data.setjmp_buffer)) {
1255 /* An error was signaled. No clean up is needed, as unwind handles that
1256 for us. Just pass the error along. */
1257 signal_image_error_2("TIFF decoding error",
1258 build_string(tiff_err_data.err_str),
1261 TIFFSetErrorHandler((TIFFErrorHandler) tiff_error_func);
1262 TIFFSetWarningHandler((TIFFErrorHandler) tiff_warning_func);
1264 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1271 assert(!NILP(data));
1275 bytes = XEFFIO(data)->fostorage;
1276 len = XEFFIO(data)->storage_size;
1278 #endif /* HAVE_FFI */
1279 /* #### This is a definite problem under Mule due to the amount of
1280 stack data it might allocate. Think about Lstreams... */
1281 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1282 ALLOCA, (bytes, len), Qbinary);
1283 mem_struct.bytes = bytes;
1284 mem_struct.len = len;
1285 mem_struct.index = 0;
1288 TIFFClientOpen("memfile", "r", (thandle_t) & mem_struct,
1289 (TIFFReadWriteProc) tiff_memory_read,
1290 (TIFFReadWriteProc) tiff_memory_write,
1291 tiff_memory_seek, tiff_memory_close,
1292 tiff_memory_size, tiff_map_noop,
1296 ("Insufficient memory to instantiate TIFF image",
1299 TIFFGetField(unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1300 TIFFGetField(unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1301 unwind.eimage = xmalloc_atomic(width * height * 3);
1303 /* #### This is little more than proof-of-concept/function testing.
1304 It needs to be reimplemented via scanline reads for both memory
1307 (uint32 *) _TIFFmalloc(width * height * sizeof(uint32));
1308 if (raster != NULL) {
1313 if (TIFFReadRGBAImage
1314 (unwind.tiff, width, height, raster, 0)) {
1315 for (i = height - 1; i >= 0; i--) {
1316 /* This is to get around weirdness in the libtiff library where properly
1317 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1318 rp = raster + (i * width);
1319 for (j = 0; (uint32) j < width; j++) {
1336 ("Unable to allocate memory for TIFFReadRGBA",
1341 /* now instantiate */
1342 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1343 init_image_instance_from_eimage,
1344 (ii, width, height, 1, unwind.eimage, dest_mask,
1345 instantiator, domain));
1347 unbind_to(speccount, Qnil);
1350 #endif /* HAVE_TIFF */
1353 /**********************************************************************
1355 **********************************************************************/
1356 static void rawrgb_validate(Lisp_Object instantiator)
1358 data_must_be_present(instantiator);
1359 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1360 signal_simple_error("Must supply :pixel-width",
1362 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1363 signal_simple_error("Must supply :pixel-height",
1366 static void rawrgba_validate(Lisp_Object instantiator)
1368 file_or_data_must_be_present(instantiator);
1369 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_width)))
1370 signal_simple_error("Must supply :pixel-width",
1372 if (NILP(find_keyword_in_vector(instantiator, Q_pixel_height)))
1373 signal_simple_error("Must supply :pixel-height",
1378 rawrgb_normalize(Lisp_Object inst, Lisp_Object console_type,
1379 Lisp_Object dest_mask)
1381 return simple_image_type_normalize(inst, console_type, Qrawrgb);
1384 rawrgba_normalize(Lisp_Object inst, Lisp_Object console_type,
1385 Lisp_Object dest_mask)
1387 return simple_image_type_normalize(inst, console_type, Qrawrgba);
1390 static int rawrgb_possible_dest_types(void)
1392 return IMAGE_COLOR_PIXMAP_MASK;
1394 static int rawrgba_possible_dest_types(void)
1396 return IMAGE_COLOR_PIXMAP_MASK;
1399 struct rawrgb_unwind_data {
1400 unsigned char *eimage;
1402 struct rawrgba_unwind_data {
1403 unsigned char *eimage;
1406 static Lisp_Object rawrgb_instantiate_unwind(Lisp_Object unwind_obj)
1408 struct rawrgb_unwind_data *data =
1409 (struct rawrgb_unwind_data *)get_opaque_ptr(unwind_obj);
1411 free_opaque_ptr(unwind_obj);
1413 xfree(data->eimage);
1417 static Lisp_Object rawrgba_instantiate_unwind(Lisp_Object unwind_obj)
1419 struct rawrgba_unwind_data *data =
1420 (struct rawrgba_unwind_data *)get_opaque_ptr(unwind_obj);
1422 free_opaque_ptr(unwind_obj);
1424 xfree(data->eimage);
1429 typedef struct rawrgb_memory_storage {
1430 Extbyte *bytes; /* The data */
1431 Extcount len; /* How big is it? */
1432 int index; /* Where are we? */
1433 } rawrgb_memory_storage;
1434 typedef struct rawrgba_memory_storage {
1435 Extbyte *bytes; /* The data */
1436 Extcount len; /* How big is it? */
1437 int index; /* Where are we? */
1438 } rawrgba_memory_storage;
1441 static size_t rawrgb_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1443 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1445 if (size > (mem->len - mem->index))
1446 return (size_t) - 1;
1447 memcpy(buf, mem->bytes + mem->index, size);
1448 mem->index = mem->index + size;
1451 static size_t rawrgba_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1453 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1455 if (size > (mem->len - mem->index))
1456 return (size_t) - 1;
1457 memcpy(buf, mem->bytes + mem->index, size);
1458 mem->index = mem->index + size;
1462 static size_t rawrgb_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1465 return 0; /* Shut up warnings. */
1467 static size_t rawrgba_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1470 return 0; /* Shut up warnings. */
1473 static toff_t rawrgb_memory_seek(thandle_t data, toff_t off, int whence)
1475 rawrgb_memory_storage *mem = (rawrgb_memory_storage *)data;
1482 newidx = mem->len + off;
1485 newidx = mem->index + off;
1489 "Eh? invalid seek mode in rawrgb_memory_seek\n");
1490 return (toff_t) - 1;
1493 if ((newidx > mem->len) || (newidx < 0))
1494 return (toff_t) - 1;
1496 mem->index = newidx;
1499 static toff_t rawrgba_memory_seek(thandle_t data, toff_t off, int whence)
1501 rawrgba_memory_storage *mem = (rawrgba_memory_storage *)data;
1508 newidx = mem->len + off;
1511 newidx = mem->index + off;
1515 "Eh? invalid seek mode in rawrgba_memory_seek\n");
1516 return (toff_t) - 1;
1519 if ((newidx > mem->len) || (newidx < 0))
1520 return (toff_t) - 1;
1522 mem->index = newidx;
1526 static int rawrgb_memory_close(thandle_t data)
1530 static int rawrgba_memory_close(thandle_t data)
1535 static int rawrgb_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1539 static int rawrgba_map_noop(thandle_t data, tdata_t * pbase, toff_t * psize)
1544 static void rawrgb_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1548 static void rawrgba_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1553 static toff_t rawrgb_memory_size(thandle_t data)
1555 rawrgb_memory_storage *mem = (rawrgb_memory_storage *) data;
1558 static toff_t rawrgba_memory_size(thandle_t data)
1560 rawrgba_memory_storage *mem = (rawrgba_memory_storage *) data;
1566 rawrgb_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1567 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1568 int dest_mask, Lisp_Object domain)
1570 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1571 rawrgb_memory_storage mem_struct;
1572 /* It is OK for the unwind data to be local to this function,
1573 because the unwind-protect is always executed when this
1574 stack frame is still valid. */
1575 struct rawrgb_unwind_data unwind;
1576 int speccount = specpdl_depth();
1577 unsigned long width, height;
1580 record_unwind_protect(rawrgb_instantiate_unwind,
1581 make_opaque_ptr(&unwind));
1584 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1585 Lisp_Object rows = find_keyword_in_vector(instantiator,
1587 Lisp_Object cols = find_keyword_in_vector(instantiator,
1595 assert(!NILP(data));
1599 bytes = XEFFIO(data)->fostorage;
1600 len = XEFFIO(data)->storage_size;
1602 #endif /* HAVE_FFI */
1603 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1604 ALLOCA, (bytes, len), Qbinary);
1605 mem_struct.bytes = bytes;
1606 mem_struct.len = len;
1607 mem_struct.index = 0;
1610 height = XINT(rows);
1612 unwind.eimage = xmalloc_atomic(len);
1614 dp = (unsigned char*)bytes;
1615 for ( ; dp < (unsigned char*)bytes+len; ep++, dp++)
1619 /* now instantiate */
1620 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1621 init_image_instance_from_eimage,
1622 (ii, width, height, 1, unwind.eimage, dest_mask,
1623 instantiator, domain));
1625 unbind_to(speccount, Qnil);
1628 rawrgba_instantiate(Lisp_Object image_instance, Lisp_Object instantiator,
1629 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1630 int dest_mask, Lisp_Object domain)
1632 Lisp_Image_Instance *ii = XIMAGE_INSTANCE(image_instance);
1633 rawrgba_memory_storage mem_struct;
1634 /* It is OK for the unwind data to be local to this function,
1635 because the unwind-protect is always executed when this
1636 stack frame is still valid. */
1637 struct rawrgba_unwind_data unwind;
1638 int speccount = specpdl_depth();
1639 unsigned long width, height;
1642 record_unwind_protect(rawrgba_instantiate_unwind,
1643 make_opaque_ptr(&unwind));
1646 Lisp_Object data = find_keyword_in_vector(instantiator, Q_data);
1647 Lisp_Object rows = find_keyword_in_vector(instantiator,
1649 Lisp_Object cols = find_keyword_in_vector(instantiator,
1657 assert(!NILP(data));
1661 bytes = XEFFIO(data)->fostorage;
1662 len = XEFFIO(data)->storage_size;
1664 #endif /* HAVE_FFI */
1665 TO_EXTERNAL_FORMAT(LISP_STRING, data,
1666 ALLOCA, (bytes, len), Qbinary);
1667 mem_struct.bytes = bytes;
1668 mem_struct.len = len;
1669 mem_struct.index = 0;
1672 height = XINT(rows);
1674 unwind.eimage = xmalloc_atomic(len);
1675 for (ep = unwind.eimage, dp = (unsigned char*)bytes;
1676 dp < (unsigned char*)bytes+len; ep++, dp++) {
1681 /* now instantiate */
1682 MAYBE_DEVMETH(DOMAIN_XDEVICE(ii->domain),
1683 init_image_instance_from_eimage,
1684 (ii, width, height, 1, unwind.eimage, dest_mask,
1685 instantiator, domain));
1687 unbind_to(speccount, Qnil);
1691 /************************************************************************/
1692 /* initialization */
1693 /************************************************************************/
1695 void syms_of_glyphs_eimage(void)
1699 static void check_valid_ffio_or_string(Lisp_Object data)
1702 if (!EFFIOP(data) && !STRINGP(data))
1703 dead_wrong_type_argument(Qstringp, data);
1706 #endif /* HAVE_FFI */
1709 void image_instantiator_format_create_glyphs_eimage(void)
1711 /* image-instantiator types */
1713 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(jpeg, "jpeg");
1715 IIFORMAT_HAS_METHOD(jpeg, validate);
1716 IIFORMAT_HAS_METHOD(jpeg, normalize);
1717 IIFORMAT_HAS_METHOD(jpeg, possible_dest_types);
1718 IIFORMAT_HAS_METHOD(jpeg, instantiate);
1720 IIFORMAT_VALID_KEYWORD(jpeg, Q_data, check_valid_ffio_or_string);
1721 IIFORMAT_VALID_KEYWORD(jpeg, Q_file, check_valid_string);
1725 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(gif, "gif");
1727 IIFORMAT_HAS_METHOD(gif, validate);
1728 IIFORMAT_HAS_METHOD(gif, normalize);
1729 IIFORMAT_HAS_METHOD(gif, possible_dest_types);
1730 IIFORMAT_HAS_METHOD(gif, instantiate);
1732 IIFORMAT_VALID_KEYWORD(gif, Q_data, check_valid_ffio_or_string);
1733 IIFORMAT_VALID_KEYWORD(gif, Q_file, check_valid_string);
1736 #if defined WITH_PNG && defined HAVE_PNG
1737 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(png, "png");
1739 IIFORMAT_HAS_METHOD(png, validate);
1740 IIFORMAT_HAS_METHOD(png, normalize);
1741 IIFORMAT_HAS_METHOD(png, possible_dest_types);
1742 IIFORMAT_HAS_METHOD(png, instantiate);
1744 IIFORMAT_VALID_KEYWORD(png, Q_data, check_valid_ffio_or_string);
1745 IIFORMAT_VALID_KEYWORD(png, Q_file, check_valid_string);
1749 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(tiff, "tiff");
1751 IIFORMAT_HAS_METHOD(tiff, validate);
1752 IIFORMAT_HAS_METHOD(tiff, normalize);
1753 IIFORMAT_HAS_METHOD(tiff, possible_dest_types);
1754 IIFORMAT_HAS_METHOD(tiff, instantiate);
1756 IIFORMAT_VALID_KEYWORD(tiff, Q_data, check_valid_ffio_or_string);
1757 IIFORMAT_VALID_KEYWORD(tiff, Q_file, check_valid_string);
1761 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgb, "rawrgb");
1762 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(rawrgba, "rawrgba");
1764 IIFORMAT_HAS_METHOD(rawrgb, validate);
1765 IIFORMAT_HAS_METHOD(rawrgb, normalize);
1766 IIFORMAT_HAS_METHOD(rawrgb, possible_dest_types);
1767 IIFORMAT_HAS_METHOD(rawrgb, instantiate);
1769 IIFORMAT_HAS_METHOD(rawrgba, validate);
1770 IIFORMAT_HAS_METHOD(rawrgba, normalize);
1771 IIFORMAT_HAS_METHOD(rawrgba, possible_dest_types);
1772 IIFORMAT_HAS_METHOD(rawrgba, instantiate);
1774 IIFORMAT_VALID_KEYWORD(rawrgb, Q_data, check_valid_ffio_or_string);
1775 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_width, check_valid_int);
1776 IIFORMAT_VALID_KEYWORD(rawrgb, Q_pixel_height, check_valid_int);
1778 IIFORMAT_VALID_KEYWORD(rawrgba, Q_data, check_valid_ffio_or_string);
1779 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_width, check_valid_int);
1780 IIFORMAT_VALID_KEYWORD(rawrgba, Q_pixel_height, check_valid_int);
1784 void vars_of_glyphs_eimage(void)
1794 #if defined WITH_PNG && defined HAVE_PNG