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