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 XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Original author: Jamie Zawinski for 19.8
28 font-truename stuff added by Jamie Zawinski for 19.10
29 subwindow support added by Chuck Thompson
30 additional XPM support added by Chuck Thompson
31 initial X-Face support added by Stig
32 rewritten/restructured by Ben Wing for 19.12/19.13
33 GIF/JPEG support added by Ben Wing for 19.14
34 PNG support added by Bill Perry for 19.14
35 Improved GIF/JPEG support added by Bill Perry for 19.14
36 Cleanup/simplification of error handling by Ben Wing for 19.14
37 Pointer/icon overhaul, more restructuring by Ben Wing for 19.14
38 GIF support changed to external Gifreader lib by Jareth Hein for 21.0
39 Many changes for color work and optimizations by Jareth Hein for 21.0
40 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
41 TIFF code by Jareth Hein for 21.0
42 Generalization for ms-windows by Andy Piper for 21.0
44 Convert images.el to C and stick it in here?
75 #include "file-coding.h"
79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
84 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
89 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif);
94 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png);
101 /**********************************************************************
103 **********************************************************************/
114 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/
116 jpeg_validate (Lisp_Object instantiator)
118 file_or_data_must_be_present (instantiator);
122 jpeg_normalize (Lisp_Object inst, Lisp_Object console_type)
124 return simple_image_type_normalize (inst, console_type, Qjpeg);
128 jpeg_possible_dest_types (void)
130 return IMAGE_COLOR_PIXMAP_MASK;
133 /* To survive the otherwise baffling complexity of making sure
134 everything gets cleaned up in the presence of an error, we
135 use an unwind_protect(). */
137 struct jpeg_unwind_data
139 /* Stream that we need to close */
141 /* Object that holds state info for JPEG decoding */
142 struct jpeg_decompress_struct *cinfo_ptr;
144 unsigned char *eimage;
148 jpeg_instantiate_unwind (Lisp_Object unwind_obj)
150 struct jpeg_unwind_data *data =
151 (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj);
153 free_opaque_ptr (unwind_obj);
155 jpeg_destroy_decompress (data->cinfo_ptr);
158 fclose (data->instream);
160 if (data->eimage) xfree (data->eimage);
168 * The JPEG library's standard error handler (jerror.c) is divided into
169 * several "methods" which you can override individually. This lets you
170 * adjust the behavior without duplicating a lot of code, which you might
171 * have to update with each future release.
173 * Our example here shows how to override the "error_exit" method so that
174 * control is returned to the library's caller when a fatal error occurs,
175 * rather than calling exit() as the standard error_exit method does.
177 * We use C's setjmp/longjmp facility to return control. This means that the
178 * routine which calls the JPEG library must first execute a setjmp() call to
179 * establish the return point. We want the replacement error_exit to do a
180 * longjmp(). But we need to make the setjmp buffer accessible to the
181 * error_exit routine. To do this, we make a private extension of the
182 * standard JPEG error handler object. (If we were using C++, we'd say we
183 * were making a subclass of the regular error handler.)
185 * Here's the extended error handler struct:
188 struct my_jpeg_error_mgr
190 struct jpeg_error_mgr pub; /* "public" fields */
191 jmp_buf setjmp_buffer; /* for return to caller */
194 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
199 our_init_source (j_decompress_ptr cinfo)
203 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
208 our_fill_input_buffer (j_decompress_ptr cinfo)
210 /* Insert a fake EOI marker */
211 struct jpeg_source_mgr *src = cinfo->src;
212 static JOCTET buffer[2];
214 buffer[0] = (JOCTET) 0xFF;
215 buffer[1] = (JOCTET) JPEG_EOI;
217 src->next_input_byte = buffer;
218 src->bytes_in_buffer = 2;
222 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
227 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
229 struct jpeg_source_mgr *src = NULL;
231 src = (struct jpeg_source_mgr *) cinfo->src;
236 } else if (num_bytes > src->bytes_in_buffer)
238 ERREXIT(cinfo, JERR_INPUT_EOF);
242 src->bytes_in_buffer -= num_bytes;
243 src->next_input_byte += num_bytes;
246 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
251 our_term_source (j_decompress_ptr cinfo)
257 struct jpeg_source_mgr pub;
258 } our_jpeg_source_mgr;
261 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
263 struct jpeg_source_mgr *src;
265 if (cinfo->src == NULL)
266 { /* first time for this JPEG object? */
267 cinfo->src = (struct jpeg_source_mgr *)
268 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
269 sizeof(our_jpeg_source_mgr));
270 src = (struct jpeg_source_mgr *) cinfo->src;
271 src->next_input_byte = data;
273 src = (struct jpeg_source_mgr *) cinfo->src;
274 src->init_source = our_init_source;
275 src->fill_input_buffer = our_fill_input_buffer;
276 src->skip_input_data = our_skip_input_data;
277 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
278 src->term_source = our_term_source;
279 src->bytes_in_buffer = len;
280 src->next_input_byte = data;
283 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
288 my_jpeg_error_exit (j_common_ptr cinfo)
290 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
291 struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err;
293 /* Return control to the setjmp point */
294 longjmp (myerr->setjmp_buffer, 1);
297 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
302 my_jpeg_output_message (j_common_ptr cinfo)
304 char buffer[JMSG_LENGTH_MAX];
306 /* Create the message */
307 (*cinfo->err->format_message) (cinfo, buffer);
308 warn_when_safe (Qjpeg, Qinfo, "%s", buffer);
311 /* The code in this routine is based on example.c from the JPEG library
312 source code and from gif_instantiate() */
314 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
315 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
316 int dest_mask, Lisp_Object domain)
318 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
319 /* It is OK for the unwind data to be local to this function,
320 because the unwind-protect is always executed when this
321 stack frame is still valid. */
322 struct jpeg_unwind_data unwind;
323 int speccount = specpdl_depth ();
325 /* This struct contains the JPEG decompression parameters and pointers to
326 * working space (which is allocated as needed by the JPEG library).
328 struct jpeg_decompress_struct cinfo;
329 /* We use our private extension JPEG error handler.
330 * Note that this struct must live as long as the main JPEG parameter
331 * struct, to avoid dangling-pointer problems.
333 struct my_jpeg_error_mgr jerr;
335 /* Step -1: First record our unwind-protect, which will clean up after
336 any exit, normal or not */
339 record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind));
341 /* Step 1: allocate and initialize JPEG decompression object */
343 /* We set up the normal JPEG error routines, then override error_exit. */
344 cinfo.err = jpeg_std_error (&jerr.pub);
345 jerr.pub.error_exit = my_jpeg_error_exit;
346 jerr.pub.output_message = my_jpeg_output_message;
348 /* Establish the setjmp return context for my_error_exit to use. */
349 if (setjmp (jerr.setjmp_buffer))
351 /* If we get here, the JPEG code has signaled an error.
352 * We need to clean up the JPEG object, close the input file, and return.
356 Lisp_Object errstring;
357 char buffer[JMSG_LENGTH_MAX];
359 /* Create the message */
360 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer);
361 errstring = build_string (buffer);
363 signal_image_error_2 ("JPEG decoding error",
364 errstring, instantiator);
368 /* Now we can initialize the JPEG decompression object. */
369 jpeg_create_decompress (&cinfo);
370 unwind.cinfo_ptr = &cinfo;
372 /* Step 2: specify data source (eg, a file) */
375 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
376 const Extbyte *bytes;
379 /* #### This is a definite problem under Mule due to the amount of
380 stack data it might allocate. Need to be able to convert and
381 write out to a file. */
382 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary);
383 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len);
386 /* Step 3: read file parameters with jpeg_read_header() */
388 jpeg_read_header (&cinfo, TRUE);
389 /* We can ignore the return value from jpeg_read_header since
390 * (a) suspension is not possible with the stdio data source, and
391 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
392 * See libjpeg.doc for more info.
396 int jpeg_gray = 0; /* if we're dealing with a grayscale */
397 /* Step 4: set parameters for decompression. */
399 /* Now that we're using EImages, send all data as 24bit color.
400 The backend routine will take care of any necessary reductions.
401 We do have to handle the grayscale case ourselves, however. */
402 if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
404 cinfo.out_color_space = JCS_GRAYSCALE;
409 /* we're relying on the jpeg driver to do any other conversions,
410 or signal an error if the conversion isn't supported. */
411 cinfo.out_color_space = JCS_RGB;
414 /* Step 5: Start decompressor */
415 jpeg_start_decompress (&cinfo);
417 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
419 unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3);
421 signal_image_error("Unable to allocate enough memory for image", instantiator);
424 JSAMPARRAY row_buffer; /* Output row buffer */
426 int row_stride; /* physical row width in output buffer */
427 unsigned char *op = unwind.eimage;
429 /* We may need to do some setup of our own at this point before reading
430 * the data. After jpeg_start_decompress() we have the correct scaled
431 * output image dimensions available
432 * We need to make an output work buffer of the right size.
434 /* JSAMPLEs per row in output buffer. */
435 row_stride = cinfo.output_width * cinfo.output_components;
436 /* Make a one-row-high sample array that will go away when done
438 row_buffer = ((*cinfo.mem->alloc_sarray)
439 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1));
441 /* Here we use the library's state variable cinfo.output_scanline as the
442 * loop counter, so that we don't have to keep track ourselves.
444 while (cinfo.output_scanline < cinfo.output_height)
448 /* jpeg_read_scanlines expects an array of pointers to scanlines.
449 * Here the array is only one element long, but you could ask for
450 * more than one scanline at a time if that's more convenient.
452 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1);
454 for (i = 0; i < cinfo.output_width; i++)
460 #if (BITS_IN_JSAMPLE == 8)
461 val = (unsigned char)*jp++;
462 #else /* other option is 12 */
463 val = (unsigned char)(*jp++ >> 4);
465 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */
470 for (clr = 0; clr < 3; clr++)
471 #if (BITS_IN_JSAMPLE == 8)
472 *op++ = (unsigned char)*jp++;
473 #else /* other option is 12 */
474 *op++ = (unsigned char)(*jp++ >> 4);
482 /* Step 6.5: Create the pixmap and set up the image instance */
483 /* now instantiate */
484 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
485 init_image_instance_from_eimage,
486 (ii, cinfo.output_width, cinfo.output_height, 1,
487 unwind.eimage, dest_mask,
488 instantiator, domain));
490 /* Step 7: Finish decompression */
492 jpeg_finish_decompress (&cinfo);
493 /* We can ignore the return value since suspension is not possible
494 * with the stdio data source.
497 /* And we're done! */
498 /* This will clean up everything else. */
499 unbind_to (speccount, Qnil);
502 #endif /* HAVE_JPEG */
505 /**********************************************************************
507 **********************************************************************/
512 gif_validate (Lisp_Object instantiator)
514 file_or_data_must_be_present (instantiator);
518 gif_normalize (Lisp_Object inst, Lisp_Object console_type)
520 return simple_image_type_normalize (inst, console_type, Qgif);
524 gif_possible_dest_types (void)
526 return IMAGE_COLOR_PIXMAP_MASK;
529 /* To survive the otherwise baffling complexity of making sure
530 everything gets cleaned up in the presence of an error, we
531 use an unwind_protect(). */
533 struct gif_unwind_data
535 unsigned char *eimage;
536 /* Object that holds the decoded data from a GIF file */
537 GifFileType *giffile;
541 gif_instantiate_unwind (Lisp_Object unwind_obj)
543 struct gif_unwind_data *data =
544 (struct gif_unwind_data *) get_opaque_ptr (unwind_obj);
546 free_opaque_ptr (unwind_obj);
549 DGifCloseFile (data->giffile);
550 GifFree(data->giffile);
552 if (data->eimage) xfree(data->eimage);
557 typedef struct gif_memory_storage
559 Extbyte *bytes; /* The data */
560 Extcount len; /* How big is it? */
561 int index; /* Where are we? */
562 } gif_memory_storage;
565 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
567 gif_memory_storage *mem = (gif_memory_storage*)data;
569 if (size > (mem->len - mem->index))
571 memcpy(buf, mem->bytes + mem->index, size);
572 mem->index = mem->index + size;
577 gif_memory_close(VoidPtr data)
582 struct gif_error_struct
584 const char *err_str; /* return the error string */
585 jmp_buf setjmp_buffer; /* for return to caller */
589 gif_error_func(const char *err_str, VoidPtr error_ptr)
591 struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr;
593 /* return to setjmp point */
594 error_data->err_str = err_str;
595 longjmp (error_data->setjmp_buffer, 1);
599 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
600 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
601 int dest_mask, Lisp_Object domain)
603 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
604 /* It is OK for the unwind data to be local to this function,
605 because the unwind-protect is always executed when this
606 stack frame is still valid. */
607 struct gif_unwind_data unwind;
608 int speccount = specpdl_depth ();
609 gif_memory_storage mem_struct;
610 struct gif_error_struct gif_err;
617 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
619 /* 1. Now decode the data. */
622 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
624 assert (!NILP (data));
626 if (!(unwind.giffile = GifSetup()))
627 signal_image_error ("Insufficient memory to instantiate GIF image", instantiator);
629 /* set up error facilities */
630 if (setjmp(gif_err.setjmp_buffer))
632 /* An error was signaled. No clean up is needed, as unwind handles that
633 for us. Just pass the error along. */
634 Lisp_Object errstring;
635 errstring = build_string (gif_err.err_str);
636 signal_image_error_2 ("GIF decoding error", errstring, instantiator);
638 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
640 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary);
641 mem_struct.bytes = bytes;
642 mem_struct.len = len;
643 mem_struct.index = 0;
644 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
645 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
646 DGifInitRead(unwind.giffile);
648 /* Then slurp the image into memory, decoding along the way.
649 The result is the image in a simple one-byte-per-pixel
650 format (#### the GIF routines only support 8-bit GIFs,
652 DGifSlurp (unwind.giffile);
655 /* 3. Now create the EImage(s) */
657 ColorMapObject *cmo = unwind.giffile->SColorMap;
658 int i, j, row, pass, interlace, slice;
660 /* interlaced gifs have rows in this order:
661 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
662 static int InterlacedOffset[] = { 0, 4, 2, 1 };
663 static int InterlacedJumps[] = { 8, 8, 4, 2 };
665 height = unwind.giffile->SHeight;
666 width = unwind.giffile->SWidth;
667 unwind.eimage = (unsigned char*)
668 xmalloc (width * height * 3 * unwind.giffile->ImageCount);
670 signal_image_error("Unable to allocate enough memory for image", instantiator);
672 /* write the data in EImage format (8bit RGB triples) */
674 for (slice = 0; slice < unwind.giffile->ImageCount; slice++)
676 /* We check here that that the current image covers the full "screen" size. */
677 if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height
678 || unwind.giffile->SavedImages[slice].ImageDesc.Width != width
679 || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0
680 || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0)
681 signal_image_error ("Image in GIF file is not full size",
684 interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace;
686 row = interlace ? InterlacedOffset[pass] : 0;
687 eip = unwind.eimage + (width * height * 3 * slice);
688 for (i = 0; i < height; i++)
692 row = InterlacedOffset[++pass];
693 while (row >= height)
694 row = InterlacedOffset[++pass];
696 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3);
697 for (j = 0; j < width; j++)
699 unsigned char pixel =
700 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j];
701 *eip++ = cmo->Colors[pixel].Red;
702 *eip++ = cmo->Colors[pixel].Green;
703 *eip++ = cmo->Colors[pixel].Blue;
705 row += interlace ? InterlacedJumps[pass] : 1;
709 /* now instantiate */
710 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
711 init_image_instance_from_eimage,
712 (ii, width, height, unwind.giffile->ImageCount, unwind.eimage, dest_mask,
713 instantiator, domain));
716 /* We read the gif successfully. If we have more than one slice then
718 if (unwind.giffile->ImageCount > 1)
720 /* See if there is a timeout value. In theory there could be one
721 for every image - but that makes the implementation way to
722 complicated for now so we just take the first. */
723 unsigned short timeout = 0;
726 if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE
728 unwind.giffile->SavedImages[0].ExtensionBlockCount)
730 timeout = (unsigned short)
731 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) +
732 unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10;
735 /* Too short a timeout will crucify us performance-wise. */
736 tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance);
739 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid);
742 unbind_to (speccount, Qnil);
745 #endif /* HAVE_GIF */
750 /**********************************************************************
752 **********************************************************************/
754 png_validate (Lisp_Object instantiator)
756 file_or_data_must_be_present (instantiator);
760 png_normalize (Lisp_Object inst, Lisp_Object console_type)
762 return simple_image_type_normalize (inst, console_type, Qpng);
766 png_possible_dest_types (void)
768 return IMAGE_COLOR_PIXMAP_MASK;
771 struct png_memory_storage
773 const Extbyte *bytes; /* The data */
774 Extcount len; /* How big is it? */
775 int index; /* Where are we? */
779 png_read_from_memory(png_structp png_ptr, png_bytep data,
782 struct png_memory_storage *tbr =
783 (struct png_memory_storage *) png_get_io_ptr (png_ptr);
785 if (length > (tbr->len - tbr->index))
786 png_error (png_ptr, (png_const_charp) "Read Error");
787 memcpy (data,tbr->bytes + tbr->index,length);
788 tbr->index = tbr->index + length;
791 struct png_error_struct
794 jmp_buf setjmp_buffer; /* for return to caller */
797 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
798 structure, and there are cases where the size can be different from
799 between inside the library, and inside the code! To do an end run
800 around this, use our own error functions, and don't rely on things
801 passed in the png_ptr to them. This is an ugly hack and must
802 go away when the lisp engine is threaded! */
803 static struct png_error_struct png_err_stct;
806 png_error_func (png_structp png_ptr, png_const_charp msg)
808 png_err_stct.err_str = msg;
809 longjmp (png_err_stct.setjmp_buffer, 1);
813 png_warning_func (png_structp png_ptr, png_const_charp msg)
815 warn_when_safe (Qpng, Qinfo, "%s", msg);
818 struct png_unwind_data
821 unsigned char *eimage;
827 png_instantiate_unwind (Lisp_Object unwind_obj)
829 struct png_unwind_data *data =
830 (struct png_unwind_data *) get_opaque_ptr (unwind_obj);
832 free_opaque_ptr (unwind_obj);
834 png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
836 fclose (data->instream);
838 if (data->eimage) xfree(data->eimage);
844 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
845 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
846 int dest_mask, Lisp_Object domain)
848 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
849 struct png_unwind_data unwind;
850 int speccount = specpdl_depth ();
852 struct png_memory_storage tbr; /* Data to be read */
858 /* Initialize all PNG structures */
859 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct,
860 png_error_func, png_warning_func);
862 signal_image_error ("Error obtaining memory for png_read", instantiator);
863 info_ptr = png_create_info_struct (png_ptr);
866 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
867 signal_image_error ("Error obtaining memory for png_read", instantiator);
871 unwind.png_ptr = png_ptr;
872 unwind.info_ptr = info_ptr;
874 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
876 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
877 this file, example.c from the libpng 0.81 distribution, and the
878 pngtopnm sources. -WMP-
880 /* It has been further modified to handle the API changes for 0.96,
881 and is no longer usable for previous versions. jh
884 /* Set the jmp_buf return context for png_error ... if this returns !0, then
885 we ran into a problem somewhere, and need to clean up after ourselves. */
886 if (setjmp (png_err_stct.setjmp_buffer))
888 /* Something blew up: just display the error (cleanup happens in the unwind) */
889 signal_image_error_2 ("Error decoding PNG",
890 build_string(png_err_stct.err_str),
894 /* Initialize the IO layer and read in header information */
896 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
897 const Extbyte *bytes;
900 assert (!NILP (data));
902 /* #### This is a definite problem under Mule due to the amount of
903 stack data it might allocate. Need to think about using Lstreams */
904 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary);
908 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory);
911 png_read_info (png_ptr, info_ptr);
915 unsigned char **row_pointers;
916 height = info_ptr->height;
917 width = info_ptr->width;
919 /* Wow, allocate all the memory. Truly, exciting. */
920 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3);
921 /* libpng expects that the image buffer passed in contains a
922 picture to draw on top of if the png has any transparencies.
923 This could be a good place to pass that in... */
925 row_pointers = xnew_array (png_byte *, height);
927 for (y = 0; y < height; y++)
928 row_pointers[y] = unwind.eimage + (width * 3 * y);
931 /* if the png specifies a background chunk, go ahead and
932 use it, else use what we can get from the default face. */
933 png_color_16 my_background, *image_background;
934 Lisp_Object bkgd = Qnil;
936 my_background.red = 0x7fff;
937 my_background.green = 0x7fff;
938 my_background.blue = 0x7fff;
939 bkgd = FACE_BACKGROUND (Vdefault_face, domain);
940 if (!COLOR_INSTANCEP (bkgd))
942 warn_when_safe (Qpng, Qinfo, "Couldn't get background color!");
946 Lisp_Color_Instance *c;
949 c = XCOLOR_INSTANCE (bkgd);
950 rgblist = MAYBE_LISP_DEVMETH (XDEVICE (c->device),
951 color_instance_rgb_components,
953 my_background.red = (unsigned short) XINT (XCAR (rgblist));
954 my_background.green = (unsigned short) XINT (XCAR (XCDR (rgblist)));
955 my_background.blue = (unsigned short) XINT (XCAR (XCDR (XCDR (rgblist))));
958 if (png_get_bKGD (png_ptr, info_ptr, &image_background))
959 png_set_background (png_ptr, image_background,
960 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
962 png_set_background (png_ptr, &my_background,
963 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
966 /* Now that we're using EImage, ask for 8bit RGB triples for any type
968 /* convert palette images to full RGB */
969 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
970 png_set_expand (png_ptr);
971 /* send grayscale images to RGB too */
972 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
973 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
974 png_set_gray_to_rgb (png_ptr);
975 /* we can't handle alpha values */
976 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
977 png_set_strip_alpha (png_ptr);
978 /* tell libpng to strip 16 bit depth files down to 8 bits */
979 if (info_ptr->bit_depth == 16)
980 png_set_strip_16 (png_ptr);
981 /* if the image is < 8 bits, pad it out */
982 if (info_ptr->bit_depth < 8)
984 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
985 png_set_expand (png_ptr);
987 png_set_packing (png_ptr);
990 png_read_image (png_ptr, row_pointers);
991 png_read_end (png_ptr, info_ptr);
993 #ifdef PNG_SHOW_COMMENTS
995 * I turn this off by default now, because the !%^@#!% comments
996 * show up every time the image is instantiated, which can get
997 * really really annoying. There should be some way to pass this
998 * type of data down into the glyph code, where you can get to it
999 * from lisp anyway. - WMP
1004 for (i = 0 ; i < info_ptr->num_text ; i++)
1006 /* How paranoid do I have to be about no trailing NULLs, and
1007 using (int)info_ptr->text[i].text_length, and strncpy and a temp
1008 string somewhere? */
1010 warn_when_safe (Qpng, Qinfo, "%s - %s",
1011 info_ptr->text[i].key,
1012 info_ptr->text[i].text);
1017 xfree (row_pointers);
1020 /* now instantiate */
1021 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
1022 init_image_instance_from_eimage,
1023 (ii, width, height, 1, unwind.eimage, dest_mask,
1024 instantiator, domain));
1026 /* This will clean up everything else. */
1027 unbind_to (speccount, Qnil);
1030 #endif /* HAVE_PNG */
1036 /**********************************************************************
1038 **********************************************************************/
1040 tiff_validate (Lisp_Object instantiator)
1042 file_or_data_must_be_present (instantiator);
1046 tiff_normalize (Lisp_Object inst, Lisp_Object console_type)
1048 return simple_image_type_normalize (inst, console_type, Qtiff);
1052 tiff_possible_dest_types (void)
1054 return IMAGE_COLOR_PIXMAP_MASK;
1057 struct tiff_unwind_data
1059 unsigned char *eimage;
1060 /* Object that holds the decoded data from a TIFF file */
1065 tiff_instantiate_unwind (Lisp_Object unwind_obj)
1067 struct tiff_unwind_data *data =
1068 (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj);
1070 free_opaque_ptr (unwind_obj);
1073 TIFFClose(data->tiff);
1076 xfree (data->eimage);
1081 typedef struct tiff_memory_storage
1083 Extbyte *bytes; /* The data */
1084 Extcount len; /* How big is it? */
1085 int index; /* Where are we? */
1086 } tiff_memory_storage;
1089 tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1091 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1093 if (size > (mem->len - mem->index))
1095 memcpy(buf, mem->bytes + mem->index, size);
1096 mem->index = mem->index + size;
1100 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1103 return 0; /* Shut up warnings. */
1106 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1108 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1115 newidx = mem->len + off;
1118 newidx = mem->index + off;
1121 fprintf(stderr,"Eh? invalid seek mode in tiff_memory_seek\n");
1125 if ((newidx > mem->len) || (newidx < 0))
1128 mem->index = newidx;
1133 tiff_memory_close(thandle_t data)
1139 tiff_map_noop(thandle_t data, tdata_t* pbase, toff_t* psize)
1145 tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1151 tiff_memory_size(thandle_t data)
1153 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1157 struct tiff_error_struct
1159 #ifdef HAVE_VSNPRINTF
1162 char err_str[1024]; /* return the error string */
1164 jmp_buf setjmp_buffer; /* for return to caller */
1167 /* jh 98/03/12 - ###This struct for passing data to the error functions
1168 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1169 have any place to store error func data. This should be rectified
1170 before XEmacs gets threads! */
1171 static struct tiff_error_struct tiff_err_data;
1174 tiff_error_func(const char *module, const char *fmt, ...)
1178 va_start (vargs, fmt);
1179 #ifdef HAVE_VSNPRINTF
1180 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs);
1182 /* pray this doesn't overflow... */
1183 vsprintf (tiff_err_data.err_str, fmt, vargs);
1186 /* return to setjmp point */
1187 longjmp (tiff_err_data.setjmp_buffer, 1);
1191 tiff_warning_func(const char *module, const char *fmt, ...)
1194 #ifdef HAVE_VSNPRINTF
1197 char warn_str[1024];
1200 va_start (vargs, fmt);
1201 #ifdef HAVE_VSNPRINTF
1202 vsnprintf (warn_str, 255, fmt, vargs);
1204 vsprintf (warn_str, fmt, vargs);
1207 warn_when_safe (Qtiff, Qinfo, "%s - %s",
1212 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1213 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1214 int dest_mask, Lisp_Object domain)
1216 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1217 tiff_memory_storage mem_struct;
1218 /* It is OK for the unwind data to be local to this function,
1219 because the unwind-protect is always executed when this
1220 stack frame is still valid. */
1221 struct tiff_unwind_data unwind;
1222 int speccount = specpdl_depth ();
1223 uint32 width, height;
1226 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
1228 /* set up error facilities */
1229 if (setjmp (tiff_err_data.setjmp_buffer))
1231 /* An error was signaled. No clean up is needed, as unwind handles that
1232 for us. Just pass the error along. */
1233 signal_image_error_2 ("TIFF decoding error",
1234 build_string(tiff_err_data.err_str),
1237 TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func);
1238 TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func);
1240 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1247 assert (!NILP (data));
1249 /* #### This is a definite problem under Mule due to the amount of
1250 stack data it might allocate. Think about Lstreams... */
1251 TO_EXTERNAL_FORMAT (LISP_STRING, data,
1252 ALLOCA, (bytes, len),
1254 mem_struct.bytes = bytes;
1255 mem_struct.len = len;
1256 mem_struct.index = 0;
1258 unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct,
1259 (TIFFReadWriteProc)tiff_memory_read,
1260 (TIFFReadWriteProc)tiff_memory_write,
1261 tiff_memory_seek, tiff_memory_close, tiff_memory_size,
1262 tiff_map_noop, tiff_unmap_noop);
1264 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator);
1266 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1267 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1268 unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
1270 /* #### This is little more than proof-of-concept/function testing.
1271 It needs to be reimplemented via scanline reads for both memory
1273 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1280 if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0))
1282 for (i = height - 1; i >= 0; i--)
1284 /* This is to get around weirdness in the libtiff library where properly
1285 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1286 rp = raster + (i * width);
1287 for (j = 0; j < width; j++)
1289 *ep++ = (unsigned char)TIFFGetR(*rp);
1290 *ep++ = (unsigned char)TIFFGetG(*rp);
1291 *ep++ = (unsigned char)TIFFGetB(*rp);
1298 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator);
1302 /* now instantiate */
1303 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
1304 init_image_instance_from_eimage,
1305 (ii, width, height, 1, unwind.eimage, dest_mask,
1306 instantiator, domain));
1308 unbind_to (speccount, Qnil);
1311 #endif /* HAVE_TIFF */
1314 /************************************************************************/
1315 /* initialization */
1316 /************************************************************************/
1319 syms_of_glyphs_eimage (void)
1324 image_instantiator_format_create_glyphs_eimage (void)
1326 /* image-instantiator types */
1328 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg");
1330 IIFORMAT_HAS_METHOD (jpeg, validate);
1331 IIFORMAT_HAS_METHOD (jpeg, normalize);
1332 IIFORMAT_HAS_METHOD (jpeg, possible_dest_types);
1333 IIFORMAT_HAS_METHOD (jpeg, instantiate);
1335 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string);
1336 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string);
1340 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif");
1342 IIFORMAT_HAS_METHOD (gif, validate);
1343 IIFORMAT_HAS_METHOD (gif, normalize);
1344 IIFORMAT_HAS_METHOD (gif, possible_dest_types);
1345 IIFORMAT_HAS_METHOD (gif, instantiate);
1347 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string);
1348 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string);
1352 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png");
1354 IIFORMAT_HAS_METHOD (png, validate);
1355 IIFORMAT_HAS_METHOD (png, normalize);
1356 IIFORMAT_HAS_METHOD (png, possible_dest_types);
1357 IIFORMAT_HAS_METHOD (png, instantiate);
1359 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string);
1360 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string);
1364 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff");
1366 IIFORMAT_HAS_METHOD (tiff, validate);
1367 IIFORMAT_HAS_METHOD (tiff, normalize);
1368 IIFORMAT_HAS_METHOD (tiff, possible_dest_types);
1369 IIFORMAT_HAS_METHOD (tiff, instantiate);
1371 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string);
1372 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string);
1378 vars_of_glyphs_eimage (void)