1 /* PDFlib GmbH cvsid: $Id: pngerror.c,v 1.6.6.1 2009/06/03 08:53:24 rjs Exp $ */
2
3 /* pngerror.c - stub functions for i/o and memory allocation
4 *
5 * Last changed in libpng 1.2.36 [May 7, 2009]
6 * For conditions of distribution and use, see copyright notice in png.h
7 * Copyright (c) 1998-2009 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 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
20
21 /* PDFlib GmbH */
22 #if defined(__ia64__) && defined (__linux__)
23 #define PDFLIB_ALIGN16
24 #endif
25
26 static void /* PRIVATE */
27 png_default_error PNGARG((png_structp png_ptr,
28 png_const_charp error_message));
29 #ifndef PNG_NO_WARNINGS
30 static void /* PRIVATE */
31 png_default_warning PNGARG((png_structp png_ptr,
32 png_const_charp warning_message));
33 #endif /* PNG_NO_WARNINGS */
34
35 /* This function is called whenever there is a fatal error. This function
36 * should not be changed. If there is a need to handle errors differently,
37 * you should supply a replacement error function and use png_set_error_fn()
38 * to replace the error function at run-time.
39 */
40 #ifndef PNG_NO_ERROR_TEXT
41 void PNGAPI
png_error(png_structp png_ptr,png_const_charp error_message)42 png_error(png_structp png_ptr, png_const_charp error_message)
43 {
44 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
45 char msg[16];
46 if (png_ptr != NULL)
47 {
48 if (png_ptr->flags&
49 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
50 {
51 if (*error_message == '#')
52 {
53 /* Strip "#nnnn " from beginning of error message. */
54 int offset;
55 for (offset = 1; offset<15; offset++)
56 if (error_message[offset] == ' ')
57 break;
58 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
59 {
60 int i;
61 for (i = 0; i < offset - 1; i++)
62 msg[i] = error_message[i + 1];
63 msg[i - 1] = '\0';
64 error_message = msg;
65 }
66 else
67 error_message += offset;
68 }
69 else
70 {
71 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
72 {
73 msg[0] = '0';
74 msg[1] = '\0';
75 error_message = msg;
76 }
77 }
78 }
79 }
80 #endif
81 if (png_ptr != NULL && png_ptr->error_fn != NULL)
82 (*(png_ptr->error_fn))(png_ptr, error_message);
83
84 /* If the custom handler doesn't exist, or if it returns,
85 use the default handler, which will not return. */
86 png_default_error(png_ptr, error_message);
87 }
88 #else
89 void PNGAPI
png_err(png_structp png_ptr)90 png_err(png_structp png_ptr)
91 {
92 if (png_ptr != NULL && png_ptr->error_fn != NULL)
93 (*(png_ptr->error_fn))(png_ptr, '\0');
94
95 /* If the custom handler doesn't exist, or if it returns,
96 use the default handler, which will not return. */
97 png_default_error(png_ptr, '\0');
98 }
99 #endif /* PNG_NO_ERROR_TEXT */
100
101 #ifndef PNG_NO_WARNINGS
102 /* This function is called whenever there is a non-fatal error. This function
103 * should not be changed. If there is a need to handle warnings differently,
104 * you should supply a replacement warning function and use
105 * png_set_error_fn() to replace the warning function at run-time.
106 */
107 void PNGAPI
png_warning(png_structp png_ptr,png_const_charp warning_message)108 png_warning(png_structp png_ptr, png_const_charp warning_message)
109 {
110 int offset = 0;
111 if (png_ptr != NULL)
112 {
113 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
114 if (png_ptr->flags&
115 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
116 #endif
117 {
118 if (*warning_message == '#')
119 {
120 for (offset = 1; offset < 15; offset++)
121 if (warning_message[offset] == ' ')
122 break;
123 }
124 }
125 }
126 if (png_ptr != NULL && png_ptr->warning_fn != NULL)
127 (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
128 else
129 png_default_warning(png_ptr, warning_message + offset);
130 }
131 #endif /* PNG_NO_WARNINGS */
132
133
134 /* These utilities are used internally to build an error message that relates
135 * to the current chunk. The chunk name comes from png_ptr->chunk_name,
136 * this is used to prefix the message. The message is limited in length
137 * to 63 bytes, the name characters are output as hex digits wrapped in []
138 * if the character is invalid.
139 */
140 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
141 static PNG_CONST char png_digit[16] = {
142 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
143 'A', 'B', 'C', 'D', 'E', 'F'
144 };
145
146 #define PNG_MAX_ERROR_TEXT 64
147
148 #if !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT)
149 static void /* PRIVATE */
png_format_buffer(png_structp png_ptr,png_charp buffer,png_const_charp error_message)150 png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
151 error_message)
152 {
153 int iout = 0, iin = 0;
154
155 while (iin < 4)
156 {
157 int c = png_ptr->chunk_name[iin++];
158 if (isnonalpha(c))
159 {
160 buffer[iout++] = '[';
161 buffer[iout++] = png_digit[(c & 0xf0) >> 4];
162 buffer[iout++] = png_digit[c & 0x0f];
163 buffer[iout++] = ']';
164 }
165 else
166 {
167 buffer[iout++] = (png_byte)c;
168 }
169 }
170
171 if (error_message == NULL)
172 buffer[iout] = '\0';
173 else
174 {
175 buffer[iout++] = ':';
176 buffer[iout++] = ' ';
177 png_memcpy(buffer + iout, error_message, PNG_MAX_ERROR_TEXT);
178 buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0';
179 }
180 }
181
182 #ifdef PNG_READ_SUPPORTED
183 void PNGAPI
png_chunk_error(png_structp png_ptr,png_const_charp error_message)184 png_chunk_error(png_structp png_ptr, png_const_charp error_message)
185 {
186 char msg[18+PNG_MAX_ERROR_TEXT];
187 if (png_ptr == NULL)
188 png_error(png_ptr, error_message);
189 else
190 {
191 png_format_buffer(png_ptr, msg, error_message);
192 png_error(png_ptr, msg);
193 }
194 }
195 #endif /* PNG_READ_SUPPORTED */
196 #endif /* !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT) */
197
198 #ifndef PNG_NO_WARNINGS
199 void PNGAPI
png_chunk_warning(png_structp png_ptr,png_const_charp warning_message)200 png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
201 {
202 char msg[18+PNG_MAX_ERROR_TEXT];
203 if (png_ptr == NULL)
204 png_warning(png_ptr, warning_message);
205 else
206 {
207 png_format_buffer(png_ptr, msg, warning_message);
208 png_warning(png_ptr, msg);
209 }
210 }
211 #endif /* PNG_NO_WARNINGS */
212
213
214 /* This is the default error handling function. Note that replacements for
215 * this function MUST NOT RETURN, or the program will likely crash. This
216 * function is used by default, or if the program supplies NULL for the
217 * error function pointer in png_set_error_fn().
218 */
219 static void /* PRIVATE */
png_default_error(png_structp png_ptr,png_const_charp error_message)220 png_default_error(png_structp png_ptr, png_const_charp error_message)
221 {
222 #ifndef PNG_NO_CONSOLE_IO
223 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
224 if (*error_message == '#')
225 {
226 /* Strip "#nnnn " from beginning of error message. */
227 int offset;
228 char error_number[16];
229 for (offset = 0; offset<15; offset++)
230 {
231 error_number[offset] = error_message[offset + 1];
232 if (error_message[offset] == ' ')
233 break;
234 }
235 if ((offset > 1) && (offset < 15))
236 {
237 error_number[offset - 1] = '\0';
238 fprintf(stderr, "libpng error no. %s: %s",
239 error_number, error_message + offset + 1);
240 fprintf(stderr, PNG_STRING_NEWLINE);
241 }
242 else
243 fprintf(stderr, "libpng error: %s, offset=%d",
244 error_message, offset);
245 fprintf(stderr, PNG_STRING_NEWLINE);
246 }
247 else
248 #endif
249 {
250 fprintf(stderr, "libpng error: %s", error_message);
251 fprintf(stderr, PNG_STRING_NEWLINE);
252 }
253 #endif
254
255 #ifdef PNG_SETJMP_SUPPORTED
256 if (png_ptr)
257 {
258 # if defined(USE_FAR_KEYWORD) || defined (PDFLIB_ALIGN16)
259 {
260 jmp_buf jmpbuf;
261 png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf));
262 longjmp(jmpbuf, 1);
263 }
264 # else
265 longjmp(png_ptr->jmpbuf, 1);
266 # endif
267 }
268 #else
269 PNG_ABORT();
270 #endif
271 #ifdef PNG_NO_CONSOLE_IO
272 error_message = error_message; /* make compiler happy */
273 #endif
274 }
275
276 #ifndef PNG_NO_WARNINGS
277 /* This function is called when there is a warning, but the library thinks
278 * it can continue anyway. Replacement functions don't have to do anything
279 * here if you don't want them to. In the default configuration, png_ptr is
280 * not used, but it is passed in case it may be useful.
281 */
282 static void /* PRIVATE */
png_default_warning(png_structp png_ptr,png_const_charp warning_message)283 png_default_warning(png_structp png_ptr, png_const_charp warning_message)
284 {
285 #ifndef PNG_NO_CONSOLE_IO
286 # ifdef PNG_ERROR_NUMBERS_SUPPORTED
287 if (*warning_message == '#')
288 {
289 int offset;
290 char warning_number[16];
291 for (offset = 0; offset < 15; offset++)
292 {
293 warning_number[offset] = warning_message[offset + 1];
294 if (warning_message[offset] == ' ')
295 break;
296 }
297 if ((offset > 1) && (offset < 15))
298 {
299 warning_number[offset + 1] = '\0';
300 fprintf(stderr, "libpng warning no. %s: %s",
301 warning_number, warning_message + offset);
302 fprintf(stderr, PNG_STRING_NEWLINE);
303 }
304 else
305 {
306 fprintf(stderr, "libpng warning: %s",
307 warning_message);
308 fprintf(stderr, PNG_STRING_NEWLINE);
309 }
310 }
311 else
312 # endif
313 {
314 fprintf(stderr, "libpng warning: %s", warning_message);
315 fprintf(stderr, PNG_STRING_NEWLINE);
316 }
317 #else
318 warning_message = warning_message; /* make compiler happy */
319 #endif
320 png_ptr = png_ptr; /* make compiler happy */
321 }
322 #endif /* PNG_NO_WARNINGS */
323
324 /* This function is called when the application wants to use another method
325 * of handling errors and warnings. Note that the error function MUST NOT
326 * return to the calling routine or serious problems will occur. The return
327 * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
328 */
329 void PNGAPI
png_set_error_fn(png_structp png_ptr,png_voidp error_ptr,png_error_ptr error_fn,png_error_ptr warning_fn)330 png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
331 png_error_ptr error_fn, png_error_ptr warning_fn)
332 {
333 if (png_ptr == NULL)
334 return;
335 png_ptr->error_ptr = error_ptr;
336 png_ptr->error_fn = error_fn;
337 png_ptr->warning_fn = warning_fn;
338 }
339
340
341 /* This function returns a pointer to the error_ptr associated with the user
342 * functions. The application should free any memory associated with this
343 * pointer before png_write_destroy and png_read_destroy are called.
344 */
345 png_voidp PNGAPI
png_get_error_ptr(png_structp png_ptr)346 png_get_error_ptr(png_structp png_ptr)
347 {
348 if (png_ptr == NULL)
349 return NULL;
350 return ((png_voidp)png_ptr->error_ptr);
351 }
352
353
354 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
355 void PNGAPI
png_set_strip_error_numbers(png_structp png_ptr,png_uint_32 strip_mode)356 png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
357 {
358 if (png_ptr != NULL)
359 {
360 png_ptr->flags &=
361 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
362 }
363 }
364 #endif
365 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
366