1/* PDFlib GmbH cvsid: $Id: pngerror.c 14574 2005-10-29 16:27:43Z bonefish $ */ 2 3/* pngerror.c - stub functions for i/o and memory allocation 4 * 5 * libpng 1.2.5 - October 3, 2002 6 * For conditions of distribution and use, see copyright notice in png.h 7 * Copyright (c) 1998-2002 Glenn Randers-Pehrson 8 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 9 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 10 * 11 * This file provides a location for all error handling. Users who 12 * need special error handling are expected to write replacement functions 13 * and use png_set_error_fn() to use those functions. See the instructions 14 * at each function. 15 */ 16 17#define PNG_INTERNAL 18#include "png.h" 19 20static void /* PRIVATE */ 21png_default_error PNGARG((png_structp png_ptr, 22 png_const_charp error_message)); 23static void /* PRIVATE */ 24png_default_warning PNGARG((png_structp png_ptr, 25 png_const_charp warning_message)); 26 27/* This function is called whenever there is a fatal error. This function 28 * should not be changed. If there is a need to handle errors differently, 29 * you should supply a replacement error function and use png_set_error_fn() 30 * to replace the error function at run-time. 31 */ 32void PNGAPI 33png_error(png_structp png_ptr, png_const_charp error_message) 34{ 35#ifdef PNG_ERROR_NUMBERS_SUPPORTED 36 char msg[16]; 37 if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) 38 { 39 int offset = 0; 40 if (*error_message == '#') 41 { 42 for (offset=1; offset<15; offset++) 43 if (*(error_message+offset) == ' ') 44 break; 45 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 46 { 47 int i; 48 for (i=0; i<offset-1; i++) 49 msg[i]=error_message[i+1]; 50 msg[i]='\0'; 51 error_message=msg; 52 } 53 else 54 error_message+=offset; 55 } 56 else 57 { 58 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 59 { 60 msg[0]='0'; 61 msg[1]='\0'; 62 error_message=msg; 63 } 64 } 65 } 66#endif 67 if (png_ptr->error_fn != NULL) 68 (*(png_ptr->error_fn))(png_ptr, error_message); 69 70 /* if the following returns or doesn't exist, use the default function, 71 which will not return */ 72 png_default_error(png_ptr, error_message); 73} 74 75/* This function is called whenever there is a non-fatal error. This function 76 * should not be changed. If there is a need to handle warnings differently, 77 * you should supply a replacement warning function and use 78 * png_set_error_fn() to replace the warning function at run-time. 79 */ 80void PNGAPI 81png_warning(png_structp png_ptr, png_const_charp warning_message) 82{ 83 int offset = 0; 84#ifdef PNG_ERROR_NUMBERS_SUPPORTED 85 if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) 86#endif 87 { 88 if (*warning_message == '#') 89 { 90 for (offset=1; offset<15; offset++) 91 if (*(warning_message+offset) == ' ') 92 break; 93 } 94 } 95 if (png_ptr->warning_fn != NULL) 96 (*(png_ptr->warning_fn))(png_ptr, 97 (png_const_charp)(warning_message+offset)); 98 else 99 png_default_warning(png_ptr, (png_const_charp)(warning_message+offset)); 100} 101 102/* These utilities are used internally to build an error message that relates 103 * to the current chunk. The chunk name comes from png_ptr->chunk_name, 104 * this is used to prefix the message. The message is limited in length 105 * to 63 bytes, the name characters are output as hex digits wrapped in [] 106 * if the character is invalid. 107 */ 108#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97)) 109static PNG_CONST char png_digit[16] = { 110 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 111 'F' }; 112 113static void /* PRIVATE */ 114png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp 115 error_message) 116{ 117 int iout = 0, iin = 0; 118 119 while (iin < 4) 120 { 121 int c = png_ptr->chunk_name[iin++]; 122 if (isnonalpha(c)) 123 { 124 buffer[iout++] = '['; 125 buffer[iout++] = png_digit[(c & 0xf0) >> 4]; 126 buffer[iout++] = png_digit[c & 0x0f]; 127 buffer[iout++] = ']'; 128 } 129 else 130 { 131 buffer[iout++] = (png_byte)c; 132 } 133 } 134 135 if (error_message == NULL) 136 buffer[iout] = 0; 137 else 138 { 139 buffer[iout++] = ':'; 140 buffer[iout++] = ' '; 141 png_memcpy(buffer+iout, error_message, 64); 142 buffer[iout+63] = 0; 143 } 144} 145 146void PNGAPI 147png_chunk_error(png_structp png_ptr, png_const_charp error_message) 148{ 149 char msg[18+64]; 150 png_format_buffer(png_ptr, msg, error_message); 151 png_error(png_ptr, msg); 152} 153 154void PNGAPI 155png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) 156{ 157 char msg[18+64]; 158 png_format_buffer(png_ptr, msg, warning_message); 159 png_warning(png_ptr, msg); 160} 161 162/* This is the default error handling function. Note that replacements for 163 * this function MUST NOT RETURN, or the program will likely crash. This 164 * function is used by default, or if the program supplies NULL for the 165 * error function pointer in png_set_error_fn(). 166 */ 167static void /* PRIVATE */ 168png_default_error(png_structp png_ptr, png_const_charp error_message) 169{ 170#ifndef PNG_NO_CONSOLE_IO 171#ifdef PNG_ERROR_NUMBERS_SUPPORTED 172 if (*error_message == '#') 173 { 174 int offset; 175 char error_number[16]; 176 for (offset=0; offset<15; offset++) 177 { 178 error_number[offset] = *(error_message+offset+1); 179 if (*(error_message+offset) == ' ') 180 break; 181 } 182 if((offset > 1) && (offset < 15)) 183 { 184 error_number[offset-1]='\0'; 185 fprintf(stderr, "libpng error no. %s: %s\n", error_number, 186 error_message+offset); 187 } 188 else 189 fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset); 190 } 191 else 192#endif 193 fprintf(stderr, "libpng error: %s\n", error_message); 194#else 195 if (error_message) 196 /* make compiler happy */ ; 197#endif 198 199#ifdef PNG_SETJMP_SUPPORTED 200# ifdef USE_FAR_KEYWORD 201 { 202 jmp_buf jmpbuf; 203 png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf)); 204 longjmp(jmpbuf, 1); 205 } 206# else 207 longjmp(png_ptr->jmpbuf, 1); 208# endif 209#else 210 if (png_ptr) 211 /* make compiler happy */ ; 212 PNG_ABORT(); 213#endif 214} 215 216/* This function is called when there is a warning, but the library thinks 217 * it can continue anyway. Replacement functions don't have to do anything 218 * here if you don't want them to. In the default configuration, png_ptr is 219 * not used, but it is passed in case it may be useful. 220 */ 221static void /* PRIVATE */ 222png_default_warning(png_structp png_ptr, png_const_charp warning_message) 223{ 224#ifndef PNG_NO_CONSOLE_IO 225# ifdef PNG_ERROR_NUMBERS_SUPPORTED 226 if (*warning_message == '#') 227 { 228 int offset; 229 char warning_number[16]; 230 for (offset=0; offset<15; offset++) 231 { 232 warning_number[offset]=*(warning_message+offset+1); 233 if (*(warning_message+offset) == ' ') 234 break; 235 } 236 if((offset > 1) && (offset < 15)) 237 { 238 warning_number[offset-1]='\0'; 239 fprintf(stderr, "libpng warning no. %s: %s\n", warning_number, 240 warning_message+offset); 241 } 242 else 243 fprintf(stderr, "libpng warning: %s\n", warning_message); 244 } 245 else 246# endif 247 fprintf(stderr, "libpng warning: %s\n", warning_message); 248#else 249 if (warning_message) 250 /* appease compiler */ ; 251#endif 252 if (png_ptr) 253 return; 254} 255 256/* This function is called when the application wants to use another method 257 * of handling errors and warnings. Note that the error function MUST NOT 258 * return to the calling routine or serious problems will occur. The return 259 * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) 260 */ 261void PNGAPI 262png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, 263 png_error_ptr error_fn, png_error_ptr warning_fn) 264{ 265 png_ptr->error_ptr = error_ptr; 266 png_ptr->error_fn = error_fn; 267 png_ptr->warning_fn = warning_fn; 268} 269 270 271/* This function returns a pointer to the error_ptr associated with the user 272 * functions. The application should free any memory associated with this 273 * pointer before png_write_destroy and png_read_destroy are called. 274 */ 275png_voidp PNGAPI 276png_get_error_ptr(png_structp png_ptr) 277{ 278 return ((png_voidp)png_ptr->error_ptr); 279} 280 281 282#ifdef PNG_ERROR_NUMBERS_SUPPORTED 283void PNGAPI 284png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) 285{ 286 if(png_ptr != NULL) 287 { 288 png_ptr->flags &= 289 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); 290 } 291} 292#endif 293