1 : /*
2 : * jerror.c
3 : *
4 : * Copyright (C) 1991-1998, Thomas G. Lane.
5 : * This file is part of the Independent JPEG Group's software.
6 : * For conditions of distribution and use, see the accompanying README file.
7 : *
8 : * This file contains simple error-reporting and trace-message routines.
9 : * These are suitable for Unix-like systems and others where writing to
10 : * stderr is the right thing to do. Many applications will want to replace
11 : * some or all of these routines.
12 : *
13 : * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
14 : * you get a Windows-specific hack to display error messages in a dialog box.
15 : * It ain't much, but it beats dropping error messages into the bit bucket,
16 : * which is what happens to output to stderr under most Windows C compilers.
17 : *
18 : * These routines are used by both the compression and decompression code.
19 : */
20 :
21 : /* this is not a core library module, so it doesn't define JPEG_INTERNALS */
22 : #include "jinclude.h"
23 : #include "jpeglib.h"
24 : #include "jversion.h"
25 : #include "jerror.h"
26 :
27 : #ifdef USE_WINDOWS_MESSAGEBOX
28 : #include <windows.h>
29 : #endif
30 :
31 : #ifndef EXIT_FAILURE /* define exit() codes if not provided */
32 : #define EXIT_FAILURE 1
33 : #endif
34 :
35 :
36 : /*
37 : * Create the message string table.
38 : * We do this from the master message list in jerror.h by re-reading
39 : * jerror.h with a suitable definition for macro JMESSAGE.
40 : * The message table is made an external symbol just in case any applications
41 : * want to refer to it directly.
42 : */
43 :
44 : #ifdef NEED_SHORT_EXTERNAL_NAMES
45 : #define jpeg_std_message_table jMsgTable
46 : #endif
47 :
48 : #define JMESSAGE(code,string) string ,
49 :
50 : const char * const jpeg_std_message_table[] = {
51 : #include "jerror.h"
52 : NULL
53 : };
54 :
55 :
56 : /*
57 : * Error exit handler: must not return to caller.
58 : *
59 : * Applications may override this if they want to get control back after
60 : * an error. Typically one would longjmp somewhere instead of exiting.
61 : * The setjmp buffer can be made a private field within an expanded error
62 : * handler object. Note that the info needed to generate an error message
63 : * is stored in the error object, so you can generate the message now or
64 : * later, at your convenience.
65 : * You should make sure that the JPEG object is cleaned up (with jpeg_abort
66 : * or jpeg_destroy) at some point.
67 : */
68 :
69 : METHODDEF(void)
70 0 : error_exit (j_common_ptr cinfo)
71 : {
72 : /* Always display the message */
73 0 : (*cinfo->err->output_message) (cinfo);
74 :
75 : /* Let the memory manager delete any temp files before we die */
76 0 : jpeg_destroy(cinfo);
77 :
78 0 : exit(EXIT_FAILURE);
79 : }
80 :
81 :
82 : /*
83 : * Actual output of an error or trace message.
84 : * Applications may override this method to send JPEG messages somewhere
85 : * other than stderr.
86 : *
87 : * On Windows, printing to stderr is generally completely useless,
88 : * so we provide optional code to produce an error-dialog popup.
89 : * Most Windows applications will still prefer to override this routine,
90 : * but if they don't, it'll do something at least marginally useful.
91 : *
92 : * NOTE: to use the library in an environment that doesn't support the
93 : * C stdio library, you may have to delete the call to fprintf() entirely,
94 : * not just not use this routine.
95 : */
96 :
97 : METHODDEF(void)
98 0 : output_message (j_common_ptr cinfo)
99 : {
100 : char buffer[JMSG_LENGTH_MAX];
101 :
102 : /* Create the message */
103 0 : (*cinfo->err->format_message) (cinfo, buffer);
104 :
105 : #ifdef USE_WINDOWS_MESSAGEBOX
106 : /* Display it in a message dialog box */
107 : MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
108 : MB_OK | MB_ICONERROR);
109 : #else
110 : /* Send it to stderr, adding a newline */
111 0 : fprintf(stderr, "%s\n", buffer);
112 : #endif
113 0 : }
114 :
115 :
116 : /*
117 : * Decide whether to emit a trace or warning message.
118 : * msg_level is one of:
119 : * -1: recoverable corrupt-data warning, may want to abort.
120 : * 0: important advisory messages (always display to user).
121 : * 1: first level of tracing detail.
122 : * 2,3,...: successively more detailed tracing messages.
123 : * An application might override this method if it wanted to abort on warnings
124 : * or change the policy about which messages to display.
125 : */
126 :
127 : METHODDEF(void)
128 138 : emit_message (j_common_ptr cinfo, int msg_level)
129 : {
130 138 : struct jpeg_error_mgr * err = cinfo->err;
131 :
132 138 : if (msg_level < 0) {
133 : /* It's a warning message. Since corrupt files may generate many warnings,
134 : * the policy implemented here is to show only the first warning,
135 : * unless trace_level >= 3.
136 : */
137 0 : if (err->num_warnings == 0 || err->trace_level >= 3)
138 0 : (*err->output_message) (cinfo);
139 : /* Always count warnings in num_warnings. */
140 0 : err->num_warnings++;
141 : } else {
142 : /* It's a trace message. Show it if trace_level >= msg_level. */
143 138 : if (err->trace_level >= msg_level)
144 0 : (*err->output_message) (cinfo);
145 : }
146 138 : }
147 :
148 :
149 : /*
150 : * Format a message string for the most recent JPEG error or message.
151 : * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
152 : * characters. Note that no '\n' character is added to the string.
153 : * Few applications should need to override this method.
154 : */
155 :
156 : METHODDEF(void)
157 0 : format_message (j_common_ptr cinfo, char * buffer)
158 : {
159 0 : struct jpeg_error_mgr * err = cinfo->err;
160 0 : int msg_code = err->msg_code;
161 0 : const char * msgtext = NULL;
162 : const char * msgptr;
163 : char ch;
164 : boolean isstring;
165 :
166 : /* Look up message string in proper table */
167 0 : if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
168 0 : msgtext = err->jpeg_message_table[msg_code];
169 0 : } else if (err->addon_message_table != NULL &&
170 0 : msg_code >= err->first_addon_message &&
171 0 : msg_code <= err->last_addon_message) {
172 0 : msgtext = err->addon_message_table[msg_code - err->first_addon_message];
173 : }
174 :
175 : /* Defend against bogus message number */
176 0 : if (msgtext == NULL) {
177 0 : err->msg_parm.i[0] = msg_code;
178 0 : msgtext = err->jpeg_message_table[0];
179 : }
180 :
181 : /* Check for string parameter, as indicated by %s in the message text */
182 0 : isstring = FALSE;
183 0 : msgptr = msgtext;
184 0 : while ((ch = *msgptr++) != '\0') {
185 0 : if (ch == '%') {
186 0 : if (*msgptr == 's') isstring = TRUE;
187 0 : break;
188 : }
189 : }
190 :
191 : /* Format the message into the passed buffer */
192 0 : if (isstring)
193 0 : sprintf(buffer, msgtext, err->msg_parm.s);
194 : else
195 0 : sprintf(buffer, msgtext,
196 : err->msg_parm.i[0], err->msg_parm.i[1],
197 : err->msg_parm.i[2], err->msg_parm.i[3],
198 : err->msg_parm.i[4], err->msg_parm.i[5],
199 : err->msg_parm.i[6], err->msg_parm.i[7]);
200 0 : }
201 :
202 :
203 : /*
204 : * Reset error state variables at start of a new image.
205 : * This is called during compression startup to reset trace/error
206 : * processing to default state, without losing any application-specific
207 : * method pointers. An application might possibly want to override
208 : * this method if it has additional error processing state.
209 : */
210 :
211 : METHODDEF(void)
212 8 : reset_error_mgr (j_common_ptr cinfo)
213 : {
214 8 : cinfo->err->num_warnings = 0;
215 : /* trace_level is not reset since it is an application-supplied parameter */
216 8 : cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
217 8 : }
218 :
219 :
220 : /*
221 : * Fill in the standard error-handling methods in a jpeg_error_mgr object.
222 : * Typical call is:
223 : * struct jpeg_compress_struct cinfo;
224 : * struct jpeg_error_mgr err;
225 : *
226 : * cinfo.err = jpeg_std_error(&err);
227 : * after which the application may override some of the methods.
228 : */
229 :
230 : GLOBAL(struct jpeg_error_mgr *)
231 8 : jpeg_std_error (struct jpeg_error_mgr * err)
232 : {
233 8 : err->error_exit = error_exit;
234 8 : err->emit_message = emit_message;
235 8 : err->output_message = output_message;
236 8 : err->format_message = format_message;
237 8 : err->reset_error_mgr = reset_error_mgr;
238 :
239 8 : err->trace_level = 0; /* default = no tracing */
240 8 : err->num_warnings = 0; /* no warnings emitted yet */
241 8 : err->msg_code = 0; /* may be useful as a flag for "no error" */
242 :
243 : /* Initialize message table pointers */
244 8 : err->jpeg_message_table = jpeg_std_message_table;
245 8 : err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
246 :
247 8 : err->addon_message_table = NULL;
248 8 : err->first_addon_message = 0; /* for safety */
249 8 : err->last_addon_message = 0;
250 :
251 8 : return err;
252 : }
|