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,
123 Lisp_Object dest_mask)
125 return simple_image_type_normalize (inst, console_type, Qjpeg);
129 jpeg_possible_dest_types (void)
131 return IMAGE_COLOR_PIXMAP_MASK;
134 /* To survive the otherwise baffling complexity of making sure
135 everything gets cleaned up in the presence of an error, we
136 use an unwind_protect(). */
138 struct jpeg_unwind_data
140 /* Stream that we need to close */
142 /* Object that holds state info for JPEG decoding */
143 struct jpeg_decompress_struct *cinfo_ptr;
145 unsigned char *eimage;
149 jpeg_instantiate_unwind (Lisp_Object unwind_obj)
151 struct jpeg_unwind_data *data =
152 (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj);
154 free_opaque_ptr (unwind_obj);
156 jpeg_destroy_decompress (data->cinfo_ptr);
159 fclose (data->instream);
161 if (data->eimage) xfree (data->eimage);
169 * The JPEG library's standard error handler (jerror.c) is divided into
170 * several "methods" which you can override individually. This lets you
171 * adjust the behavior without duplicating a lot of code, which you might
172 * have to update with each future release.
174 * Our example here shows how to override the "error_exit" method so that
175 * control is returned to the library's caller when a fatal error occurs,
176 * rather than calling exit() as the standard error_exit method does.
178 * We use C's setjmp/longjmp facility to return control. This means that the
179 * routine which calls the JPEG library must first execute a setjmp() call to
180 * establish the return point. We want the replacement error_exit to do a
181 * longjmp(). But we need to make the setjmp buffer accessible to the
182 * error_exit routine. To do this, we make a private extension of the
183 * standard JPEG error handler object. (If we were using C++, we'd say we
184 * were making a subclass of the regular error handler.)
186 * Here's the extended error handler struct:
189 struct my_jpeg_error_mgr
191 struct jpeg_error_mgr pub; /* "public" fields */
192 jmp_buf setjmp_buffer; /* for return to caller */
195 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
200 our_init_source (j_decompress_ptr cinfo)
204 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
209 our_fill_input_buffer (j_decompress_ptr cinfo)
211 /* Insert a fake EOI marker */
212 struct jpeg_source_mgr *src = cinfo->src;
213 static JOCTET buffer[2];
215 buffer[0] = (JOCTET) 0xFF;
216 buffer[1] = (JOCTET) JPEG_EOI;
218 src->next_input_byte = buffer;
219 src->bytes_in_buffer = 2;
223 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
228 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
230 struct jpeg_source_mgr *src = NULL;
232 src = (struct jpeg_source_mgr *) cinfo->src;
237 } else if (num_bytes > src->bytes_in_buffer)
239 ERREXIT(cinfo, JERR_INPUT_EOF);
243 src->bytes_in_buffer -= num_bytes;
244 src->next_input_byte += num_bytes;
247 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
252 our_term_source (j_decompress_ptr cinfo)
258 struct jpeg_source_mgr pub;
259 } our_jpeg_source_mgr;
262 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
264 struct jpeg_source_mgr *src;
266 if (cinfo->src == NULL)
267 { /* first time for this JPEG object? */
268 cinfo->src = (struct jpeg_source_mgr *)
269 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
270 sizeof(our_jpeg_source_mgr));
271 src = (struct jpeg_source_mgr *) cinfo->src;
272 src->next_input_byte = data;
274 src = (struct jpeg_source_mgr *) cinfo->src;
275 src->init_source = our_init_source;
276 src->fill_input_buffer = our_fill_input_buffer;
277 src->skip_input_data = our_skip_input_data;
278 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
279 src->term_source = our_term_source;
280 src->bytes_in_buffer = len;
281 src->next_input_byte = data;
284 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
289 my_jpeg_error_exit (j_common_ptr cinfo)
291 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
292 struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err;
294 /* Return control to the setjmp point */
295 longjmp (myerr->setjmp_buffer, 1);
298 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
303 my_jpeg_output_message (j_common_ptr cinfo)
305 char buffer[JMSG_LENGTH_MAX];
307 /* Create the message */
308 (*cinfo->err->format_message) (cinfo, buffer);
309 warn_when_safe (Qjpeg, Qinfo, "%s", buffer);
312 /* The code in this routine is based on example.c from the JPEG library
313 source code and from gif_instantiate() */
315 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
316 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
317 int dest_mask, Lisp_Object domain)
319 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
320 /* It is OK for the unwind data to be local to this function,
321 because the unwind-protect is always executed when this
322 stack frame is still valid. */
323 struct jpeg_unwind_data unwind;
324 int speccount = specpdl_depth ();
326 /* This struct contains the JPEG decompression parameters and pointers to
327 * working space (which is allocated as needed by the JPEG library).
329 struct jpeg_decompress_struct cinfo;
330 /* We use our private extension JPEG error handler.
331 * Note that this struct must live as long as the main JPEG parameter
332 * struct, to avoid dangling-pointer problems.
334 struct my_jpeg_error_mgr jerr;
336 /* Step -1: First record our unwind-protect, which will clean up after
337 any exit, normal or not */
340 record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind));
342 /* Step 1: allocate and initialize JPEG decompression object */
344 /* We set up the normal JPEG error routines, then override error_exit. */
345 cinfo.err = jpeg_std_error (&jerr.pub);
346 jerr.pub.error_exit = my_jpeg_error_exit;
347 jerr.pub.output_message = my_jpeg_output_message;
349 /* Establish the setjmp return context for my_error_exit to use. */
350 if (setjmp (jerr.setjmp_buffer))
352 /* If we get here, the JPEG code has signaled an error.
353 * We need to clean up the JPEG object, close the input file, and return.
357 Lisp_Object errstring;
358 char buffer[JMSG_LENGTH_MAX];
360 /* Create the message */
361 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer);
362 errstring = build_string (buffer);
364 signal_image_error_2 ("JPEG decoding error",
365 errstring, instantiator);
369 /* Now we can initialize the JPEG decompression object. */
370 jpeg_create_decompress (&cinfo);
371 unwind.cinfo_ptr = &cinfo;
373 /* Step 2: specify data source (eg, a file) */
376 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
377 const Extbyte *bytes;
380 /* #### This is a definite problem under Mule due to the amount of
381 stack data it might allocate. Need to be able to convert and
382 write out to a file. */
383 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary);
384 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len);
387 /* Step 3: read file parameters with jpeg_read_header() */
389 jpeg_read_header (&cinfo, TRUE);
390 /* We can ignore the return value from jpeg_read_header since
391 * (a) suspension is not possible with the stdio data source, and
392 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
393 * See libjpeg.doc for more info.
397 int jpeg_gray = 0; /* if we're dealing with a grayscale */
398 /* Step 4: set parameters for decompression. */
400 /* Now that we're using EImages, send all data as 24bit color.
401 The backend routine will take care of any necessary reductions.
402 We do have to handle the grayscale case ourselves, however. */
403 if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
405 cinfo.out_color_space = JCS_GRAYSCALE;
410 /* we're relying on the jpeg driver to do any other conversions,
411 or signal an error if the conversion isn't supported. */
412 cinfo.out_color_space = JCS_RGB;
415 /* Step 5: Start decompressor */
416 jpeg_start_decompress (&cinfo);
418 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
420 unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3);
422 signal_image_error("Unable to allocate enough memory for image", instantiator);
425 JSAMPARRAY row_buffer; /* Output row buffer */
427 int row_stride; /* physical row width in output buffer */
428 unsigned char *op = unwind.eimage;
430 /* We may need to do some setup of our own at this point before reading
431 * the data. After jpeg_start_decompress() we have the correct scaled
432 * output image dimensions available
433 * We need to make an output work buffer of the right size.
435 /* JSAMPLEs per row in output buffer. */
436 row_stride = cinfo.output_width * cinfo.output_components;
437 /* Make a one-row-high sample array that will go away when done
439 row_buffer = ((*cinfo.mem->alloc_sarray)
440 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1));
442 /* Here we use the library's state variable cinfo.output_scanline as the
443 * loop counter, so that we don't have to keep track ourselves.
445 while (cinfo.output_scanline < cinfo.output_height)
449 /* jpeg_read_scanlines expects an array of pointers to scanlines.
450 * Here the array is only one element long, but you could ask for
451 * more than one scanline at a time if that's more convenient.
453 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1);
455 for (i = 0; i < cinfo.output_width; i++)
461 #if (BITS_IN_JSAMPLE == 8)
462 val = (unsigned char)*jp++;
463 #else /* other option is 12 */
464 val = (unsigned char)(*jp++ >> 4);
466 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */
471 for (clr = 0; clr < 3; clr++)
472 #if (BITS_IN_JSAMPLE == 8)
473 *op++ = (unsigned char)*jp++;
474 #else /* other option is 12 */
475 *op++ = (unsigned char)(*jp++ >> 4);
483 /* Step 6.5: Create the pixmap and set up the image instance */
484 /* now instantiate */
485 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
486 init_image_instance_from_eimage,
487 (ii, cinfo.output_width, cinfo.output_height, 1,
488 unwind.eimage, dest_mask,
489 instantiator, domain));
491 /* Step 7: Finish decompression */
493 jpeg_finish_decompress (&cinfo);
494 /* We can ignore the return value since suspension is not possible
495 * with the stdio data source.
498 /* And we're done! */
499 /* This will clean up everything else. */
500 unbind_to (speccount, Qnil);
503 #endif /* HAVE_JPEG */
506 /**********************************************************************
508 **********************************************************************/
513 gif_validate (Lisp_Object instantiator)
515 file_or_data_must_be_present (instantiator);
519 gif_normalize (Lisp_Object inst, Lisp_Object console_type,
520 Lisp_Object dest_mask)
522 return simple_image_type_normalize (inst, console_type, Qgif);
526 gif_possible_dest_types (void)
528 return IMAGE_COLOR_PIXMAP_MASK;
531 /* To survive the otherwise baffling complexity of making sure
532 everything gets cleaned up in the presence of an error, we
533 use an unwind_protect(). */
535 struct gif_unwind_data
537 unsigned char *eimage;
538 /* Object that holds the decoded data from a GIF file */
539 GifFileType *giffile;
543 gif_instantiate_unwind (Lisp_Object unwind_obj)
545 struct gif_unwind_data *data =
546 (struct gif_unwind_data *) get_opaque_ptr (unwind_obj);
548 free_opaque_ptr (unwind_obj);
551 DGifCloseFile (data->giffile);
552 GifFree(data->giffile);
554 if (data->eimage) xfree(data->eimage);
559 typedef struct gif_memory_storage
561 Extbyte *bytes; /* The data */
562 Extcount len; /* How big is it? */
563 int index; /* Where are we? */
564 } gif_memory_storage;
567 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
569 gif_memory_storage *mem = (gif_memory_storage*)data;
571 if (size > (mem->len - mem->index))
573 memcpy(buf, mem->bytes + mem->index, size);
574 mem->index = mem->index + size;
579 gif_memory_close(VoidPtr data)
584 struct gif_error_struct
586 const char *err_str; /* return the error string */
587 jmp_buf setjmp_buffer; /* for return to caller */
591 gif_error_func(const char *err_str, VoidPtr error_ptr)
593 struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr;
595 /* return to setjmp point */
596 error_data->err_str = err_str;
597 longjmp (error_data->setjmp_buffer, 1);
601 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
602 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
603 int dest_mask, Lisp_Object domain)
605 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
606 /* It is OK for the unwind data to be local to this function,
607 because the unwind-protect is always executed when this
608 stack frame is still valid. */
609 struct gif_unwind_data unwind;
610 int speccount = specpdl_depth ();
611 gif_memory_storage mem_struct;
612 struct gif_error_struct gif_err;
619 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
621 /* 1. Now decode the data. */
624 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
626 assert (!NILP (data));
628 if (!(unwind.giffile = GifSetup()))
629 signal_image_error ("Insufficient memory to instantiate GIF image", instantiator);
631 /* set up error facilities */
632 if (setjmp(gif_err.setjmp_buffer))
634 /* An error was signaled. No clean up is needed, as unwind handles that
635 for us. Just pass the error along. */
636 Lisp_Object errstring;
637 errstring = build_string (gif_err.err_str);
638 signal_image_error_2 ("GIF decoding error", errstring, instantiator);
640 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
642 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary);
643 mem_struct.bytes = bytes;
644 mem_struct.len = len;
645 mem_struct.index = 0;
646 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
647 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
648 DGifInitRead(unwind.giffile);
650 /* Then slurp the image into memory, decoding along the way.
651 The result is the image in a simple one-byte-per-pixel
652 format (#### the GIF routines only support 8-bit GIFs,
654 DGifSlurp (unwind.giffile);
657 /* 3. Now create the EImage(s) */
659 ColorMapObject *cmo = unwind.giffile->SColorMap;
660 int i, j, row, pass, interlace, slice;
662 /* interlaced gifs have rows in this order:
663 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
664 static int InterlacedOffset[] = { 0, 4, 2, 1 };
665 static int InterlacedJumps[] = { 8, 8, 4, 2 };
667 height = unwind.giffile->SHeight;
668 width = unwind.giffile->SWidth;
669 unwind.eimage = (unsigned char*)
670 xmalloc (width * height * 3 * unwind.giffile->ImageCount);
672 signal_image_error("Unable to allocate enough memory for image", instantiator);
674 /* write the data in EImage format (8bit RGB triples) */
676 for (slice = 0; slice < unwind.giffile->ImageCount; slice++)
678 /* We check here that that the current image covers the full "screen" size. */
679 if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height
680 || unwind.giffile->SavedImages[slice].ImageDesc.Width != width
681 || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0
682 || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0)
683 signal_image_error ("Image in GIF file is not full size",
686 interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace;
688 row = interlace ? InterlacedOffset[pass] : 0;
689 eip = unwind.eimage + (width * height * 3 * slice);
690 for (i = 0; i < height; i++)
694 row = InterlacedOffset[++pass];
695 while (row >= height)
696 row = InterlacedOffset[++pass];
698 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3);
699 for (j = 0; j < width; j++)
701 unsigned char pixel =
702 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j];
703 *eip++ = cmo->Colors[pixel].Red;
704 *eip++ = cmo->Colors[pixel].Green;
705 *eip++ = cmo->Colors[pixel].Blue;
707 row += interlace ? InterlacedJumps[pass] : 1;
711 /* now instantiate */
712 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
713 init_image_instance_from_eimage,
714 (ii, width, height, unwind.giffile->ImageCount, unwind.eimage, dest_mask,
715 instantiator, domain));
718 /* We read the gif successfully. If we have more than one slice then
720 if (unwind.giffile->ImageCount > 1)
722 /* See if there is a timeout value. In theory there could be one
723 for every image - but that makes the implementation way to
724 complicated for now so we just take the first. */
725 unsigned short timeout = 0;
728 if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE
730 unwind.giffile->SavedImages[0].ExtensionBlockCount)
732 timeout = (unsigned short)
733 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) +
734 unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10;
737 /* Too short a timeout will crucify us performance-wise. */
738 tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance);
741 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid);
744 unbind_to (speccount, Qnil);
747 #endif /* HAVE_GIF */
752 /**********************************************************************
754 **********************************************************************/
756 png_validate (Lisp_Object instantiator)
758 file_or_data_must_be_present (instantiator);
762 png_normalize (Lisp_Object inst, Lisp_Object console_type,
763 Lisp_Object dest_mask)
765 return simple_image_type_normalize (inst, console_type, Qpng);
769 png_possible_dest_types (void)
771 return IMAGE_COLOR_PIXMAP_MASK;
774 struct png_memory_storage
776 const Extbyte *bytes; /* The data */
777 Extcount len; /* How big is it? */
778 int index; /* Where are we? */
782 png_read_from_memory(png_structp png_ptr, png_bytep data,
785 struct png_memory_storage *tbr =
786 (struct png_memory_storage *) png_get_io_ptr (png_ptr);
788 if (length > (tbr->len - tbr->index))
789 png_error (png_ptr, (png_const_charp) "Read Error");
790 memcpy (data,tbr->bytes + tbr->index,length);
791 tbr->index = tbr->index + length;
794 struct png_error_struct
797 jmp_buf setjmp_buffer; /* for return to caller */
800 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
801 structure, and there are cases where the size can be different from
802 between inside the library, and inside the code! To do an end run
803 around this, use our own error functions, and don't rely on things
804 passed in the png_ptr to them. This is an ugly hack and must
805 go away when the lisp engine is threaded! */
806 static struct png_error_struct png_err_stct;
809 png_error_func (png_structp png_ptr, png_const_charp msg)
811 png_err_stct.err_str = msg;
812 longjmp (png_err_stct.setjmp_buffer, 1);
816 png_warning_func (png_structp png_ptr, png_const_charp msg)
818 warn_when_safe (Qpng, Qinfo, "%s", msg);
821 struct png_unwind_data
824 unsigned char *eimage;
830 png_instantiate_unwind (Lisp_Object unwind_obj)
832 struct png_unwind_data *data =
833 (struct png_unwind_data *) get_opaque_ptr (unwind_obj);
835 free_opaque_ptr (unwind_obj);
837 png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
839 fclose (data->instream);
841 if (data->eimage) xfree(data->eimage);
847 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
848 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
849 int dest_mask, Lisp_Object domain)
851 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
852 struct png_unwind_data unwind;
853 int speccount = specpdl_depth ();
855 struct png_memory_storage tbr; /* Data to be read */
861 /* Initialize all PNG structures */
862 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct,
863 png_error_func, png_warning_func);
865 signal_image_error ("Error obtaining memory for png_read", instantiator);
866 info_ptr = png_create_info_struct (png_ptr);
869 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
870 signal_image_error ("Error obtaining memory for png_read", instantiator);
874 unwind.png_ptr = png_ptr;
875 unwind.info_ptr = info_ptr;
877 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
879 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
880 this file, example.c from the libpng 0.81 distribution, and the
881 pngtopnm sources. -WMP-
883 /* It has been further modified to handle the API changes for 0.96,
884 and is no longer usable for previous versions. jh
887 /* Set the jmp_buf return context for png_error ... if this returns !0, then
888 we ran into a problem somewhere, and need to clean up after ourselves. */
889 if (setjmp (png_err_stct.setjmp_buffer))
891 /* Something blew up: just display the error (cleanup happens in the unwind) */
892 signal_image_error_2 ("Error decoding PNG",
893 build_string(png_err_stct.err_str),
897 /* Initialize the IO layer and read in header information */
899 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
900 const Extbyte *bytes;
903 assert (!NILP (data));
905 /* #### This is a definite problem under Mule due to the amount of
906 stack data it might allocate. Need to think about using Lstreams */
907 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary);
911 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory);
914 png_read_info (png_ptr, info_ptr);
918 unsigned char **row_pointers;
919 height = info_ptr->height;
920 width = info_ptr->width;
922 /* Wow, allocate all the memory. Truly, exciting. */
923 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3);
924 /* libpng expects that the image buffer passed in contains a
925 picture to draw on top of if the png has any transparencies.
926 This could be a good place to pass that in... */
928 row_pointers = xnew_array (png_byte *, height);
930 for (y = 0; y < height; y++)
931 row_pointers[y] = unwind.eimage + (width * 3 * y);
934 /* if the png specifies a background chunk, go ahead and
935 use it, else use what we can get from the default face. */
936 png_color_16 my_background, *image_background;
937 Lisp_Object bkgd = Qnil;
939 my_background.red = 0x7fff;
940 my_background.green = 0x7fff;
941 my_background.blue = 0x7fff;
942 bkgd = FACE_BACKGROUND (Vdefault_face, domain);
943 if (!COLOR_INSTANCEP (bkgd))
945 warn_when_safe (Qpng, Qinfo, "Couldn't get background color!");
949 Lisp_Color_Instance *c;
952 c = XCOLOR_INSTANCE (bkgd);
953 rgblist = MAYBE_LISP_DEVMETH (XDEVICE (c->device),
954 color_instance_rgb_components,
956 my_background.red = (unsigned short) XINT (XCAR (rgblist));
957 my_background.green = (unsigned short) XINT (XCAR (XCDR (rgblist)));
958 my_background.blue = (unsigned short) XINT (XCAR (XCDR (XCDR (rgblist))));
961 if (png_get_bKGD (png_ptr, info_ptr, &image_background))
962 png_set_background (png_ptr, image_background,
963 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
965 png_set_background (png_ptr, &my_background,
966 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
969 /* Now that we're using EImage, ask for 8bit RGB triples for any type
971 /* convert palette images to full RGB */
972 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
973 png_set_expand (png_ptr);
974 /* send grayscale images to RGB too */
975 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
976 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
977 png_set_gray_to_rgb (png_ptr);
978 /* we can't handle alpha values */
979 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
980 png_set_strip_alpha (png_ptr);
981 /* tell libpng to strip 16 bit depth files down to 8 bits */
982 if (info_ptr->bit_depth == 16)
983 png_set_strip_16 (png_ptr);
984 /* if the image is < 8 bits, pad it out */
985 if (info_ptr->bit_depth < 8)
987 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
988 png_set_expand (png_ptr);
990 png_set_packing (png_ptr);
993 png_read_image (png_ptr, row_pointers);
994 png_read_end (png_ptr, info_ptr);
996 #ifdef PNG_SHOW_COMMENTS
998 * I turn this off by default now, because the !%^@#!% comments
999 * show up every time the image is instantiated, which can get
1000 * really really annoying. There should be some way to pass this
1001 * type of data down into the glyph code, where you can get to it
1002 * from lisp anyway. - WMP
1007 for (i = 0 ; i < info_ptr->num_text ; i++)
1009 /* How paranoid do I have to be about no trailing NULLs, and
1010 using (int)info_ptr->text[i].text_length, and strncpy and a temp
1011 string somewhere? */
1013 warn_when_safe (Qpng, Qinfo, "%s - %s",
1014 info_ptr->text[i].key,
1015 info_ptr->text[i].text);
1020 xfree (row_pointers);
1023 /* now instantiate */
1024 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
1025 init_image_instance_from_eimage,
1026 (ii, width, height, 1, unwind.eimage, dest_mask,
1027 instantiator, domain));
1029 /* This will clean up everything else. */
1030 unbind_to (speccount, Qnil);
1033 #endif /* HAVE_PNG */
1039 /**********************************************************************
1041 **********************************************************************/
1043 tiff_validate (Lisp_Object instantiator)
1045 file_or_data_must_be_present (instantiator);
1049 tiff_normalize (Lisp_Object inst, Lisp_Object console_type,
1050 Lisp_Object dest_mask)
1052 return simple_image_type_normalize (inst, console_type, Qtiff);
1056 tiff_possible_dest_types (void)
1058 return IMAGE_COLOR_PIXMAP_MASK;
1061 struct tiff_unwind_data
1063 unsigned char *eimage;
1064 /* Object that holds the decoded data from a TIFF file */
1069 tiff_instantiate_unwind (Lisp_Object unwind_obj)
1071 struct tiff_unwind_data *data =
1072 (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj);
1074 free_opaque_ptr (unwind_obj);
1077 TIFFClose(data->tiff);
1080 xfree (data->eimage);
1085 typedef struct tiff_memory_storage
1087 Extbyte *bytes; /* The data */
1088 Extcount len; /* How big is it? */
1089 int index; /* Where are we? */
1090 } tiff_memory_storage;
1093 tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1095 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1097 if (size > (mem->len - mem->index))
1099 memcpy(buf, mem->bytes + mem->index, size);
1100 mem->index = mem->index + size;
1104 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1107 return 0; /* Shut up warnings. */
1110 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1112 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1119 newidx = mem->len + off;
1122 newidx = mem->index + off;
1125 fprintf(stderr,"Eh? invalid seek mode in tiff_memory_seek\n");
1129 if ((newidx > mem->len) || (newidx < 0))
1132 mem->index = newidx;
1137 tiff_memory_close(thandle_t data)
1143 tiff_map_noop(thandle_t data, tdata_t* pbase, toff_t* psize)
1149 tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1155 tiff_memory_size(thandle_t data)
1157 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1161 struct tiff_error_struct
1163 #ifdef HAVE_VSNPRINTF
1166 char err_str[1024]; /* return the error string */
1168 jmp_buf setjmp_buffer; /* for return to caller */
1171 /* jh 98/03/12 - ###This struct for passing data to the error functions
1172 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1173 have any place to store error func data. This should be rectified
1174 before XEmacs gets threads! */
1175 static struct tiff_error_struct tiff_err_data;
1178 tiff_error_func(const char *module, const char *fmt, ...)
1182 va_start (vargs, fmt);
1183 #ifdef HAVE_VSNPRINTF
1184 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs);
1186 /* pray this doesn't overflow... */
1187 vsprintf (tiff_err_data.err_str, fmt, vargs);
1190 /* return to setjmp point */
1191 longjmp (tiff_err_data.setjmp_buffer, 1);
1195 tiff_warning_func(const char *module, const char *fmt, ...)
1198 #ifdef HAVE_VSNPRINTF
1201 char warn_str[1024];
1204 va_start (vargs, fmt);
1205 #ifdef HAVE_VSNPRINTF
1206 vsnprintf (warn_str, 255, fmt, vargs);
1208 vsprintf (warn_str, fmt, vargs);
1211 warn_when_safe (Qtiff, Qinfo, "%s - %s",
1216 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1217 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1218 int dest_mask, Lisp_Object domain)
1220 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1221 tiff_memory_storage mem_struct;
1222 /* It is OK for the unwind data to be local to this function,
1223 because the unwind-protect is always executed when this
1224 stack frame is still valid. */
1225 struct tiff_unwind_data unwind;
1226 int speccount = specpdl_depth ();
1227 uint32 width, height;
1230 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
1232 /* set up error facilities */
1233 if (setjmp (tiff_err_data.setjmp_buffer))
1235 /* An error was signaled. No clean up is needed, as unwind handles that
1236 for us. Just pass the error along. */
1237 signal_image_error_2 ("TIFF decoding error",
1238 build_string(tiff_err_data.err_str),
1241 TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func);
1242 TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func);
1244 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1251 assert (!NILP (data));
1253 /* #### This is a definite problem under Mule due to the amount of
1254 stack data it might allocate. Think about Lstreams... */
1255 TO_EXTERNAL_FORMAT (LISP_STRING, data,
1256 ALLOCA, (bytes, len),
1258 mem_struct.bytes = bytes;
1259 mem_struct.len = len;
1260 mem_struct.index = 0;
1262 unwind.tiff = TIFFClientOpen ("memfile", "r", (thandle_t) &mem_struct,
1263 (TIFFReadWriteProc)tiff_memory_read,
1264 (TIFFReadWriteProc)tiff_memory_write,
1265 tiff_memory_seek, tiff_memory_close, tiff_memory_size,
1266 tiff_map_noop, tiff_unmap_noop);
1268 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator);
1270 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1271 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1272 unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
1274 /* #### This is little more than proof-of-concept/function testing.
1275 It needs to be reimplemented via scanline reads for both memory
1277 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1284 if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0))
1286 for (i = height - 1; i >= 0; i--)
1288 /* This is to get around weirdness in the libtiff library where properly
1289 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1290 rp = raster + (i * width);
1291 for (j = 0; j < width; j++)
1293 *ep++ = (unsigned char)TIFFGetR(*rp);
1294 *ep++ = (unsigned char)TIFFGetG(*rp);
1295 *ep++ = (unsigned char)TIFFGetB(*rp);
1302 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator);
1306 /* now instantiate */
1307 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
1308 init_image_instance_from_eimage,
1309 (ii, width, height, 1, unwind.eimage, dest_mask,
1310 instantiator, domain));
1312 unbind_to (speccount, Qnil);
1315 #endif /* HAVE_TIFF */
1318 /************************************************************************/
1319 /* initialization */
1320 /************************************************************************/
1323 syms_of_glyphs_eimage (void)
1328 image_instantiator_format_create_glyphs_eimage (void)
1330 /* image-instantiator types */
1332 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg");
1334 IIFORMAT_HAS_METHOD (jpeg, validate);
1335 IIFORMAT_HAS_METHOD (jpeg, normalize);
1336 IIFORMAT_HAS_METHOD (jpeg, possible_dest_types);
1337 IIFORMAT_HAS_METHOD (jpeg, instantiate);
1339 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string);
1340 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string);
1344 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif");
1346 IIFORMAT_HAS_METHOD (gif, validate);
1347 IIFORMAT_HAS_METHOD (gif, normalize);
1348 IIFORMAT_HAS_METHOD (gif, possible_dest_types);
1349 IIFORMAT_HAS_METHOD (gif, instantiate);
1351 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string);
1352 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string);
1356 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png");
1358 IIFORMAT_HAS_METHOD (png, validate);
1359 IIFORMAT_HAS_METHOD (png, normalize);
1360 IIFORMAT_HAS_METHOD (png, possible_dest_types);
1361 IIFORMAT_HAS_METHOD (png, instantiate);
1363 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string);
1364 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string);
1368 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff");
1370 IIFORMAT_HAS_METHOD (tiff, validate);
1371 IIFORMAT_HAS_METHOD (tiff, normalize);
1372 IIFORMAT_HAS_METHOD (tiff, possible_dest_types);
1373 IIFORMAT_HAS_METHOD (tiff, instantiate);
1375 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string);
1376 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string);
1382 vars_of_glyphs_eimage (void)