Mercurial > hg > xemacs-beta
annotate src/glyphs-eimage.c @ 5724:ede80ef92a74
Make soft links in src for module source files, if built in to the executable.
This ensures that those files are built with the same compiler flags as all
other source files.
See these xemacs-beta messages:
<CAHCOHQn+q=Xuwq+y68dvqi7afAP9f-TdB7=8YiZ8VYO816sjHg@mail.gmail.com>
<f5by5ejqiyk.fsf@calexico.inf.ed.ac.uk>
author | Jerry James <james@xemacs.org> |
---|---|
date | Sat, 02 Mar 2013 14:32:37 -0700 |
parents | 56144c8593a8 |
children |
rev | line source |
---|---|
428 | 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 | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
5 Copyright (C) 1995, 1996, 2001, 2002, 2004, 2005, 2010 Ben Wing |
428 | 6 Copyright (C) 1995 Sun Microsystems |
7 | |
8 This file is part of XEmacs. | |
9 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5250
diff
changeset
|
10 XEmacs is free software: you can redistribute it and/or modify it |
428 | 11 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5250
diff
changeset
|
12 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5250
diff
changeset
|
13 option) any later version. |
428 | 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 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5250
diff
changeset
|
21 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 22 |
23 /* Synched up with: Not in FSF. */ | |
24 | |
2959 | 25 /* Originally part of glyphs.c. |
26 | |
428 | 27 GIF/JPEG support added by Ben Wing for 19.14 |
28 PNG support added by Bill Perry for 19.14 | |
29 Improved GIF/JPEG support added by Bill Perry for 19.14 | |
30 Cleanup/simplification of error handling by Ben Wing for 19.14 | |
31 GIF support changed to external Gifreader lib by Jareth Hein for 21.0 | |
32 Many changes for color work and optimizations by Jareth Hein for 21.0 | |
33 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0 | |
34 TIFF code by Jareth Hein for 21.0 | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
35 GIF support changed to external giflib by Jerry James for 21.5 |
428 | 36 TODO: |
37 Convert images.el to C and stick it in here? | |
3094 | 38 This file is really repetitious; can we refactor? |
428 | 39 */ |
40 | |
41 #include <config.h> | |
42 #include "lisp.h" | |
43 #include "lstream.h" | |
44 #include "console.h" | |
872 | 45 #include "device-impl.h" |
428 | 46 #include "faces.h" |
47 #include "glyphs.h" | |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
48 #include "fontcolor-impl.h" |
428 | 49 |
50 #include "buffer.h" | |
51 #include "frame.h" | |
52 #include "opaque.h" | |
442 | 53 #include "window.h" |
428 | 54 |
55 #include "sysfile.h" | |
56 | |
57 #ifdef HAVE_PNG | |
1743 | 58 |
59 BEGIN_C_DECLS | |
60 | |
647 | 61 #define message message_ /* Yuck */ |
5536
bbcf3f979099
Suppress the "undefined macros" warnings for zlib.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5473
diff
changeset
|
62 #if !defined(_LARGEFILE64_SOURCE) /* Yuck**2 -- see <zconf.h>. */ |
bbcf3f979099
Suppress the "undefined macros" warnings for zlib.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5473
diff
changeset
|
63 #define _LARGEFILE64_SOURCE 0 |
bbcf3f979099
Suppress the "undefined macros" warnings for zlib.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5473
diff
changeset
|
64 #endif |
bbcf3f979099
Suppress the "undefined macros" warnings for zlib.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5473
diff
changeset
|
65 #if !defined(_FILE_OFFSET_BITS) /* Yuck**2 -- see <zlib.h>. */ |
bbcf3f979099
Suppress the "undefined macros" warnings for zlib.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5473
diff
changeset
|
66 #define _FILE_OFFSET_BITS 0 |
bbcf3f979099
Suppress the "undefined macros" warnings for zlib.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5473
diff
changeset
|
67 #endif |
428 | 68 #include <png.h> |
647 | 69 #undef message |
1743 | 70 |
71 END_C_DECLS | |
72 | |
428 | 73 #else |
74 #include <setjmp.h> | |
75 #endif | |
76 #include "file-coding.h" | |
77 | |
78 #ifdef HAVE_TIFF | |
79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff); | |
80 Lisp_Object Qtiff; | |
81 #endif | |
82 | |
83 #ifdef HAVE_JPEG | |
84 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg); | |
85 Lisp_Object Qjpeg; | |
86 #endif | |
87 | |
88 #ifdef HAVE_GIF | |
89 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif); | |
90 Lisp_Object Qgif; | |
91 #endif | |
92 | |
93 #ifdef HAVE_PNG | |
94 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png); | |
95 Lisp_Object Qpng; | |
96 #endif | |
97 | |
98 | |
99 #ifdef HAVE_JPEG | |
100 | |
101 /********************************************************************** | |
102 * JPEG * | |
103 **********************************************************************/ | |
104 | |
1743 | 105 BEGIN_C_DECLS |
106 | |
4854 | 107 #ifdef WIN32_ANY |
108 /* #### Yuck! More horrifitude. tiffio.h, below, and sysfile.h above, | |
109 include <windows.h>, which defines INT32 and INT16, the former | |
110 differently and incompatibly from jmorecfg.h, included by jpeglib.h. We | |
111 can disable the stuff in jmorecfg.h by defining XMD_H (clever, huh?); | |
112 then we define these typedefs the way that <windows.h> wants them (which | |
113 is more correct, anyway; jmorecfg.h defines INT32 as `long'). */ | |
2500 | 114 #define XMD_H |
115 typedef signed int INT32; | |
116 typedef signed short INT16; | |
4326
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
117 |
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
118 /* And another one... jmorecfg.h defines the 'boolean' type as int, |
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
119 which conflicts with the standard Windows 'boolean' definition as |
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
120 unsigned char. Ref: http://www.asmail.be/msg0054688232.html */ |
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
121 #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ |
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
122 typedef unsigned char boolean; |
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
123 #endif |
a5ff7e67ac1b
Don't let libtiff override the size of a boolean, Win32. From Ron Isaacson.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3839
diff
changeset
|
124 #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ |
2500 | 125 #endif |
126 | |
5009
2eec7322eb7f
Miscellaneous small fixes to Windows VS6 build
Vin Shelton <acs@xemacs.org>
parents:
4982
diff
changeset
|
127 /* Yet more breakage... jmorecfg.h unconditionally defines FAR either as |
2eec7322eb7f
Miscellaneous small fixes to Windows VS6 build
Vin Shelton <acs@xemacs.org>
parents:
4982
diff
changeset
|
128 "far" or as blank. Windef.h unconditionally defines FAR as "far". |
2eec7322eb7f
Miscellaneous small fixes to Windows VS6 build
Vin Shelton <acs@xemacs.org>
parents:
4982
diff
changeset
|
129 We'll avoid the compile warning by redefing FAR the way windows defines it, |
2eec7322eb7f
Miscellaneous small fixes to Windows VS6 build
Vin Shelton <acs@xemacs.org>
parents:
4982
diff
changeset
|
130 after loading the JPEG headers. */ |
2eec7322eb7f
Miscellaneous small fixes to Windows VS6 build
Vin Shelton <acs@xemacs.org>
parents:
4982
diff
changeset
|
131 #undef FAR |
428 | 132 #include <jpeglib.h> |
133 #include <jerror.h> | |
5009
2eec7322eb7f
Miscellaneous small fixes to Windows VS6 build
Vin Shelton <acs@xemacs.org>
parents:
4982
diff
changeset
|
134 #undef FAR |
2eec7322eb7f
Miscellaneous small fixes to Windows VS6 build
Vin Shelton <acs@xemacs.org>
parents:
4982
diff
changeset
|
135 #define FAR far |
1743 | 136 |
137 END_C_DECLS | |
428 | 138 |
139 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/ | |
140 static void | |
141 jpeg_validate (Lisp_Object instantiator) | |
142 { | |
143 file_or_data_must_be_present (instantiator); | |
144 } | |
145 | |
146 static Lisp_Object | |
442 | 147 jpeg_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 148 Lisp_Object UNUSED (dest_mask)) |
428 | 149 { |
150 return simple_image_type_normalize (inst, console_type, Qjpeg); | |
151 } | |
152 | |
153 static int | |
154 jpeg_possible_dest_types (void) | |
155 { | |
156 return IMAGE_COLOR_PIXMAP_MASK; | |
157 } | |
158 | |
159 /* To survive the otherwise baffling complexity of making sure | |
160 everything gets cleaned up in the presence of an error, we | |
161 use an unwind_protect(). */ | |
162 | |
163 struct jpeg_unwind_data | |
164 { | |
165 /* Stream that we need to close */ | |
166 FILE *instream; | |
167 /* Object that holds state info for JPEG decoding */ | |
168 struct jpeg_decompress_struct *cinfo_ptr; | |
169 /* EImage data */ | |
2367 | 170 Binbyte *eimage; |
428 | 171 }; |
172 | |
173 static Lisp_Object | |
174 jpeg_instantiate_unwind (Lisp_Object unwind_obj) | |
175 { | |
176 struct jpeg_unwind_data *data = | |
177 (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj); | |
178 | |
179 free_opaque_ptr (unwind_obj); | |
180 if (data->cinfo_ptr) | |
181 jpeg_destroy_decompress (data->cinfo_ptr); | |
182 | |
183 if (data->instream) | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
184 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
185 retry_fclose (data->instream); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
186 data->instream = 0; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
187 } |
428 | 188 |
1726 | 189 if (data->eimage) |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
190 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
191 xfree (data->eimage); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
192 data->eimage = 0; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
193 } |
428 | 194 |
195 return Qnil; | |
196 } | |
197 | |
198 /* | |
199 * ERROR HANDLING: | |
200 * | |
201 * The JPEG library's standard error handler (jerror.c) is divided into | |
202 * several "methods" which you can override individually. This lets you | |
203 * adjust the behavior without duplicating a lot of code, which you might | |
204 * have to update with each future release. | |
205 * | |
206 * Our example here shows how to override the "error_exit" method so that | |
207 * control is returned to the library's caller when a fatal error occurs, | |
208 * rather than calling exit() as the standard error_exit method does. | |
209 * | |
210 * We use C's setjmp/longjmp facility to return control. This means that the | |
211 * routine which calls the JPEG library must first execute a setjmp() call to | |
212 * establish the return point. We want the replacement error_exit to do a | |
213 * longjmp(). But we need to make the setjmp buffer accessible to the | |
214 * error_exit routine. To do this, we make a private extension of the | |
215 * standard JPEG error handler object. (If we were using C++, we'd say we | |
216 * were making a subclass of the regular error handler.) | |
217 * | |
218 * Here's the extended error handler struct: | |
219 */ | |
220 | |
221 struct my_jpeg_error_mgr | |
222 { | |
223 struct jpeg_error_mgr pub; /* "public" fields */ | |
224 jmp_buf setjmp_buffer; /* for return to caller */ | |
225 }; | |
226 | |
227 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
228 METHODDEF(void) | |
229 #else | |
230 METHODDEF void | |
231 #endif | |
2286 | 232 our_init_source (j_decompress_ptr UNUSED (cinfo)) |
428 | 233 { |
234 } | |
235 | |
236 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
237 METHODDEF(boolean) | |
238 #else | |
239 METHODDEF boolean | |
240 #endif | |
241 our_fill_input_buffer (j_decompress_ptr cinfo) | |
242 { | |
243 /* Insert a fake EOI marker */ | |
244 struct jpeg_source_mgr *src = cinfo->src; | |
245 static JOCTET buffer[2]; | |
246 | |
247 buffer[0] = (JOCTET) 0xFF; | |
248 buffer[1] = (JOCTET) JPEG_EOI; | |
249 | |
250 src->next_input_byte = buffer; | |
251 src->bytes_in_buffer = 2; | |
252 return TRUE; | |
253 } | |
254 | |
255 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
256 METHODDEF(void) | |
257 #else | |
258 METHODDEF void | |
259 #endif | |
260 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes) | |
261 { | |
262 struct jpeg_source_mgr *src = NULL; | |
263 | |
264 src = (struct jpeg_source_mgr *) cinfo->src; | |
265 | |
266 if (!src) | |
647 | 267 return; |
268 else if (num_bytes > (long) src->bytes_in_buffer) | |
428 | 269 { |
647 | 270 ERREXIT (cinfo, JERR_INPUT_EOF); |
271 /*NOTREACHED*/ | |
272 } | |
428 | 273 |
274 src->bytes_in_buffer -= num_bytes; | |
275 src->next_input_byte += num_bytes; | |
276 } | |
277 | |
278 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
279 METHODDEF(void) | |
280 #else | |
281 METHODDEF void | |
282 #endif | |
2286 | 283 our_term_source (j_decompress_ptr UNUSED (cinfo)) |
428 | 284 { |
285 } | |
286 | |
287 typedef struct | |
288 { | |
289 struct jpeg_source_mgr pub; | |
290 } our_jpeg_source_mgr; | |
291 | |
292 static void | |
665 | 293 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, Bytecount len) |
428 | 294 { |
295 struct jpeg_source_mgr *src; | |
296 | |
297 if (cinfo->src == NULL) | |
298 { /* first time for this JPEG object? */ | |
299 cinfo->src = (struct jpeg_source_mgr *) | |
300 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, | |
301 sizeof(our_jpeg_source_mgr)); | |
302 src = (struct jpeg_source_mgr *) cinfo->src; | |
303 src->next_input_byte = data; | |
304 } | |
305 src = (struct jpeg_source_mgr *) cinfo->src; | |
306 src->init_source = our_init_source; | |
307 src->fill_input_buffer = our_fill_input_buffer; | |
308 src->skip_input_data = our_skip_input_data; | |
309 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ | |
310 src->term_source = our_term_source; | |
311 src->bytes_in_buffer = len; | |
312 src->next_input_byte = data; | |
313 } | |
314 | |
315 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
316 METHODDEF(void) | |
317 #else | |
318 METHODDEF void | |
319 #endif | |
320 my_jpeg_error_exit (j_common_ptr cinfo) | |
321 { | |
322 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ | |
323 struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err; | |
324 | |
325 /* Return control to the setjmp point */ | |
326 longjmp (myerr->setjmp_buffer, 1); | |
327 } | |
328 | |
329 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
330 METHODDEF(void) | |
331 #else | |
332 METHODDEF void | |
333 #endif | |
334 my_jpeg_output_message (j_common_ptr cinfo) | |
335 { | |
771 | 336 Extbyte buffer[JMSG_LENGTH_MAX]; |
867 | 337 Ibyte *intbuf; |
428 | 338 |
339 /* Create the message */ | |
340 (*cinfo->err->format_message) (cinfo, buffer); | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
341 intbuf = EXTERNAL_TO_ITEXT (buffer, Qjpeg_error_message_encoding); |
771 | 342 warn_when_safe (Qjpeg, Qinfo, "%s", intbuf); |
428 | 343 } |
344 | |
345 /* The code in this routine is based on example.c from the JPEG library | |
346 source code and from gif_instantiate() */ | |
347 static void | |
348 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 349 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 350 int dest_mask, Lisp_Object domain) |
351 { | |
440 | 352 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 353 /* It is OK for the unwind data to be local to this function, |
354 because the unwind-protect is always executed when this | |
355 stack frame is still valid. */ | |
356 struct jpeg_unwind_data unwind; | |
357 int speccount = specpdl_depth (); | |
358 | |
359 /* This struct contains the JPEG decompression parameters and pointers to | |
360 * working space (which is allocated as needed by the JPEG library). | |
361 */ | |
362 struct jpeg_decompress_struct cinfo; | |
363 /* We use our private extension JPEG error handler. | |
364 * Note that this struct must live as long as the main JPEG parameter | |
365 * struct, to avoid dangling-pointer problems. | |
366 */ | |
367 struct my_jpeg_error_mgr jerr; | |
368 | |
369 /* Step -1: First record our unwind-protect, which will clean up after | |
370 any exit, normal or not */ | |
371 | |
372 xzero (unwind); | |
373 record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind)); | |
374 | |
375 /* Step 1: allocate and initialize JPEG decompression object */ | |
376 | |
377 /* We set up the normal JPEG error routines, then override error_exit. */ | |
378 cinfo.err = jpeg_std_error (&jerr.pub); | |
379 jerr.pub.error_exit = my_jpeg_error_exit; | |
380 jerr.pub.output_message = my_jpeg_output_message; | |
381 | |
382 /* Establish the setjmp return context for my_error_exit to use. */ | |
383 if (setjmp (jerr.setjmp_buffer)) | |
384 { | |
385 /* If we get here, the JPEG code has signaled an error. | |
386 * We need to clean up the JPEG object, close the input file, and return. | |
387 */ | |
388 | |
389 { | |
390 Lisp_Object errstring; | |
771 | 391 Extbyte buffer[JMSG_LENGTH_MAX]; |
428 | 392 |
393 /* Create the message */ | |
394 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer); | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
395 errstring = build_extstring (buffer, Qjpeg_error_message_encoding); |
428 | 396 |
397 signal_image_error_2 ("JPEG decoding error", | |
398 errstring, instantiator); | |
399 } | |
400 } | |
401 | |
402 /* Now we can initialize the JPEG decompression object. */ | |
403 jpeg_create_decompress (&cinfo); | |
404 unwind.cinfo_ptr = &cinfo; | |
405 | |
406 /* Step 2: specify data source (eg, a file) */ | |
407 | |
408 { | |
409 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 410 const Binbyte *bytes; |
665 | 411 Bytecount len; |
428 | 412 |
413 /* #### This is a definite problem under Mule due to the amount of | |
414 stack data it might allocate. Need to be able to convert and | |
415 write out to a file. */ | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
416 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 417 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len); |
418 } | |
419 | |
420 /* Step 3: read file parameters with jpeg_read_header() */ | |
421 | |
422 jpeg_read_header (&cinfo, TRUE); | |
423 /* We can ignore the return value from jpeg_read_header since | |
424 * (a) suspension is not possible with the stdio data source, and | |
425 * (b) we passed TRUE to reject a tables-only JPEG file as an error. | |
426 * See libjpeg.doc for more info. | |
427 */ | |
428 | |
429 { | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
430 UINT_64_BIT pixels_sq; |
428 | 431 int jpeg_gray = 0; /* if we're dealing with a grayscale */ |
432 /* Step 4: set parameters for decompression. */ | |
433 | |
434 /* Now that we're using EImages, send all data as 24bit color. | |
435 The backend routine will take care of any necessary reductions. | |
436 We do have to handle the grayscale case ourselves, however. */ | |
437 if (cinfo.jpeg_color_space == JCS_GRAYSCALE) | |
438 { | |
439 cinfo.out_color_space = JCS_GRAYSCALE; | |
440 jpeg_gray = 1; | |
441 } | |
442 else | |
443 { | |
444 /* we're relying on the jpeg driver to do any other conversions, | |
445 or signal an error if the conversion isn't supported. */ | |
446 cinfo.out_color_space = JCS_RGB; | |
447 } | |
448 | |
449 /* Step 5: Start decompressor */ | |
450 jpeg_start_decompress (&cinfo); | |
451 | |
452 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/ | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
453 pixels_sq = |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
454 (UINT_64_BIT) cinfo.output_width * (UINT_64_BIT) cinfo.output_height; |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
455 if (pixels_sq > ((size_t) -1) / 3) |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
456 signal_image_error ("JPEG image too large to instantiate", instantiator); |
2367 | 457 unwind.eimage = |
458 xnew_binbytes (cinfo.output_width * cinfo.output_height * 3); | |
428 | 459 if (!unwind.eimage) |
460 signal_image_error("Unable to allocate enough memory for image", instantiator); | |
461 | |
462 { | |
463 JSAMPARRAY row_buffer; /* Output row buffer */ | |
464 JSAMPLE *jp; | |
465 int row_stride; /* physical row width in output buffer */ | |
2367 | 466 Binbyte *op = unwind.eimage; |
428 | 467 |
468 /* We may need to do some setup of our own at this point before reading | |
469 * the data. After jpeg_start_decompress() we have the correct scaled | |
470 * output image dimensions available | |
471 * We need to make an output work buffer of the right size. | |
472 */ | |
473 /* JSAMPLEs per row in output buffer. */ | |
474 row_stride = cinfo.output_width * cinfo.output_components; | |
475 /* Make a one-row-high sample array that will go away when done | |
476 with image */ | |
477 row_buffer = ((*cinfo.mem->alloc_sarray) | |
478 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1)); | |
479 | |
480 /* Here we use the library's state variable cinfo.output_scanline as the | |
481 * loop counter, so that we don't have to keep track ourselves. | |
482 */ | |
483 while (cinfo.output_scanline < cinfo.output_height) | |
484 { | |
485 int i; | |
486 | |
487 /* jpeg_read_scanlines expects an array of pointers to scanlines. | |
488 * Here the array is only one element long, but you could ask for | |
489 * more than one scanline at a time if that's more convenient. | |
490 */ | |
491 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1); | |
492 jp = row_buffer[0]; | |
647 | 493 for (i = 0; i < (int) cinfo.output_width; i++) |
428 | 494 { |
495 int clr; | |
496 if (jpeg_gray) | |
497 { | |
2367 | 498 Binbyte val; |
428 | 499 #if (BITS_IN_JSAMPLE == 8) |
2367 | 500 val = (Binbyte) *jp++; |
428 | 501 #else /* other option is 12 */ |
2367 | 502 val = (Binbyte) (*jp++ >> 4); |
428 | 503 #endif |
504 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */ | |
505 *op++ = val; | |
506 } | |
507 else | |
508 { | |
509 for (clr = 0; clr < 3; clr++) | |
510 #if (BITS_IN_JSAMPLE == 8) | |
2367 | 511 *op++ = (Binbyte)*jp++; |
428 | 512 #else /* other option is 12 */ |
2367 | 513 *op++ = (Binbyte)(*jp++ >> 4); |
428 | 514 #endif |
515 } | |
516 } | |
517 } | |
518 } | |
519 } | |
520 | |
521 /* Step 6.5: Create the pixmap and set up the image instance */ | |
522 /* now instantiate */ | |
442 | 523 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 524 init_image_instance_from_eimage, |
525 (ii, cinfo.output_width, cinfo.output_height, 1, | |
526 unwind.eimage, dest_mask, | |
2959 | 527 instantiator, pointer_fg, pointer_bg, domain)); |
428 | 528 |
529 /* Step 7: Finish decompression */ | |
530 | |
531 jpeg_finish_decompress (&cinfo); | |
532 /* We can ignore the return value since suspension is not possible | |
533 * with the stdio data source. | |
534 */ | |
535 | |
536 /* And we're done! */ | |
537 /* This will clean up everything else. */ | |
771 | 538 unbind_to (speccount); |
428 | 539 } |
540 | |
541 #endif /* HAVE_JPEG */ | |
542 | |
543 #ifdef HAVE_GIF | |
544 /********************************************************************** | |
545 * GIF * | |
546 **********************************************************************/ | |
547 | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
548 #include <gif_lib.h> |
428 | 549 |
550 static void | |
551 gif_validate (Lisp_Object instantiator) | |
552 { | |
553 file_or_data_must_be_present (instantiator); | |
554 } | |
555 | |
556 static Lisp_Object | |
442 | 557 gif_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 558 Lisp_Object UNUSED (dest_mask)) |
428 | 559 { |
560 return simple_image_type_normalize (inst, console_type, Qgif); | |
561 } | |
562 | |
563 static int | |
564 gif_possible_dest_types (void) | |
565 { | |
566 return IMAGE_COLOR_PIXMAP_MASK; | |
567 } | |
568 | |
569 /* To survive the otherwise baffling complexity of making sure | |
570 everything gets cleaned up in the presence of an error, we | |
571 use an unwind_protect(). */ | |
572 | |
573 struct gif_unwind_data | |
574 { | |
2367 | 575 Binbyte *eimage; |
428 | 576 /* Object that holds the decoded data from a GIF file */ |
577 GifFileType *giffile; | |
578 }; | |
579 | |
580 static Lisp_Object | |
581 gif_instantiate_unwind (Lisp_Object unwind_obj) | |
582 { | |
583 struct gif_unwind_data *data = | |
584 (struct gif_unwind_data *) get_opaque_ptr (unwind_obj); | |
585 | |
586 free_opaque_ptr (unwind_obj); | |
587 if (data->giffile) | |
588 { | |
589 DGifCloseFile (data->giffile); | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
590 FreeSavedImages (data->giffile); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
591 data->giffile = 0; |
428 | 592 } |
647 | 593 if (data->eimage) |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
594 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
595 xfree (data->eimage); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
596 data->eimage = 0; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
597 } |
428 | 598 |
599 return Qnil; | |
600 } | |
601 | |
602 typedef struct gif_memory_storage | |
603 { | |
2367 | 604 Binbyte *bytes; /* The data */ |
665 | 605 Bytecount len; /* How big is it? */ |
606 Bytecount index; /* Where are we? */ | |
428 | 607 } gif_memory_storage; |
608 | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
609 static int |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
610 gif_read_from_memory (GifFileType *gif, GifByteType *buf, int size) |
428 | 611 { |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
612 gif_memory_storage *mem = (gif_memory_storage *) gif->UserData; |
428 | 613 |
614 if (size > (mem->len - mem->index)) | |
647 | 615 return -1; |
616 memcpy (buf, mem->bytes + mem->index, size); | |
428 | 617 mem->index = mem->index + size; |
618 return size; | |
619 } | |
620 | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
621 static const char * |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4982
diff
changeset
|
622 gif_decode_error_string (void) |
428 | 623 { |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
624 switch (GifLastError ()) |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
625 { |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
626 case D_GIF_ERR_OPEN_FAILED: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
627 return "GIF error: unable to open"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
628 case D_GIF_ERR_READ_FAILED: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
629 return "GIF error: read failed"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
630 case D_GIF_ERR_NOT_GIF_FILE: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
631 return "GIF error: not a GIF file"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
632 case D_GIF_ERR_NO_SCRN_DSCR: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
633 return "GIF error: no Screen Descriptor detected"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
634 case D_GIF_ERR_NO_IMAG_DSCR: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
635 return "GIF error: no Image Descriptor detected"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
636 case D_GIF_ERR_NO_COLOR_MAP: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
637 return "GIF error: no global or local color map"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
638 case D_GIF_ERR_WRONG_RECORD: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
639 return "GIF error: wrong record type"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
640 case D_GIF_ERR_DATA_TOO_BIG: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
641 return "GIF error: image is larger than indicated by header"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
642 case D_GIF_ERR_NOT_ENOUGH_MEM: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
643 return "GIF error: out of memory"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
644 case D_GIF_ERR_CLOSE_FAILED: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
645 return "GIF error: failed to close file"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
646 case D_GIF_ERR_NOT_READABLE: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
647 return "GIF error: file is not readable"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
648 case D_GIF_ERR_IMAGE_DEFECT: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
649 return "GIF error: image is defective"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
650 case D_GIF_ERR_EOF_TOO_SOON: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
651 return "GIF error: image EOF detected before image complete"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
652 default: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
653 return "GIF error: unknown error"; |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
654 } |
428 | 655 } |
656 | |
657 static void | |
658 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 659 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 660 int dest_mask, Lisp_Object domain) |
661 { | |
440 | 662 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 663 /* It is OK for the unwind data to be local to this function, |
664 because the unwind-protect is always executed when this | |
665 stack frame is still valid. */ | |
666 struct gif_unwind_data unwind; | |
667 int speccount = specpdl_depth (); | |
668 gif_memory_storage mem_struct; | |
2367 | 669 Binbyte *bytes; |
665 | 670 Bytecount len; |
428 | 671 int height = 0; |
672 int width = 0; | |
673 | |
674 xzero (unwind); | |
675 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind)); | |
676 | |
677 /* 1. Now decode the data. */ | |
678 | |
679 { | |
680 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
681 | |
682 assert (!NILP (data)); | |
683 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
684 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 685 mem_struct.bytes = bytes; |
686 mem_struct.len = len; | |
687 mem_struct.index = 0; | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
688 unwind.giffile = DGifOpen (&mem_struct, gif_read_from_memory); |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
689 if (unwind.giffile == NULL) |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
690 signal_image_error (gif_decode_error_string (), instantiator); |
428 | 691 |
692 /* Then slurp the image into memory, decoding along the way. | |
693 The result is the image in a simple one-byte-per-pixel | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
694 format. */ |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
695 if (DGifSlurp (unwind.giffile) == GIF_ERROR) |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
696 signal_image_error (gif_decode_error_string (), instantiator); |
428 | 697 } |
698 | |
699 /* 3. Now create the EImage(s) */ | |
700 { | |
5250
db84c9d41437
Apply GIF colormap fix from Adam Sjogren for issues 150 and 713
Vin Shelton <acs@xemacs.org>
parents:
5178
diff
changeset
|
701 ColorMapObject *cmo = (unwind.giffile->Image.ColorMap ? unwind.giffile->Image.ColorMap : unwind.giffile->SColorMap); |
428 | 702 int i, j, row, pass, interlace, slice; |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
703 UINT_64_BIT pixels_sq; |
2367 | 704 Binbyte *eip; |
428 | 705 /* interlaced gifs have rows in this order: |
706 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ | |
707 static int InterlacedOffset[] = { 0, 4, 2, 1 }; | |
708 static int InterlacedJumps[] = { 8, 8, 4, 2 }; | |
709 | |
5250
db84c9d41437
Apply GIF colormap fix from Adam Sjogren for issues 150 and 713
Vin Shelton <acs@xemacs.org>
parents:
5178
diff
changeset
|
710 if (cmo == NULL) |
db84c9d41437
Apply GIF colormap fix from Adam Sjogren for issues 150 and 713
Vin Shelton <acs@xemacs.org>
parents:
5178
diff
changeset
|
711 signal_image_error ("GIF image has no color map", instantiator); |
db84c9d41437
Apply GIF colormap fix from Adam Sjogren for issues 150 and 713
Vin Shelton <acs@xemacs.org>
parents:
5178
diff
changeset
|
712 |
428 | 713 height = unwind.giffile->SHeight; |
714 width = unwind.giffile->SWidth; | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
715 pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height; |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
716 if (pixels_sq > ((size_t) -1) / (3 * unwind.giffile->ImageCount)) |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
717 signal_image_error ("GIF image too large to instantiate", instantiator); |
2367 | 718 unwind.eimage = |
719 xnew_binbytes (width * height * 3 * unwind.giffile->ImageCount); | |
428 | 720 if (!unwind.eimage) |
721 signal_image_error("Unable to allocate enough memory for image", instantiator); | |
722 | |
723 /* write the data in EImage format (8bit RGB triples) */ | |
724 | |
725 for (slice = 0; slice < unwind.giffile->ImageCount; slice++) | |
726 { | |
638 | 727 /* We check here that the current image covers the full "screen" size. */ |
428 | 728 if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height |
729 || unwind.giffile->SavedImages[slice].ImageDesc.Width != width | |
730 || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0 | |
731 || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0) | |
732 signal_image_error ("Image in GIF file is not full size", | |
733 instantiator); | |
734 | |
735 interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace; | |
736 pass = 0; | |
737 row = interlace ? InterlacedOffset[pass] : 0; | |
738 eip = unwind.eimage + (width * height * 3 * slice); | |
739 for (i = 0; i < height; i++) | |
740 { | |
741 if (interlace) | |
742 if (row >= height) { | |
743 row = InterlacedOffset[++pass]; | |
744 while (row >= height) | |
745 row = InterlacedOffset[++pass]; | |
746 } | |
747 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3); | |
748 for (j = 0; j < width; j++) | |
749 { | |
2367 | 750 Binbyte pixel = |
428 | 751 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j]; |
752 *eip++ = cmo->Colors[pixel].Red; | |
753 *eip++ = cmo->Colors[pixel].Green; | |
754 *eip++ = cmo->Colors[pixel].Blue; | |
755 } | |
756 row += interlace ? InterlacedJumps[pass] : 1; | |
757 } | |
758 } | |
759 | |
760 /* now instantiate */ | |
442 | 761 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 762 init_image_instance_from_eimage, |
2959 | 763 (ii, width, height, unwind.giffile->ImageCount, |
764 unwind.eimage, dest_mask, instantiator, pointer_fg, | |
765 pointer_bg, domain)); | |
428 | 766 } |
767 | |
768 /* We read the gif successfully. If we have more than one slice then | |
769 animate the gif. */ | |
770 if (unwind.giffile->ImageCount > 1) | |
771 { | |
772 /* See if there is a timeout value. In theory there could be one | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
773 for every image - but that makes the implementation way too |
428 | 774 complicated for now so we just take the first. */ |
775 unsigned short timeout = 0; | |
776 Lisp_Object tid; | |
777 | |
778 if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE | |
779 && | |
780 unwind.giffile->SavedImages[0].ExtensionBlockCount) | |
781 { | |
782 timeout = (unsigned short) | |
438 | 783 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) + |
428 | 784 unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10; |
785 } | |
786 | |
787 /* Too short a timeout will crucify us performance-wise. */ | |
788 tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance); | |
789 | |
790 if (!NILP (tid)) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5537
diff
changeset
|
791 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XFIXNUM (tid); |
428 | 792 } |
438 | 793 |
771 | 794 unbind_to (speccount); |
428 | 795 } |
796 | |
797 #endif /* HAVE_GIF */ | |
798 | |
799 | |
800 #ifdef HAVE_PNG | |
801 | |
802 /********************************************************************** | |
803 * PNG * | |
804 **********************************************************************/ | |
805 static void | |
806 png_validate (Lisp_Object instantiator) | |
807 { | |
808 file_or_data_must_be_present (instantiator); | |
809 } | |
810 | |
811 static Lisp_Object | |
442 | 812 png_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 813 Lisp_Object UNUSED (dest_mask)) |
428 | 814 { |
815 return simple_image_type_normalize (inst, console_type, Qpng); | |
816 } | |
817 | |
818 static int | |
819 png_possible_dest_types (void) | |
820 { | |
821 return IMAGE_COLOR_PIXMAP_MASK; | |
822 } | |
823 | |
824 struct png_memory_storage | |
825 { | |
2367 | 826 const Binbyte *bytes; /* The data */ |
665 | 827 Bytecount len; /* How big is it? */ |
828 Bytecount index; /* Where are we? */ | |
428 | 829 }; |
830 | |
831 static void | |
647 | 832 png_read_from_memory (png_structp png_ptr, png_bytep data, |
833 png_size_t length) | |
428 | 834 { |
835 struct png_memory_storage *tbr = | |
836 (struct png_memory_storage *) png_get_io_ptr (png_ptr); | |
837 | |
665 | 838 if ((Bytecount) length > (tbr->len - tbr->index)) |
428 | 839 png_error (png_ptr, (png_const_charp) "Read Error"); |
647 | 840 memcpy (data, tbr->bytes + tbr->index,length); |
428 | 841 tbr->index = tbr->index + length; |
842 } | |
843 | |
844 struct png_error_struct | |
845 { | |
442 | 846 const char *err_str; |
428 | 847 jmp_buf setjmp_buffer; /* for return to caller */ |
848 }; | |
849 | |
850 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own | |
851 structure, and there are cases where the size can be different from | |
852 between inside the library, and inside the code! To do an end run | |
853 around this, use our own error functions, and don't rely on things | |
854 passed in the png_ptr to them. This is an ugly hack and must | |
855 go away when the lisp engine is threaded! */ | |
856 static struct png_error_struct png_err_stct; | |
857 | |
858 static void | |
2286 | 859 png_error_func (png_structp UNUSED (png_ptr), png_const_charp msg) |
428 | 860 { |
861 png_err_stct.err_str = msg; | |
862 longjmp (png_err_stct.setjmp_buffer, 1); | |
863 } | |
864 | |
865 static void | |
2286 | 866 png_warning_func (png_structp UNUSED (png_ptr), png_const_charp msg) |
428 | 867 { |
3734 | 868 DECLARE_EISTRING (eimsg); |
869 | |
870 eicpy_ext(eimsg, msg, Qbinary); | |
871 warn_when_safe (Qpng, Qinfo, "%s", eidata(eimsg)); | |
428 | 872 } |
873 | |
874 struct png_unwind_data | |
875 { | |
876 FILE *instream; | |
2367 | 877 Binbyte *eimage; |
428 | 878 png_structp png_ptr; |
879 png_infop info_ptr; | |
880 }; | |
881 | |
882 static Lisp_Object | |
883 png_instantiate_unwind (Lisp_Object unwind_obj) | |
884 { | |
885 struct png_unwind_data *data = | |
886 (struct png_unwind_data *) get_opaque_ptr (unwind_obj); | |
887 | |
888 free_opaque_ptr (unwind_obj); | |
889 if (data->png_ptr) | |
3839 | 890 { |
891 /* ensure we can't get here again */ | |
892 png_structp tmp = data->png_ptr; | |
893 data->png_ptr = NULL; | |
894 png_destroy_read_struct (&tmp, &(data->info_ptr), (png_infopp)NULL); | |
895 } | |
896 | |
428 | 897 if (data->instream) |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
898 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
899 retry_fclose (data->instream); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
900 data->instream = 0; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
901 } |
428 | 902 |
1726 | 903 if (data->eimage) |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
904 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
905 xfree (data->eimage); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
906 data->eimage = 0; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
907 } |
428 | 908 |
909 return Qnil; | |
910 } | |
911 | |
912 static void | |
913 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 914 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 915 int dest_mask, Lisp_Object domain) |
916 { | |
440 | 917 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 918 struct png_unwind_data unwind; |
919 int speccount = specpdl_depth (); | |
920 int height, width; | |
921 struct png_memory_storage tbr; /* Data to be read */ | |
922 | |
923 /* PNG variables */ | |
924 png_structp png_ptr; | |
925 png_infop info_ptr; | |
926 | |
3839 | 927 xzero (unwind); |
928 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind)); | |
929 | |
930 if (setjmp (png_err_stct.setjmp_buffer)) | |
931 { | |
932 /* Something blew up: | |
933 just display the error (cleanup happens in the unwind) */ | |
934 signal_image_error_2 ("Error decoding PNG", | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
935 build_extstring (png_err_stct.err_str, |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
936 Qerror_message_encoding), |
3839 | 937 instantiator); |
938 } | |
939 | |
428 | 940 /* Initialize all PNG structures */ |
3839 | 941 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, |
942 (void *) &png_err_stct, | |
428 | 943 png_error_func, png_warning_func); |
944 if (!png_ptr) | |
945 signal_image_error ("Error obtaining memory for png_read", instantiator); | |
3839 | 946 unwind.png_ptr = png_ptr; |
947 | |
428 | 948 info_ptr = png_create_info_struct (png_ptr); |
949 if (!info_ptr) | |
950 { | |
3839 | 951 unwind.png_ptr = NULL; /* avoid re-calling png_destroy_read_struct |
952 when unwinding */ | |
428 | 953 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); |
954 signal_image_error ("Error obtaining memory for png_read", instantiator); | |
955 } | |
956 unwind.info_ptr = info_ptr; | |
957 | |
958 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from | |
959 this file, example.c from the libpng 0.81 distribution, and the | |
960 pngtopnm sources. -WMP- | |
961 */ | |
962 /* It has been further modified to handle the API changes for 0.96, | |
963 and is no longer usable for previous versions. jh | |
964 */ | |
965 | |
966 /* Initialize the IO layer and read in header information */ | |
967 { | |
968 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 969 const Binbyte *bytes; |
665 | 970 Bytecount len; |
428 | 971 |
972 assert (!NILP (data)); | |
973 | |
974 /* #### This is a definite problem under Mule due to the amount of | |
975 stack data it might allocate. Need to think about using Lstreams */ | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
976 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 977 tbr.bytes = bytes; |
978 tbr.len = len; | |
979 tbr.index = 0; | |
980 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory); | |
981 } | |
982 | |
983 png_read_info (png_ptr, info_ptr); | |
984 | |
985 { | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
986 int y, padding; |
2367 | 987 Binbyte **row_pointers; |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
988 UINT_64_BIT pixels_sq; |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
989 height = png_get_image_height (png_ptr, info_ptr); |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
990 width = png_get_image_width (png_ptr, info_ptr); |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
991 pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height; |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
992 if (pixels_sq > ((size_t) -1) / 3) |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
993 signal_image_error ("PNG image too large to instantiate", instantiator); |
428 | 994 |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
995 /* Wow, allocate all the memory. Truly, exciting. |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
996 Well, yes, there's excitement to be had. It turns out that libpng |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
997 strips in place, so the last row overruns the buffer if depth is 16 |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
998 or there's an alpha channel. This is a crash on Linux. So we need |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
999 to add padding. |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1000 The worst case is reducing 8 bytes (16-bit RGBA) to 3 (8-bit RGB). */ |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1001 |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1002 padding = 5 * width; |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1003 unwind.eimage = xnew_array_and_zero (Binbyte, |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1004 (size_t) (pixels_sq * 3 + padding)); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1005 |
428 | 1006 /* libpng expects that the image buffer passed in contains a |
1007 picture to draw on top of if the png has any transparencies. | |
1008 This could be a good place to pass that in... */ | |
1009 | |
1010 row_pointers = xnew_array (png_byte *, height); | |
1011 for (y = 0; y < height; y++) | |
1012 row_pointers[y] = unwind.eimage + (width * 3 * y); | |
1013 | |
1014 { | |
1015 /* if the png specifies a background chunk, go ahead and | |
1016 use it, else use what we can get from the default face. */ | |
1017 png_color_16 my_background, *image_background; | |
1018 Lisp_Object bkgd = Qnil; | |
1019 | |
1020 my_background.red = 0x7fff; | |
1021 my_background.green = 0x7fff; | |
1022 my_background.blue = 0x7fff; | |
1023 bkgd = FACE_BACKGROUND (Vdefault_face, domain); | |
1024 if (!COLOR_INSTANCEP (bkgd)) | |
1025 { | |
1026 warn_when_safe (Qpng, Qinfo, "Couldn't get background color!"); | |
1027 } | |
1028 else | |
1029 { | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1030 Lisp_Color_Instance *c = XCOLOR_INSTANCE (bkgd); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1031 Lisp_Object rgb = MAYBE_LISP_DEVMETH (XDEVICE (c->device), |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1032 color_instance_rgb_components, |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1033 (c)); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5537
diff
changeset
|
1034 #define GETCOLOR(col) my_background.col = (unsigned short) XFIXNUM (XCAR (rgb)) |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1035 GETCOLOR(red); rgb = XCDR (rgb); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1036 GETCOLOR(green); rgb = XCDR (rgb); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1037 GETCOLOR(blue); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1038 #undef GETCOLOR |
428 | 1039 } |
1040 | |
1041 if (png_get_bKGD (png_ptr, info_ptr, &image_background)) | |
1042 png_set_background (png_ptr, image_background, | |
1043 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); | |
1044 else | |
1045 png_set_background (png_ptr, &my_background, | |
1046 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); | |
1047 } | |
1048 | |
1049 /* Now that we're using EImage, ask for 8bit RGB triples for any type | |
1050 of image*/ | |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1051 switch (png_get_color_type (png_ptr, info_ptr)) |
428 | 1052 { |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1053 case PNG_COLOR_TYPE_PALETTE: |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1054 /* convert palette images to RGB */ |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1055 png_set_palette_to_rgb (png_ptr); |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1056 break; |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1057 |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1058 case PNG_COLOR_TYPE_GRAY: |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1059 case PNG_COLOR_TYPE_GRAY_ALPHA: |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1060 /* convert grayscale images to RGB */ |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1061 png_set_gray_to_rgb (png_ptr); |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1062 break; |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1063 |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1064 default: |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1065 /* pad images with depth < 8 bits */ |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1066 if (png_get_bit_depth (png_ptr, info_ptr) < 8) |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1067 { |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1068 png_set_packing (png_ptr); |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1069 } |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1070 break; |
428 | 1071 } |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1072 |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1073 /* strip 16-bit depth files down to 8 bits */ |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1074 if (png_get_bit_depth (png_ptr, info_ptr) == 16) |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1075 png_set_strip_16 (png_ptr); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1076 /* strip alpha channel |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1077 #### shouldn't we handle this? |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1078 first call png_read_update_info in case above transformations |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1079 have generated an alpha channel */ |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1080 png_read_update_info(png_ptr, info_ptr); |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1081 if (png_get_color_type (png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1082 png_set_strip_alpha (png_ptr); |
428 | 1083 |
1084 png_read_image (png_ptr, row_pointers); | |
1085 png_read_end (png_ptr, info_ptr); | |
1086 | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1087 /* #### There should be some way to pass this type of data down |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1088 * into the glyph code, where you can get to it from lisp |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1089 * anyway. - WMP */ |
428 | 1090 { |
5537
2df2d9171f20
Suppress a "shadowed local" warning.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5536
diff
changeset
|
1091 int i, num_text = 0; |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1092 png_textp text_ptr = NULL; |
3734 | 1093 DECLARE_EISTRING (key); |
1094 DECLARE_EISTRING (text); | |
428 | 1095 |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1096 if (png_get_text (png_ptr, info_ptr, &text_ptr, &num_text) > 0) |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1097 { |
5537
2df2d9171f20
Suppress a "shadowed local" warning.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5536
diff
changeset
|
1098 for (i = 0 ; i < num_text; i++) |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1099 { |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1100 eireset (key); |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1101 eireset (text); |
428 | 1102 |
5537
2df2d9171f20
Suppress a "shadowed local" warning.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5536
diff
changeset
|
1103 eicpy_ext (key, text_ptr[i].key, Qbinary); |
2df2d9171f20
Suppress a "shadowed local" warning.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5536
diff
changeset
|
1104 eicpy_ext (text, text_ptr[i].text, Qbinary); |
5372
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1105 |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1106 warn_when_safe (Qpng, Qinfo, "%s - %s", eidata (key), |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1107 eidata (text)); |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1108 } |
6c3a695f54f5
Update png_instantiate () to work with more recent versions of libpng.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5250
diff
changeset
|
1109 } |
428 | 1110 } |
1111 | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
1112 xfree (row_pointers); |
428 | 1113 } |
1114 | |
1115 /* now instantiate */ | |
442 | 1116 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 1117 init_image_instance_from_eimage, |
1118 (ii, width, height, 1, unwind.eimage, dest_mask, | |
2959 | 1119 instantiator, pointer_fg, pointer_bg, domain)); |
428 | 1120 |
1121 /* This will clean up everything else. */ | |
771 | 1122 unbind_to (speccount); |
428 | 1123 } |
1124 | |
1125 #endif /* HAVE_PNG */ | |
1126 | |
1127 | |
1128 #ifdef HAVE_TIFF | |
1129 #include "tiffio.h" | |
1130 | |
1131 /********************************************************************** | |
1132 * TIFF * | |
1133 **********************************************************************/ | |
1134 static void | |
1135 tiff_validate (Lisp_Object instantiator) | |
1136 { | |
1137 file_or_data_must_be_present (instantiator); | |
1138 } | |
1139 | |
1140 static Lisp_Object | |
442 | 1141 tiff_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 1142 Lisp_Object UNUSED (dest_mask)) |
428 | 1143 { |
1144 return simple_image_type_normalize (inst, console_type, Qtiff); | |
1145 } | |
1146 | |
1147 static int | |
1148 tiff_possible_dest_types (void) | |
1149 { | |
1150 return IMAGE_COLOR_PIXMAP_MASK; | |
1151 } | |
1152 | |
1153 struct tiff_unwind_data | |
1154 { | |
2367 | 1155 Binbyte *eimage; |
428 | 1156 /* Object that holds the decoded data from a TIFF file */ |
1157 TIFF *tiff; | |
1158 }; | |
1159 | |
1160 static Lisp_Object | |
1161 tiff_instantiate_unwind (Lisp_Object unwind_obj) | |
1162 { | |
1163 struct tiff_unwind_data *data = | |
1164 (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj); | |
1165 | |
1166 free_opaque_ptr (unwind_obj); | |
1167 if (data->tiff) | |
1168 { | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
1169 TIFFClose (data->tiff); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
1170 data->tiff = 0; |
428 | 1171 } |
1172 if (data->eimage) | |
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
1173 { |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
1174 xfree (data->eimage); |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
1175 data->eimage = 0; |
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5024
diff
changeset
|
1176 } |
428 | 1177 |
1178 return Qnil; | |
1179 } | |
1180 | |
1181 typedef struct tiff_memory_storage | |
1182 { | |
2367 | 1183 Binbyte *bytes; /* The data */ |
665 | 1184 Bytecount len; /* How big is it? */ |
1185 Bytecount index; /* Where are we? */ | |
428 | 1186 } tiff_memory_storage; |
1187 | |
1188 static size_t | |
647 | 1189 tiff_memory_read (thandle_t data, tdata_t buf, tsize_t size) |
428 | 1190 { |
647 | 1191 tiff_memory_storage *mem = (tiff_memory_storage *) data; |
428 | 1192 |
665 | 1193 if ((Bytecount) size > (mem->len - mem->index)) |
428 | 1194 return (size_t) -1; |
647 | 1195 memcpy (buf, mem->bytes + mem->index, size); |
428 | 1196 mem->index = mem->index + size; |
1197 return size; | |
1198 } | |
1199 | |
647 | 1200 static size_t |
2286 | 1201 tiff_memory_write (thandle_t UNUSED (data), tdata_t UNUSED (buf), |
1202 tsize_t UNUSED (size)) | |
428 | 1203 { |
2500 | 1204 ABORT(); |
2270 | 1205 return 0; |
428 | 1206 } |
1207 | |
647 | 1208 static toff_t |
1209 tiff_memory_seek (thandle_t data, toff_t off, int whence) | |
428 | 1210 { |
647 | 1211 tiff_memory_storage *mem = (tiff_memory_storage *) data; |
428 | 1212 int newidx; |
647 | 1213 switch(whence) |
1214 { | |
1215 case SEEK_SET: | |
1216 newidx = off; | |
1217 break; | |
1218 case SEEK_END: | |
1219 newidx = mem->len + off; | |
1220 break; | |
1221 case SEEK_CUR: | |
1222 newidx = mem->index + off; | |
1223 break; | |
1224 default: | |
1225 fprintf (stderr, "Eh? invalid seek mode in tiff_memory_seek\n"); | |
1226 return (toff_t) -1; | |
1227 } | |
428 | 1228 |
1229 if ((newidx > mem->len) || (newidx < 0)) | |
593 | 1230 return (toff_t) -1; |
428 | 1231 |
1232 mem->index = newidx; | |
1233 return newidx; | |
1234 } | |
1235 | |
1236 static int | |
2286 | 1237 tiff_memory_close (thandle_t UNUSED (data)) |
428 | 1238 { |
1239 return 0; | |
1240 } | |
1241 | |
1242 static int | |
2286 | 1243 tiff_map_noop (thandle_t UNUSED (data), tdata_t* UNUSED (pbase), |
1244 toff_t* UNUSED (psize)) | |
428 | 1245 { |
1246 return 0; | |
1247 } | |
1248 | |
1249 static void | |
2286 | 1250 tiff_unmap_noop (thandle_t UNUSED (data), tdata_t UNUSED (pbase), |
1251 toff_t UNUSED (psize)) | |
428 | 1252 { |
1253 return; | |
1254 } | |
1255 | |
1256 static toff_t | |
647 | 1257 tiff_memory_size (thandle_t data) |
428 | 1258 { |
1259 tiff_memory_storage *mem = (tiff_memory_storage*)data; | |
1260 return mem->len; | |
1261 } | |
1262 | |
1263 struct tiff_error_struct | |
1264 { | |
438 | 1265 #ifdef HAVE_VSNPRINTF |
428 | 1266 char err_str[256]; |
1267 #else | |
1268 char err_str[1024]; /* return the error string */ | |
1269 #endif | |
1270 jmp_buf setjmp_buffer; /* for return to caller */ | |
1271 }; | |
1272 | |
1273 /* jh 98/03/12 - ###This struct for passing data to the error functions | |
1274 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't | |
1275 have any place to store error func data. This should be rectified | |
1276 before XEmacs gets threads! */ | |
1277 static struct tiff_error_struct tiff_err_data; | |
1278 | |
1279 static void | |
2286 | 1280 tiff_error_func (const char *UNUSED (module), const char *fmt, ...) |
428 | 1281 { |
1282 va_list vargs; | |
1283 | |
1284 va_start (vargs, fmt); | |
438 | 1285 #ifdef HAVE_VSNPRINTF |
428 | 1286 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs); |
1287 #else | |
1288 /* pray this doesn't overflow... */ | |
1289 vsprintf (tiff_err_data.err_str, fmt, vargs); | |
1290 #endif | |
1291 va_end (vargs); | |
1292 /* return to setjmp point */ | |
1293 longjmp (tiff_err_data.setjmp_buffer, 1); | |
1294 } | |
1295 | |
1296 static void | |
647 | 1297 tiff_warning_func (const char *module, const char *fmt, ...) |
428 | 1298 { |
1299 va_list vargs; | |
438 | 1300 #ifdef HAVE_VSNPRINTF |
428 | 1301 char warn_str[256]; |
1302 #else | |
1303 char warn_str[1024]; | |
1304 #endif | |
3734 | 1305 DECLARE_EISTRING (eimodule); |
1306 DECLARE_EISTRING (eiwarnstr); | |
428 | 1307 |
1308 va_start (vargs, fmt); | |
438 | 1309 #ifdef HAVE_VSNPRINTF |
428 | 1310 vsnprintf (warn_str, 255, fmt, vargs); |
1311 #else | |
1312 vsprintf (warn_str, fmt, vargs); | |
1313 #endif | |
1314 va_end (vargs); | |
3734 | 1315 |
1316 eicpy_ext(eimodule, module, Qbinary); | |
1317 eicpy_ext(eiwarnstr, warn_str, Qbinary); | |
1318 | |
428 | 1319 warn_when_safe (Qtiff, Qinfo, "%s - %s", |
3734 | 1320 eidata(eimodule), |
1321 eidata(eiwarnstr)); | |
428 | 1322 } |
1323 | |
1324 static void | |
1325 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 1326 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 1327 int dest_mask, Lisp_Object domain) |
1328 { | |
440 | 1329 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1330 tiff_memory_storage mem_struct; |
1331 /* It is OK for the unwind data to be local to this function, | |
1332 because the unwind-protect is always executed when this | |
1333 stack frame is still valid. */ | |
1334 struct tiff_unwind_data unwind; | |
1335 int speccount = specpdl_depth (); | |
1336 uint32 width, height; | |
1337 | |
1338 xzero (unwind); | |
1339 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind)); | |
1340 | |
1341 /* set up error facilities */ | |
1342 if (setjmp (tiff_err_data.setjmp_buffer)) | |
1343 { | |
1344 /* An error was signaled. No clean up is needed, as unwind handles that | |
1345 for us. Just pass the error along. */ | |
1346 signal_image_error_2 ("TIFF decoding error", | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1347 build_extstring (tiff_err_data.err_str, |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
1348 Qerror_message_encoding), |
428 | 1349 instantiator); |
1350 } | |
1351 TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func); | |
1352 TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func); | |
1353 { | |
1354 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 1355 Binbyte *bytes; |
665 | 1356 Bytecount len; |
428 | 1357 |
1358 uint32 *raster; | |
2367 | 1359 Binbyte *ep; |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
1360 UINT_64_BIT pixels_sq; |
428 | 1361 |
1362 assert (!NILP (data)); | |
1363 | |
1364 /* #### This is a definite problem under Mule due to the amount of | |
1365 stack data it might allocate. Think about Lstreams... */ | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
1366 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 1367 mem_struct.bytes = bytes; |
1368 mem_struct.len = len; | |
1369 mem_struct.index = 0; | |
1370 | |
442 | 1371 unwind.tiff = TIFFClientOpen ("memfile", "r", (thandle_t) &mem_struct, |
428 | 1372 (TIFFReadWriteProc)tiff_memory_read, |
1373 (TIFFReadWriteProc)tiff_memory_write, | |
1374 tiff_memory_seek, tiff_memory_close, tiff_memory_size, | |
1375 tiff_map_noop, tiff_unmap_noop); | |
1376 if (!unwind.tiff) | |
440 | 1377 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator); |
428 | 1378 |
1379 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); | |
1380 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
1381 pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height; |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
1382 if (pixels_sq >= 1 << 29) |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
1383 signal_image_error ("TIFF image too large to instantiate", instantiator); |
4682
648f4a0dac3e
Fix build problems on WIN32 platforms caused by the large image crash fix.
Jerry James <james@xemacs.org>
parents:
4646
diff
changeset
|
1384 unwind.eimage = xnew_binbytes ((size_t) pixels_sq * 3); |
428 | 1385 |
440 | 1386 /* #### This is little more than proof-of-concept/function testing. |
428 | 1387 It needs to be reimplemented via scanline reads for both memory |
1388 compactness. */ | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
1389 raster = (uint32*) _TIFFmalloc ((tsize_t) (pixels_sq * sizeof (uint32))); |
428 | 1390 if (raster != NULL) |
1391 { | |
647 | 1392 int i, j; |
428 | 1393 uint32 *rp; |
1394 ep = unwind.eimage; | |
1395 rp = raster; | |
1396 if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0)) | |
1397 { | |
1398 for (i = height - 1; i >= 0; i--) | |
1399 { | |
1400 /* This is to get around weirdness in the libtiff library where properly | |
1401 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */ | |
1402 rp = raster + (i * width); | |
647 | 1403 for (j = 0; j < (int) width; j++) |
428 | 1404 { |
2367 | 1405 *ep++ = (Binbyte)TIFFGetR(*rp); |
1406 *ep++ = (Binbyte)TIFFGetG(*rp); | |
1407 *ep++ = (Binbyte)TIFFGetB(*rp); | |
428 | 1408 rp++; |
1409 } | |
1410 } | |
1411 } | |
1412 _TIFFfree (raster); | |
1413 } else | |
1414 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator); | |
1415 | |
1416 } | |
1417 | |
1418 /* now instantiate */ | |
442 | 1419 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 1420 init_image_instance_from_eimage, |
1421 (ii, width, height, 1, unwind.eimage, dest_mask, | |
2959 | 1422 instantiator, pointer_fg, pointer_bg, domain)); |
428 | 1423 |
771 | 1424 unbind_to (speccount); |
428 | 1425 } |
1426 | |
1427 #endif /* HAVE_TIFF */ | |
1428 | |
1429 | |
1430 /************************************************************************/ | |
1431 /* initialization */ | |
1432 /************************************************************************/ | |
1433 | |
1434 void | |
1435 syms_of_glyphs_eimage (void) | |
1436 { | |
1437 } | |
1438 | |
1439 void | |
1440 image_instantiator_format_create_glyphs_eimage (void) | |
1441 { | |
1442 /* image-instantiator types */ | |
1443 #ifdef HAVE_JPEG | |
1444 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg"); | |
1445 | |
1446 IIFORMAT_HAS_METHOD (jpeg, validate); | |
1447 IIFORMAT_HAS_METHOD (jpeg, normalize); | |
1448 IIFORMAT_HAS_METHOD (jpeg, possible_dest_types); | |
1449 IIFORMAT_HAS_METHOD (jpeg, instantiate); | |
1450 | |
1451 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string); | |
1452 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string); | |
1453 #endif | |
1454 | |
1455 #ifdef HAVE_GIF | |
1456 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif"); | |
1457 | |
1458 IIFORMAT_HAS_METHOD (gif, validate); | |
1459 IIFORMAT_HAS_METHOD (gif, normalize); | |
1460 IIFORMAT_HAS_METHOD (gif, possible_dest_types); | |
1461 IIFORMAT_HAS_METHOD (gif, instantiate); | |
1462 | |
1463 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string); | |
1464 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string); | |
1465 #endif | |
1466 | |
1467 #ifdef HAVE_PNG | |
1468 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png"); | |
1469 | |
1470 IIFORMAT_HAS_METHOD (png, validate); | |
1471 IIFORMAT_HAS_METHOD (png, normalize); | |
1472 IIFORMAT_HAS_METHOD (png, possible_dest_types); | |
1473 IIFORMAT_HAS_METHOD (png, instantiate); | |
1474 | |
1475 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string); | |
1476 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string); | |
1477 #endif | |
1478 | |
1479 #ifdef HAVE_TIFF | |
1480 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff"); | |
1481 | |
1482 IIFORMAT_HAS_METHOD (tiff, validate); | |
1483 IIFORMAT_HAS_METHOD (tiff, normalize); | |
1484 IIFORMAT_HAS_METHOD (tiff, possible_dest_types); | |
1485 IIFORMAT_HAS_METHOD (tiff, instantiate); | |
1486 | |
1487 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string); | |
1488 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string); | |
1489 #endif | |
1490 | |
1491 } | |
1492 | |
1493 void | |
1494 vars_of_glyphs_eimage (void) | |
1495 { | |
1496 #ifdef HAVE_JPEG | |
1497 Fprovide (Qjpeg); | |
1498 #endif | |
1499 | |
1500 #ifdef HAVE_GIF | |
1501 Fprovide (Qgif); | |
1502 #endif | |
1503 | |
1504 #ifdef HAVE_PNG | |
1505 Fprovide (Qpng); | |
1506 #endif | |
1507 | |
1508 #ifdef HAVE_TIFF | |
1509 Fprovide (Qtiff); | |
1510 #endif | |
1511 | |
1512 } |