00001 /* 00002 * jerror.c 00003 * 00004 * Copyright (C) 1991-1998, Thomas G. Lane. 00005 * This file is part of the Independent JPEG Group's software. 00006 * For conditions of distribution and use, see the accompanying README file. 00007 * 00008 * This file contains simple error-reporting and trace-message routines. 00009 * These are suitable for Unix-like systems and others where writing to 00010 * stderr is the right thing to do. Many applications will want to replace 00011 * some or all of these routines. 00012 * 00013 * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile, 00014 * you get a Windows-specific hack to display error messages in a dialog box. 00015 * It ain't much, but it beats dropping error messages into the bit bucket, 00016 * which is what happens to output to stderr under most Windows C compilers. 00017 * 00018 * These routines are used by both the compression and decompression code. 00019 */ 00020 00021 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 00022 #include "jinclude.h" 00023 #include "jpeglib.h" 00024 #include "jversion.h" 00025 #include "jerror.h" 00026 00027 #ifdef USE_WINDOWS_MESSAGEBOX 00028 #include <windows.h> 00029 #endif 00030 00031 #ifndef EXIT_FAILURE /* define exit() codes if not provided */ 00032 #define EXIT_FAILURE 1 00033 #endif 00034 00035 00036 /* 00037 * Create the message string table. 00038 * We do this from the master message list in jerror.h by re-reading 00039 * jerror.h with a suitable definition for macro JMESSAGE. 00040 * The message table is made an external symbol just in case any applications 00041 * want to refer to it directly. 00042 */ 00043 00044 #ifdef NEED_SHORT_EXTERNAL_NAMES 00045 #define jpeg_std_message_table jMsgTable 00046 #endif 00047 00048 #define JMESSAGE(code,string) string , 00049 00050 const char * const jpeg_std_message_table[] = { 00051 #include "jerror.h" 00052 NULL 00053 }; 00054 00055 00056 /* 00057 * Error exit handler: must not return to caller. 00058 * 00059 * Applications may override this if they want to get control back after 00060 * an error. Typically one would longjmp somewhere instead of exiting. 00061 * The setjmp buffer can be made a private field within an expanded error 00062 * handler object. Note that the info needed to generate an error message 00063 * is stored in the error object, so you can generate the message now or 00064 * later, at your convenience. 00065 * You should make sure that the JPEG object is cleaned up (with jpeg_abort 00066 * or jpeg_destroy) at some point. 00067 */ 00068 00069 METHODDEF(void) 00070 error_exit (j_common_ptr cinfo) 00071 { 00072 /* Always display the message */ 00073 (*cinfo->err->output_message) (cinfo); 00074 00075 /* Let the memory manager delete any temp files before we die */ 00076 jpeg_destroy(cinfo); 00077 00078 exit(EXIT_FAILURE); 00079 } 00080 00081 00082 /* 00083 * Actual output of an error or trace message. 00084 * Applications may override this method to send JPEG messages somewhere 00085 * other than stderr. 00086 * 00087 * On Windows, printing to stderr is generally completely useless, 00088 * so we provide optional code to produce an error-dialog popup. 00089 * Most Windows applications will still prefer to override this routine, 00090 * but if they don't, it'll do something at least marginally useful. 00091 * 00092 * NOTE: to use the library in an environment that doesn't support the 00093 * C stdio library, you may have to delete the call to fprintf() entirely, 00094 * not just not use this routine. 00095 */ 00096 00097 METHODDEF(void) 00098 output_message (j_common_ptr cinfo) 00099 { 00100 char buffer[JMSG_LENGTH_MAX]; 00101 00102 /* Create the message */ 00103 (*cinfo->err->format_message) (cinfo, buffer); 00104 00105 #ifdef USE_WINDOWS_MESSAGEBOX 00106 /* Display it in a message dialog box */ 00107 MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", 00108 MB_OK | MB_ICONERROR); 00109 #else 00110 /* Send it to stderr, adding a newline */ 00111 fprintf(stderr, "%s\n", buffer); 00112 #endif 00113 } 00114 00115 00116 /* 00117 * Decide whether to emit a trace or warning message. 00118 * msg_level is one of: 00119 * -1: recoverable corrupt-data warning, may want to abort. 00120 * 0: important advisory messages (always display to user). 00121 * 1: first level of tracing detail. 00122 * 2,3,...: successively more detailed tracing messages. 00123 * An application might override this method if it wanted to abort on warnings 00124 * or change the policy about which messages to display. 00125 */ 00126 00127 METHODDEF(void) 00128 emit_message (j_common_ptr cinfo, int msg_level) 00129 { 00130 struct jpeg_error_mgr * err = cinfo->err; 00131 00132 if (msg_level < 0) { 00133 /* It's a warning message. Since corrupt files may generate many warnings, 00134 * the policy implemented here is to show only the first warning, 00135 * unless trace_level >= 3. 00136 */ 00137 if (err->num_warnings == 0 || err->trace_level >= 3) 00138 (*err->output_message) (cinfo); 00139 /* Always count warnings in num_warnings. */ 00140 err->num_warnings++; 00141 } else { 00142 /* It's a trace message. Show it if trace_level >= msg_level. */ 00143 if (err->trace_level >= msg_level) 00144 (*err->output_message) (cinfo); 00145 } 00146 } 00147 00148 00149 /* 00150 * Format a message string for the most recent JPEG error or message. 00151 * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX 00152 * characters. Note that no '\n' character is added to the string. 00153 * Few applications should need to override this method. 00154 */ 00155 00156 METHODDEF(void) 00157 format_message (j_common_ptr cinfo, char * buffer) 00158 { 00159 struct jpeg_error_mgr * err = cinfo->err; 00160 int msg_code = err->msg_code; 00161 const char * msgtext = NULL; 00162 const char * msgptr; 00163 char ch; 00164 boolean isstring; 00165 00166 /* Look up message string in proper table */ 00167 if (msg_code > 0 && msg_code <= err->last_jpeg_message) { 00168 msgtext = err->jpeg_message_table[msg_code]; 00169 } else if (err->addon_message_table != NULL && 00170 msg_code >= err->first_addon_message && 00171 msg_code <= err->last_addon_message) { 00172 msgtext = err->addon_message_table[msg_code - err->first_addon_message]; 00173 } 00174 00175 /* Defend against bogus message number */ 00176 if (msgtext == NULL) { 00177 err->msg_parm.i[0] = msg_code; 00178 msgtext = err->jpeg_message_table[0]; 00179 } 00180 00181 /* Check for string parameter, as indicated by %s in the message text */ 00182 isstring = FALSE; 00183 msgptr = msgtext; 00184 while ((ch = *msgptr++) != '\0') { 00185 if (ch == '%') { 00186 if (*msgptr == 's') isstring = TRUE; 00187 break; 00188 } 00189 } 00190 00191 /* Format the message into the passed buffer */ 00192 if (isstring) 00193 sprintf(buffer, msgtext, err->msg_parm.s); 00194 else 00195 sprintf(buffer, msgtext, 00196 err->msg_parm.i[0], err->msg_parm.i[1], 00197 err->msg_parm.i[2], err->msg_parm.i[3], 00198 err->msg_parm.i[4], err->msg_parm.i[5], 00199 err->msg_parm.i[6], err->msg_parm.i[7]); 00200 } 00201 00202 00203 /* 00204 * Reset error state variables at start of a new image. 00205 * This is called during compression startup to reset trace/error 00206 * processing to default state, without losing any application-specific 00207 * method pointers. An application might possibly want to override 00208 * this method if it has additional error processing state. 00209 */ 00210 00211 METHODDEF(void) 00212 reset_error_mgr (j_common_ptr cinfo) 00213 { 00214 cinfo->err->num_warnings = 0; 00215 /* trace_level is not reset since it is an application-supplied parameter */ 00216 cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ 00217 } 00218 00219 00220 /* 00221 * Fill in the standard error-handling methods in a jpeg_error_mgr object. 00222 * Typical call is: 00223 * struct jpeg_compress_struct cinfo; 00224 * struct jpeg_error_mgr err; 00225 * 00226 * cinfo.err = jpeg_std_error(&err); 00227 * after which the application may override some of the methods. 00228 */ 00229 00230 GLOBAL(struct jpeg_error_mgr *) 00231 jpeg_std_error (struct jpeg_error_mgr * err) 00232 { 00233 err->error_exit = error_exit; 00234 err->emit_message = emit_message; 00235 err->output_message = output_message; 00236 err->format_message = format_message; 00237 err->reset_error_mgr = reset_error_mgr; 00238 00239 err->trace_level = 0; /* default = no tracing */ 00240 err->num_warnings = 0; /* no warnings emitted yet */ 00241 err->msg_code = 0; /* may be useful as a flag for "no error" */ 00242 00243 /* Initialize message table pointers */ 00244 err->jpeg_message_table = jpeg_std_message_table; 00245 err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; 00246 00247 err->addon_message_table = NULL; 00248 err->first_addon_message = 0; /* for safety */ 00249 err->last_addon_message = 0; 00250 00251 return err; 00252 }