Back to index

plt-scheme  4.2.1
jerror.c
Go to the documentation of this file.
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 }