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 FOUR_BYTE_TYPE unsigned int
81 # define FOUR_BYTE_TYPE unsigned long
83 # define FOUR_BYTE_TYPE unsigned short
85 #error What kind of strange-ass system are we running on?
89 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
94 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
99 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif);
104 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png);
111 /**********************************************************************
113 **********************************************************************/
124 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/
126 jpeg_validate (Lisp_Object instantiator)
128 file_or_data_must_be_present (instantiator);
132 jpeg_normalize (Lisp_Object inst, Lisp_Object console_type)
134 return simple_image_type_normalize (inst, console_type, Qjpeg);
138 jpeg_possible_dest_types (void)
140 return IMAGE_COLOR_PIXMAP_MASK;
143 /* To survive the otherwise baffling complexity of making sure
144 everything gets cleaned up in the presence of an error, we
145 use an unwind_protect(). */
147 struct jpeg_unwind_data
149 /* Stream that we need to close */
151 /* Object that holds state info for JPEG decoding */
152 struct jpeg_decompress_struct *cinfo_ptr;
154 unsigned char *eimage;
158 jpeg_instantiate_unwind (Lisp_Object unwind_obj)
160 struct jpeg_unwind_data *data =
161 (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj);
163 free_opaque_ptr (unwind_obj);
165 jpeg_destroy_decompress (data->cinfo_ptr);
168 fclose (data->instream);
170 if (data->eimage) xfree (data->eimage);
178 * The JPEG library's standard error handler (jerror.c) is divided into
179 * several "methods" which you can override individually. This lets you
180 * adjust the behavior without duplicating a lot of code, which you might
181 * have to update with each future release.
183 * Our example here shows how to override the "error_exit" method so that
184 * control is returned to the library's caller when a fatal error occurs,
185 * rather than calling exit() as the standard error_exit method does.
187 * We use C's setjmp/longjmp facility to return control. This means that the
188 * routine which calls the JPEG library must first execute a setjmp() call to
189 * establish the return point. We want the replacement error_exit to do a
190 * longjmp(). But we need to make the setjmp buffer accessible to the
191 * error_exit routine. To do this, we make a private extension of the
192 * standard JPEG error handler object. (If we were using C++, we'd say we
193 * were making a subclass of the regular error handler.)
195 * Here's the extended error handler struct:
198 struct my_jpeg_error_mgr
200 struct jpeg_error_mgr pub; /* "public" fields */
201 jmp_buf setjmp_buffer; /* for return to caller */
204 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
209 our_init_source (j_decompress_ptr cinfo)
213 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
218 our_fill_input_buffer (j_decompress_ptr cinfo)
220 /* Insert a fake EOI marker */
221 struct jpeg_source_mgr *src = cinfo->src;
222 static JOCTET buffer[2];
224 buffer[0] = (JOCTET) 0xFF;
225 buffer[1] = (JOCTET) JPEG_EOI;
227 src->next_input_byte = buffer;
228 src->bytes_in_buffer = 2;
232 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
237 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
239 struct jpeg_source_mgr *src = NULL;
241 src = (struct jpeg_source_mgr *) cinfo->src;
246 } else if (num_bytes > src->bytes_in_buffer)
248 ERREXIT(cinfo, JERR_INPUT_EOF);
252 src->bytes_in_buffer -= num_bytes;
253 src->next_input_byte += num_bytes;
256 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
261 our_term_source (j_decompress_ptr cinfo)
267 struct jpeg_source_mgr pub;
268 } our_jpeg_source_mgr;
271 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
273 struct jpeg_source_mgr *src;
275 if (cinfo->src == NULL)
276 { /* first time for this JPEG object? */
277 cinfo->src = (struct jpeg_source_mgr *)
278 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
279 sizeof(our_jpeg_source_mgr));
280 src = (struct jpeg_source_mgr *) cinfo->src;
281 src->next_input_byte = data;
283 src = (struct jpeg_source_mgr *) cinfo->src;
284 src->init_source = our_init_source;
285 src->fill_input_buffer = our_fill_input_buffer;
286 src->skip_input_data = our_skip_input_data;
287 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
288 src->term_source = our_term_source;
289 src->bytes_in_buffer = len;
290 src->next_input_byte = data;
293 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
298 my_jpeg_error_exit (j_common_ptr cinfo)
300 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
301 struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err;
303 /* Return control to the setjmp point */
304 longjmp (myerr->setjmp_buffer, 1);
307 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
312 my_jpeg_output_message (j_common_ptr cinfo)
314 char buffer[JMSG_LENGTH_MAX];
316 /* Create the message */
317 (*cinfo->err->format_message) (cinfo, buffer);
318 warn_when_safe (Qjpeg, Qinfo, "%s", buffer);
321 /* The code in this routine is based on example.c from the JPEG library
322 source code and from gif_instantiate() */
324 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
325 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
326 int dest_mask, Lisp_Object domain)
328 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
329 /* It is OK for the unwind data to be local to this function,
330 because the unwind-protect is always executed when this
331 stack frame is still valid. */
332 struct jpeg_unwind_data unwind;
333 int speccount = specpdl_depth ();
335 /* This struct contains the JPEG decompression parameters and pointers to
336 * working space (which is allocated as needed by the JPEG library).
338 struct jpeg_decompress_struct cinfo;
339 /* We use our private extension JPEG error handler.
340 * Note that this struct must live as long as the main JPEG parameter
341 * struct, to avoid dangling-pointer problems.
343 struct my_jpeg_error_mgr jerr;
345 /* Step -1: First record our unwind-protect, which will clean up after
346 any exit, normal or not */
349 record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind));
351 /* Step 1: allocate and initialize JPEG decompression object */
353 /* We set up the normal JPEG error routines, then override error_exit. */
354 cinfo.err = jpeg_std_error (&jerr.pub);
355 jerr.pub.error_exit = my_jpeg_error_exit;
356 jerr.pub.output_message = my_jpeg_output_message;
358 /* Establish the setjmp return context for my_error_exit to use. */
359 if (setjmp (jerr.setjmp_buffer))
361 /* If we get here, the JPEG code has signaled an error.
362 * We need to clean up the JPEG object, close the input file, and return.
366 Lisp_Object errstring;
367 char buffer[JMSG_LENGTH_MAX];
369 /* Create the message */
370 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer);
371 errstring = build_string (buffer);
373 signal_image_error_2 ("JPEG decoding error",
374 errstring, instantiator);
378 /* Now we can initialize the JPEG decompression object. */
379 jpeg_create_decompress (&cinfo);
380 unwind.cinfo_ptr = &cinfo;
382 /* Step 2: specify data source (eg, a file) */
385 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
386 CONST Extbyte *bytes;
389 /* #### This is a definite problem under Mule due to the amount of
390 stack data it might allocate. Need to be able to convert and
391 write out to a file. */
392 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
393 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len);
396 /* Step 3: read file parameters with jpeg_read_header() */
398 jpeg_read_header (&cinfo, TRUE);
399 /* We can ignore the return value from jpeg_read_header since
400 * (a) suspension is not possible with the stdio data source, and
401 * (b) we passed TRUE to reject a tables-only JPEG file as an error.
402 * See libjpeg.doc for more info.
406 int jpeg_gray = 0; /* if we're dealing with a grayscale */
407 /* Step 4: set parameters for decompression. */
409 /* Now that we're using EImages, send all data as 24bit color.
410 The backend routine will take care of any necessary reductions.
411 We do have to handle the grayscale case ourselves, however. */
412 if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
414 cinfo.out_color_space = JCS_GRAYSCALE;
419 /* we're relying on the jpeg driver to do any other conversions,
420 or signal an error if the conversion isn't supported. */
421 cinfo.out_color_space = JCS_RGB;
424 /* Step 5: Start decompressor */
425 jpeg_start_decompress (&cinfo);
427 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
429 unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3);
431 signal_image_error("Unable to allocate enough memory for image", instantiator);
434 JSAMPARRAY row_buffer; /* Output row buffer */
436 int row_stride; /* physical row width in output buffer */
437 unsigned char *op = unwind.eimage;
439 /* We may need to do some setup of our own at this point before reading
440 * the data. After jpeg_start_decompress() we have the correct scaled
441 * output image dimensions available
442 * We need to make an output work buffer of the right size.
444 /* JSAMPLEs per row in output buffer. */
445 row_stride = cinfo.output_width * cinfo.output_components;
446 /* Make a one-row-high sample array that will go away when done
448 row_buffer = ((*cinfo.mem->alloc_sarray)
449 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1));
451 /* Here we use the library's state variable cinfo.output_scanline as the
452 * loop counter, so that we don't have to keep track ourselves.
454 while (cinfo.output_scanline < cinfo.output_height)
458 /* jpeg_read_scanlines expects an array of pointers to scanlines.
459 * Here the array is only one element long, but you could ask for
460 * more than one scanline at a time if that's more convenient.
462 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1);
464 for (i = 0; i < cinfo.output_width; i++)
470 #if (BITS_IN_JSAMPLE == 8)
471 val = (unsigned char)*jp++;
472 #else /* other option is 12 */
473 val = (unsigned char)(*jp++ >> 4);
475 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */
480 for (clr = 0; clr < 3; clr++)
481 #if (BITS_IN_JSAMPLE == 8)
482 *op++ = (unsigned char)*jp++;
483 #else /* other option is 12 */
484 *op++ = (unsigned char)(*jp++ >> 4);
492 /* Step 6.5: Create the pixmap and set up the image instance */
493 /* now instantiate */
494 MAYBE_DEVMETH (XDEVICE (ii->device),
495 init_image_instance_from_eimage,
496 (ii, cinfo.output_width, cinfo.output_height,
497 unwind.eimage, dest_mask,
498 instantiator, domain));
500 /* Step 7: Finish decompression */
502 jpeg_finish_decompress (&cinfo);
503 /* We can ignore the return value since suspension is not possible
504 * with the stdio data source.
507 /* And we're done! */
508 /* This will clean up everything else. */
509 unbind_to (speccount, Qnil);
512 #endif /* HAVE_JPEG */
515 /**********************************************************************
517 **********************************************************************/
522 gif_validate (Lisp_Object instantiator)
524 file_or_data_must_be_present (instantiator);
528 gif_normalize (Lisp_Object inst, Lisp_Object console_type)
530 return simple_image_type_normalize (inst, console_type, Qgif);
534 gif_possible_dest_types (void)
536 return IMAGE_COLOR_PIXMAP_MASK;
539 /* To survive the otherwise baffling complexity of making sure
540 everything gets cleaned up in the presence of an error, we
541 use an unwind_protect(). */
543 struct gif_unwind_data
545 unsigned char *eimage;
546 /* Object that holds the decoded data from a GIF file */
547 GifFileType *giffile;
551 gif_instantiate_unwind (Lisp_Object unwind_obj)
553 struct gif_unwind_data *data =
554 (struct gif_unwind_data *) get_opaque_ptr (unwind_obj);
556 free_opaque_ptr (unwind_obj);
559 DGifCloseFile (data->giffile);
560 GifFree(data->giffile);
562 if (data->eimage) xfree(data->eimage);
567 typedef struct gif_memory_storage
569 Extbyte *bytes; /* The data */
570 Extcount len; /* How big is it? */
571 int index; /* Where are we? */
572 } gif_memory_storage;
575 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
577 gif_memory_storage *mem = (gif_memory_storage*)data;
579 if (size > (mem->len - mem->index))
581 memcpy(buf, mem->bytes + mem->index, size);
582 mem->index = mem->index + size;
587 gif_memory_close(VoidPtr data)
592 struct gif_error_struct
594 CONST char *err_str; /* return the error string */
595 jmp_buf setjmp_buffer; /* for return to caller */
599 gif_error_func(CONST char *err_str, VoidPtr error_ptr)
601 struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr;
603 /* return to setjmp point */
604 error_data->err_str = err_str;
605 longjmp (error_data->setjmp_buffer, 1);
609 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
610 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
611 int dest_mask, Lisp_Object domain)
613 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
614 /* It is OK for the unwind data to be local to this function,
615 because the unwind-protect is always executed when this
616 stack frame is still valid. */
617 struct gif_unwind_data unwind;
618 int speccount = specpdl_depth ();
619 gif_memory_storage mem_struct;
620 struct gif_error_struct gif_err;
627 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
629 /* 1. Now decode the data. */
632 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
634 assert (!NILP (data));
636 if (!(unwind.giffile = GifSetup()))
637 signal_image_error ("Insufficent memory to instantiate GIF image", instantiator);
639 /* set up error facilities */
640 if (setjmp(gif_err.setjmp_buffer))
642 /* An error was signaled. No clean up is needed, as unwind handles that
643 for us. Just pass the error along. */
644 Lisp_Object errstring;
645 errstring = build_string (gif_err.err_str);
646 signal_image_error_2 ("GIF decoding error", errstring, instantiator);
648 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
650 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
651 mem_struct.bytes = bytes;
652 mem_struct.len = len;
653 mem_struct.index = 0;
654 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
655 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
656 DGifInitRead(unwind.giffile);
658 /* Then slurp the image into memory, decoding along the way.
659 The result is the image in a simple one-byte-per-pixel
660 format (#### the GIF routines only support 8-bit GIFs,
662 DGifSlurp (unwind.giffile);
665 /* 3. Now create the EImage */
667 ColorMapObject *cmo = unwind.giffile->SColorMap;
668 int i, j, row, pass, interlace;
670 /* interlaced gifs have rows in this order:
671 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
672 static int InterlacedOffset[] = { 0, 4, 2, 1 };
673 static int InterlacedJumps[] = { 8, 8, 4, 2 };
675 height = unwind.giffile->SHeight;
676 width = unwind.giffile->SWidth;
677 unwind.eimage = (unsigned char*) xmalloc (width * height * 3);
679 signal_image_error("Unable to allocate enough memory for image", instantiator);
681 /* write the data in EImage format (8bit RGB triples) */
683 /* Note: We just use the first image in the file and ignore the rest.
684 We check here that that image covers the full "screen" size.
685 I don't know whether that's always the case.
686 -dkindred@cs.cmu.edu */
687 if (unwind.giffile->SavedImages[0].ImageDesc.Height != height
688 || unwind.giffile->SavedImages[0].ImageDesc.Width != width
689 || unwind.giffile->SavedImages[0].ImageDesc.Left != 0
690 || unwind.giffile->SavedImages[0].ImageDesc.Top != 0)
691 signal_image_error ("First image in GIF file is not full size",
694 interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace;
696 row = interlace ? InterlacedOffset[pass] : 0;
698 for (i = 0; i < height; i++)
700 if (interlace && row >= height)
701 row = InterlacedOffset[++pass];
702 eip = unwind.eimage + (row * width * 3);
703 for (j = 0; j < width; j++)
705 unsigned char pixel = unwind.giffile->SavedImages[0].RasterBits[(i * width) + j];
706 *eip++ = cmo->Colors[pixel].Red;
707 *eip++ = cmo->Colors[pixel].Green;
708 *eip++ = cmo->Colors[pixel].Blue;
710 row += interlace ? InterlacedJumps[pass] : 1;
713 /* now instantiate */
714 MAYBE_DEVMETH (XDEVICE (ii->device),
715 init_image_instance_from_eimage,
716 (ii, width, height, unwind.eimage, dest_mask,
717 instantiator, domain));
719 unbind_to (speccount, Qnil);
722 #endif /* HAVE_GIF */
727 /**********************************************************************
729 **********************************************************************/
731 png_validate (Lisp_Object instantiator)
733 file_or_data_must_be_present (instantiator);
737 png_normalize (Lisp_Object inst, Lisp_Object console_type)
739 return simple_image_type_normalize (inst, console_type, Qpng);
743 png_possible_dest_types (void)
745 return IMAGE_COLOR_PIXMAP_MASK;
748 struct png_memory_storage
750 CONST Extbyte *bytes; /* The data */
751 Extcount len; /* How big is it? */
752 int index; /* Where are we? */
756 png_read_from_memory(png_structp png_ptr, png_bytep data,
759 struct png_memory_storage *tbr =
760 (struct png_memory_storage *) png_get_io_ptr (png_ptr);
762 if (length > (tbr->len - tbr->index))
763 png_error (png_ptr, (png_const_charp) "Read Error");
764 memcpy (data,tbr->bytes + tbr->index,length);
765 tbr->index = tbr->index + length;
768 struct png_error_struct
771 jmp_buf setjmp_buffer; /* for return to caller */
774 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
775 structure, and there are cases where the size can be different from
776 between inside the libarary, and inside the code! To do an end run
777 around this, use our own error functions, and don't rely on things
778 passed in the png_ptr to them. This is an ugly hack and must
779 go away when the lisp engine is threaded! */
780 static struct png_error_struct png_err_stct;
783 png_error_func (png_structp png_ptr, png_const_charp msg)
785 png_err_stct.err_str = msg;
786 longjmp (png_err_stct.setjmp_buffer, 1);
790 png_warning_func (png_structp png_ptr, png_const_charp msg)
792 warn_when_safe (Qpng, Qinfo, "%s", msg);
795 struct png_unwind_data
798 unsigned char *eimage;
804 png_instantiate_unwind (Lisp_Object unwind_obj)
806 struct png_unwind_data *data =
807 (struct png_unwind_data *) get_opaque_ptr (unwind_obj);
809 free_opaque_ptr (unwind_obj);
811 png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
813 fclose (data->instream);
819 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
820 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
821 int dest_mask, Lisp_Object domain)
823 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
824 struct png_unwind_data unwind;
825 int speccount = specpdl_depth ();
827 struct png_memory_storage tbr; /* Data to be read */
833 /* Initialize all PNG structures */
834 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct,
835 png_error_func, png_warning_func);
837 signal_image_error ("Error obtaining memory for png_read", instantiator);
838 info_ptr = png_create_info_struct (png_ptr);
841 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
842 signal_image_error ("Error obtaining memory for png_read", instantiator);
846 unwind.png_ptr = png_ptr;
847 unwind.info_ptr = info_ptr;
849 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
851 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
852 this file, example.c from the libpng 0.81 distribution, and the
853 pngtopnm sources. -WMP-
855 /* It has been further modified to handle the API changes for 0.96,
856 and is no longer usable for previous versions. jh
859 /* Set the jmp_buf reurn context for png_error ... if this returns !0, then
860 we ran into a problem somewhere, and need to clean up after ourselves. */
861 if (setjmp (png_err_stct.setjmp_buffer))
863 /* Something blew up: just display the error (cleanup happens in the unwind) */
864 signal_image_error_2 ("Error decoding PNG",
865 build_string(png_err_stct.err_str),
869 /* Initialize the IO layer and read in header information */
871 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
872 CONST Extbyte *bytes;
875 assert (!NILP (data));
877 /* #### This is a definite problem under Mule due to the amount of
878 stack data it might allocate. Need to think about using Lstreams */
879 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
883 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory);
886 png_read_info (png_ptr, info_ptr);
890 unsigned char **row_pointers;
891 height = info_ptr->height;
892 width = info_ptr->width;
894 /* Wow, allocate all the memory. Truly, exciting. */
895 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3);
896 /* libpng expects that the image buffer passed in contains a
897 picture to draw on top of if the png has any transparencies.
898 This could be a good place to pass that in... */
900 row_pointers = xnew_array (png_byte *, height);
902 for (y = 0; y < height; y++)
903 row_pointers[y] = unwind.eimage + (width * 3 * y);
905 /* Now that we're using EImage, ask for 8bit RGB triples for any type
907 /* convert palatte images to full RGB */
908 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
909 png_set_expand (png_ptr);
910 /* send grayscale images to RGB too */
911 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
912 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
913 png_set_gray_to_rgb (png_ptr);
914 /* we can't handle alpha values */
915 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
916 png_set_strip_alpha (png_ptr);
917 /* rip out any transparancy layers/colors */
918 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
920 png_set_expand (png_ptr);
921 png_set_strip_alpha (png_ptr);
923 /* tell libpng to strip 16 bit depth files down to 8 bits */
924 if (info_ptr->bit_depth == 16)
925 png_set_strip_16 (png_ptr);
926 /* if the image is < 8 bits, pad it out */
927 if (info_ptr->bit_depth < 8)
929 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
930 png_set_expand (png_ptr);
932 png_set_packing (png_ptr);
935 #if 1 /* tests? or permanent? */
937 /* if the png specifies a background chunk, go ahead and
939 png_color_16 my_background, *image_background;
941 /* ### how do I get the background of the current frame? */
942 my_background.red = 0x7fff;
943 my_background.green = 0x7fff;
944 my_background.blue = 0x7fff;
946 if (png_get_bKGD (png_ptr, info_ptr, &image_background))
947 png_set_background (png_ptr, image_background,
948 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
950 png_set_background (png_ptr, &my_background,
951 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
954 png_read_image (png_ptr, row_pointers);
955 png_read_end (png_ptr, info_ptr);
957 #ifdef PNG_SHOW_COMMENTS
959 * I turn this off by default now, because the !%^@#!% comments
960 * show up every time the image is instantiated, which can get
961 * really really annoying. There should be some way to pass this
962 * type of data down into the glyph code, where you can get to it
963 * from lisp anyway. - WMP
968 for (i = 0 ; i < info_ptr->num_text ; i++)
970 /* How paranoid do I have to be about no trailing NULLs, and
971 using (int)info_ptr->text[i].text_length, and strncpy and a temp
974 warn_when_safe (Qpng, Qinfo, "%s - %s",
975 info_ptr->text[i].key,
976 info_ptr->text[i].text);
981 xfree (row_pointers);
984 /* now instantiate */
985 MAYBE_DEVMETH (XDEVICE (ii->device),
986 init_image_instance_from_eimage,
987 (ii, width, height, unwind.eimage, dest_mask,
988 instantiator, domain));
990 /* This will clean up everything else. */
991 unbind_to (speccount, Qnil);
994 #endif /* HAVE_PNG */
1000 /**********************************************************************
1002 **********************************************************************/
1004 tiff_validate (Lisp_Object instantiator)
1006 file_or_data_must_be_present (instantiator);
1010 tiff_normalize (Lisp_Object inst, Lisp_Object console_type)
1012 return simple_image_type_normalize (inst, console_type, Qtiff);
1016 tiff_possible_dest_types (void)
1018 return IMAGE_COLOR_PIXMAP_MASK;
1021 struct tiff_unwind_data
1023 unsigned char *eimage;
1024 /* Object that holds the decoded data from a TIFF file */
1029 tiff_instantiate_unwind (Lisp_Object unwind_obj)
1031 struct tiff_unwind_data *data =
1032 (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj);
1034 free_opaque_ptr (unwind_obj);
1037 TIFFClose(data->tiff);
1040 xfree (data->eimage);
1045 typedef struct tiff_memory_storage
1047 Extbyte *bytes; /* The data */
1048 Extcount len; /* How big is it? */
1049 int index; /* Where are we? */
1050 } tiff_memory_storage;
1053 tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1055 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1057 if (size > (mem->len - mem->index))
1059 memcpy(buf, mem->bytes + mem->index, size);
1060 mem->index = mem->index + size;
1064 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1067 return 0; /* Shut up warnings. */
1070 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1072 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1079 newidx = mem->len + off;
1082 newidx = mem->index + off;
1085 fprintf(stderr,"Eh? invalid seek mode in tiff_memory_seek\n");
1089 if ((newidx > mem->len) || (newidx < 0))
1092 mem->index = newidx;
1097 tiff_memory_close(thandle_t data)
1103 tiff_map_noop(thandle_t data, tdata_t* pbase, toff_t* psize)
1109 tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1115 tiff_memory_size(thandle_t data)
1117 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1121 struct tiff_error_struct
1126 char err_str[1024]; /* return the error string */
1128 jmp_buf setjmp_buffer; /* for return to caller */
1131 /* jh 98/03/12 - ###This struct for passing data to the error functions
1132 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1133 have any place to store error func data. This should be rectified
1134 before XEmacs gets threads! */
1135 static struct tiff_error_struct tiff_err_data;
1138 tiff_error_func(CONST char *module, CONST char *fmt, ...)
1142 va_start (vargs, fmt);
1144 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs);
1146 /* pray this doesn't overflow... */
1147 vsprintf (tiff_err_data.err_str, fmt, vargs);
1150 /* return to setjmp point */
1151 longjmp (tiff_err_data.setjmp_buffer, 1);
1155 tiff_warning_func(CONST char *module, CONST char *fmt, ...)
1161 char warn_str[1024];
1164 va_start (vargs, fmt);
1166 vsnprintf (warn_str, 255, fmt, vargs);
1168 vsprintf (warn_str, fmt, vargs);
1171 warn_when_safe (Qtiff, Qinfo, "%s - %s",
1176 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1177 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1178 int dest_mask, Lisp_Object domain)
1180 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1181 tiff_memory_storage mem_struct;
1182 /* It is OK for the unwind data to be local to this function,
1183 because the unwind-protect is always executed when this
1184 stack frame is still valid. */
1185 struct tiff_unwind_data unwind;
1186 int speccount = specpdl_depth ();
1187 uint32 width, height;
1190 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
1192 /* set up error facilities */
1193 if (setjmp (tiff_err_data.setjmp_buffer))
1195 /* An error was signaled. No clean up is needed, as unwind handles that
1196 for us. Just pass the error along. */
1197 signal_image_error_2 ("TIFF decoding error",
1198 build_string(tiff_err_data.err_str),
1201 TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func);
1202 TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func);
1204 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1211 assert (!NILP (data));
1213 /* #### This is a definite problem under Mule due to the amount of
1214 stack data it might allocate. Think about Lstreams... */
1215 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
1216 mem_struct.bytes = bytes;
1217 mem_struct.len = len;
1218 mem_struct.index = 0;
1220 unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct,
1221 (TIFFReadWriteProc)tiff_memory_read,
1222 (TIFFReadWriteProc)tiff_memory_write,
1223 tiff_memory_seek, tiff_memory_close, tiff_memory_size,
1224 tiff_map_noop, tiff_unmap_noop);
1226 signal_image_error ("Insufficent memory to instantiate TIFF image", instantiator);
1228 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1229 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1230 unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
1232 /* ### This is little more than proof-of-concept/function testing.
1233 It needs to be reimplimented via scanline reads for both memory
1235 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1242 if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0))
1244 for (i = height - 1; i >= 0; i--)
1246 /* This is to get around weirdness in the libtiff library where properly
1247 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1248 rp = raster + (i * width);
1249 for (j = 0; j < width; j++)
1251 *ep++ = (unsigned char)TIFFGetR(*rp);
1252 *ep++ = (unsigned char)TIFFGetG(*rp);
1253 *ep++ = (unsigned char)TIFFGetB(*rp);
1260 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator);
1264 /* now instantiate */
1265 MAYBE_DEVMETH (XDEVICE (ii->device),
1266 init_image_instance_from_eimage,
1267 (ii, width, height, unwind.eimage, dest_mask,
1268 instantiator, domain));
1270 unbind_to (speccount, Qnil);
1273 #endif /* HAVE_TIFF */
1276 /************************************************************************/
1277 /* initialization */
1278 /************************************************************************/
1281 syms_of_glyphs_eimage (void)
1286 image_instantiator_format_create_glyphs_eimage (void)
1288 /* image-instantiator types */
1290 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg");
1292 IIFORMAT_HAS_METHOD (jpeg, validate);
1293 IIFORMAT_HAS_METHOD (jpeg, normalize);
1294 IIFORMAT_HAS_METHOD (jpeg, possible_dest_types);
1295 IIFORMAT_HAS_METHOD (jpeg, instantiate);
1297 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string);
1298 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string);
1302 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif");
1304 IIFORMAT_HAS_METHOD (gif, validate);
1305 IIFORMAT_HAS_METHOD (gif, normalize);
1306 IIFORMAT_HAS_METHOD (gif, possible_dest_types);
1307 IIFORMAT_HAS_METHOD (gif, instantiate);
1309 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string);
1310 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string);
1314 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png");
1316 IIFORMAT_HAS_METHOD (png, validate);
1317 IIFORMAT_HAS_METHOD (png, normalize);
1318 IIFORMAT_HAS_METHOD (png, possible_dest_types);
1319 IIFORMAT_HAS_METHOD (png, instantiate);
1321 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string);
1322 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string);
1326 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff");
1328 IIFORMAT_HAS_METHOD (tiff, validate);
1329 IIFORMAT_HAS_METHOD (tiff, normalize);
1330 IIFORMAT_HAS_METHOD (tiff, possible_dest_types);
1331 IIFORMAT_HAS_METHOD (tiff, instantiate);
1333 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string);
1334 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string);
1340 vars_of_glyphs_eimage (void)