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