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