xref: /aosp_15_r20/external/libjpeg-turbo/jerror.c (revision dfc6aa5c1cfd4bc4e2018dc74aa96e29ee49c6da)
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