Mercurial > hg > xemacs-beta
annotate src/glyphs-eimage.c @ 4981:4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
-------------------- ChangeLog entries follow: --------------------
modules/ChangeLog addition:
2010-02-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
* postgresql/postgresql.c (CHECK_LIVE_CONNECTION):
* postgresql/postgresql.c (Fpq_connectdb):
* postgresql/postgresql.c (Fpq_connect_start):
* postgresql/postgresql.c (Fpq_lo_import):
* postgresql/postgresql.c (Fpq_lo_export):
* ldap/eldap.c (Fldap_open):
* ldap/eldap.c (Fldap_search_basic):
* ldap/eldap.c (Fldap_add):
* ldap/eldap.c (Fldap_modify):
* ldap/eldap.c (Fldap_delete):
* canna/canna_api.c (Fcanna_initialize):
* canna/canna_api.c (Fcanna_store_yomi):
* canna/canna_api.c (Fcanna_parse):
* canna/canna_api.c (Fcanna_henkan_begin):
EXTERNAL_TO_C_STRING returns its argument instead of storing it
in a parameter, and is renamed to EXTERNAL_TO_ITEXT. Similar
things happen to related macros. See entry in src/ChangeLog.
More Mule-izing of postgresql.c. Extract out common code
between `pq-connectdb' and `pq-connect-start'. Fix places
that signal an error string using a formatted string to instead
follow the standard and have a fixed reason followed by the
particular error message stored as one of the frobs.
src/ChangeLog addition:
2010-02-05 Ben Wing <ben@xemacs.org>
* console-msw.c (write_string_to_mswindows_debugging_output):
* console-msw.c (Fmswindows_message_box):
* console-x.c (x_perhaps_init_unseen_key_defaults):
* console.c:
* database.c (dbm_get):
* database.c (dbm_put):
* database.c (dbm_remove):
* database.c (berkdb_get):
* database.c (berkdb_put):
* database.c (berkdb_remove):
* database.c (Fopen_database):
* device-gtk.c (gtk_init_device):
* device-msw.c (msprinter_init_device_internal):
* device-msw.c (msprinter_default_printer):
* device-msw.c (msprinter_init_device):
* device-msw.c (sync_printer_with_devmode):
* device-msw.c (Fmsprinter_select_settings):
* device-x.c (sanity_check_geometry_resource):
* device-x.c (Dynarr_add_validified_lisp_string):
* device-x.c (x_init_device):
* device-x.c (Fx_put_resource):
* device-x.c (Fx_valid_keysym_name_p):
* device-x.c (Fx_set_font_path):
* dialog-msw.c (push_lisp_string_as_unicode):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-msw.c (handle_file_dialog_box):
* dialog-x.c (dbox_descriptor_to_widget_value):
* editfns.c (Fformat_time_string):
* editfns.c (Fencode_time):
* editfns.c (Fset_time_zone_rule):
* emacs.c (make_argc_argv):
* emacs.c (Fdump_emacs):
* emodules.c (emodules_load):
* eval.c:
* eval.c (maybe_signal_error_1):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (mswindows_wnd_proc):
* fileio.c (report_error_with_errno):
* fileio.c (Fsysnetunam):
* fileio.c (Fdo_auto_save):
* font-mgr.c (extract_fcapi_string):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_filename):
* frame-gtk.c (gtk_set_frame_text_value):
* frame-gtk.c (gtk_create_widgets):
* frame-msw.c (mswindows_init_frame_1):
* frame-msw.c (mswindows_set_title_from_ibyte):
* frame-msw.c (msprinter_init_frame_3):
* frame-x.c (x_set_frame_text_value):
* frame-x.c (x_set_frame_properties):
* frame-x.c (start_drag_internal_1):
* frame-x.c (x_cde_transfer_callback):
* frame-x.c (x_create_widgets):
* glyphs-eimage.c (my_jpeg_output_message):
* glyphs-eimage.c (jpeg_instantiate):
* glyphs-eimage.c (gif_instantiate):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate):
* glyphs-gtk.c (xbm_instantiate_1):
* glyphs-gtk.c (gtk_xbm_instantiate):
* glyphs-gtk.c (gtk_xpm_instantiate):
* glyphs-gtk.c (gtk_xface_instantiate):
* glyphs-gtk.c (cursor_font_instantiate):
* glyphs-gtk.c (gtk_redisplay_widget):
* glyphs-gtk.c (gtk_widget_instantiate_1):
* glyphs-gtk.c (gtk_add_tab_item):
* glyphs-msw.c (mswindows_xpm_instantiate):
* glyphs-msw.c (bmp_instantiate):
* glyphs-msw.c (mswindows_resource_instantiate):
* glyphs-msw.c (xbm_instantiate_1):
* glyphs-msw.c (mswindows_xbm_instantiate):
* glyphs-msw.c (mswindows_xface_instantiate):
* glyphs-msw.c (mswindows_redisplay_widget):
* glyphs-msw.c (mswindows_widget_instantiate):
* glyphs-msw.c (add_tree_item):
* glyphs-msw.c (add_tab_item):
* glyphs-msw.c (mswindows_combo_box_instantiate):
* glyphs-msw.c (mswindows_widget_query_string_geometry):
* glyphs-x.c (x_locate_pixmap_file):
* glyphs-x.c (xbm_instantiate_1):
* glyphs-x.c (x_xbm_instantiate):
* glyphs-x.c (extract_xpm_color_names):
* glyphs-x.c (x_xpm_instantiate):
* glyphs-x.c (x_xface_instantiate):
* glyphs-x.c (autodetect_instantiate):
* glyphs-x.c (safe_XLoadFont):
* glyphs-x.c (cursor_font_instantiate):
* glyphs-x.c (x_redisplay_widget):
* glyphs-x.c (Fchange_subwindow_property):
* glyphs-x.c (x_widget_instantiate):
* glyphs-x.c (x_tab_control_redisplay):
* glyphs.c (pixmap_to_lisp_data):
* gui-x.c (menu_separator_style_and_to_external):
* gui-x.c (add_accel_and_to_external):
* gui-x.c (button_item_to_widget_value):
* hpplay.c (player_error_internal):
* hpplay.c (play_sound_file):
* hpplay.c (play_sound_data):
* intl.c (Fset_current_locale):
* lisp.h:
* menubar-gtk.c (gtk_xemacs_set_accel_keys):
* menubar-msw.c (populate_menu_add_item):
* menubar-msw.c (populate_or_checksum_helper):
* menubar-x.c (menu_item_descriptor_to_widget_value_1):
* nt.c (init_user_info):
* nt.c (get_long_basename):
* nt.c (nt_get_resource):
* nt.c (init_mswindows_environment):
* nt.c (get_cached_volume_information):
* nt.c (mswindows_readdir):
* nt.c (read_unc_volume):
* nt.c (mswindows_stat):
* nt.c (mswindows_getdcwd):
* nt.c (mswindows_executable_type):
* nt.c (Fmswindows_short_file_name):
* ntplay.c (nt_play_sound_file):
* objects-gtk.c:
* objects-gtk.c (gtk_valid_color_name_p):
* objects-gtk.c (gtk_initialize_font_instance):
* objects-gtk.c (gtk_font_list):
* objects-msw.c (font_enum_callback_2):
* objects-msw.c (parse_font_spec):
* objects-x.c (x_parse_nearest_color):
* objects-x.c (x_valid_color_name_p):
* objects-x.c (x_initialize_font_instance):
* objects-x.c (x_font_instance_truename):
* objects-x.c (x_font_list):
* objects-xlike-inc.c (XFUN):
* objects-xlike-inc.c (xft_find_charset_font):
* process-nt.c (mswindows_report_winsock_error):
* process-nt.c (nt_create_process):
* process-nt.c (get_internet_address):
* process-nt.c (nt_open_network_stream):
* process-unix.c:
* process-unix.c (allocate_pty):
* process-unix.c (get_internet_address):
* process-unix.c (unix_canonicalize_host_name):
* process-unix.c (unix_open_network_stream):
* realpath.c:
* select-common.h (lisp_data_to_selection_data):
* select-gtk.c (symbol_to_gtk_atom):
* select-gtk.c (atom_to_symbol):
* select-msw.c (symbol_to_ms_cf):
* select-msw.c (mswindows_register_selection_data_type):
* select-x.c (symbol_to_x_atom):
* select-x.c (x_atom_to_symbol):
* select-x.c (hack_motif_clipboard_selection):
* select-x.c (Fx_store_cutbuffer_internal):
* sound.c (Fplay_sound_file):
* sound.c (Fplay_sound):
* sound.h (sound_perror):
* sysdep.c:
* sysdep.c (qxe_allocating_getcwd):
* sysdep.c (qxe_execve):
* sysdep.c (copy_in_passwd):
* sysdep.c (qxe_getpwnam):
* sysdep.c (qxe_ctime):
* sysdll.c (dll_open):
* sysdll.c (dll_function):
* sysdll.c (dll_variable):
* sysdll.c (search_linked_libs):
* sysdll.c (dll_error):
* sysfile.h:
* sysfile.h (PATHNAME_CONVERT_OUT_TSTR):
* sysfile.h (PATHNAME_CONVERT_OUT_UTF_8):
* sysfile.h (PATHNAME_CONVERT_OUT):
* sysfile.h (LISP_PATHNAME_CONVERT_OUT):
* syswindows.h (ITEXT_TO_TSTR):
* syswindows.h (LOCAL_FILE_FORMAT_TO_TSTR):
* syswindows.h (TSTR_TO_LOCAL_FILE_FORMAT):
* syswindows.h (LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN):
* syswindows.h (LISP_LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR):
* text.h:
* text.h (eicpy_ext_len):
* text.h (enum new_dfc_src_type):
* text.h (EXTERNAL_TO_ITEXT):
* text.h (GET_STRERROR):
* tooltalk.c (check_status):
* tooltalk.c (Fadd_tooltalk_message_arg):
* tooltalk.c (Fadd_tooltalk_pattern_attribute):
* tooltalk.c (Fadd_tooltalk_pattern_arg):
* win32.c (tstr_to_local_file_format):
* win32.c (mswindows_lisp_error_1):
* win32.c (mswindows_report_process_error):
* win32.c (Fmswindows_shell_execute):
* win32.c (mswindows_read_link_1):
Changes involving external/internal format conversion,
mostly code cleanup and renaming.
1. Eliminate the previous macros like LISP_STRING_TO_EXTERNAL
that stored its result in a parameter. The new version of
LISP_STRING_TO_EXTERNAL returns its result through the
return value, same as the previous NEW_LISP_STRING_TO_EXTERNAL.
Use the new-style macros throughout the code.
2. Rename C_STRING_TO_EXTERNAL and friends to ITEXT_TO_EXTERNAL,
in keeping with overall naming rationalization involving
Itext and related types.
Macros involved in previous two:
EXTERNAL_TO_C_STRING -> EXTERNAL_TO_ITEXT
EXTERNAL_TO_C_STRING_MALLOC -> EXTERNAL_TO_ITEXT_MALLOC
SIZED_EXTERNAL_TO_C_STRING -> SIZED_EXTERNAL_TO_ITEXT
SIZED_EXTERNAL_TO_C_STRING_MALLOC -> SIZED_EXTERNAL_TO_ITEXT_MALLOC
C_STRING_TO_EXTERNAL -> ITEXT_TO_EXTERNAL
C_STRING_TO_EXTERNAL_MALLOC -> ITEXT_TO_EXTERNAL_MALLOC
LISP_STRING_TO_EXTERNAL
LISP_STRING_TO_EXTERNAL_MALLOC
LISP_STRING_TO_TSTR
C_STRING_TO_TSTR -> ITEXT_TO_TSTR
TSTR_TO_C_STRING -> TSTR_TO_ITEXT
The following four still return their values through parameters,
since they have more than one value to return:
C_STRING_TO_SIZED_EXTERNAL -> ITEXT_TO_SIZED_EXTERNAL
LISP_STRING_TO_SIZED_EXTERNAL
C_STRING_TO_SIZED_EXTERNAL_MALLOC -> ITEXT_TO_SIZED_EXTERNAL_MALLOC
LISP_STRING_TO_SIZED_EXTERNAL_MALLOC
Sometimes additional casts had to be inserted, since the old
macros played strange games and completely defeated the type system
of the store params.
3. Rewrite many places where direct calls to TO_EXTERNAL_FORMAT
occurred with calls to one of the convenience macros listed above,
or to make_extstring().
4. Eliminate SIZED_C_STRING macros (they were hardly used, anyway)
and use a direct call to TO_EXTERNAL_FORMAT or TO_INTERNAL_FORMAT.
4. Use LISP_PATHNAME_CONVERT_OUT in many places instead of something
like LISP_STRING_TO_EXTERNAL(..., Qfile_name).
5. Eliminate some temporary variables that are no longer necessary
now that we return a value rather than storing it into a variable.
6. Some Mule-izing in database.c.
7. Error functions:
-- A bit of code cleanup in maybe_signal_error_1.
-- Eliminate report_file_type_error; it's just an alias for
signal_error_2 with params in a different order.
-- Fix some places in the hostname-handling code that directly
inserted externally-retrieved error strings into the
supposed ASCII "reason" param instead of doing the right thing
and sticking text descriptive of what was going on in "reason"
and putting the external message in a frob.
8. Use Ascbyte instead of CIbyte in process-unix.c and maybe one
or two other places.
9. Some code cleanup in copy_in_passwd() in sysdep.c.
10. Fix a real bug due to accidental variable shadowing in
tstr_to_local_file_format() in win32.c.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Feb 2010 11:02:24 -0600 |
parents | 304aebb79cd3 |
children | 3c3c1d139863 |
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 | |
2959 | 5 Copyright (C) 1995, 1996, 2001, 2002, 2004, 2005 Ben Wing |
428 | 6 Copyright (C) 1995 Sun Microsystems |
7 | |
8 This file is part of XEmacs. | |
9 | |
10 XEmacs is free software; you can redistribute it and/or modify it | |
11 under the terms of the GNU General Public License as published by the | |
12 Free Software Foundation; either version 2, or (at your option) any | |
13 later version. | |
14 | |
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with XEmacs; see the file COPYING. If not, write to | |
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
23 Boston, MA 02111-1307, USA. */ | |
24 | |
25 /* Synched up with: Not in FSF. */ | |
26 | |
2959 | 27 /* Originally part of glyphs.c. |
28 | |
428 | 29 GIF/JPEG support added by Ben Wing for 19.14 |
30 PNG support added by Bill Perry for 19.14 | |
31 Improved GIF/JPEG support added by Bill Perry for 19.14 | |
32 Cleanup/simplification of error handling by Ben Wing for 19.14 | |
33 GIF support changed to external Gifreader lib by Jareth Hein for 21.0 | |
34 Many changes for color work and optimizations by Jareth Hein for 21.0 | |
35 Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0 | |
36 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
|
37 GIF support changed to external giflib by Jerry James for 21.5 |
428 | 38 TODO: |
39 Convert images.el to C and stick it in here? | |
3094 | 40 This file is really repetitious; can we refactor? |
428 | 41 */ |
42 | |
43 #include <config.h> | |
44 #include "lisp.h" | |
45 #include "lstream.h" | |
46 #include "console.h" | |
872 | 47 #include "device-impl.h" |
428 | 48 #include "faces.h" |
49 #include "glyphs.h" | |
872 | 50 #include "objects-impl.h" |
428 | 51 |
52 #include "buffer.h" | |
53 #include "frame.h" | |
54 #include "opaque.h" | |
442 | 55 #include "window.h" |
428 | 56 |
57 #include "sysfile.h" | |
58 | |
59 #ifdef HAVE_PNG | |
1743 | 60 |
61 BEGIN_C_DECLS | |
62 | |
647 | 63 #define message message_ /* Yuck */ |
428 | 64 #include <png.h> |
647 | 65 #undef message |
1743 | 66 |
67 END_C_DECLS | |
68 | |
428 | 69 #else |
70 #include <setjmp.h> | |
71 #endif | |
72 #include "file-coding.h" | |
73 | |
74 #ifdef HAVE_TIFF | |
75 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff); | |
76 Lisp_Object Qtiff; | |
77 #endif | |
78 | |
79 #ifdef HAVE_JPEG | |
80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (jpeg); | |
81 Lisp_Object Qjpeg; | |
82 #endif | |
83 | |
84 #ifdef HAVE_GIF | |
85 DEFINE_IMAGE_INSTANTIATOR_FORMAT (gif); | |
86 Lisp_Object Qgif; | |
87 #endif | |
88 | |
89 #ifdef HAVE_PNG | |
90 DEFINE_IMAGE_INSTANTIATOR_FORMAT (png); | |
91 Lisp_Object Qpng; | |
92 #endif | |
93 | |
94 | |
95 #ifdef HAVE_JPEG | |
96 | |
97 /********************************************************************** | |
98 * JPEG * | |
99 **********************************************************************/ | |
100 | |
1743 | 101 BEGIN_C_DECLS |
102 | |
4854 | 103 #ifdef WIN32_ANY |
104 /* #### Yuck! More horrifitude. tiffio.h, below, and sysfile.h above, | |
105 include <windows.h>, which defines INT32 and INT16, the former | |
106 differently and incompatibly from jmorecfg.h, included by jpeglib.h. We | |
107 can disable the stuff in jmorecfg.h by defining XMD_H (clever, huh?); | |
108 then we define these typedefs the way that <windows.h> wants them (which | |
109 is more correct, anyway; jmorecfg.h defines INT32 as `long'). */ | |
2500 | 110 #define XMD_H |
111 typedef signed int INT32; | |
112 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
|
113 |
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 /* 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
|
115 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
|
116 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
|
117 #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
|
118 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
|
119 #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
|
120 #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ |
2500 | 121 #endif |
122 | |
428 | 123 #include <jpeglib.h> |
124 #include <jerror.h> | |
1743 | 125 |
126 END_C_DECLS | |
428 | 127 |
128 /*#define USE_TEMP_FILES_FOR_JPEG_IMAGES 1*/ | |
129 static void | |
130 jpeg_validate (Lisp_Object instantiator) | |
131 { | |
132 file_or_data_must_be_present (instantiator); | |
133 } | |
134 | |
135 static Lisp_Object | |
442 | 136 jpeg_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 137 Lisp_Object UNUSED (dest_mask)) |
428 | 138 { |
139 return simple_image_type_normalize (inst, console_type, Qjpeg); | |
140 } | |
141 | |
142 static int | |
143 jpeg_possible_dest_types (void) | |
144 { | |
145 return IMAGE_COLOR_PIXMAP_MASK; | |
146 } | |
147 | |
148 /* To survive the otherwise baffling complexity of making sure | |
149 everything gets cleaned up in the presence of an error, we | |
150 use an unwind_protect(). */ | |
151 | |
152 struct jpeg_unwind_data | |
153 { | |
154 /* Stream that we need to close */ | |
155 FILE *instream; | |
156 /* Object that holds state info for JPEG decoding */ | |
157 struct jpeg_decompress_struct *cinfo_ptr; | |
158 /* EImage data */ | |
2367 | 159 Binbyte *eimage; |
428 | 160 }; |
161 | |
162 static Lisp_Object | |
163 jpeg_instantiate_unwind (Lisp_Object unwind_obj) | |
164 { | |
165 struct jpeg_unwind_data *data = | |
166 (struct jpeg_unwind_data *) get_opaque_ptr (unwind_obj); | |
167 | |
168 free_opaque_ptr (unwind_obj); | |
169 if (data->cinfo_ptr) | |
170 jpeg_destroy_decompress (data->cinfo_ptr); | |
171 | |
172 if (data->instream) | |
771 | 173 retry_fclose (data->instream); |
428 | 174 |
1726 | 175 if (data->eimage) |
2367 | 176 xfree (data->eimage, Binbyte *); |
428 | 177 |
178 return Qnil; | |
179 } | |
180 | |
181 /* | |
182 * ERROR HANDLING: | |
183 * | |
184 * The JPEG library's standard error handler (jerror.c) is divided into | |
185 * several "methods" which you can override individually. This lets you | |
186 * adjust the behavior without duplicating a lot of code, which you might | |
187 * have to update with each future release. | |
188 * | |
189 * Our example here shows how to override the "error_exit" method so that | |
190 * control is returned to the library's caller when a fatal error occurs, | |
191 * rather than calling exit() as the standard error_exit method does. | |
192 * | |
193 * We use C's setjmp/longjmp facility to return control. This means that the | |
194 * routine which calls the JPEG library must first execute a setjmp() call to | |
195 * establish the return point. We want the replacement error_exit to do a | |
196 * longjmp(). But we need to make the setjmp buffer accessible to the | |
197 * error_exit routine. To do this, we make a private extension of the | |
198 * standard JPEG error handler object. (If we were using C++, we'd say we | |
199 * were making a subclass of the regular error handler.) | |
200 * | |
201 * Here's the extended error handler struct: | |
202 */ | |
203 | |
204 struct my_jpeg_error_mgr | |
205 { | |
206 struct jpeg_error_mgr pub; /* "public" fields */ | |
207 jmp_buf setjmp_buffer; /* for return to caller */ | |
208 }; | |
209 | |
210 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
211 METHODDEF(void) | |
212 #else | |
213 METHODDEF void | |
214 #endif | |
2286 | 215 our_init_source (j_decompress_ptr UNUSED (cinfo)) |
428 | 216 { |
217 } | |
218 | |
219 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
220 METHODDEF(boolean) | |
221 #else | |
222 METHODDEF boolean | |
223 #endif | |
224 our_fill_input_buffer (j_decompress_ptr cinfo) | |
225 { | |
226 /* Insert a fake EOI marker */ | |
227 struct jpeg_source_mgr *src = cinfo->src; | |
228 static JOCTET buffer[2]; | |
229 | |
230 buffer[0] = (JOCTET) 0xFF; | |
231 buffer[1] = (JOCTET) JPEG_EOI; | |
232 | |
233 src->next_input_byte = buffer; | |
234 src->bytes_in_buffer = 2; | |
235 return TRUE; | |
236 } | |
237 | |
238 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
239 METHODDEF(void) | |
240 #else | |
241 METHODDEF void | |
242 #endif | |
243 our_skip_input_data (j_decompress_ptr cinfo, long num_bytes) | |
244 { | |
245 struct jpeg_source_mgr *src = NULL; | |
246 | |
247 src = (struct jpeg_source_mgr *) cinfo->src; | |
248 | |
249 if (!src) | |
647 | 250 return; |
251 else if (num_bytes > (long) src->bytes_in_buffer) | |
428 | 252 { |
647 | 253 ERREXIT (cinfo, JERR_INPUT_EOF); |
254 /*NOTREACHED*/ | |
255 } | |
428 | 256 |
257 src->bytes_in_buffer -= num_bytes; | |
258 src->next_input_byte += num_bytes; | |
259 } | |
260 | |
261 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
262 METHODDEF(void) | |
263 #else | |
264 METHODDEF void | |
265 #endif | |
2286 | 266 our_term_source (j_decompress_ptr UNUSED (cinfo)) |
428 | 267 { |
268 } | |
269 | |
270 typedef struct | |
271 { | |
272 struct jpeg_source_mgr pub; | |
273 } our_jpeg_source_mgr; | |
274 | |
275 static void | |
665 | 276 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, Bytecount len) |
428 | 277 { |
278 struct jpeg_source_mgr *src; | |
279 | |
280 if (cinfo->src == NULL) | |
281 { /* first time for this JPEG object? */ | |
282 cinfo->src = (struct jpeg_source_mgr *) | |
283 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, | |
284 sizeof(our_jpeg_source_mgr)); | |
285 src = (struct jpeg_source_mgr *) cinfo->src; | |
286 src->next_input_byte = data; | |
287 } | |
288 src = (struct jpeg_source_mgr *) cinfo->src; | |
289 src->init_source = our_init_source; | |
290 src->fill_input_buffer = our_fill_input_buffer; | |
291 src->skip_input_data = our_skip_input_data; | |
292 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ | |
293 src->term_source = our_term_source; | |
294 src->bytes_in_buffer = len; | |
295 src->next_input_byte = data; | |
296 } | |
297 | |
298 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
299 METHODDEF(void) | |
300 #else | |
301 METHODDEF void | |
302 #endif | |
303 my_jpeg_error_exit (j_common_ptr cinfo) | |
304 { | |
305 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ | |
306 struct my_jpeg_error_mgr *myerr = (struct my_jpeg_error_mgr *) cinfo->err; | |
307 | |
308 /* Return control to the setjmp point */ | |
309 longjmp (myerr->setjmp_buffer, 1); | |
310 } | |
311 | |
312 #if defined(JPEG_LIB_VERSION) && (JPEG_LIB_VERSION >= 61) | |
313 METHODDEF(void) | |
314 #else | |
315 METHODDEF void | |
316 #endif | |
317 my_jpeg_output_message (j_common_ptr cinfo) | |
318 { | |
771 | 319 Extbyte buffer[JMSG_LENGTH_MAX]; |
867 | 320 Ibyte *intbuf; |
428 | 321 |
322 /* Create the message */ | |
323 (*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
|
324 intbuf = EXTERNAL_TO_ITEXT (buffer, Qjpeg_error_message_encoding); |
771 | 325 warn_when_safe (Qjpeg, Qinfo, "%s", intbuf); |
428 | 326 } |
327 | |
328 /* The code in this routine is based on example.c from the JPEG library | |
329 source code and from gif_instantiate() */ | |
330 static void | |
331 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 332 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 333 int dest_mask, Lisp_Object domain) |
334 { | |
440 | 335 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 336 /* It is OK for the unwind data to be local to this function, |
337 because the unwind-protect is always executed when this | |
338 stack frame is still valid. */ | |
339 struct jpeg_unwind_data unwind; | |
340 int speccount = specpdl_depth (); | |
341 | |
342 /* This struct contains the JPEG decompression parameters and pointers to | |
343 * working space (which is allocated as needed by the JPEG library). | |
344 */ | |
345 struct jpeg_decompress_struct cinfo; | |
346 /* We use our private extension JPEG error handler. | |
347 * Note that this struct must live as long as the main JPEG parameter | |
348 * struct, to avoid dangling-pointer problems. | |
349 */ | |
350 struct my_jpeg_error_mgr jerr; | |
351 | |
352 /* Step -1: First record our unwind-protect, which will clean up after | |
353 any exit, normal or not */ | |
354 | |
355 xzero (unwind); | |
356 record_unwind_protect (jpeg_instantiate_unwind, make_opaque_ptr (&unwind)); | |
357 | |
358 /* Step 1: allocate and initialize JPEG decompression object */ | |
359 | |
360 /* We set up the normal JPEG error routines, then override error_exit. */ | |
361 cinfo.err = jpeg_std_error (&jerr.pub); | |
362 jerr.pub.error_exit = my_jpeg_error_exit; | |
363 jerr.pub.output_message = my_jpeg_output_message; | |
364 | |
365 /* Establish the setjmp return context for my_error_exit to use. */ | |
366 if (setjmp (jerr.setjmp_buffer)) | |
367 { | |
368 /* If we get here, the JPEG code has signaled an error. | |
369 * We need to clean up the JPEG object, close the input file, and return. | |
370 */ | |
371 | |
372 { | |
373 Lisp_Object errstring; | |
771 | 374 Extbyte buffer[JMSG_LENGTH_MAX]; |
428 | 375 |
376 /* Create the message */ | |
377 (*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
|
378 errstring = build_extstring (buffer, Qjpeg_error_message_encoding); |
428 | 379 |
380 signal_image_error_2 ("JPEG decoding error", | |
381 errstring, instantiator); | |
382 } | |
383 } | |
384 | |
385 /* Now we can initialize the JPEG decompression object. */ | |
386 jpeg_create_decompress (&cinfo); | |
387 unwind.cinfo_ptr = &cinfo; | |
388 | |
389 /* Step 2: specify data source (eg, a file) */ | |
390 | |
391 { | |
392 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 393 const Binbyte *bytes; |
665 | 394 Bytecount len; |
428 | 395 |
396 /* #### This is a definite problem under Mule due to the amount of | |
397 stack data it might allocate. Need to be able to convert and | |
398 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
|
399 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 400 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len); |
401 } | |
402 | |
403 /* Step 3: read file parameters with jpeg_read_header() */ | |
404 | |
405 jpeg_read_header (&cinfo, TRUE); | |
406 /* We can ignore the return value from jpeg_read_header since | |
407 * (a) suspension is not possible with the stdio data source, and | |
408 * (b) we passed TRUE to reject a tables-only JPEG file as an error. | |
409 * See libjpeg.doc for more info. | |
410 */ | |
411 | |
412 { | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
413 UINT_64_BIT pixels_sq; |
428 | 414 int jpeg_gray = 0; /* if we're dealing with a grayscale */ |
415 /* Step 4: set parameters for decompression. */ | |
416 | |
417 /* Now that we're using EImages, send all data as 24bit color. | |
418 The backend routine will take care of any necessary reductions. | |
419 We do have to handle the grayscale case ourselves, however. */ | |
420 if (cinfo.jpeg_color_space == JCS_GRAYSCALE) | |
421 { | |
422 cinfo.out_color_space = JCS_GRAYSCALE; | |
423 jpeg_gray = 1; | |
424 } | |
425 else | |
426 { | |
427 /* we're relying on the jpeg driver to do any other conversions, | |
428 or signal an error if the conversion isn't supported. */ | |
429 cinfo.out_color_space = JCS_RGB; | |
430 } | |
431 | |
432 /* Step 5: Start decompressor */ | |
433 jpeg_start_decompress (&cinfo); | |
434 | |
435 /* 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
|
436 pixels_sq = |
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
437 (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
|
438 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
|
439 signal_image_error ("JPEG image too large to instantiate", instantiator); |
2367 | 440 unwind.eimage = |
441 xnew_binbytes (cinfo.output_width * cinfo.output_height * 3); | |
428 | 442 if (!unwind.eimage) |
443 signal_image_error("Unable to allocate enough memory for image", instantiator); | |
444 | |
445 { | |
446 JSAMPARRAY row_buffer; /* Output row buffer */ | |
447 JSAMPLE *jp; | |
448 int row_stride; /* physical row width in output buffer */ | |
2367 | 449 Binbyte *op = unwind.eimage; |
428 | 450 |
451 /* We may need to do some setup of our own at this point before reading | |
452 * the data. After jpeg_start_decompress() we have the correct scaled | |
453 * output image dimensions available | |
454 * We need to make an output work buffer of the right size. | |
455 */ | |
456 /* JSAMPLEs per row in output buffer. */ | |
457 row_stride = cinfo.output_width * cinfo.output_components; | |
458 /* Make a one-row-high sample array that will go away when done | |
459 with image */ | |
460 row_buffer = ((*cinfo.mem->alloc_sarray) | |
461 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1)); | |
462 | |
463 /* Here we use the library's state variable cinfo.output_scanline as the | |
464 * loop counter, so that we don't have to keep track ourselves. | |
465 */ | |
466 while (cinfo.output_scanline < cinfo.output_height) | |
467 { | |
468 int i; | |
469 | |
470 /* jpeg_read_scanlines expects an array of pointers to scanlines. | |
471 * Here the array is only one element long, but you could ask for | |
472 * more than one scanline at a time if that's more convenient. | |
473 */ | |
474 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1); | |
475 jp = row_buffer[0]; | |
647 | 476 for (i = 0; i < (int) cinfo.output_width; i++) |
428 | 477 { |
478 int clr; | |
479 if (jpeg_gray) | |
480 { | |
2367 | 481 Binbyte val; |
428 | 482 #if (BITS_IN_JSAMPLE == 8) |
2367 | 483 val = (Binbyte) *jp++; |
428 | 484 #else /* other option is 12 */ |
2367 | 485 val = (Binbyte) (*jp++ >> 4); |
428 | 486 #endif |
487 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */ | |
488 *op++ = val; | |
489 } | |
490 else | |
491 { | |
492 for (clr = 0; clr < 3; clr++) | |
493 #if (BITS_IN_JSAMPLE == 8) | |
2367 | 494 *op++ = (Binbyte)*jp++; |
428 | 495 #else /* other option is 12 */ |
2367 | 496 *op++ = (Binbyte)(*jp++ >> 4); |
428 | 497 #endif |
498 } | |
499 } | |
500 } | |
501 } | |
502 } | |
503 | |
504 /* Step 6.5: Create the pixmap and set up the image instance */ | |
505 /* now instantiate */ | |
442 | 506 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 507 init_image_instance_from_eimage, |
508 (ii, cinfo.output_width, cinfo.output_height, 1, | |
509 unwind.eimage, dest_mask, | |
2959 | 510 instantiator, pointer_fg, pointer_bg, domain)); |
428 | 511 |
512 /* Step 7: Finish decompression */ | |
513 | |
514 jpeg_finish_decompress (&cinfo); | |
515 /* We can ignore the return value since suspension is not possible | |
516 * with the stdio data source. | |
517 */ | |
518 | |
519 /* And we're done! */ | |
520 /* This will clean up everything else. */ | |
771 | 521 unbind_to (speccount); |
428 | 522 } |
523 | |
524 #endif /* HAVE_JPEG */ | |
525 | |
526 #ifdef HAVE_GIF | |
527 /********************************************************************** | |
528 * GIF * | |
529 **********************************************************************/ | |
530 | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
531 #include <gif_lib.h> |
428 | 532 |
533 static void | |
534 gif_validate (Lisp_Object instantiator) | |
535 { | |
536 file_or_data_must_be_present (instantiator); | |
537 } | |
538 | |
539 static Lisp_Object | |
442 | 540 gif_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 541 Lisp_Object UNUSED (dest_mask)) |
428 | 542 { |
543 return simple_image_type_normalize (inst, console_type, Qgif); | |
544 } | |
545 | |
546 static int | |
547 gif_possible_dest_types (void) | |
548 { | |
549 return IMAGE_COLOR_PIXMAP_MASK; | |
550 } | |
551 | |
552 /* To survive the otherwise baffling complexity of making sure | |
553 everything gets cleaned up in the presence of an error, we | |
554 use an unwind_protect(). */ | |
555 | |
556 struct gif_unwind_data | |
557 { | |
2367 | 558 Binbyte *eimage; |
428 | 559 /* Object that holds the decoded data from a GIF file */ |
560 GifFileType *giffile; | |
561 }; | |
562 | |
563 static Lisp_Object | |
564 gif_instantiate_unwind (Lisp_Object unwind_obj) | |
565 { | |
566 struct gif_unwind_data *data = | |
567 (struct gif_unwind_data *) get_opaque_ptr (unwind_obj); | |
568 | |
569 free_opaque_ptr (unwind_obj); | |
570 if (data->giffile) | |
571 { | |
572 DGifCloseFile (data->giffile); | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
573 FreeSavedImages(data->giffile); |
428 | 574 } |
647 | 575 if (data->eimage) |
2367 | 576 xfree (data->eimage, Binbyte *); |
428 | 577 |
578 return Qnil; | |
579 } | |
580 | |
581 typedef struct gif_memory_storage | |
582 { | |
2367 | 583 Binbyte *bytes; /* The data */ |
665 | 584 Bytecount len; /* How big is it? */ |
585 Bytecount index; /* Where are we? */ | |
428 | 586 } gif_memory_storage; |
587 | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
588 static int |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
589 gif_read_from_memory (GifFileType *gif, GifByteType *buf, int size) |
428 | 590 { |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
591 gif_memory_storage *mem = (gif_memory_storage *) gif->UserData; |
428 | 592 |
593 if (size > (mem->len - mem->index)) | |
647 | 594 return -1; |
595 memcpy (buf, mem->bytes + mem->index, size); | |
428 | 596 mem->index = mem->index + size; |
597 return size; | |
598 } | |
599 | |
4708
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
600 static const char * |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
601 gif_decode_error_string () |
428 | 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 switch (GifLastError ()) |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
604 { |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
605 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
|
606 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
|
607 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
|
608 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
|
609 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
|
610 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
|
611 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
|
612 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
|
613 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
|
614 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
|
615 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
|
616 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
|
617 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
|
618 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
|
619 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
|
620 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
|
621 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
|
622 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
|
623 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
|
624 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
|
625 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
|
626 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
|
627 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
|
628 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
|
629 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
|
630 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
|
631 default: |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
632 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
|
633 } |
428 | 634 } |
635 | |
636 static void | |
637 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 638 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 639 int dest_mask, Lisp_Object domain) |
640 { | |
440 | 641 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 642 /* It is OK for the unwind data to be local to this function, |
643 because the unwind-protect is always executed when this | |
644 stack frame is still valid. */ | |
645 struct gif_unwind_data unwind; | |
646 int speccount = specpdl_depth (); | |
647 gif_memory_storage mem_struct; | |
2367 | 648 Binbyte *bytes; |
665 | 649 Bytecount len; |
428 | 650 int height = 0; |
651 int width = 0; | |
652 | |
653 xzero (unwind); | |
654 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind)); | |
655 | |
656 /* 1. Now decode the data. */ | |
657 | |
658 { | |
659 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
660 | |
661 assert (!NILP (data)); | |
662 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
663 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 664 mem_struct.bytes = bytes; |
665 mem_struct.len = len; | |
666 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
|
667 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
|
668 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
|
669 signal_image_error (gif_decode_error_string (), instantiator); |
428 | 670 |
671 /* Then slurp the image into memory, decoding along the way. | |
672 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
|
673 format. */ |
1cecc3e9f0a0
Use giflib or libungif to provide GIF support, instead of using internal
Jerry James <james@xemacs.org>
parents:
4698
diff
changeset
|
674 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
|
675 signal_image_error (gif_decode_error_string (), instantiator); |
428 | 676 } |
677 | |
678 /* 3. Now create the EImage(s) */ | |
679 { | |
680 ColorMapObject *cmo = unwind.giffile->SColorMap; | |
681 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
|
682 UINT_64_BIT pixels_sq; |
2367 | 683 Binbyte *eip; |
428 | 684 /* interlaced gifs have rows in this order: |
685 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ | |
686 static int InterlacedOffset[] = { 0, 4, 2, 1 }; | |
687 static int InterlacedJumps[] = { 8, 8, 4, 2 }; | |
688 | |
689 height = unwind.giffile->SHeight; | |
690 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
|
691 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
|
692 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
|
693 signal_image_error ("GIF image too large to instantiate", instantiator); |
2367 | 694 unwind.eimage = |
695 xnew_binbytes (width * height * 3 * unwind.giffile->ImageCount); | |
428 | 696 if (!unwind.eimage) |
697 signal_image_error("Unable to allocate enough memory for image", instantiator); | |
698 | |
699 /* write the data in EImage format (8bit RGB triples) */ | |
700 | |
701 for (slice = 0; slice < unwind.giffile->ImageCount; slice++) | |
702 { | |
638 | 703 /* We check here that the current image covers the full "screen" size. */ |
428 | 704 if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height |
705 || unwind.giffile->SavedImages[slice].ImageDesc.Width != width | |
706 || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0 | |
707 || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0) | |
708 signal_image_error ("Image in GIF file is not full size", | |
709 instantiator); | |
710 | |
711 interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace; | |
712 pass = 0; | |
713 row = interlace ? InterlacedOffset[pass] : 0; | |
714 eip = unwind.eimage + (width * height * 3 * slice); | |
715 for (i = 0; i < height; i++) | |
716 { | |
717 if (interlace) | |
718 if (row >= height) { | |
719 row = InterlacedOffset[++pass]; | |
720 while (row >= height) | |
721 row = InterlacedOffset[++pass]; | |
722 } | |
723 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3); | |
724 for (j = 0; j < width; j++) | |
725 { | |
2367 | 726 Binbyte pixel = |
428 | 727 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j]; |
728 *eip++ = cmo->Colors[pixel].Red; | |
729 *eip++ = cmo->Colors[pixel].Green; | |
730 *eip++ = cmo->Colors[pixel].Blue; | |
731 } | |
732 row += interlace ? InterlacedJumps[pass] : 1; | |
733 } | |
734 } | |
735 | |
736 /* now instantiate */ | |
442 | 737 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 738 init_image_instance_from_eimage, |
2959 | 739 (ii, width, height, unwind.giffile->ImageCount, |
740 unwind.eimage, dest_mask, instantiator, pointer_fg, | |
741 pointer_bg, domain)); | |
428 | 742 } |
743 | |
744 /* We read the gif successfully. If we have more than one slice then | |
745 animate the gif. */ | |
746 if (unwind.giffile->ImageCount > 1) | |
747 { | |
748 /* 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
|
749 for every image - but that makes the implementation way too |
428 | 750 complicated for now so we just take the first. */ |
751 unsigned short timeout = 0; | |
752 Lisp_Object tid; | |
753 | |
754 if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE | |
755 && | |
756 unwind.giffile->SavedImages[0].ExtensionBlockCount) | |
757 { | |
758 timeout = (unsigned short) | |
438 | 759 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) + |
428 | 760 unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10; |
761 } | |
762 | |
763 /* Too short a timeout will crucify us performance-wise. */ | |
764 tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance); | |
765 | |
766 if (!NILP (tid)) | |
767 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid); | |
768 } | |
438 | 769 |
771 | 770 unbind_to (speccount); |
428 | 771 } |
772 | |
773 #endif /* HAVE_GIF */ | |
774 | |
775 | |
776 #ifdef HAVE_PNG | |
777 | |
778 /********************************************************************** | |
779 * PNG * | |
780 **********************************************************************/ | |
781 static void | |
782 png_validate (Lisp_Object instantiator) | |
783 { | |
784 file_or_data_must_be_present (instantiator); | |
785 } | |
786 | |
787 static Lisp_Object | |
442 | 788 png_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 789 Lisp_Object UNUSED (dest_mask)) |
428 | 790 { |
791 return simple_image_type_normalize (inst, console_type, Qpng); | |
792 } | |
793 | |
794 static int | |
795 png_possible_dest_types (void) | |
796 { | |
797 return IMAGE_COLOR_PIXMAP_MASK; | |
798 } | |
799 | |
800 struct png_memory_storage | |
801 { | |
2367 | 802 const Binbyte *bytes; /* The data */ |
665 | 803 Bytecount len; /* How big is it? */ |
804 Bytecount index; /* Where are we? */ | |
428 | 805 }; |
806 | |
807 static void | |
647 | 808 png_read_from_memory (png_structp png_ptr, png_bytep data, |
809 png_size_t length) | |
428 | 810 { |
811 struct png_memory_storage *tbr = | |
812 (struct png_memory_storage *) png_get_io_ptr (png_ptr); | |
813 | |
665 | 814 if ((Bytecount) length > (tbr->len - tbr->index)) |
428 | 815 png_error (png_ptr, (png_const_charp) "Read Error"); |
647 | 816 memcpy (data, tbr->bytes + tbr->index,length); |
428 | 817 tbr->index = tbr->index + length; |
818 } | |
819 | |
820 struct png_error_struct | |
821 { | |
442 | 822 const char *err_str; |
428 | 823 jmp_buf setjmp_buffer; /* for return to caller */ |
824 }; | |
825 | |
826 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own | |
827 structure, and there are cases where the size can be different from | |
828 between inside the library, and inside the code! To do an end run | |
829 around this, use our own error functions, and don't rely on things | |
830 passed in the png_ptr to them. This is an ugly hack and must | |
831 go away when the lisp engine is threaded! */ | |
832 static struct png_error_struct png_err_stct; | |
833 | |
834 static void | |
2286 | 835 png_error_func (png_structp UNUSED (png_ptr), png_const_charp msg) |
428 | 836 { |
837 png_err_stct.err_str = msg; | |
838 longjmp (png_err_stct.setjmp_buffer, 1); | |
839 } | |
840 | |
841 static void | |
2286 | 842 png_warning_func (png_structp UNUSED (png_ptr), png_const_charp msg) |
428 | 843 { |
3734 | 844 DECLARE_EISTRING (eimsg); |
845 | |
846 eicpy_ext(eimsg, msg, Qbinary); | |
847 warn_when_safe (Qpng, Qinfo, "%s", eidata(eimsg)); | |
428 | 848 } |
849 | |
850 struct png_unwind_data | |
851 { | |
852 FILE *instream; | |
2367 | 853 Binbyte *eimage; |
428 | 854 png_structp png_ptr; |
855 png_infop info_ptr; | |
856 }; | |
857 | |
858 static Lisp_Object | |
859 png_instantiate_unwind (Lisp_Object unwind_obj) | |
860 { | |
861 struct png_unwind_data *data = | |
862 (struct png_unwind_data *) get_opaque_ptr (unwind_obj); | |
863 | |
864 free_opaque_ptr (unwind_obj); | |
865 if (data->png_ptr) | |
3839 | 866 { |
867 /* ensure we can't get here again */ | |
868 png_structp tmp = data->png_ptr; | |
869 data->png_ptr = NULL; | |
870 png_destroy_read_struct (&tmp, &(data->info_ptr), (png_infopp)NULL); | |
871 } | |
872 | |
428 | 873 if (data->instream) |
771 | 874 retry_fclose (data->instream); |
428 | 875 |
1726 | 876 if (data->eimage) |
2367 | 877 xfree(data->eimage, Binbyte *); |
428 | 878 |
879 return Qnil; | |
880 } | |
881 | |
882 static void | |
883 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 884 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 885 int dest_mask, Lisp_Object domain) |
886 { | |
440 | 887 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 888 struct png_unwind_data unwind; |
889 int speccount = specpdl_depth (); | |
890 int height, width; | |
891 struct png_memory_storage tbr; /* Data to be read */ | |
892 | |
893 /* PNG variables */ | |
894 png_structp png_ptr; | |
895 png_infop info_ptr; | |
896 | |
3839 | 897 xzero (unwind); |
898 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind)); | |
899 | |
900 if (setjmp (png_err_stct.setjmp_buffer)) | |
901 { | |
902 /* Something blew up: | |
903 just display the error (cleanup happens in the unwind) */ | |
904 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
|
905 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
|
906 Qerror_message_encoding), |
3839 | 907 instantiator); |
908 } | |
909 | |
428 | 910 /* Initialize all PNG structures */ |
3839 | 911 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, |
912 (void *) &png_err_stct, | |
428 | 913 png_error_func, png_warning_func); |
914 if (!png_ptr) | |
915 signal_image_error ("Error obtaining memory for png_read", instantiator); | |
3839 | 916 unwind.png_ptr = png_ptr; |
917 | |
428 | 918 info_ptr = png_create_info_struct (png_ptr); |
919 if (!info_ptr) | |
920 { | |
3839 | 921 unwind.png_ptr = NULL; /* avoid re-calling png_destroy_read_struct |
922 when unwinding */ | |
428 | 923 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); |
924 signal_image_error ("Error obtaining memory for png_read", instantiator); | |
925 } | |
926 unwind.info_ptr = info_ptr; | |
927 | |
928 /* This code is a mixture of stuff from Ben's GIF/JPEG stuff from | |
929 this file, example.c from the libpng 0.81 distribution, and the | |
930 pngtopnm sources. -WMP- | |
931 */ | |
932 /* It has been further modified to handle the API changes for 0.96, | |
933 and is no longer usable for previous versions. jh | |
934 */ | |
935 | |
936 /* Initialize the IO layer and read in header information */ | |
937 { | |
938 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 939 const Binbyte *bytes; |
665 | 940 Bytecount len; |
428 | 941 |
942 assert (!NILP (data)); | |
943 | |
944 /* #### This is a definite problem under Mule due to the amount of | |
945 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
|
946 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 947 tbr.bytes = bytes; |
948 tbr.len = len; | |
949 tbr.index = 0; | |
950 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory); | |
951 } | |
952 | |
953 png_read_info (png_ptr, info_ptr); | |
954 | |
955 { | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
956 int y, padding; |
2367 | 957 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
|
958 UINT_64_BIT pixels_sq; |
428 | 959 height = info_ptr->height; |
960 width = info_ptr->width; | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
961 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
|
962 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
|
963 signal_image_error ("PNG image too large to instantiate", instantiator); |
428 | 964 |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
965 /* Wow, allocate all the memory. Truly, exciting. |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
966 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
|
967 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
|
968 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
|
969 to add padding. |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
970 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
|
971 |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
972 padding = 5 * width; |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
973 unwind.eimage = xnew_array_and_zero (Binbyte, |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
974 (size_t) (pixels_sq * 3 + padding)); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
975 |
428 | 976 /* libpng expects that the image buffer passed in contains a |
977 picture to draw on top of if the png has any transparencies. | |
978 This could be a good place to pass that in... */ | |
979 | |
980 row_pointers = xnew_array (png_byte *, height); | |
981 for (y = 0; y < height; y++) | |
982 row_pointers[y] = unwind.eimage + (width * 3 * y); | |
983 | |
984 { | |
985 /* if the png specifies a background chunk, go ahead and | |
986 use it, else use what we can get from the default face. */ | |
987 png_color_16 my_background, *image_background; | |
988 Lisp_Object bkgd = Qnil; | |
989 | |
990 my_background.red = 0x7fff; | |
991 my_background.green = 0x7fff; | |
992 my_background.blue = 0x7fff; | |
993 bkgd = FACE_BACKGROUND (Vdefault_face, domain); | |
994 if (!COLOR_INSTANCEP (bkgd)) | |
995 { | |
996 warn_when_safe (Qpng, Qinfo, "Couldn't get background color!"); | |
997 } | |
998 else | |
999 { | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1000 Lisp_Color_Instance *c = XCOLOR_INSTANCE (bkgd); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1001 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
|
1002 color_instance_rgb_components, |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1003 (c)); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1004 #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
|
1005 GETCOLOR(red); rgb = XCDR (rgb); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1006 GETCOLOR(green); rgb = XCDR (rgb); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1007 GETCOLOR(blue); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1008 #undef GETCOLOR |
428 | 1009 } |
1010 | |
1011 if (png_get_bKGD (png_ptr, info_ptr, &image_background)) | |
1012 png_set_background (png_ptr, image_background, | |
1013 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); | |
1014 else | |
1015 png_set_background (png_ptr, &my_background, | |
1016 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); | |
1017 } | |
1018 | |
1019 /* Now that we're using EImage, ask for 8bit RGB triples for any type | |
1020 of image*/ | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1021 /* convert palette images to RGB */ |
428 | 1022 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1023 png_set_palette_to_rgb (png_ptr); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1024 /* convert grayscale images to RGB */ |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1025 else if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || |
428 | 1026 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
1027 png_set_gray_to_rgb (png_ptr); | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1028 /* pad images with depth < 8 bits */ |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1029 else if (info_ptr->bit_depth < 8) |
428 | 1030 { |
1031 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY) | |
1032 png_set_expand (png_ptr); | |
1033 else | |
1034 png_set_packing (png_ptr); | |
1035 } | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1036 /* strip 16-bit depth files down to 8 bits */ |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1037 if (info_ptr->bit_depth == 16) |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1038 png_set_strip_16 (png_ptr); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1039 /* strip alpha channel |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1040 #### shouldn't we handle this? |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1041 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
|
1042 have generated an alpha channel */ |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1043 png_read_update_info(png_ptr, info_ptr); |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1044 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) |
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1045 png_set_strip_alpha (png_ptr); |
428 | 1046 |
1047 png_read_image (png_ptr, row_pointers); | |
1048 png_read_end (png_ptr, info_ptr); | |
1049 | |
4698
a9493cab536f
Fix crash due to mishandling transparency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4682
diff
changeset
|
1050 /* #### 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
|
1051 * 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
|
1052 * anyway. - WMP */ |
428 | 1053 { |
1054 int i; | |
3734 | 1055 DECLARE_EISTRING (key); |
1056 DECLARE_EISTRING (text); | |
428 | 1057 |
1058 for (i = 0 ; i < info_ptr->num_text ; i++) | |
1059 { | |
1060 /* How paranoid do I have to be about no trailing NULLs, and | |
1061 using (int)info_ptr->text[i].text_length, and strncpy and a temp | |
1062 string somewhere? */ | |
3734 | 1063 eireset(key); |
1064 eireset(text); | |
1065 eicpy_ext(key, info_ptr->text[i].key, Qbinary); | |
1066 eicpy_ext(text, info_ptr->text[i].text, Qbinary); | |
428 | 1067 |
1068 warn_when_safe (Qpng, Qinfo, "%s - %s", | |
3734 | 1069 eidata(key), eidata(text)); |
428 | 1070 } |
1071 } | |
1072 | |
2367 | 1073 xfree (row_pointers, Binbyte **); |
428 | 1074 } |
1075 | |
1076 /* now instantiate */ | |
442 | 1077 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 1078 init_image_instance_from_eimage, |
1079 (ii, width, height, 1, unwind.eimage, dest_mask, | |
2959 | 1080 instantiator, pointer_fg, pointer_bg, domain)); |
428 | 1081 |
1082 /* This will clean up everything else. */ | |
771 | 1083 unbind_to (speccount); |
428 | 1084 } |
1085 | |
1086 #endif /* HAVE_PNG */ | |
1087 | |
1088 | |
1089 #ifdef HAVE_TIFF | |
1090 #include "tiffio.h" | |
1091 | |
1092 /********************************************************************** | |
1093 * TIFF * | |
1094 **********************************************************************/ | |
1095 static void | |
1096 tiff_validate (Lisp_Object instantiator) | |
1097 { | |
1098 file_or_data_must_be_present (instantiator); | |
1099 } | |
1100 | |
1101 static Lisp_Object | |
442 | 1102 tiff_normalize (Lisp_Object inst, Lisp_Object console_type, |
2286 | 1103 Lisp_Object UNUSED (dest_mask)) |
428 | 1104 { |
1105 return simple_image_type_normalize (inst, console_type, Qtiff); | |
1106 } | |
1107 | |
1108 static int | |
1109 tiff_possible_dest_types (void) | |
1110 { | |
1111 return IMAGE_COLOR_PIXMAP_MASK; | |
1112 } | |
1113 | |
1114 struct tiff_unwind_data | |
1115 { | |
2367 | 1116 Binbyte *eimage; |
428 | 1117 /* Object that holds the decoded data from a TIFF file */ |
1118 TIFF *tiff; | |
1119 }; | |
1120 | |
1121 static Lisp_Object | |
1122 tiff_instantiate_unwind (Lisp_Object unwind_obj) | |
1123 { | |
1124 struct tiff_unwind_data *data = | |
1125 (struct tiff_unwind_data *) get_opaque_ptr (unwind_obj); | |
1126 | |
1127 free_opaque_ptr (unwind_obj); | |
1128 if (data->tiff) | |
1129 { | |
1130 TIFFClose(data->tiff); | |
1131 } | |
1132 if (data->eimage) | |
2367 | 1133 xfree (data->eimage, Binbyte *); |
428 | 1134 |
1135 return Qnil; | |
1136 } | |
1137 | |
1138 typedef struct tiff_memory_storage | |
1139 { | |
2367 | 1140 Binbyte *bytes; /* The data */ |
665 | 1141 Bytecount len; /* How big is it? */ |
1142 Bytecount index; /* Where are we? */ | |
428 | 1143 } tiff_memory_storage; |
1144 | |
1145 static size_t | |
647 | 1146 tiff_memory_read (thandle_t data, tdata_t buf, tsize_t size) |
428 | 1147 { |
647 | 1148 tiff_memory_storage *mem = (tiff_memory_storage *) data; |
428 | 1149 |
665 | 1150 if ((Bytecount) size > (mem->len - mem->index)) |
428 | 1151 return (size_t) -1; |
647 | 1152 memcpy (buf, mem->bytes + mem->index, size); |
428 | 1153 mem->index = mem->index + size; |
1154 return size; | |
1155 } | |
1156 | |
647 | 1157 static size_t |
2286 | 1158 tiff_memory_write (thandle_t UNUSED (data), tdata_t UNUSED (buf), |
1159 tsize_t UNUSED (size)) | |
428 | 1160 { |
2500 | 1161 ABORT(); |
2270 | 1162 return 0; |
428 | 1163 } |
1164 | |
647 | 1165 static toff_t |
1166 tiff_memory_seek (thandle_t data, toff_t off, int whence) | |
428 | 1167 { |
647 | 1168 tiff_memory_storage *mem = (tiff_memory_storage *) data; |
428 | 1169 int newidx; |
647 | 1170 switch(whence) |
1171 { | |
1172 case SEEK_SET: | |
1173 newidx = off; | |
1174 break; | |
1175 case SEEK_END: | |
1176 newidx = mem->len + off; | |
1177 break; | |
1178 case SEEK_CUR: | |
1179 newidx = mem->index + off; | |
1180 break; | |
1181 default: | |
1182 fprintf (stderr, "Eh? invalid seek mode in tiff_memory_seek\n"); | |
1183 return (toff_t) -1; | |
1184 } | |
428 | 1185 |
1186 if ((newidx > mem->len) || (newidx < 0)) | |
593 | 1187 return (toff_t) -1; |
428 | 1188 |
1189 mem->index = newidx; | |
1190 return newidx; | |
1191 } | |
1192 | |
1193 static int | |
2286 | 1194 tiff_memory_close (thandle_t UNUSED (data)) |
428 | 1195 { |
1196 return 0; | |
1197 } | |
1198 | |
1199 static int | |
2286 | 1200 tiff_map_noop (thandle_t UNUSED (data), tdata_t* UNUSED (pbase), |
1201 toff_t* UNUSED (psize)) | |
428 | 1202 { |
1203 return 0; | |
1204 } | |
1205 | |
1206 static void | |
2286 | 1207 tiff_unmap_noop (thandle_t UNUSED (data), tdata_t UNUSED (pbase), |
1208 toff_t UNUSED (psize)) | |
428 | 1209 { |
1210 return; | |
1211 } | |
1212 | |
1213 static toff_t | |
647 | 1214 tiff_memory_size (thandle_t data) |
428 | 1215 { |
1216 tiff_memory_storage *mem = (tiff_memory_storage*)data; | |
1217 return mem->len; | |
1218 } | |
1219 | |
1220 struct tiff_error_struct | |
1221 { | |
438 | 1222 #ifdef HAVE_VSNPRINTF |
428 | 1223 char err_str[256]; |
1224 #else | |
1225 char err_str[1024]; /* return the error string */ | |
1226 #endif | |
1227 jmp_buf setjmp_buffer; /* for return to caller */ | |
1228 }; | |
1229 | |
1230 /* jh 98/03/12 - ###This struct for passing data to the error functions | |
1231 is an ugly hack caused by the fact that libtiff (as of v3.4) doesn't | |
1232 have any place to store error func data. This should be rectified | |
1233 before XEmacs gets threads! */ | |
1234 static struct tiff_error_struct tiff_err_data; | |
1235 | |
1236 static void | |
2286 | 1237 tiff_error_func (const char *UNUSED (module), const char *fmt, ...) |
428 | 1238 { |
1239 va_list vargs; | |
1240 | |
1241 va_start (vargs, fmt); | |
438 | 1242 #ifdef HAVE_VSNPRINTF |
428 | 1243 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs); |
1244 #else | |
1245 /* pray this doesn't overflow... */ | |
1246 vsprintf (tiff_err_data.err_str, fmt, vargs); | |
1247 #endif | |
1248 va_end (vargs); | |
1249 /* return to setjmp point */ | |
1250 longjmp (tiff_err_data.setjmp_buffer, 1); | |
1251 } | |
1252 | |
1253 static void | |
647 | 1254 tiff_warning_func (const char *module, const char *fmt, ...) |
428 | 1255 { |
1256 va_list vargs; | |
438 | 1257 #ifdef HAVE_VSNPRINTF |
428 | 1258 char warn_str[256]; |
1259 #else | |
1260 char warn_str[1024]; | |
1261 #endif | |
3734 | 1262 DECLARE_EISTRING (eimodule); |
1263 DECLARE_EISTRING (eiwarnstr); | |
428 | 1264 |
1265 va_start (vargs, fmt); | |
438 | 1266 #ifdef HAVE_VSNPRINTF |
428 | 1267 vsnprintf (warn_str, 255, fmt, vargs); |
1268 #else | |
1269 vsprintf (warn_str, fmt, vargs); | |
1270 #endif | |
1271 va_end (vargs); | |
3734 | 1272 |
1273 eicpy_ext(eimodule, module, Qbinary); | |
1274 eicpy_ext(eiwarnstr, warn_str, Qbinary); | |
1275 | |
428 | 1276 warn_when_safe (Qtiff, Qinfo, "%s - %s", |
3734 | 1277 eidata(eimodule), |
1278 eidata(eiwarnstr)); | |
428 | 1279 } |
1280 | |
1281 static void | |
1282 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | |
2959 | 1283 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
428 | 1284 int dest_mask, Lisp_Object domain) |
1285 { | |
440 | 1286 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
428 | 1287 tiff_memory_storage mem_struct; |
1288 /* It is OK for the unwind data to be local to this function, | |
1289 because the unwind-protect is always executed when this | |
1290 stack frame is still valid. */ | |
1291 struct tiff_unwind_data unwind; | |
1292 int speccount = specpdl_depth (); | |
1293 uint32 width, height; | |
1294 | |
1295 xzero (unwind); | |
1296 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind)); | |
1297 | |
1298 /* set up error facilities */ | |
1299 if (setjmp (tiff_err_data.setjmp_buffer)) | |
1300 { | |
1301 /* An error was signaled. No clean up is needed, as unwind handles that | |
1302 for us. Just pass the error along. */ | |
1303 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
|
1304 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
|
1305 Qerror_message_encoding), |
428 | 1306 instantiator); |
1307 } | |
1308 TIFFSetErrorHandler ((TIFFErrorHandler)tiff_error_func); | |
1309 TIFFSetWarningHandler ((TIFFErrorHandler)tiff_warning_func); | |
1310 { | |
1311 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | |
2367 | 1312 Binbyte *bytes; |
665 | 1313 Bytecount len; |
428 | 1314 |
1315 uint32 *raster; | |
2367 | 1316 Binbyte *ep; |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
1317 UINT_64_BIT pixels_sq; |
428 | 1318 |
1319 assert (!NILP (data)); | |
1320 | |
1321 /* #### This is a definite problem under Mule due to the amount of | |
1322 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
|
1323 LISP_STRING_TO_SIZED_EXTERNAL (data, bytes, len, Qbinary); |
428 | 1324 mem_struct.bytes = bytes; |
1325 mem_struct.len = len; | |
1326 mem_struct.index = 0; | |
1327 | |
442 | 1328 unwind.tiff = TIFFClientOpen ("memfile", "r", (thandle_t) &mem_struct, |
428 | 1329 (TIFFReadWriteProc)tiff_memory_read, |
1330 (TIFFReadWriteProc)tiff_memory_write, | |
1331 tiff_memory_seek, tiff_memory_close, tiff_memory_size, | |
1332 tiff_map_noop, tiff_unmap_noop); | |
1333 if (!unwind.tiff) | |
440 | 1334 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator); |
428 | 1335 |
1336 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); | |
1337 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
|
1338 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
|
1339 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
|
1340 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
|
1341 unwind.eimage = xnew_binbytes ((size_t) pixels_sq * 3); |
428 | 1342 |
440 | 1343 /* #### This is little more than proof-of-concept/function testing. |
428 | 1344 It needs to be reimplemented via scanline reads for both memory |
1345 compactness. */ | |
4646
6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
Jerry James <james@xemacs.org>
parents:
4326
diff
changeset
|
1346 raster = (uint32*) _TIFFmalloc ((tsize_t) (pixels_sq * sizeof (uint32))); |
428 | 1347 if (raster != NULL) |
1348 { | |
647 | 1349 int i, j; |
428 | 1350 uint32 *rp; |
1351 ep = unwind.eimage; | |
1352 rp = raster; | |
1353 if (TIFFReadRGBAImage (unwind.tiff, width, height, raster, 0)) | |
1354 { | |
1355 for (i = height - 1; i >= 0; i--) | |
1356 { | |
1357 /* This is to get around weirdness in the libtiff library where properly | |
1358 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */ | |
1359 rp = raster + (i * width); | |
647 | 1360 for (j = 0; j < (int) width; j++) |
428 | 1361 { |
2367 | 1362 *ep++ = (Binbyte)TIFFGetR(*rp); |
1363 *ep++ = (Binbyte)TIFFGetG(*rp); | |
1364 *ep++ = (Binbyte)TIFFGetB(*rp); | |
428 | 1365 rp++; |
1366 } | |
1367 } | |
1368 } | |
1369 _TIFFfree (raster); | |
1370 } else | |
1371 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator); | |
1372 | |
1373 } | |
1374 | |
1375 /* now instantiate */ | |
442 | 1376 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), |
428 | 1377 init_image_instance_from_eimage, |
1378 (ii, width, height, 1, unwind.eimage, dest_mask, | |
2959 | 1379 instantiator, pointer_fg, pointer_bg, domain)); |
428 | 1380 |
771 | 1381 unbind_to (speccount); |
428 | 1382 } |
1383 | |
1384 #endif /* HAVE_TIFF */ | |
1385 | |
1386 | |
1387 /************************************************************************/ | |
1388 /* initialization */ | |
1389 /************************************************************************/ | |
1390 | |
1391 void | |
1392 syms_of_glyphs_eimage (void) | |
1393 { | |
1394 } | |
1395 | |
1396 void | |
1397 image_instantiator_format_create_glyphs_eimage (void) | |
1398 { | |
1399 /* image-instantiator types */ | |
1400 #ifdef HAVE_JPEG | |
1401 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (jpeg, "jpeg"); | |
1402 | |
1403 IIFORMAT_HAS_METHOD (jpeg, validate); | |
1404 IIFORMAT_HAS_METHOD (jpeg, normalize); | |
1405 IIFORMAT_HAS_METHOD (jpeg, possible_dest_types); | |
1406 IIFORMAT_HAS_METHOD (jpeg, instantiate); | |
1407 | |
1408 IIFORMAT_VALID_KEYWORD (jpeg, Q_data, check_valid_string); | |
1409 IIFORMAT_VALID_KEYWORD (jpeg, Q_file, check_valid_string); | |
1410 #endif | |
1411 | |
1412 #ifdef HAVE_GIF | |
1413 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (gif, "gif"); | |
1414 | |
1415 IIFORMAT_HAS_METHOD (gif, validate); | |
1416 IIFORMAT_HAS_METHOD (gif, normalize); | |
1417 IIFORMAT_HAS_METHOD (gif, possible_dest_types); | |
1418 IIFORMAT_HAS_METHOD (gif, instantiate); | |
1419 | |
1420 IIFORMAT_VALID_KEYWORD (gif, Q_data, check_valid_string); | |
1421 IIFORMAT_VALID_KEYWORD (gif, Q_file, check_valid_string); | |
1422 #endif | |
1423 | |
1424 #ifdef HAVE_PNG | |
1425 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (png, "png"); | |
1426 | |
1427 IIFORMAT_HAS_METHOD (png, validate); | |
1428 IIFORMAT_HAS_METHOD (png, normalize); | |
1429 IIFORMAT_HAS_METHOD (png, possible_dest_types); | |
1430 IIFORMAT_HAS_METHOD (png, instantiate); | |
1431 | |
1432 IIFORMAT_VALID_KEYWORD (png, Q_data, check_valid_string); | |
1433 IIFORMAT_VALID_KEYWORD (png, Q_file, check_valid_string); | |
1434 #endif | |
1435 | |
1436 #ifdef HAVE_TIFF | |
1437 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tiff, "tiff"); | |
1438 | |
1439 IIFORMAT_HAS_METHOD (tiff, validate); | |
1440 IIFORMAT_HAS_METHOD (tiff, normalize); | |
1441 IIFORMAT_HAS_METHOD (tiff, possible_dest_types); | |
1442 IIFORMAT_HAS_METHOD (tiff, instantiate); | |
1443 | |
1444 IIFORMAT_VALID_KEYWORD (tiff, Q_data, check_valid_string); | |
1445 IIFORMAT_VALID_KEYWORD (tiff, Q_file, check_valid_string); | |
1446 #endif | |
1447 | |
1448 } | |
1449 | |
1450 void | |
1451 vars_of_glyphs_eimage (void) | |
1452 { | |
1453 #ifdef HAVE_JPEG | |
1454 Fprovide (Qjpeg); | |
1455 #endif | |
1456 | |
1457 #ifdef HAVE_GIF | |
1458 Fprovide (Qgif); | |
1459 #endif | |
1460 | |
1461 #ifdef HAVE_PNG | |
1462 Fprovide (Qpng); | |
1463 #endif | |
1464 | |
1465 #ifdef HAVE_TIFF | |
1466 Fprovide (Qtiff); | |
1467 #endif | |
1468 | |
1469 } |