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