comparison src/glyphs-eimage.c @ 278:90d73dddcdc4 r21-0b37

Import from CVS: tag r21-0b37
author cvs
date Mon, 13 Aug 2007 10:31:29 +0200
parents
children 7df0dd720c89
comparison
equal deleted inserted replaced
277:cfdf3ff11843 278:90d73dddcdc4
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
7
8 This file is part of XEmacs.
9
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
13 later version.
14
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
18 for more details.
19
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. */
24
25 /* Synched up with: Not in FSF. */
26
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 GIFlib 3.1 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
43 TODO:
44 Convert images.el to C and stick it in here?
45 */
46
47 #include <config.h>
48 #include "lisp.h"
49 #include "lstream.h"
50 #include "console.h"
51 #include "device.h"
52 #include "glyphs.h"
53 #include "objects.h"
54
55 #include "buffer.h"
56 #include "frame.h"
57 #include "insdel.h"
58 #include "opaque.h"
59
60 #include "imgproc.h"
61 #include "sysfile.h"
62
63 #ifdef HAVE_PNG
64 #ifdef __cplusplus
65 extern "C" {
66 #endif
67 #include <png.h>
68 #ifdef __cplusplus
69 }
70 #endif
71 #else
72 #include <setjmp.h>
73 #endif
74 #ifdef FILE_CODING
75 #include "file-coding.h"
76 #endif
77
78 #if INTBITS == 32
79 # define FOUR_BYTE_TYPE unsigned int
80 #elif LONGBITS == 32
81 # define FOUR_BYTE_TYPE unsigned long
82 #elif SHORTBITS == 32
83 # define FOUR_BYTE_TYPE unsigned short
84 #else
85 #error What kind of strange-ass system are we running on?
86 #endif
87
88 #ifdef HAVE_TIFF
89 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
90 Lisp_Object Qtiff;
91 #endif
92
93 #ifdef HAVE_JPEG
94 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
95 Lisp_Object Qjpeg;
96 #endif
97
98 #ifdef HAVE_GIF
99 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif);
100 Lisp_Object Qgif;
101 #endif
102
103 #ifdef HAVE_PNG
104 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png);
105 Lisp_Object Qpng;
106 #endif
107
108
109 #ifdef HAVE_JPEG
110
111 /**********************************************************************
112 * JPEG *
113 **********************************************************************/
114
115 #ifdef __cplusplus
116 extern "C" {
117 #endif
118 #include <jpeglib.h>
119 #include <jerror.h>
120 #ifdef __cplusplus
121 }
122 #endif
123
124 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/
125 static void
126 jpeg_validate (Lisp_Object instantiator)
127 {
128 file_or_data_must_be_present (instantiator);
129 }
130
131 static Lisp_Object
132 jpeg_normalize (Lisp_Object inst, Lisp_Object console_type)
133 {
134 return simple_image_type_normalize (inst, console_type, Qjpeg);
135 }
136
137 static int
138 jpeg_possible_dest_types (void)
139 {
140 return IMAGE_COLOR_PIXMAP_MASK;
141 }
142
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(). */
146
147 struct jpeg_unwind_data
148 {
149 /* Stream that we need to close */
150 FILE *instream;
151 /* Object that holds state info for JPEG decoding */
152 struct jpeg_decompress_struct *cinfo_ptr;
153 /* EImage data */
154 unsigned char *eimage;
155 };
156
157 static Lisp_Object
158 jpeg_instantiate_unwind (Lisp_Object unwind_obj)
159 {
160 struct jpeg_unwind_data *data =
161 (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj);
162
163 free_opaque_ptr (unwind_obj);
164 if (data->cinfo_ptr)
165 jpeg_destroy_decompress (data->cinfo_ptr);
166
167 if (data->instream)
168 fclose (data->instream);
169
170 if (data->eimage) xfree (data->eimage);
171
172 return Qnil;
173 }
174
175 /*
176 * ERROR HANDLING:
177 *
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.
182 *
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.
186 *
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.)
194 *
195 * Here's the extended error handler struct:
196 */
197
198 struct my_jpeg_error_mgr
199 {
200 struct jpeg_error_mgr pub; /* "public" fields */
201 jmp_buf setjmp_buffer; /* for return to caller */
202 };
203
204 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
205 METHODDEF(void)
206 #else
207 METHODDEF void
208 #endif
209 our_init_source (j_decompress_ptr cinfo)
210 {
211 }
212
213 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
214 METHODDEF(boolean)
215 #else
216 METHODDEF boolean
217 #endif
218 our_fill_input_buffer (j_decompress_ptr cinfo)
219 {
220 /* Insert a fake EOI marker */
221 struct jpeg_source_mgr *src = cinfo->src;
222 static JOCTET buffer[2];
223
224 buffer[0] = (JOCTET) 0xFF;
225 buffer[1] = (JOCTET) JPEG_EOI;
226
227 src->next_input_byte = buffer;
228 src->bytes_in_buffer = 2;
229 return TRUE;
230 }
231
232 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
233 METHODDEF(void)
234 #else
235 METHODDEF void
236 #endif
237 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
238 {
239 struct jpeg_source_mgr *src = NULL;
240
241 src = (struct jpeg_source_mgr *) cinfo->src;
242
243 if (!src)
244 {
245 return;
246 } else if (num_bytes > src->bytes_in_buffer)
247 {
248 ERREXIT(cinfo, JERR_INPUT_EOF);
249 /*NOTREACHED*/
250 }
251
252 src->bytes_in_buffer -= num_bytes;
253 src->next_input_byte += num_bytes;
254 }
255
256 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
257 METHODDEF(void)
258 #else
259 METHODDEF void
260 #endif
261 our_term_source (j_decompress_ptr cinfo)
262 {
263 }
264
265 typedef struct
266 {
267 struct jpeg_source_mgr pub;
268 } our_jpeg_source_mgr;
269
270 static void
271 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len)
272 {
273 struct jpeg_source_mgr *src;
274
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;
282 }
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;
291 }
292
293 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
294 METHODDEF(void)
295 #else
296 METHODDEF void
297 #endif
298 my_jpeg_error_exit (j_common_ptr cinfo)
299 {
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;
302
303 /* Return control to the setjmp point */
304 longjmp (myerr->setjmp_buffer, 1);
305 }
306
307 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61)
308 METHODDEF(void)
309 #else
310 METHODDEF void
311 #endif
312 my_jpeg_output_message (j_common_ptr cinfo)
313 {
314 char buffer[JMSG_LENGTH_MAX];
315
316 /* Create the message */
317 (*cinfo->err->format_message) (cinfo, buffer);
318 warn_when_safe (Qjpeg, Qinfo, "%s", buffer);
319 }
320
321 /* The code in this routine is based on example.c from the JPEG library
322 source code and from gif_instantiate() */
323 static void
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)
327 {
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 ();
334
335 /* This struct contains the JPEG decompression parameters and pointers to
336 * working space (which is allocated as needed by the JPEG library).
337 */
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.
342 */
343 struct my_jpeg_error_mgr jerr;
344
345 /* Step -1: First record our unwind-protect, which will clean up after
346 any exit, normal or not */
347
348 xzero (unwind);
349 record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind));
350
351 /* Step 1: allocate and initialize JPEG decompression object */
352
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;
357
358 /* Establish the setjmp return context for my_error_exit to use. */
359 if (setjmp (jerr.setjmp_buffer))
360 {
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.
363 */
364
365 {
366 Lisp_Object errstring;
367 char buffer[JMSG_LENGTH_MAX];
368
369 /* Create the message */
370 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer);
371 errstring = build_string (buffer);
372
373 signal_image_error_2 ("JPEG decoding error",
374 errstring, instantiator);
375 }
376 }
377
378 /* Now we can initialize the JPEG decompression object. */
379 jpeg_create_decompress (&cinfo);
380 unwind.cinfo_ptr = &cinfo;
381
382 /* Step 2: specify data source (eg, a file) */
383
384 {
385 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
386 CONST Extbyte *bytes;
387 Extcount len;
388
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);
394 }
395
396 /* Step 3: read file parameters with jpeg_read_header() */
397
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.
403 */
404
405 {
406 /* Step 4: set parameters for decompression. */
407
408 /* Now that we're using EImages, use the default of all data in 24bit color.
409 The backend routine will take care of any necessary reductions. */
410
411 /* Step 5: Start decompressor */
412 jpeg_start_decompress (&cinfo);
413
414 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
415
416 unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3);
417 if (!unwind.eimage)
418 signal_image_error("Unable to allocate enough memory for image", instantiator);
419
420 {
421 JSAMPARRAY row_buffer; /* Output row buffer */
422 JSAMPLE *jp;
423 int row_stride; /* physical row width in output buffer */
424 unsigned char *op = unwind.eimage;
425
426 /* We may need to do some setup of our own at this point before reading
427 * the data. After jpeg_start_decompress() we have the correct scaled
428 * output image dimensions available
429 * We need to make an output work buffer of the right size.
430 */
431 /* JSAMPLEs per row in output buffer. */
432 row_stride = cinfo.output_width * cinfo.output_components;
433 /* Make a one-row-high sample array that will go away when done
434 with image */
435 row_buffer = ((*cinfo.mem->alloc_sarray)
436 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1));
437
438 /* Here we use the library's state variable cinfo.output_scanline as the
439 * loop counter, so that we don't have to keep track ourselves.
440 */
441 while (cinfo.output_scanline < cinfo.output_height)
442 {
443 int i;
444
445 /* jpeg_read_scanlines expects an array of pointers to scanlines.
446 * Here the array is only one element long, but you could ask for
447 * more than one scanline at a time if that's more convenient.
448 */
449 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1);
450 jp = row_buffer[0];
451 for (i = 0; i < cinfo.output_width; i++)
452 {
453 int clr;
454 #if (BITS_IN_JSAMPLE == 8)
455 for (clr = 0; clr < 3; clr++)
456 *op++ = (unsigned char)*jp++;
457 #else /* other option is 12 */
458 for (clr = 0; clr < 3; clr++)
459 *op++ = (unsigned char)(*jp++ >> 4);
460 #endif
461 }
462 }
463 }
464 }
465
466 /* Step 6.5: Create the pixmap and set up the image instance */
467 /* now instantiate */
468 MAYBE_DEVMETH (XDEVICE (ii->device),
469 init_image_instance_from_eimage,
470 (ii, cinfo.output_width, cinfo.output_height,
471 unwind.eimage, dest_mask,
472 instantiator, domain));
473
474 /* Step 7: Finish decompression */
475
476 jpeg_finish_decompress (&cinfo);
477 /* We can ignore the return value since suspension is not possible
478 * with the stdio data source.
479 */
480
481 /* And we're done! */
482 /* This will clean up everything else. */
483 unbind_to (speccount, Qnil);
484 }
485
486 #endif /* HAVE_JPEG */
487
488 #ifdef HAVE_GIF
489 /**********************************************************************
490 * GIF *
491 **********************************************************************/
492
493 #include <gif_lib.h>
494
495 static void
496 gif_validate (Lisp_Object instantiator)
497 {
498 file_or_data_must_be_present (instantiator);
499 }
500
501 static Lisp_Object
502 gif_normalize (Lisp_Object inst, Lisp_Object console_type)
503 {
504 return simple_image_type_normalize (inst, console_type, Qgif);
505 }
506
507 static int
508 gif_possible_dest_types (void)
509 {
510 return IMAGE_COLOR_PIXMAP_MASK;
511 }
512
513 /* To survive the otherwise baffling complexity of making sure
514 everything gets cleaned up in the presence of an error, we
515 use an unwind_protect(). */
516
517 struct gif_unwind_data
518 {
519 unsigned char *eimage;
520 /* Object that holds the decoded data from a GIF file */
521 GifFileType *giffile;
522 };
523
524 static Lisp_Object
525 gif_instantiate_unwind (Lisp_Object unwind_obj)
526 {
527 struct gif_unwind_data *data =
528 (struct gif_unwind_data *) get_opaque_ptr (unwind_obj);
529
530 free_opaque_ptr (unwind_obj);
531 if (data->giffile)
532 {
533 DGifCloseFile (data->giffile);
534 GifFree(data->giffile);
535 }
536 if (data->eimage) xfree(data->eimage);
537
538 return Qnil;
539 }
540
541 typedef struct gif_memory_storage
542 {
543 Extbyte *bytes; /* The data */
544 Extcount len; /* How big is it? */
545 int index; /* Where are we? */
546 } gif_memory_storage;
547
548 static size_t
549 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
550 {
551 gif_memory_storage *mem = (gif_memory_storage*)data;
552
553 if (size > (mem->len - mem->index))
554 return -1;
555 memcpy(buf, mem->bytes + mem->index, size);
556 mem->index = mem->index + size;
557 return size;
558 }
559
560 static int
561 gif_memory_close(VoidPtr data)
562 {
563 return 0;
564 }
565
566 struct gif_error_struct
567 {
568 CONST char *err_str; /* return the error string */
569 jmp_buf setjmp_buffer; /* for return to caller */
570 };
571
572 static void
573 gif_error_func(CONST char *err_str, VoidPtr error_ptr)
574 {
575 struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr;
576
577 /* return to setjmp point */
578 error_data->err_str = err_str;
579 longjmp (error_data->setjmp_buffer, 1);
580 }
581
582 static void
583 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
584 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
585 int dest_mask, Lisp_Object domain)
586 {
587 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
588 /* It is OK for the unwind data to be local to this function,
589 because the unwind-protect is always executed when this
590 stack frame is still valid. */
591 struct gif_unwind_data unwind;
592 int speccount = specpdl_depth ();
593 gif_memory_storage mem_struct;
594 struct gif_error_struct gif_err;
595 Extbyte *bytes;
596 Extcount len;
597 int height = 0;
598 int width = 0;
599
600 xzero (unwind);
601 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
602
603 /* 1. Now decode the data. */
604
605 {
606 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
607
608 assert (!NILP (data));
609
610 if (!(unwind.giffile = GifSetup()))
611 signal_image_error ("Insufficent memory to instantiate GIF image", instantiator);
612
613 /* set up error facilities */
614 if (setjmp(gif_err.setjmp_buffer))
615 {
616 /* An error was signaled. No clean up is needed, as unwind handles that
617 for us. Just pass the error along. */
618 Lisp_Object errstring;
619 errstring = build_string (gif_err.err_str);
620 signal_image_error_2 ("GIF decoding error", errstring, instantiator);
621 }
622 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
623
624 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
625 mem_struct.bytes = bytes;
626 mem_struct.len = len;
627 mem_struct.index = 0;
628 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
629 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
630 DGifInitRead(unwind.giffile);
631
632 /* Then slurp the image into memory, decoding along the way.
633 The result is the image in a simple one-byte-per-pixel
634 format (#### the GIF routines only support 8-bit GIFs,
635 it appears). */
636 DGifSlurp (unwind.giffile);
637 }
638
639 /* 3. Now create the EImage */
640 {
641 ColorMapObject *cmo = unwind.giffile->SColorMap;
642 int i, j, row, pass, interlace;
643 unsigned char *eip;
644 /* interlaced gifs have rows in this order:
645 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
646 static int InterlacedOffset[] = { 0, 4, 2, 1 };
647 static int InterlacedJumps[] = { 8, 8, 4, 2 };
648
649 height = unwind.giffile->SHeight;
650 width = unwind.giffile->SWidth;
651 unwind.eimage = (unsigned char*) xmalloc (width * height * 3);
652 if (!unwind.eimage)
653 signal_image_error("Unable to allocate enough memory for image", instantiator);
654
655 /* write the data in EImage format (8bit RGB triples) */
656
657 /* Note: We just use the first image in the file and ignore the rest.
658 We check here that that image covers the full "screen" size.
659 I don't know whether that's always the case.
660 -dkindred@cs.cmu.edu */
661 if (unwind.giffile->SavedImages[0].ImageDesc.Height != height
662 || unwind.giffile->SavedImages[0].ImageDesc.Width != width
663 || unwind.giffile->SavedImages[0].ImageDesc.Left != 0
664 || unwind.giffile->SavedImages[0].ImageDesc.Top != 0)
665 signal_image_error ("First image in GIF file is not full size",
666 instantiator);
667
668 interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace;
669 pass = 0;
670 row = interlace ? InterlacedOffset[pass] : 0;
671 eip = unwind.eimage;
672 for (i = 0; i < height; i++)
673 {
674 if (interlace && row >= height)
675 row = InterlacedOffset[++pass];
676 eip = unwind.eimage + (row * width * 3);
677 for (j = 0; j < width; j++)
678 {
679 unsigned char pixel = unwind.giffile->SavedImages[0].RasterBits[(i * width) + j];
680 *eip++ = cmo->Colors[pixel].Red;
681 *eip++ = cmo->Colors[pixel].Green;
682 *eip++ = cmo->Colors[pixel].Blue;
683 }
684 row += interlace ? InterlacedJumps[pass] : 1;
685 }
686 }
687 /* now instantiate */
688 MAYBE_DEVMETH (XDEVICE (ii->device),
689 init_image_instance_from_eimage,
690 (ii, width, height, unwind.eimage, dest_mask,
691 instantiator, domain));
692
693 unbind_to (speccount, Qnil);
694 }
695
696 #endif /* HAVE_GIF */
697
698
699 #ifdef HAVE_PNG
700
701 /**********************************************************************
702 * PNG *
703 **********************************************************************/
704 static void
705 png_validate (Lisp_Object instantiator)
706 {
707 file_or_data_must_be_present (instantiator);
708 }
709
710 static Lisp_Object
711 png_normalize (Lisp_Object inst, Lisp_Object console_type)
712 {
713 return simple_image_type_normalize (inst, console_type, Qpng);
714 }
715
716 static int
717 png_possible_dest_types (void)
718 {
719 return IMAGE_COLOR_PIXMAP_MASK;
720 }
721
722 struct png_memory_storage
723 {
724 CONST Extbyte *bytes; /* The data */
725 Extcount len; /* How big is it? */
726 int index; /* Where are we? */
727 };
728
729 static void
730 png_read_from_memory(png_structp png_ptr, png_bytep data,
731 png_size_t length)
732 {
733 struct png_memory_storage *tbr =
734 (struct png_memory_storage *) png_get_io_ptr (png_ptr);
735
736 if (length > (tbr->len - tbr->index))
737 png_error (png_ptr, (png_const_charp) "Read Error");
738 memcpy (data,tbr->bytes + tbr->index,length);
739 tbr->index = tbr->index + length;
740 }
741
742 struct png_error_struct
743 {
744 CONST char *err_str;
745 jmp_buf setjmp_buffer; /* for return to caller */
746 };
747
748 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own
749 structure, and there are cases where the size can be different from
750 between inside the libarary, and inside the code! To do an end run
751 around this, use our own error functions, and don't rely on things
752 passed in the png_ptr to them. This is an ugly hack and must
753 go away when the lisp engine is threaded! */
754 static struct png_error_struct png_err_stct;
755
756 static void
757 png_error_func (png_structp png_ptr, png_const_charp msg)
758 {
759 png_err_stct.err_str = msg;
760 longjmp (png_err_stct.setjmp_buffer, 1);
761 }
762
763 static void
764 png_warning_func (png_structp png_ptr, png_const_charp msg)
765 {
766 warn_when_safe (Qpng, Qinfo, "%s", msg);
767 }
768
769 struct png_unwind_data
770 {
771 FILE *instream;
772 unsigned char *eimage;
773 png_structp png_ptr;
774 png_infop info_ptr;
775 };
776
777 static Lisp_Object
778 png_instantiate_unwind (Lisp_Object unwind_obj)
779 {
780 struct png_unwind_data *data =
781 (struct png_unwind_data *) get_opaque_ptr (unwind_obj);
782
783 free_opaque_ptr (unwind_obj);
784 if (data->png_ptr)
785 png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
786 if (data->instream)
787 fclose (data->instream);
788
789 return Qnil;
790 }
791
792 static void
793 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
794 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
795 int dest_mask, Lisp_Object domain)
796 {
797 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
798 struct png_unwind_data unwind;
799 int speccount = specpdl_depth ();
800 int height, width;
801
802 /* PNG variables */
803 png_structp png_ptr;
804 png_infop info_ptr;
805
806 /* Initialize all PNG structures */
807 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (void*)&png_err_stct,
808 png_error_func, png_warning_func);
809 if (!png_ptr)
810 signal_image_error ("Error obtaining memory for png_read", instantiator);
811 info_ptr = png_create_info_struct (png_ptr);
812 if (!info_ptr)
813 {
814 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
815 signal_image_error ("Error obtaining memory for png_read", instantiator);
816 }
817
818 xzero (unwind);
819 unwind.png_ptr = png_ptr;
820 unwind.info_ptr = info_ptr;
821
822 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
823
824 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from
825 this file, example.c from the libpng 0.81 distribution, and the
826 pngtopnm sources. -WMP-
827 */
828 /* It has been further modified to handle the API changes for 0.96,
829 and is no longer usable for previous versions. jh
830 */
831
832 /* Set the jmp_buf reurn context for png_error ... if this returns !0, then
833 we ran into a problem somewhere, and need to clean up after ourselves. */
834 if (setjmp (png_err_stct.setjmp_buffer))
835 {
836 /* Something blew up: just display the error (cleanup happens in the unwind) */
837 signal_image_error_2 ("Error decoding PNG",
838 build_string(png_err_stct.err_str),
839 instantiator);
840 }
841
842 /* Initialize the IO layer and read in header information */
843 {
844 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
845 CONST Extbyte *bytes;
846 Extcount len;
847 struct png_memory_storage tbr; /* Data to be read */
848
849 assert (!NILP (data));
850
851 /* #### This is a definite problem under Mule due to the amount of
852 stack data it might allocate. Need to think about using Lstreams */
853 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
854 tbr.bytes = bytes;
855 tbr.len = len;
856 tbr.index = 0;
857 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory);
858 }
859
860 png_read_info (png_ptr, info_ptr);
861
862 {
863 int y;
864 unsigned char **row_pointers;
865 height = info_ptr->height;
866 width = info_ptr->width;
867
868 /* Wow, allocate all the memory. Truly, exciting. */
869 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3);
870 /* libpng expects that the image buffer passed in contains a
871 picture to draw on top of if the png has any transparencies.
872 This could be a good place to pass that in... */
873
874 row_pointers = xnew_array (png_byte *, height);
875
876 for (y = 0; y < height; y++)
877 row_pointers[y] = unwind.eimage + (width * 3 * y);
878
879 /* Now that we're using EImage, ask for 8bit RGB triples for any type
880 of image*/
881 /* convert palatte images to full RGB */
882 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
883 png_set_expand (png_ptr);
884 /* send grayscale images to RGB too */
885 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
886 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
887 png_set_gray_to_rgb (png_ptr);
888 /* we can't handle alpha values */
889 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
890 png_set_strip_alpha (png_ptr);
891 /* rip out any transparancy layers/colors */
892 if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
893 {
894 png_set_expand (png_ptr);
895 png_set_strip_alpha (png_ptr);
896 }
897 /* tell libpng to strip 16 bit depth files down to 8 bits */
898 if (info_ptr->bit_depth == 16)
899 png_set_strip_16 (png_ptr);
900 /* if the image is < 8 bits, pad it out */
901 if (info_ptr->bit_depth < 8)
902 {
903 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)
904 png_set_expand (png_ptr);
905 else
906 png_set_packing (png_ptr);
907 }
908
909 #if 1 /* tests? or permanent? */
910 {
911 /* if the png specifies a background chunk, go ahead and
912 use it */
913 png_color_16 my_background, *image_background;
914
915 /* ### how do I get the background of the current frame? */
916 my_background.red = 0x7fff;
917 my_background.green = 0x7fff;
918 my_background.blue = 0x7fff;
919
920 if (png_get_bKGD (png_ptr, info_ptr, &image_background))
921 png_set_background (png_ptr, image_background,
922 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
923 else
924 png_set_background (png_ptr, &my_background,
925 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
926 }
927 #endif
928 png_read_image (png_ptr, row_pointers);
929 png_read_end (png_ptr, info_ptr);
930
931 #ifdef PNG_SHOW_COMMENTS
932 /* ####
933 * I turn this off by default now, because the !%^@#!% comments
934 * show up every time the image is instantiated, which can get
935 * really really annoying. There should be some way to pass this
936 * type of data down into the glyph code, where you can get to it
937 * from lisp anyway. - WMP
938 */
939 {
940 int i;
941
942 for (i = 0 ; i < info_ptr->num_text ; i++)
943 {
944 /* How paranoid do I have to be about no trailing NULLs, and
945 using (int)info_ptr->text[i].text_length, and strncpy and a temp
946 string somewhere? */
947
948 warn_when_safe (Qpng, Qinfo, "%s - %s",
949 info_ptr->text[i].key,
950 info_ptr->text[i].text);
951 }
952 }
953 #endif
954
955 xfree (row_pointers);
956 }
957
958 /* now instantiate */
959 MAYBE_DEVMETH (XDEVICE (ii->device),
960 init_image_instance_from_eimage,
961 (ii, width, height, unwind.eimage, dest_mask,
962 instantiator, domain));
963
964 /* This will clean up everything else. */
965 unbind_to (speccount, Qnil);
966 }
967
968 #endif /* HAVE_PNG */
969
970
971 #ifdef HAVE_TIFF
972 #include "tiffio.h"
973
974 /**********************************************************************
975 * TIFF *
976 **********************************************************************/
977 static void
978 tiff_validate (Lisp_Object instantiator)
979 {
980 file_or_data_must_be_present (instantiator);
981 }
982
983 static Lisp_Object
984 tiff_normalize (Lisp_Object inst, Lisp_Object console_type)
985 {
986 return simple_image_type_normalize (inst, console_type, Qtiff);
987 }
988
989 static int
990 tiff_possible_dest_types (void)
991 {
992 return IMAGE_COLOR_PIXMAP_MASK;
993 }
994
995 struct tiff_unwind_data
996 {
997 unsigned char *eimage;
998 /* Object that holds the decoded data from a TIFF file */
999 TIFF *tiff;
1000 };
1001
1002 static Lisp_Object
1003 tiff_instantiate_unwind (Lisp_Object unwind_obj)
1004 {
1005 struct tiff_unwind_data *data =
1006 (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj);
1007
1008 free_opaque_ptr (unwind_obj);
1009 if (data->tiff)
1010 {
1011 TIFFClose(data->tiff);
1012 }
1013 if (data->eimage)
1014 xfree (data->eimage);
1015
1016 return Qnil;
1017 }
1018
1019 typedef struct tiff_memory_storage
1020 {
1021 Extbyte *bytes; /* The data */
1022 Extcount len; /* How big is it? */
1023 int index; /* Where are we? */
1024 } tiff_memory_storage;
1025
1026 static size_t
1027 tiff_memory_read(thandle_t data, tdata_t buf, tsize_t size)
1028 {
1029 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1030
1031 if (size > (mem->len - mem->index))
1032 return (size_t) -1;
1033 memcpy(buf, mem->bytes + mem->index, size);
1034 mem->index = mem->index + size;
1035 return size;
1036 }
1037
1038 static size_t tiff_memory_write(thandle_t data, tdata_t buf, tsize_t size)
1039 {
1040 abort();
1041 return 0; /* Shut up warnings. */
1042 }
1043
1044 static toff_t tiff_memory_seek(thandle_t data, toff_t off, int whence)
1045 {
1046 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1047 int newidx;
1048 switch(whence) {
1049 case SEEK_SET:
1050 newidx = off;
1051 break;
1052 case SEEK_END:
1053 newidx = mem->len + off;
1054 break;
1055 case SEEK_CUR:
1056 newidx = mem->index + off;
1057 break;
1058 default:
1059 fprintf(stderr,"Eh? invalid seek mode in tiff_memory_seek\n");
1060 return -1;
1061 }
1062
1063 if ((newidx > mem->len) || (newidx < 0))
1064 return -1;
1065
1066 mem->index = newidx;
1067 return newidx;
1068 }
1069
1070 static int
1071 tiff_memory_close(thandle_t data)
1072 {
1073 return 0;
1074 }
1075
1076 static int
1077 tiff_map_noop(thandle_t data, tdata_t* pbase, toff_t* psize)
1078 {
1079 return 0;
1080 }
1081
1082 static void
1083 tiff_unmap_noop(thandle_t data, tdata_t pbase, toff_t psize)
1084 {
1085 return;
1086 }
1087
1088 static toff_t
1089 tiff_memory_size(thandle_t data)
1090 {
1091 tiff_memory_storage *mem = (tiff_memory_storage*)data;
1092 return mem->len;
1093 }
1094
1095 struct tiff_error_struct
1096 {
1097 #if HAVE_VSNPRINTF
1098 char err_str[256];
1099 #else
1100 char err_str[1024]; /* return the error string */
1101 #endif
1102 jmp_buf setjmp_buffer; /* for return to caller */
1103 };
1104
1105 /* jh 98/03/12 - ###This struct for passing data to the error functions
1106 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't
1107 have any place to store error func data. This should be rectified
1108 before XEmacs gets threads! */
1109 static struct tiff_error_struct tiff_err_data;
1110
1111 static void
1112 tiff_error_func(CONST char *module, CONST char *fmt, ...)
1113 {
1114 va_list vargs;
1115
1116 va_start (vargs, fmt);
1117 #if HAVE_VSNPRINTF
1118 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs);
1119 #else
1120 /* pray this doesn't overflow... */
1121 vsprintf (tiff_err_data.err_str, fmt, vargs);
1122 #endif
1123 va_end (vargs);
1124 /* return to setjmp point */
1125 longjmp (tiff_err_data.setjmp_buffer, 1);
1126 }
1127
1128 static void
1129 tiff_warning_func(CONST char *module, CONST char *fmt, ...)
1130 {
1131 va_list vargs;
1132 #if HAVE_VSNPRINTF
1133 char warn_str[256];
1134 #else
1135 char warn_str[1024];
1136 #endif
1137
1138 va_start (vargs, fmt);
1139 #if HAVE_VSNPRINTF
1140 vsnprintf (warn_str, 255, fmt, vargs);
1141 #else
1142 vsprintf (warn_str, fmt, vargs);
1143 #endif
1144 va_end (vargs);
1145 warn_when_safe (Qtiff, Qinfo, "%s - %s",
1146 module, warn_str);
1147 }
1148
1149 static void
1150 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1151 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1152 int dest_mask, Lisp_Object domain)
1153 {
1154 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1155 tiff_memory_storage mem_struct;
1156 /* It is OK for the unwind data to be local to this function,
1157 because the unwind-protect is always executed when this
1158 stack frame is still valid. */
1159 struct tiff_unwind_data unwind;
1160 int speccount = specpdl_depth ();
1161 uint32 width, height;
1162
1163 xzero (unwind);
1164 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
1165
1166 /* set up error facilities */
1167 if (setjmp (tiff_err_data.setjmp_buffer))
1168 {
1169 /* An error was signaled. No clean up is needed, as unwind handles that
1170 for us. Just pass the error along. */
1171 signal_image_error_2 ("TIFF decoding error",
1172 build_string(tiff_err_data.err_str),
1173 instantiator);
1174 }
1175 TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func);
1176 TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func);
1177 {
1178 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1179 Extbyte *bytes;
1180 Extcount len;
1181
1182 uint32 *raster;
1183 unsigned char *ep;
1184
1185 assert (!NILP (data));
1186
1187 /* #### This is a definite problem under Mule due to the amount of
1188 stack data it might allocate. Think about Lstreams... */
1189 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
1190 mem_struct.bytes = bytes;
1191 mem_struct.len = len;
1192 mem_struct.index = 0;
1193
1194 unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct,
1195 (TIFFReadWriteProc)tiff_memory_read,
1196 (TIFFReadWriteProc)tiff_memory_write,
1197 tiff_memory_seek, tiff_memory_close, tiff_memory_size,
1198 tiff_map_noop, tiff_unmap_noop);
1199 if (!unwind.tiff)
1200 signal_image_error ("Insufficent memory to instantiate TIFF image", instantiator);
1201
1202 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1203 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1204 unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
1205
1206 /* ### This is little more than proof-of-concept/function testing.
1207 It needs to be reimplimented via scanline reads for both memory
1208 compactness. */
1209 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1210 if (raster != NULL)
1211 {
1212 int i,j;
1213 uint32 *rp;
1214 ep = unwind.eimage;
1215 rp = raster;
1216 if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0))
1217 {
1218 for (i = height - 1; i >= 0; i--)
1219 {
1220 /* This is to get around weirdness in the libtiff library where properly
1221 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1222 rp = raster + (i * width);
1223 for (j = 0; j < width; j++)
1224 {
1225 *ep++ = (unsigned char)TIFFGetR(*rp);
1226 *ep++ = (unsigned char)TIFFGetG(*rp);
1227 *ep++ = (unsigned char)TIFFGetB(*rp);
1228 rp++;
1229 }
1230 }
1231 }
1232 _TIFFfree (raster);
1233 } else
1234 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator);
1235
1236 }
1237
1238 /* now instantiate */
1239 MAYBE_DEVMETH (XDEVICE (ii->device),
1240 init_image_instance_from_eimage,
1241 (ii, width, height, unwind.eimage, dest_mask,
1242 instantiator, domain));
1243
1244 unbind_to (speccount, Qnil);
1245 }
1246
1247 #endif /* HAVE_TIFF */
1248
1249
1250 /************************************************************************/
1251 /* initialization */
1252 /************************************************************************/
1253
1254 void
1255 syms_of_glyphs_read (void)
1256 {
1257 }
1258
1259 void
1260 image_instantiator_format_create_glyphs_read (void)
1261 {
1262 /* image-instantiator types */
1263 #ifdef HAVE_JPEG
1264 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg");
1265
1266 IIFORMAT_HAS_METHOD (jpeg, validate);
1267 IIFORMAT_HAS_METHOD (jpeg, normalize);
1268 IIFORMAT_HAS_METHOD (jpeg, possible_dest_types);
1269 IIFORMAT_HAS_METHOD (jpeg, instantiate);
1270
1271 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string);
1272 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string);
1273 #endif
1274
1275 #ifdef HAVE_GIF
1276 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif");
1277
1278 IIFORMAT_HAS_METHOD (gif, validate);
1279 IIFORMAT_HAS_METHOD (gif, normalize);
1280 IIFORMAT_HAS_METHOD (gif, possible_dest_types);
1281 IIFORMAT_HAS_METHOD (gif, instantiate);
1282
1283 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string);
1284 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string);
1285 #endif
1286
1287 #ifdef HAVE_PNG
1288 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png");
1289
1290 IIFORMAT_HAS_METHOD (png, validate);
1291 IIFORMAT_HAS_METHOD (png, normalize);
1292 IIFORMAT_HAS_METHOD (png, possible_dest_types);
1293 IIFORMAT_HAS_METHOD (png, instantiate);
1294
1295 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string);
1296 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string);
1297 #endif
1298
1299 #ifdef HAVE_TIFF
1300 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff");
1301
1302 IIFORMAT_HAS_METHOD (tiff, validate);
1303 IIFORMAT_HAS_METHOD (tiff, normalize);
1304 IIFORMAT_HAS_METHOD (tiff, possible_dest_types);
1305 IIFORMAT_HAS_METHOD (tiff, instantiate);
1306
1307 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string);
1308 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string);
1309 #endif
1310
1311 }
1312
1313 void
1314 vars_of_glyphs_read (void)
1315 {
1316 #ifdef HAVE_JPEG
1317 Fprovide (Qjpeg);
1318 #endif
1319
1320 #ifdef HAVE_GIF
1321 Fprovide (Qgif);
1322 #endif
1323
1324 #ifdef HAVE_PNG
1325 Fprovide (Qpng);
1326 #endif
1327
1328 #ifdef HAVE_TIFF
1329 Fprovide (Qtiff);
1330 #endif
1331
1332 }