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?
74 #include "file-coding.h"
78 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
83 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
88 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif);
93 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png);
100 /**********************************************************************
102 **********************************************************************/
113 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/
115 jpeg_validate (Lisp_Object instantiator)
117 file_or_data_must_be_present (instantiator);
121 jpeg_normalize (Lisp_Object inst, Lisp_Object console_type)
123 return simple_image_type_normalize (inst, console_type, Qjpeg);
127 jpeg_possible_dest_types (void)
129 return IMAGE_COLOR_PIXMAP_MASK;
132 /* To survive the otherwise baffling complexity of making sure
133 everything gets cleaned up in the presence of an error, we
134 use an unwind_protect(). */
136 struct jpeg_unwind_data
138 /* Stream that we need to close */
140 /* Object that holds state info for JPEG decoding */
141 struct jpeg_decompress_struct *cinfo_ptr;
143 unsigned char *eimage;
147 jpeg_instantiate_unwind (Lisp_Object unwind_obj)
149 struct jpeg_unwind_data *data =
150 (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj);
152 free_opaque_ptr (unwind_obj);
154 jpeg_destroy_decompress (data->cinfo_ptr);
157 fclose (data->instream);
159 if (data->eimage) xfree (data->eimage);
167 * The JPEG library's standard error handler (jerror.c) is divided into
168 * several "methods" which you can override individually. This lets you
169 * adjust the behavior without duplicating a lot of code, which you might
170 * have to update with each future release.
172 * Our example here shows how to override the "error_exit" method so that
173 * control is returned to the library's caller when a fatal error occurs,
174 * rather than calling exit() as the standard error_exit method does.
176 * We use C's setjmp/longjmp facility to return control. This means that the
177 * routine which calls the JPEG library must first execute a setjmp() call to
178 * establish the return point. We want the replacement error_exit to do a
179 * longjmp(). But we need to make the setjmp buffer accessible to the
180 * error_exit routine. To do this, we make a private extension of the
181 * standard JPEG error handler object. (If we were using C++, we'd say we
182 * were making a subclass of the regular error handler.)
184 * Here's the extended error handler struct:
187 struct my_jpeg_error_mgr
189 struct jpeg_error_mgr pub; /* "public" fields */
190 jmp_buf setjmp_buffer; /* for return to caller */
193 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
198 our_init_source (j_decompress_ptr cinfo)
202 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
207 our_fill_input_buffer (j_decompress_ptr cinfo)
209 /* Insert a fake EOI marker */
210 struct jpeg_source_mgr *src = cinfo->src;
211 static JOCTET buffer[2];
213 buffer[0] = (JOCTET) 0xFF;
214 buffer[1] = (JOCTET) JPEG_EOI;
216 src->next_input_byte = buffer;
217 src->bytes_in_buffer = 2;
221 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
226 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
228 struct jpeg_source_mgr *src = NULL;
230 src = (struct jpeg_source_mgr *) cinfo->src;
235 } else if (num_bytes > src->bytes_in_buffer)
237 ERREXIT(cinfo, JERR_INPUT_EOF);
241 src->bytes_in_buffer -= num_bytes;
242 src->next_input_byte += num_bytes;
245 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
250 our_term_source (j_decompress_ptr cinfo)
256 struct jpeg_source_mgr pub;
257 } our_jpeg_source_mgr;
260 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
262 struct jpeg_source_mgr *src;
264 if (cinfo->src == NULL)
265 { /* first time for this JPEG object? */
266 cinfo->src = (struct jpeg_source_mgr *)
267 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
268 sizeof(our_jpeg_source_mgr));
269 src = (struct jpeg_source_mgr *) cinfo->src;
270 src->next_input_byte = data;
272 src = (struct jpeg_source_mgr *) cinfo->src;
273 src->init_source = our_init_source;
274 src->fill_input_buffer = our_fill_input_buffer;
275 src->skip_input_data = our_skip_input_data;
276 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
277 src->term_source = our_term_source;
278 src->bytes_in_buffer = len;
279 src->next_input_byte = data;
282 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
287 my_jpeg_error_exit (j_common_ptr cinfo)
289 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
290 struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err;
292 /* Return control to the setjmp point */
293 longjmp (myerr->setjmp_buffer, 1);
296 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
301 my_jpeg_output_message (j_common_ptr cinfo)
303 char buffer[JMSG_LENGTH_MAX];
305 /* Create the message */
306 (*cinfo->err->format_message) (cinfo, buffer);
307 warn_when_safe (Qjpeg, Qinfo, "%s", buffer);
310 /* The code in this routine is based on example.c from the JPEG library
311 source code and from gif_instantiate() */
313 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
314 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
315 int dest_mask, Lisp_Object domain)
317 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
318 /* It is OK for the unwind data to be local to this function,
319 because the unwind-protect is always executed when this
320 stack frame is still valid. */
321 struct jpeg_unwind_data unwind;
322 int speccount = specpdl_depth ();
324 /* This struct contains the JPEG decompression parameters and pointers to
325 * working space (which is allocated as needed by the JPEG library).
327 struct jpeg_decompress_struct cinfo;
328 /* We use our private extension JPEG error handler.
329 * Note that this struct must live as long as the main JPEG parameter
330 * struct, to avoid dangling-pointer problems.
332 struct my_jpeg_error_mgr jerr;
334 /* Step -1: First record our unwind-protect, which will clean up after
335 any exit, normal or not */
338 record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind));
340 /* Step 1: allocate and initialize JPEG decompression object */
342 /* We set up the normal JPEG error routines, then override error_exit. */
343 cinfo.err = jpeg_std_error (&jerr.pub);
344 jerr.pub.error_exit = my_jpeg_error_exit;
345 jerr.pub.output_message = my_jpeg_output_message;
347 /* Establish the setjmp return context for my_error_exit to use. */
348 if (setjmp (jerr.setjmp_buffer))
350 /* If we get here, the JPEG code has signaled an error.
351 * We need to clean up the JPEG object, close the input file, and return.
355 Lisp_Object errstring;
356 char buffer[JMSG_LENGTH_MAX];
358 /* Create the message */
359 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer);
360 errstring = build_string (buffer);
362 signal_image_error_2 ("JPEG decoding error",
363 errstring, instantiator);
367 /* Now we can initialize the JPEG decompression object. */
368 jpeg_create_decompress (&cinfo);
369 unwind.cinfo_ptr = &cinfo;
371 /* Step 2: specify data source (eg, a file) */
374 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
375 CONST Extbyte *bytes;
378 /* #### This is a definite problem under Mule due to the amount of
379 stack data it might allocate. Need to be able to convert and
380 write out to a file. */
381 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
382 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len);
385 /* Step 3: read file parameters with jpeg_read_header() */
387 jpeg_read_header (&cinfo, TRUE);
388 /* We can ignore the return value from jpeg_read_header since
389 * (a) suspension is not possible with the stdio data source, and
390 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
391 * See libjpeg.doc for more info.
395 int jpeg_gray = 0; /* if we're dealing with a grayscale */
396 /* Step 4: set parameters for decompression. */
398 /* Now that we're using EImages, send all data as 24bit color.
399 The backend routine will take care of any necessary reductions.
400 We do have to handle the grayscale case ourselves, however. */
401 if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
403 cinfo.out_color_space = JCS_GRAYSCALE;
408 /* we're relying on the jpeg driver to do any other conversions,
409 or signal an error if the conversion isn't supported. */
410 cinfo.out_color_space = JCS_RGB;
413 /* Step 5: Start decompressor */
414 jpeg_start_decompress (&cinfo);
416 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
418 unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3);
420 signal_image_error("Unable to allocate enough memory for image", instantiator);
423 JSAMPARRAY row_buffer; /* Output row buffer */
425 int row_stride; /* physical row width in output buffer */
426 unsigned char *op = unwind.eimage;
428 /* We may need to do some setup of our own at this point before reading
429 * the data. After jpeg_start_decompress() we have the correct scaled
430 * output image dimensions available
431 * We need to make an output work buffer of the right size.
433 /* JSAMPLEs per row in output buffer. */
434 row_stride = cinfo.output_width * cinfo.output_components;
435 /* Make a one-row-high sample array that will go away when done
437 row_buffer = ((*cinfo.mem->alloc_sarray)
438 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1));
440 /* Here we use the library's state variable cinfo.output_scanline as the
441 * loop counter, so that we don't have to keep track ourselves.
443 while (cinfo.output_scanline < cinfo.output_height)
447 /* jpeg_read_scanlines expects an array of pointers to scanlines.
448 * Here the array is only one element long, but you could ask for
449 * more than one scanline at a time if that's more convenient.
451 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1);
453 for (i = 0; i < cinfo.output_width; i++)
459 #if (BITS_IN_JSAMPLE == 8)
460 val = (unsigned char)*jp++;
461 #else /* other option is 12 */
462 val = (unsigned char)(*jp++ >> 4);
464 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */
469 for (clr = 0; clr < 3; clr++)
470 #if (BITS_IN_JSAMPLE == 8)
471 *op++ = (unsigned char)*jp++;
472 #else /* other option is 12 */
473 *op++ = (unsigned char)(*jp++ >> 4);
481 /* Step 6.5: Create the pixmap and set up the image instance */
482 /* now instantiate */
483 MAYBE_DEVMETH (XDEVICE (ii->device),
484 init_image_instance_from_eimage,
485 (ii, cinfo.output_width, cinfo.output_height, 1,
486 unwind.eimage, dest_mask,
487 instantiator, domain));
489 /* Step 7: Finish decompression */
491 jpeg_finish_decompress (&cinfo);
492 /* We can ignore the return value since suspension is not possible
493 * with the stdio data source.
496 /* And we're done! */
497 /* This will clean up everything else. */
498 unbind_to (speccount, Qnil);
501 #endif /* HAVE_JPEG */
504 /**********************************************************************
506 **********************************************************************/
511 gif_validate (Lisp_Object instantiator)
513 file_or_data_must_be_present (instantiator);
517 gif_normalize (Lisp_Object inst, Lisp_Object console_type)
519 return simple_image_type_normalize (inst, console_type, Qgif);
523 gif_possible_dest_types (void)
525 return IMAGE_COLOR_PIXMAP_MASK;
528 /* To survive the otherwise baffling complexity of making sure
529 everything gets cleaned up in the presence of an error, we
530 use an unwind_protect(). */
532 struct gif_unwind_data
534 unsigned char *eimage;
535 /* Object that holds the decoded data from a GIF file */
536 GifFileType *giffile;
540 gif_instantiate_unwind (Lisp_Object unwind_obj)
542 struct gif_unwind_data *data =
543 (struct gif_unwind_data *) get_opaque_ptr (unwind_obj);
545 free_opaque_ptr (unwind_obj);
548 DGifCloseFile (data->giffile);
549 GifFree(data->giffile);
551 if (data->eimage) xfree(data->eimage);
556 typedef struct gif_memory_storage
558 Extbyte *bytes; /* The data */
559 Extcount len; /* How big is it? */
560 int index; /* Where are we? */
561 } gif_memory_storage;
564 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
566 gif_memory_storage *mem = (gif_memory_storage*)data;
568 if (size > (mem->len - mem->index))
570 memcpy(buf, mem->bytes + mem->index, size);
571 mem->index = mem->index + size;
576 gif_memory_close(VoidPtr data)
581 struct gif_error_struct
583 CONST char *err_str; /* return the error string */
584 jmp_buf setjmp_buffer; /* for return to caller */
588 gif_error_func(CONST char *err_str, VoidPtr error_ptr)
590 struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr;
592 /* return to setjmp point */
593 error_data->err_str = err_str;
594 longjmp (error_data->setjmp_buffer, 1);
598 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
599 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
600 int dest_mask, Lisp_Object domain)
602 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
603 /* It is OK for the unwind data to be local to this function,
604 because the unwind-protect is always executed when this
605 stack frame is still valid. */
606 struct gif_unwind_data unwind;
607 int speccount = specpdl_depth ();
608 gif_memory_storage mem_struct;
609 struct gif_error_struct gif_err;
616 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
618 /* 1. Now decode the data. */
621 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
623 assert (!NILP (data));
625 if (!(unwind.giffile = GifSetup()))
626 signal_image_error ("Insufficent memory to instantiate GIF image", instantiator);
628 /* set up error facilities */
629 if (setjmp(gif_err.setjmp_buffer))
631 /* An error was signaled. No clean up is needed, as unwind handles that
632 for us. Just pass the error along. */
633 Lisp_Object errstring;
634 errstring = build_string (gif_err.err_str);
635 signal_image_error_2 ("GIF decoding error", errstring, instantiator);
637 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
639 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
640 mem_struct.bytes = bytes;
641 mem_struct.len = len;
642 mem_struct.index = 0;
643 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
644 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
645 DGifInitRead(unwind.giffile);
647 /* Then slurp the image into memory, decoding along the way.
648 The result is the image in a simple one-byte-per-pixel
649 format (#### the GIF routines only support 8-bit GIFs,
651 DGifSlurp (unwind.giffile);
654 /* 3. Now create the EImage(s) */
656 ColorMapObject *cmo = unwind.giffile->SColorMap;
657 int i, j, row, pass, interlace, slice;
659 /* interlaced gifs have rows in this order:
660 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
661 static int InterlacedOffset[] = { 0, 4, 2, 1 };
662 static int InterlacedJumps[] = { 8, 8, 4, 2 };
664 height = unwind.giffile->SHeight;
665 width = unwind.giffile->SWidth;
666 unwind.eimage = (unsigned char*)
667 xmalloc (width * height * 3 * unwind.giffile->ImageCount);
669 signal_image_error("Unable to allocate enough memory for image", instantiator);
671 /* write the data in EImage format (8bit RGB triples) */
673 for (slice = 0; slice < unwind.giffile->ImageCount; slice++)
675 /* We check here that that the current image covers the full "screen" size. */
676 if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height
677 || unwind.giffile->SavedImages[slice].ImageDesc.Width != width
678 || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0
679 || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0)
680 signal_image_error ("Image in GIF file is not full size",
683 interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace;
685 row = interlace ? InterlacedOffset[pass] : 0;
686 eip = unwind.eimage + (width * height * 3 * slice);
687 for (i = 0; i < height; i++)
691 row = InterlacedOffset[++pass];
692 while (row >= height)
693 row = InterlacedOffset[++pass];
695 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3);
696 for (j = 0; j < width; j++)
698 unsigned char pixel =
699 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j];
700 *eip++ = cmo->Colors[pixel].Red;
701 *eip++ = cmo->Colors[pixel].Green;
702 *eip++ = cmo->Colors[pixel].Blue;
704 row += interlace ? InterlacedJumps[pass] : 1;
708 /* now instantiate */
709 MAYBE_DEVMETH (XDEVICE (ii->device),
710 init_image_instance_from_eimage,
711 (ii, width, height, unwind.giffile->ImageCount, unwind.eimage, dest_mask,
712 instantiator, domain));
715 /* We read the gif successfully. If we have more than one slice then
717 if (unwind.giffile->ImageCount > 1)
719 /* See if there is a timeout value. In theory there could be one
720 for every image - but that makes the implementation way to
721 complicated for now so we just take the first. */
722 unsigned short timeout = 0;
725 if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE
727 unwind.giffile->SavedImages[0].ExtensionBlockCount)
729 timeout = (unsigned short)
730 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) +
731 unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10;
734 /* Too short a timeout will crucify us performance-wise. */
735 tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance);
738 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid);
741 unbind_to (speccount, Qnil);
744 #endif /* HAVE_GIF */
749 /**********************************************************************
751 **********************************************************************/
753 png_validate (Lisp_Object instantiator)
755 file_or_data_must_be_present (instantiator);
759 png_normalize (Lisp_Object inst, Lisp_Object console_type)
761 return simple_image_type_normalize (inst, console_type, Qpng);
765 png_possible_dest_types (void)
767 return IMAGE_COLOR_PIXMAP_MASK;
770 struct png_memory_storage
772 CONST Extbyte *bytes; /* The data */
773 Extcount len; /* How big is it? */
774 int index; /* Where are we? */
778 png_read_from_memory(png_structp png_ptr, png_bytep data,
781 struct png_memory_storage *tbr =
782 (struct png_memory_storage *) png_get_io_ptr (png_ptr);
784 if (length > (tbr->len - tbr->index))
785 png_error (png_ptr, (png_const_charp) "Read Error");
786 memcpy (data,tbr->bytes + tbr->index,length);
787 tbr->index = tbr->index + length;
790 struct png_error_struct
793 jmp_buf setjmp_buffer; /* for return to caller */
796 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
797 structure, and there are cases where the size can be different from
798 between inside the library, and inside the code! To do an end run
799 around this, use our own error functions, and don't rely on things
800 passed in the png_ptr to them. This is an ugly hack and must
801 go away when the lisp engine is threaded! */
802 static struct png_error_struct png_err_stct;
805 png_error_func (png_structp png_ptr, png_const_charp msg)
807 png_err_stct.err_str = msg;
808 longjmp (png_err_stct.setjmp_buffer, 1);
812 png_warning_func (png_structp png_ptr, png_const_charp msg)
814 warn_when_safe (Qpng, Qinfo, "%s", msg);
817 struct png_unwind_data
820 unsigned char *eimage;
826 png_instantiate_unwind (Lisp_Object unwind_obj)
828 struct png_unwind_data *data =
829 (struct png_unwind_data *) get_opaque_ptr (unwind_obj);
831 free_opaque_ptr (unwind_obj);
833 png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
835 fclose (data->instream);
837 if (data->eimage) xfree(data->eimage);
843 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
844 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
845 int dest_mask, Lisp_Object domain)
847 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
848 struct png_unwind_data unwind;
849 int speccount = specpdl_depth ();
851 struct png_memory_storage tbr; /* Data to be read */
857 /* Initialize all PNG structures */
858 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct,
859 png_error_func, png_warning_func);
861 signal_image_error ("Error obtaining memory for png_read", instantiator);
862 info_ptr = png_create_info_struct (png_ptr);
865 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
866 signal_image_error ("Error obtaining memory for png_read", instantiator);
870 unwind.png_ptr = png_ptr;
871 unwind.info_ptr = info_ptr;
873 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
875 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
876 this file, example.c from the libpng 0.81 distribution, and the
877 pngtopnm sources. -WMP-
879 /* It has been further modified to handle the API changes for 0.96,
880 and is no longer usable for previous versions. jh
883 /* Set the jmp_buf return context for png_error ... if this returns !0, then
884 we ran into a problem somewhere, and need to clean up after ourselves. */
885 if (setjmp (png_err_stct.setjmp_buffer))
887 /* Something blew up: just display the error (cleanup happens in the unwind) */
888 signal_image_error_2 ("Error decoding PNG",
889 build_string(png_err_stct.err_str),
893 /* Initialize the IO layer and read in header information */
895 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
896 CONST Extbyte *bytes;
899 assert (!NILP (data));
901 /* #### This is a definite problem under Mule due to the amount of
902 stack data it might allocate. Need to think about using Lstreams */
903 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
907 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory);
910 png_read_info (png_ptr, info_ptr);
914 unsigned char **row_pointers;
915 height = info_ptr->height;
916 width = info_ptr->width;
918 /* Wow, allocate all the memory. Truly, exciting. */
919 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3);
920 /* libpng expects that the image buffer passed in contains a
921 picture to draw on top of if the png has any transparencies.
922 This could be a good place to pass that in... */
924 row_pointers = xnew_array (png_byte *, height);
926 for (y = 0; y < height; y++)
927 row_pointers[y] = unwind.eimage + (width * 3 * y);
930 /* if the png specifies a background chunk, go ahead and
931 use it, else use what we can get from the default face. */
932 png_color_16 my_background, *image_background;
933 Lisp_Object bkgd = Qnil;
935 my_background.red = 0x7fff;
936 my_background.green = 0x7fff;
937 my_background.blue = 0x7fff;
938 bkgd = FACE_BACKGROUND (Vdefault_face, domain);
939 if (!COLOR_INSTANCEP (bkgd))
941 warn_when_safe (Qpng, Qinfo, "Couldn't get background color!");
945 struct Lisp_Color_Instance *c;
948 c = XCOLOR_INSTANCE (bkgd);
949 rgblist = MAYBE_LISP_DEVMETH (XDEVICE (c->device),
950 color_instance_rgb_components,
952 my_background.red = XINT (XCAR (rgblist));
953 my_background.green = XINT (XCAR (XCDR (rgblist)));
954 my_background.blue = XINT (XCAR (XCDR (XCDR (rgblist))));
957 if (png_get_bKGD (png_ptr, info_ptr, &image_background))
958 png_set_background (png_ptr, image_background,
959 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
961 png_set_background (png_ptr, &my_background,
962 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
965 /* Now that we're using EImage, ask for 8bit RGB triples for any type
967 /* convert palette images to full RGB */
968 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
969 png_set_expand (png_ptr);
970 /* send grayscale images to RGB too */
971 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
972 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
973 png_set_gray_to_rgb (png_ptr);
974 /* we can't handle alpha values */
975 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
976 png_set_strip_alpha (png_ptr);
977 /* tell libpng to strip 16 bit depth files down to 8 bits */
978 if (info_ptr->bit_depth == 16)
979 png_set_strip_16 (png_ptr);
980 /* if the image is < 8 bits, pad it out */
981 if (info_ptr->bit_depth < 8)
983 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
984 png_set_expand (png_ptr);
986 png_set_packing (png_ptr);
989 png_read_image (png_ptr, row_pointers);
990 png_read_end (png_ptr, info_ptr);
992 #ifdef PNG_SHOW_COMMENTS
994 * I turn this off by default now, because the !%^@#!% comments
995 * show up every time the image is instantiated, which can get
996 * really really annoying. There should be some way to pass this
997 * type of data down into the glyph code, where you can get to it
998 * from lisp anyway. - WMP
1003 for (i = 0 ; i < info_ptr->num_text ; i++)
1005 /* How paranoid do I have to be about no trailing NULLs, and
1006 using (int)info_ptr->text[i].text_length, and strncpy and a temp
1007 string somewhere? */
1009 warn_when_safe (Qpng, Qinfo, "%s - %s",
1010 info_ptr->text[i].key,
1011 info_ptr->text[i].text);
1016 xfree (row_pointers);
1019 /* now instantiate */
1020 MAYBE_DEVMETH (XDEVICE (ii->device),
1021 init_image_instance_from_eimage,
1022 (ii, width, height, 1, unwind.eimage, dest_mask,
1023 instantiator, domain));
1025 /* This will clean up everything else. */
1026 unbind_to (speccount, Qnil);
1029 #endif /* HAVE_PNG */
1035 /**********************************************************************
1037 **********************************************************************/
1039 tiff_validate (Lisp_Object instantiator)
1041 file_or_data_must_be_present (instantiator);
1045 tiff_normalize (Lisp_Object inst, Lisp_Object console_type)
1047 return simple_image_type_normalize (inst, console_type, Qtiff);
1051 tiff_possible_dest_types (void)
1053 return IMAGE_COLOR_PIXMAP_MASK;
1056 struct tiff_unwind_data
1058 unsigned char *eimage;
1059 /* Object that holds the decoded data from a TIFF file */
1064 tiff_instantiate_unwind (Lisp_Object unwind_obj)
1066 struct tiff_unwind_data *data =
1067 (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj);
1069 free_opaque_ptr (unwind_obj);
1072 TIFFClose(data->tiff);
1075 xfree (data->eimage);
1080 typedef struct tiff_memory_storage
1082 Extbyte *bytes; /* The data */
1083 Extcount len; /* How big is it? */
1084 int index; /* Where are we? */
1085 } tiff_memory_storage;
1088 tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1090 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1092 if (size > (mem->len - mem->index))
1094 memcpy(buf, mem->bytes + mem->index, size);
1095 mem->index = mem->index + size;
1099 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1102 return 0; /* Shut up warnings. */
1105 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1107 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1114 newidx = mem->len + off;
1117 newidx = mem->index + off;
1120 fprintf(stderr,"Eh? invalid seek mode in tiff_memory_seek\n");
1124 if ((newidx > mem->len) || (newidx < 0))
1127 mem->index = newidx;
1132 tiff_memory_close(thandle_t data)
1138 tiff_map_noop(thandle_t data, tdata_t* pbase, toff_t* psize)
1144 tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1150 tiff_memory_size(thandle_t data)
1152 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1156 struct tiff_error_struct
1161 char err_str[1024]; /* return the error string */
1163 jmp_buf setjmp_buffer; /* for return to caller */
1166 /* jh 98/03/12 - ###This struct for passing data to the error functions
1167 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1168 have any place to store error func data. This should be rectified
1169 before XEmacs gets threads! */
1170 static struct tiff_error_struct tiff_err_data;
1173 tiff_error_func(CONST char *module, CONST char *fmt, ...)
1177 va_start (vargs, fmt);
1179 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs);
1181 /* pray this doesn't overflow... */
1182 vsprintf (tiff_err_data.err_str, fmt, vargs);
1185 /* return to setjmp point */
1186 longjmp (tiff_err_data.setjmp_buffer, 1);
1190 tiff_warning_func(CONST char *module, CONST char *fmt, ...)
1196 char warn_str[1024];
1199 va_start (vargs, fmt);
1201 vsnprintf (warn_str, 255, fmt, vargs);
1203 vsprintf (warn_str, fmt, vargs);
1206 warn_when_safe (Qtiff, Qinfo, "%s - %s",
1211 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1212 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1213 int dest_mask, Lisp_Object domain)
1215 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1216 tiff_memory_storage mem_struct;
1217 /* It is OK for the unwind data to be local to this function,
1218 because the unwind-protect is always executed when this
1219 stack frame is still valid. */
1220 struct tiff_unwind_data unwind;
1221 int speccount = specpdl_depth ();
1222 uint32 width, height;
1225 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
1227 /* set up error facilities */
1228 if (setjmp (tiff_err_data.setjmp_buffer))
1230 /* An error was signaled. No clean up is needed, as unwind handles that
1231 for us. Just pass the error along. */
1232 signal_image_error_2 ("TIFF decoding error",
1233 build_string(tiff_err_data.err_str),
1236 TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func);
1237 TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func);
1239 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1246 assert (!NILP (data));
1248 /* #### This is a definite problem under Mule due to the amount of
1249 stack data it might allocate. Think about Lstreams... */
1250 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
1251 mem_struct.bytes = bytes;
1252 mem_struct.len = len;
1253 mem_struct.index = 0;
1255 unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct,
1256 (TIFFReadWriteProc)tiff_memory_read,
1257 (TIFFReadWriteProc)tiff_memory_write,
1258 tiff_memory_seek, tiff_memory_close, tiff_memory_size,
1259 tiff_map_noop, tiff_unmap_noop);
1261 signal_image_error ("Insufficent memory to instantiate TIFF image", instantiator);
1263 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1264 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1265 unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
1267 /* ### This is little more than proof-of-concept/function testing.
1268 It needs to be reimplemented via scanline reads for both memory
1270 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1277 if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0))
1279 for (i = height - 1; i >= 0; i--)
1281 /* This is to get around weirdness in the libtiff library where properly
1282 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1283 rp = raster + (i * width);
1284 for (j = 0; j < width; j++)
1286 *ep++ = (unsigned char)TIFFGetR(*rp);
1287 *ep++ = (unsigned char)TIFFGetG(*rp);
1288 *ep++ = (unsigned char)TIFFGetB(*rp);
1295 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator);
1299 /* now instantiate */
1300 MAYBE_DEVMETH (XDEVICE (ii->device),
1301 init_image_instance_from_eimage,
1302 (ii, width, height, 1, unwind.eimage, dest_mask,
1303 instantiator, domain));
1305 unbind_to (speccount, Qnil);
1308 #endif /* HAVE_TIFF */
1311 /************************************************************************/
1312 /* initialization */
1313 /************************************************************************/
1316 syms_of_glyphs_eimage (void)
1321 image_instantiator_format_create_glyphs_eimage (void)
1323 /* image-instantiator types */
1325 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg");
1327 IIFORMAT_HAS_METHOD (jpeg, validate);
1328 IIFORMAT_HAS_METHOD (jpeg, normalize);
1329 IIFORMAT_HAS_METHOD (jpeg, possible_dest_types);
1330 IIFORMAT_HAS_METHOD (jpeg, instantiate);
1332 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string);
1333 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string);
1337 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif");
1339 IIFORMAT_HAS_METHOD (gif, validate);
1340 IIFORMAT_HAS_METHOD (gif, normalize);
1341 IIFORMAT_HAS_METHOD (gif, possible_dest_types);
1342 IIFORMAT_HAS_METHOD (gif, instantiate);
1344 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string);
1345 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string);
1349 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png");
1351 IIFORMAT_HAS_METHOD (png, validate);
1352 IIFORMAT_HAS_METHOD (png, normalize);
1353 IIFORMAT_HAS_METHOD (png, possible_dest_types);
1354 IIFORMAT_HAS_METHOD (png, instantiate);
1356 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string);
1357 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string);
1361 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff");
1363 IIFORMAT_HAS_METHOD (tiff, validate);
1364 IIFORMAT_HAS_METHOD (tiff, normalize);
1365 IIFORMAT_HAS_METHOD (tiff, possible_dest_types);
1366 IIFORMAT_HAS_METHOD (tiff, instantiate);
1368 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string);
1369 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string);
1375 vars_of_glyphs_eimage (void)