Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(396)

Side by Side Diff: third_party/libpng/pngerror.c

Issue 2021403002: Update libpng to 1.6.22 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rearrange pnglibconf.h Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libpng/pngdebug.h ('k') | third_party/libpng/pnggccrd.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* pngerror.c - stub functions for i/o and memory allocation 2 /* pngerror.c - stub functions for i/o and memory allocation
3 * 3 *
4 * Last changed in libpng 1.2.51 [February 6, 2014] 4 * Last changed in libpng 1.6.15 [November 20, 2014]
5 * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson 5 * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 * 8 *
9 * This code is released under the libpng license. 9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer 10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h 11 * and license in png.h
12 * 12 *
13 * This file provides a location for all error handling. Users who 13 * This file provides a location for all error handling. Users who
14 * need special error handling are expected to write replacement functions 14 * need special error handling are expected to write replacement functions
15 * and use png_set_error_fn() to use those functions. See the instructions 15 * and use png_set_error_fn() to use those functions. See the instructions
16 * at each function. 16 * at each function.
17 */ 17 */
18 18
19 #define PNG_INTERNAL 19 #include "pngpriv.h"
20 #define PNG_NO_PEDANTIC_WARNINGS 20
21 #include "png.h"
22 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 21 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
23 22
24 static void /* PRIVATE */ 23 static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
25 png_default_error PNGARG((png_structp png_ptr, 24 png_const_charp error_message)),PNG_NORETURN);
26 png_const_charp error_message)) PNG_NORETURN; 25
27 #ifdef PNG_WARNINGS_SUPPORTED 26 #ifdef PNG_WARNINGS_SUPPORTED
28 static void /* PRIVATE */ 27 static void /* PRIVATE */
29 png_default_warning PNGARG((png_structp png_ptr, 28 png_default_warning PNGARG((png_const_structrp png_ptr,
30 png_const_charp warning_message)); 29 png_const_charp warning_message));
31 #endif /* PNG_WARNINGS_SUPPORTED */ 30 #endif /* WARNINGS */
32 31
33 /* This function is called whenever there is a fatal error. This function 32 /* This function is called whenever there is a fatal error. This function
34 * should not be changed. If there is a need to handle errors differently, 33 * should not be changed. If there is a need to handle errors differently,
35 * you should supply a replacement error function and use png_set_error_fn() 34 * you should supply a replacement error function and use png_set_error_fn()
36 * to replace the error function at run-time. 35 * to replace the error function at run-time.
37 */ 36 */
38 #ifdef PNG_ERROR_TEXT_SUPPORTED 37 #ifdef PNG_ERROR_TEXT_SUPPORTED
39 void PNGAPI 38 PNG_FUNCTION(void,PNGAPI
40 png_error(png_structp png_ptr, png_const_charp error_message) 39 png_error,(png_const_structrp png_ptr, png_const_charp error_message),
40 PNG_NORETURN)
41 { 41 {
42 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 42 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
43 char msg[16]; 43 char msg[16];
44 if (png_ptr != NULL) 44 if (png_ptr != NULL)
45 { 45 {
46 if (png_ptr->flags& 46 if ((png_ptr->flags &
47 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) 47 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
48 { 48 {
49 if (*error_message == PNG_LITERAL_SHARP) 49 if (*error_message == PNG_LITERAL_SHARP)
50 { 50 {
51 /* Strip "#nnnn " from beginning of error message. */ 51 /* Strip "#nnnn " from beginning of error message. */
52 int offset; 52 int offset;
53 for (offset = 1; offset<15; offset++) 53 for (offset = 1; offset<15; offset++)
54 if (error_message[offset] == ' ') 54 if (error_message[offset] == ' ')
55 break; 55 break;
56 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 56
57 { 57 if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
58 int i; 58 {
59 for (i = 0; i < offset - 1; i++) 59 int i;
60 msg[i] = error_message[i + 1]; 60 for (i = 0; i < offset - 1; i++)
61 msg[i - 1] = '\0'; 61 msg[i] = error_message[i + 1];
62 error_message = msg; 62 msg[i - 1] = '\0';
63 } 63 error_message = msg;
64 else 64 }
65 error_message += offset; 65
66 } 66 else
67 else 67 error_message += offset;
68 { 68 }
69 if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) 69
70 { 70 else
71 msg[0] = '0'; 71 {
72 msg[1] = '\0'; 72 if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
73 error_message = msg; 73 {
74 } 74 msg[0] = '0';
75 msg[1] = '\0';
76 error_message = msg;
77 }
75 } 78 }
76 } 79 }
77 } 80 }
78 #endif 81 #endif
79 if (png_ptr != NULL && png_ptr->error_fn != NULL) 82 if (png_ptr != NULL && png_ptr->error_fn != NULL)
80 (*(png_ptr->error_fn))(png_ptr, error_message); 83 (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
84 error_message);
81 85
82 /* If the custom handler doesn't exist, or if it returns, 86 /* If the custom handler doesn't exist, or if it returns,
83 use the default handler, which will not return. */ 87 use the default handler, which will not return. */
84 png_default_error(png_ptr, error_message); 88 png_default_error(png_ptr, error_message);
85 } 89 }
86 #else 90 #else
87 void PNGAPI 91 PNG_FUNCTION(void,PNGAPI
88 png_err(png_structp png_ptr) 92 png_err,(png_const_structrp png_ptr),PNG_NORETURN)
89 { 93 {
90 /* Prior to 1.2.45 the error_fn received a NULL pointer, expressed 94 /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
91 * erroneously as '\0', instead of the empty string "". This was 95 * erroneously as '\0', instead of the empty string "". This was
92 * apparently an error, introduced in libpng-1.2.20, and png_default_error 96 * apparently an error, introduced in libpng-1.2.20, and png_default_error
93 * will crash in this case. 97 * will crash in this case.
94 */ 98 */
95 if (png_ptr != NULL && png_ptr->error_fn != NULL) 99 if (png_ptr != NULL && png_ptr->error_fn != NULL)
96 (*(png_ptr->error_fn))(png_ptr, ""); 100 (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
97 101
98 /* If the custom handler doesn't exist, or if it returns, 102 /* If the custom handler doesn't exist, or if it returns,
99 use the default handler, which will not return. */ 103 use the default handler, which will not return. */
100 png_default_error(png_ptr, ""); 104 png_default_error(png_ptr, "");
101 } 105 }
102 #endif /* PNG_ERROR_TEXT_SUPPORTED */ 106 #endif /* ERROR_TEXT */
107
108 /* Utility to safely appends strings to a buffer. This never errors out so
109 * error checking is not required in the caller.
110 */
111 size_t
112 png_safecat(png_charp buffer, size_t bufsize, size_t pos,
113 png_const_charp string)
114 {
115 if (buffer != NULL && pos < bufsize)
116 {
117 if (string != NULL)
118 while (*string != '\0' && pos < bufsize-1)
119 buffer[pos++] = *string++;
120
121 buffer[pos] = '\0';
122 }
123
124 return pos;
125 }
126
127 #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
128 /* Utility to dump an unsigned value into a buffer, given a start pointer and
129 * and end pointer (which should point just *beyond* the end of the buffer!)
130 * Returns the pointer to the start of the formatted string.
131 */
132 png_charp
133 png_format_number(png_const_charp start, png_charp end, int format,
134 png_alloc_size_t number)
135 {
136 int count = 0; /* number of digits output */
137 int mincount = 1; /* minimum number required */
138 int output = 0; /* digit output (for the fixed point format) */
139
140 *--end = '\0';
141
142 /* This is written so that the loop always runs at least once, even with
143 * number zero.
144 */
145 while (end > start && (number != 0 || count < mincount))
146 {
147
148 static const char digits[] = "0123456789ABCDEF";
149
150 switch (format)
151 {
152 case PNG_NUMBER_FORMAT_fixed:
153 /* Needs five digits (the fraction) */
154 mincount = 5;
155 if (output != 0 || number % 10 != 0)
156 {
157 *--end = digits[number % 10];
158 output = 1;
159 }
160 number /= 10;
161 break;
162
163 case PNG_NUMBER_FORMAT_02u:
164 /* Expects at least 2 digits. */
165 mincount = 2;
166 /* FALL THROUGH */
167
168 case PNG_NUMBER_FORMAT_u:
169 *--end = digits[number % 10];
170 number /= 10;
171 break;
172
173 case PNG_NUMBER_FORMAT_02x:
174 /* This format expects at least two digits */
175 mincount = 2;
176 /* FALL THROUGH */
177
178 case PNG_NUMBER_FORMAT_x:
179 *--end = digits[number & 0xf];
180 number >>= 4;
181 break;
182
183 default: /* an error */
184 number = 0;
185 break;
186 }
187
188 /* Keep track of the number of digits added */
189 ++count;
190
191 /* Float a fixed number here: */
192 if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))
193 {
194 /* End of the fraction, but maybe nothing was output? In that case
195 * drop the decimal point. If the number is a true zero handle that
196 * here.
197 */
198 if (output != 0)
199 *--end = '.';
200 else if (number == 0) /* and !output */
201 *--end = '0';
202 }
203 }
204
205 return end;
206 }
207 #endif
103 208
104 #ifdef PNG_WARNINGS_SUPPORTED 209 #ifdef PNG_WARNINGS_SUPPORTED
105 /* This function is called whenever there is a non-fatal error. This function 210 /* This function is called whenever there is a non-fatal error. This function
106 * should not be changed. If there is a need to handle warnings differently, 211 * should not be changed. If there is a need to handle warnings differently,
107 * you should supply a replacement warning function and use 212 * you should supply a replacement warning function and use
108 * png_set_error_fn() to replace the warning function at run-time. 213 * png_set_error_fn() to replace the warning function at run-time.
109 */ 214 */
110 void PNGAPI 215 void PNGAPI
111 png_warning(png_structp png_ptr, png_const_charp warning_message) 216 png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
112 { 217 {
113 int offset = 0; 218 int offset = 0;
114 if (png_ptr != NULL) 219 if (png_ptr != NULL)
115 { 220 {
116 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 221 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
117 if (png_ptr->flags& 222 if ((png_ptr->flags &
118 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) 223 (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
119 #endif 224 #endif
120 { 225 {
121 if (*warning_message == PNG_LITERAL_SHARP) 226 if (*warning_message == PNG_LITERAL_SHARP)
122 { 227 {
123 for (offset = 1; offset < 15; offset++) 228 for (offset = 1; offset < 15; offset++)
124 if (warning_message[offset] == ' ') 229 if (warning_message[offset] == ' ')
125 break; 230 break;
126 } 231 }
127 } 232 }
128 } 233 }
129 if (png_ptr != NULL && png_ptr->warning_fn != NULL) 234 if (png_ptr != NULL && png_ptr->warning_fn != NULL)
130 (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); 235 (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
236 warning_message + offset);
131 else 237 else
132 png_default_warning(png_ptr, warning_message + offset); 238 png_default_warning(png_ptr, warning_message + offset);
133 } 239 }
134 #endif /* PNG_WARNINGS_SUPPORTED */ 240
241 /* These functions support 'formatted' warning messages with up to
242 * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter
243 * is introduced by @<number>, where 'number' starts at 1. This follows the
244 * standard established by X/Open for internationalizable error messages.
245 */
246 void
247 png_warning_parameter(png_warning_parameters p, int number,
248 png_const_charp string)
249 {
250 if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
251 (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
252 }
253
254 void
255 png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
256 png_alloc_size_t value)
257 {
258 char buffer[PNG_NUMBER_BUFFER_SIZE];
259 png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
260 }
261
262 void
263 png_warning_parameter_signed(png_warning_parameters p, int number, int format,
264 png_int_32 value)
265 {
266 png_alloc_size_t u;
267 png_charp str;
268 char buffer[PNG_NUMBER_BUFFER_SIZE];
269
270 /* Avoid overflow by doing the negate in a png_alloc_size_t: */
271 u = (png_alloc_size_t)value;
272 if (value < 0)
273 u = ~u + 1;
274
275 str = PNG_FORMAT_NUMBER(buffer, format, u);
276
277 if (value < 0 && str > buffer)
278 *--str = '-';
279
280 png_warning_parameter(p, number, str);
281 }
282
283 void
284 png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
285 png_const_charp message)
286 {
287 /* The internal buffer is just 192 bytes - enough for all our messages,
288 * overflow doesn't happen because this code checks! If someone figures
289 * out how to send us a message longer than 192 bytes, all that will
290 * happen is that the message will be truncated appropriately.
291 */
292 size_t i = 0; /* Index in the msg[] buffer: */
293 char msg[192];
294
295 /* Each iteration through the following loop writes at most one character
296 * to msg[i++] then returns here to validate that there is still space for
297 * the trailing '\0'. It may (in the case of a parameter) read more than
298 * one character from message[]; it must check for '\0' and continue to the
299 * test if it finds the end of string.
300 */
301 while (i<(sizeof msg)-1 && *message != '\0')
302 {
303 /* '@' at end of string is now just printed (previously it was skipped);
304 * it is an error in the calling code to terminate the string with @.
305 */
306 if (p != NULL && *message == '@' && message[1] != '\0')
307 {
308 int parameter_char = *++message; /* Consume the '@' */
309 static const char valid_parameters[] = "123456789";
310 int parameter = 0;
311
312 /* Search for the parameter digit, the index in the string is the
313 * parameter to use.
314 */
315 while (valid_parameters[parameter] != parameter_char &&
316 valid_parameters[parameter] != '\0')
317 ++parameter;
318
319 /* If the parameter digit is out of range it will just get printed. */
320 if (parameter < PNG_WARNING_PARAMETER_COUNT)
321 {
322 /* Append this parameter */
323 png_const_charp parm = p[parameter];
324 png_const_charp pend = p[parameter] + (sizeof p[parameter]);
325
326 /* No need to copy the trailing '\0' here, but there is no guarantee
327 * that parm[] has been initialized, so there is no guarantee of a
328 * trailing '\0':
329 */
330 while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
331 msg[i++] = *parm++;
332
333 /* Consume the parameter digit too: */
334 ++message;
335 continue;
336 }
337
338 /* else not a parameter and there is a character after the @ sign; just
339 * copy that. This is known not to be '\0' because of the test above.
340 */
341 }
342
343 /* At this point *message can't be '\0', even in the bad parameter case
344 * above where there is a lone '@' at the end of the message string.
345 */
346 msg[i++] = *message++;
347 }
348
349 /* i is always less than (sizeof msg), so: */
350 msg[i] = '\0';
351
352 /* And this is the formatted message. It may be larger than
353 * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
354 * are not (currently) formatted.
355 */
356 png_warning(png_ptr, msg);
357 }
358 #endif /* WARNINGS */
135 359
136 #ifdef PNG_BENIGN_ERRORS_SUPPORTED 360 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
137 void PNGAPI 361 void PNGAPI
138 png_benign_error(png_structp png_ptr, png_const_charp error_message) 362 png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
139 { 363 {
140 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) 364 if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
141 png_warning(png_ptr, error_message); 365 {
366 # ifdef PNG_READ_SUPPORTED
367 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
368 png_ptr->chunk_name != 0)
369 png_chunk_warning(png_ptr, error_message);
370 else
371 # endif
372 png_warning(png_ptr, error_message);
373 }
374
375 else
376 {
377 # ifdef PNG_READ_SUPPORTED
378 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
379 png_ptr->chunk_name != 0)
380 png_chunk_error(png_ptr, error_message);
381 else
382 # endif
383 png_error(png_ptr, error_message);
384 }
385
386 # ifndef PNG_ERROR_TEXT_SUPPORTED
387 PNG_UNUSED(error_message)
388 # endif
389 }
390
391 void /* PRIVATE */
392 png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
393 {
394 if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
395 png_warning(png_ptr, error_message);
142 else 396 else
143 png_error(png_ptr, error_message); 397 png_error(png_ptr, error_message);
144 } 398
145 #endif 399 # ifndef PNG_ERROR_TEXT_SUPPORTED
146 400 PNG_UNUSED(error_message)
401 # endif
402 }
403
404 void /* PRIVATE */
405 png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
406 {
407 if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
408 png_warning(png_ptr, error_message);
409 else
410 png_error(png_ptr, error_message);
411
412 # ifndef PNG_ERROR_TEXT_SUPPORTED
413 PNG_UNUSED(error_message)
414 # endif
415 }
416 #endif /* BENIGN_ERRORS */
417
418 #define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */
419 #if defined(PNG_WARNINGS_SUPPORTED) || \
420 (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
147 /* These utilities are used internally to build an error message that relates 421 /* These utilities are used internally to build an error message that relates
148 * to the current chunk. The chunk name comes from png_ptr->chunk_name, 422 * to the current chunk. The chunk name comes from png_ptr->chunk_name,
149 * this is used to prefix the message. The message is limited in length 423 * which is used to prefix the message. The message is limited in length
150 * to 63 bytes, the name characters are output as hex digits wrapped in [] 424 * to 63 bytes. The name characters are output as hex digits wrapped in []
151 * if the character is invalid. 425 * if the character is invalid.
152 */ 426 */
153 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 427 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
154 static PNG_CONST char png_digit[16] = { 428 static PNG_CONST char png_digit[16] = {
155 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 429 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
156 'A', 'B', 'C', 'D', 'E', 'F' 430 'A', 'B', 'C', 'D', 'E', 'F'
157 }; 431 };
158 432
159 #define PNG_MAX_ERROR_TEXT 64
160 #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
161 static void /* PRIVATE */ 433 static void /* PRIVATE */
162 png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp 434 png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
163 error_message) 435 error_message)
164 { 436 {
165 int iout = 0, iin = 0; 437 png_uint_32 chunk_name = png_ptr->chunk_name;
438 int iout = 0, ishift = 24;
166 439
167 while (iin < 4) 440 while (ishift >= 0)
168 { 441 {
169 int c = png_ptr->chunk_name[iin++]; 442 int c = (int)(chunk_name >> ishift) & 0xff;
170 if (isnonalpha(c)) 443
444 ishift -= 8;
445 if (isnonalpha(c) != 0)
171 { 446 {
172 buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; 447 buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
173 buffer[iout++] = png_digit[(c & 0xf0) >> 4]; 448 buffer[iout++] = png_digit[(c & 0xf0) >> 4];
174 buffer[iout++] = png_digit[c & 0x0f]; 449 buffer[iout++] = png_digit[c & 0x0f];
175 buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; 450 buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
176 } 451 }
452
177 else 453 else
178 { 454 {
179 buffer[iout++] = (png_byte)c; 455 buffer[iout++] = (char)c;
180 } 456 }
181 } 457 }
182 458
183 if (error_message == NULL) 459 if (error_message == NULL)
184 buffer[iout] = '\0'; 460 buffer[iout] = '\0';
461
185 else 462 else
186 { 463 {
464 int iin = 0;
465
187 buffer[iout++] = ':'; 466 buffer[iout++] = ':';
188 buffer[iout++] = ' '; 467 buffer[iout++] = ' ';
189 468
190 iin = 0;
191 while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') 469 while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
192 buffer[iout++] = error_message[iin++]; 470 buffer[iout++] = error_message[iin++];
193 471
194 /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ 472 /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
195 buffer[iout] = '\0'; 473 buffer[iout] = '\0';
196 } 474 }
197 } 475 }
198 476 #endif /* WARNINGS || ERROR_TEXT */
199 #ifdef PNG_READ_SUPPORTED 477
200 void PNGAPI 478 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
201 png_chunk_error(png_structp png_ptr, png_const_charp error_message) 479 PNG_FUNCTION(void,PNGAPI
480 png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
481 PNG_NORETURN)
202 { 482 {
203 char msg[18+PNG_MAX_ERROR_TEXT]; 483 char msg[18+PNG_MAX_ERROR_TEXT];
204 if (png_ptr == NULL) 484 if (png_ptr == NULL)
205 png_error(png_ptr, error_message); 485 png_error(png_ptr, error_message);
486
206 else 487 else
207 { 488 {
208 png_format_buffer(png_ptr, msg, error_message); 489 png_format_buffer(png_ptr, msg, error_message);
209 png_error(png_ptr, msg); 490 png_error(png_ptr, msg);
210 } 491 }
211 } 492 }
212 #endif /* PNG_READ_SUPPORTED */ 493 #endif /* READ && ERROR_TEXT */
213 #endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
214 494
215 #ifdef PNG_WARNINGS_SUPPORTED 495 #ifdef PNG_WARNINGS_SUPPORTED
216 void PNGAPI 496 void PNGAPI
217 png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) 497 png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
218 { 498 {
219 char msg[18+PNG_MAX_ERROR_TEXT]; 499 char msg[18+PNG_MAX_ERROR_TEXT];
220 if (png_ptr == NULL) 500 if (png_ptr == NULL)
221 png_warning(png_ptr, warning_message); 501 png_warning(png_ptr, warning_message);
502
222 else 503 else
223 { 504 {
224 png_format_buffer(png_ptr, msg, warning_message); 505 png_format_buffer(png_ptr, msg, warning_message);
225 png_warning(png_ptr, msg); 506 png_warning(png_ptr, msg);
226 } 507 }
227 } 508 }
228 #endif /* PNG_WARNINGS_SUPPORTED */ 509 #endif /* WARNINGS */
229 510
230 #ifdef PNG_READ_SUPPORTED 511 #ifdef PNG_READ_SUPPORTED
231 #ifdef PNG_BENIGN_ERRORS_SUPPORTED 512 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
232 void PNGAPI 513 void PNGAPI
233 png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) 514 png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
234 { 515 error_message)
235 if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) 516 {
236 png_chunk_warning(png_ptr, error_message); 517 if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
237 else 518 png_chunk_warning(png_ptr, error_message);
238 png_chunk_error(png_ptr, error_message); 519
239 } 520 else
240 #endif 521 png_chunk_error(png_ptr, error_message);
241 #endif /* PNG_READ_SUPPORTED */ 522
523 # ifndef PNG_ERROR_TEXT_SUPPORTED
524 PNG_UNUSED(error_message)
525 # endif
526 }
527 #endif
528 #endif /* READ */
529
530 void /* PRIVATE */
531 png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
532 {
533 # ifndef PNG_WARNINGS_SUPPORTED
534 PNG_UNUSED(message)
535 # endif
536
537 /* This is always supported, but for just read or just write it
538 * unconditionally does the right thing.
539 */
540 # if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
541 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
542 # endif
543
544 # ifdef PNG_READ_SUPPORTED
545 {
546 if (error < PNG_CHUNK_ERROR)
547 png_chunk_warning(png_ptr, message);
548
549 else
550 png_chunk_benign_error(png_ptr, message);
551 }
552 # endif
553
554 # if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
555 else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
556 # endif
557
558 # ifdef PNG_WRITE_SUPPORTED
559 {
560 if (error < PNG_CHUNK_WRITE_ERROR)
561 png_app_warning(png_ptr, message);
562
563 else
564 png_app_error(png_ptr, message);
565 }
566 # endif
567 }
568
569 #ifdef PNG_ERROR_TEXT_SUPPORTED
570 #ifdef PNG_FLOATING_POINT_SUPPORTED
571 PNG_FUNCTION(void,
572 png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
573 {
574 # define fixed_message "fixed point overflow in "
575 # define fixed_message_ln ((sizeof fixed_message)-1)
576 int iin;
577 char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
578 memcpy(msg, fixed_message, fixed_message_ln);
579 iin = 0;
580 if (name != NULL)
581 while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
582 {
583 msg[fixed_message_ln + iin] = name[iin];
584 ++iin;
585 }
586 msg[fixed_message_ln + iin] = 0;
587 png_error(png_ptr, msg);
588 }
589 #endif
590 #endif
591
592 #ifdef PNG_SETJMP_SUPPORTED
593 /* This API only exists if ANSI-C style error handling is used,
594 * otherwise it is necessary for png_default_error to be overridden.
595 */
596 jmp_buf* PNGAPI
597 png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
598 size_t jmp_buf_size)
599 {
600 /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
601 * and it must not change after that. Libpng doesn't care how big the
602 * buffer is, just that it doesn't change.
603 *
604 * If the buffer size is no *larger* than the size of jmp_buf when libpng is
605 * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
606 * semantics that this call will not fail. If the size is larger, however,
607 * the buffer is allocated and this may fail, causing the function to return
608 * NULL.
609 */
610 if (png_ptr == NULL)
611 return NULL;
612
613 if (png_ptr->jmp_buf_ptr == NULL)
614 {
615 png_ptr->jmp_buf_size = 0; /* not allocated */
616
617 if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
618 png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
619
620 else
621 {
622 png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
623 png_malloc_warn(png_ptr, jmp_buf_size));
624
625 if (png_ptr->jmp_buf_ptr == NULL)
626 return NULL; /* new NULL return on OOM */
627
628 png_ptr->jmp_buf_size = jmp_buf_size;
629 }
630 }
631
632 else /* Already allocated: check the size */
633 {
634 size_t size = png_ptr->jmp_buf_size;
635
636 if (size == 0)
637 {
638 size = (sizeof png_ptr->jmp_buf_local);
639 if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
640 {
641 /* This is an internal error in libpng: somehow we have been left
642 * with a stack allocated jmp_buf when the application regained
643 * control. It's always possible to fix this up, but for the moment
644 * this is a png_error because that makes it easy to detect.
645 */
646 png_error(png_ptr, "Libpng jmp_buf still allocated");
647 /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
648 }
649 }
650
651 if (size != jmp_buf_size)
652 {
653 png_warning(png_ptr, "Application jmp_buf size changed");
654 return NULL; /* caller will probably crash: no choice here */
655 }
656 }
657
658 /* Finally fill in the function, now we have a satisfactory buffer. It is
659 * valid to change the function on every call.
660 */
661 png_ptr->longjmp_fn = longjmp_fn;
662 return png_ptr->jmp_buf_ptr;
663 }
664
665 void /* PRIVATE */
666 png_free_jmpbuf(png_structrp png_ptr)
667 {
668 if (png_ptr != NULL)
669 {
670 jmp_buf *jb = png_ptr->jmp_buf_ptr;
671
672 /* A size of 0 is used to indicate a local, stack, allocation of the
673 * pointer; used here and in png.c
674 */
675 if (jb != NULL && png_ptr->jmp_buf_size > 0)
676 {
677
678 /* This stuff is so that a failure to free the error control structure
679 * does not leave libpng in a state with no valid error handling: the
680 * free always succeeds, if there is an error it gets ignored.
681 */
682 if (jb != &png_ptr->jmp_buf_local)
683 {
684 /* Make an internal, libpng, jmp_buf to return here */
685 jmp_buf free_jmp_buf;
686
687 if (!setjmp(free_jmp_buf))
688 {
689 png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
690 png_ptr->jmp_buf_size = 0; /* stack allocation */
691 png_ptr->longjmp_fn = longjmp;
692 png_free(png_ptr, jb); /* Return to setjmp on error */
693 }
694 }
695 }
696
697 /* *Always* cancel everything out: */
698 png_ptr->jmp_buf_size = 0;
699 png_ptr->jmp_buf_ptr = NULL;
700 png_ptr->longjmp_fn = 0;
701 }
702 }
703 #endif
242 704
243 /* This is the default error handling function. Note that replacements for 705 /* This is the default error handling function. Note that replacements for
244 * this function MUST NOT RETURN, or the program will likely crash. This 706 * this function MUST NOT RETURN, or the program will likely crash. This
245 * function is used by default, or if the program supplies NULL for the 707 * function is used by default, or if the program supplies NULL for the
246 * error function pointer in png_set_error_fn(). 708 * error function pointer in png_set_error_fn().
247 */ 709 */
248 static void /* PRIVATE */ 710 static PNG_FUNCTION(void /* PRIVATE */,
249 png_default_error(png_structp png_ptr, png_const_charp error_message) 711 png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
712 PNG_NORETURN)
250 { 713 {
251 #ifdef PNG_CONSOLE_IO_SUPPORTED 714 #ifdef PNG_CONSOLE_IO_SUPPORTED
252 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 715 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
253 if (*error_message == PNG_LITERAL_SHARP) 716 /* Check on NULL only added in 1.5.4 */
254 { 717 if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
255 /* Strip "#nnnn " from beginning of error message. */ 718 {
256 int offset; 719 /* Strip "#nnnn " from beginning of error message. */
257 char error_number[16]; 720 int offset;
258 for (offset = 0; offset<15; offset++) 721 char error_number[16];
259 { 722 for (offset = 0; offset<15; offset++)
723 {
260 error_number[offset] = error_message[offset + 1]; 724 error_number[offset] = error_message[offset + 1];
261 if (error_message[offset] == ' ') 725 if (error_message[offset] == ' ')
262 break; 726 break;
263 } 727 }
264 if ((offset > 1) && (offset < 15)) 728
265 { 729 if ((offset > 1) && (offset < 15))
266 error_number[offset - 1] = '\0'; 730 {
267 fprintf(stderr, "libpng error no. %s: %s", 731 error_number[offset - 1] = '\0';
268 error_number, error_message + offset + 1); 732 fprintf(stderr, "libpng error no. %s: %s",
269 fprintf(stderr, PNG_STRING_NEWLINE); 733 error_number, error_message + offset + 1);
270 } 734 fprintf(stderr, PNG_STRING_NEWLINE);
271 else 735 }
272 { 736
273 fprintf(stderr, "libpng error: %s, offset=%d", 737 else
274 error_message, offset); 738 {
275 fprintf(stderr, PNG_STRING_NEWLINE); 739 fprintf(stderr, "libpng error: %s, offset=%d",
276 } 740 error_message, offset);
741 fprintf(stderr, PNG_STRING_NEWLINE);
742 }
277 } 743 }
278 else 744 else
279 #endif 745 #endif
280 { 746 {
281 fprintf(stderr, "libpng error: %s", error_message); 747 fprintf(stderr, "libpng error: %s", error_message ? error_message :
748 "undefined");
282 fprintf(stderr, PNG_STRING_NEWLINE); 749 fprintf(stderr, PNG_STRING_NEWLINE);
283 } 750 }
284 #endif 751 #else
285 752 PNG_UNUSED(error_message) /* Make compiler happy */
753 #endif
754 png_longjmp(png_ptr, 1);
755 }
756
757 PNG_FUNCTION(void,PNGAPI
758 png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
759 {
286 #ifdef PNG_SETJMP_SUPPORTED 760 #ifdef PNG_SETJMP_SUPPORTED
287 if (png_ptr) 761 if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
288 { 762 png_ptr->jmp_buf_ptr != NULL)
289 # ifdef USE_FAR_KEYWORD 763 png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
290 { 764 #else
291 jmp_buf jmpbuf; 765 PNG_UNUSED(png_ptr)
292 png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf)); 766 PNG_UNUSED(val)
293 longjmp(jmpbuf,1); 767 #endif
294 } 768
295 # else 769 /* If control reaches this point, png_longjmp() must not return. The only
296 longjmp(png_ptr->jmpbuf, 1); 770 * choice is to terminate the whole process (or maybe the thread); to do
297 # endif 771 * this the ANSI-C abort() function is used unless a different method is
298 } 772 * implemented by overriding the default configuration setting for
299 #endif 773 * PNG_ABORT().
300 /* Here if not setjmp support or if png_ptr is null. */ 774 */
301 PNG_ABORT(); 775 PNG_ABORT();
302 #ifndef PNG_CONSOLE_IO_SUPPORTED
303 PNG_UNUSED(error_message) /* Make compiler happy */
304 #endif
305 } 776 }
306 777
307 #ifdef PNG_WARNINGS_SUPPORTED 778 #ifdef PNG_WARNINGS_SUPPORTED
308 /* This function is called when there is a warning, but the library thinks 779 /* This function is called when there is a warning, but the library thinks
309 * it can continue anyway. Replacement functions don't have to do anything 780 * it can continue anyway. Replacement functions don't have to do anything
310 * here if you don't want them to. In the default configuration, png_ptr is 781 * here if you don't want them to. In the default configuration, png_ptr is
311 * not used, but it is passed in case it may be useful. 782 * not used, but it is passed in case it may be useful.
312 */ 783 */
313 static void /* PRIVATE */ 784 static void /* PRIVATE */
314 png_default_warning(png_structp png_ptr, png_const_charp warning_message) 785 png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
315 { 786 {
316 #ifdef PNG_CONSOLE_IO_SUPPORTED 787 #ifdef PNG_CONSOLE_IO_SUPPORTED
317 # ifdef PNG_ERROR_NUMBERS_SUPPORTED 788 # ifdef PNG_ERROR_NUMBERS_SUPPORTED
318 if (*warning_message == PNG_LITERAL_SHARP) 789 if (*warning_message == PNG_LITERAL_SHARP)
319 { 790 {
320 int offset; 791 int offset;
321 char warning_number[16]; 792 char warning_number[16];
322 for (offset = 0; offset < 15; offset++) 793 for (offset = 0; offset < 15; offset++)
323 { 794 {
324 warning_number[offset] = warning_message[offset + 1]; 795 warning_number[offset] = warning_message[offset + 1];
325 if (warning_message[offset] == ' ') 796 if (warning_message[offset] == ' ')
326 break; 797 break;
327 } 798 }
328 if ((offset > 1) && (offset < 15)) 799
329 { 800 if ((offset > 1) && (offset < 15))
330 warning_number[offset + 1] = '\0'; 801 {
331 fprintf(stderr, "libpng warning no. %s: %s", 802 warning_number[offset + 1] = '\0';
332 warning_number, warning_message + offset); 803 fprintf(stderr, "libpng warning no. %s: %s",
333 fprintf(stderr, PNG_STRING_NEWLINE); 804 warning_number, warning_message + offset);
334 } 805 fprintf(stderr, PNG_STRING_NEWLINE);
335 else 806 }
336 { 807
337 fprintf(stderr, "libpng warning: %s", 808 else
338 warning_message); 809 {
339 fprintf(stderr, PNG_STRING_NEWLINE); 810 fprintf(stderr, "libpng warning: %s",
340 } 811 warning_message);
812 fprintf(stderr, PNG_STRING_NEWLINE);
813 }
341 } 814 }
342 else 815 else
343 # endif 816 # endif
817
344 { 818 {
345 fprintf(stderr, "libpng warning: %s", warning_message); 819 fprintf(stderr, "libpng warning: %s", warning_message);
346 fprintf(stderr, PNG_STRING_NEWLINE); 820 fprintf(stderr, PNG_STRING_NEWLINE);
347 } 821 }
348 #else 822 #else
349 PNG_UNUSED(warning_message) /* Make compiler happy */ 823 PNG_UNUSED(warning_message) /* Make compiler happy */
350 #endif 824 #endif
351 PNG_UNUSED(png_ptr) /* Make compiler happy */ 825 PNG_UNUSED(png_ptr) /* Make compiler happy */
352 } 826 }
353 #endif /* PNG_WARNINGS_SUPPORTED */ 827 #endif /* WARNINGS */
354 828
355 /* This function is called when the application wants to use another method 829 /* This function is called when the application wants to use another method
356 * of handling errors and warnings. Note that the error function MUST NOT 830 * of handling errors and warnings. Note that the error function MUST NOT
357 * return to the calling routine or serious problems will occur. The return 831 * return to the calling routine or serious problems will occur. The return
358 * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) 832 * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
359 */ 833 */
360 void PNGAPI 834 void PNGAPI
361 png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, 835 png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
362 png_error_ptr error_fn, png_error_ptr warning_fn) 836 png_error_ptr error_fn, png_error_ptr warning_fn)
363 { 837 {
364 if (png_ptr == NULL) 838 if (png_ptr == NULL)
365 return; 839 return;
840
366 png_ptr->error_ptr = error_ptr; 841 png_ptr->error_ptr = error_ptr;
367 png_ptr->error_fn = error_fn; 842 png_ptr->error_fn = error_fn;
843 #ifdef PNG_WARNINGS_SUPPORTED
368 png_ptr->warning_fn = warning_fn; 844 png_ptr->warning_fn = warning_fn;
845 #else
846 PNG_UNUSED(warning_fn)
847 #endif
369 } 848 }
370 849
371 850
372 /* This function returns a pointer to the error_ptr associated with the user 851 /* This function returns a pointer to the error_ptr associated with the user
373 * functions. The application should free any memory associated with this 852 * functions. The application should free any memory associated with this
374 * pointer before png_write_destroy and png_read_destroy are called. 853 * pointer before png_write_destroy and png_read_destroy are called.
375 */ 854 */
376 png_voidp PNGAPI 855 png_voidp PNGAPI
377 png_get_error_ptr(png_structp png_ptr) 856 png_get_error_ptr(png_const_structrp png_ptr)
378 { 857 {
379 if (png_ptr == NULL) 858 if (png_ptr == NULL)
380 return NULL; 859 return NULL;
860
381 return ((png_voidp)png_ptr->error_ptr); 861 return ((png_voidp)png_ptr->error_ptr);
382 } 862 }
383 863
384 864
385 #ifdef PNG_ERROR_NUMBERS_SUPPORTED 865 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
386 void PNGAPI 866 void PNGAPI
387 png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) 867 png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
388 { 868 {
389 if (png_ptr != NULL) 869 if (png_ptr != NULL)
390 { 870 {
391 png_ptr->flags &= 871 png_ptr->flags &=
392 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); 872 ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
873 PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
393 } 874 }
394 } 875 }
395 #endif 876 #endif
396 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ 877
878 #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
879 defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
880 /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
881 * possible to implement without setjmp support just so long as there is some
882 * way to handle the error return here:
883 */
884 PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
885 png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
886 PNG_NORETURN)
887 {
888 const png_const_structrp png_ptr = png_nonconst_ptr;
889 png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
890
891 /* An error is always logged here, overwriting anything (typically a warning)
892 * that is already there:
893 */
894 if (image != NULL)
895 {
896 png_safecat(image->message, (sizeof image->message), 0, error_message);
897 image->warning_or_error |= PNG_IMAGE_ERROR;
898
899 /* Retrieve the jmp_buf from within the png_control, making this work for
900 * C++ compilation too is pretty tricky: C++ wants a pointer to the first
901 * element of a jmp_buf, but C doesn't tell us the type of that.
902 */
903 if (image->opaque != NULL && image->opaque->error_buf != NULL)
904 longjmp(png_control_jmp_buf(image->opaque), 1);
905
906 /* Missing longjmp buffer, the following is to help debugging: */
907 {
908 size_t pos = png_safecat(image->message, (sizeof image->message), 0,
909 "bad longjmp: ");
910 png_safecat(image->message, (sizeof image->message), pos,
911 error_message);
912 }
913 }
914
915 /* Here on an internal programming error. */
916 abort();
917 }
918
919 #ifdef PNG_WARNINGS_SUPPORTED
920 void /* PRIVATE */ PNGCBAPI
921 png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
922 {
923 const png_const_structrp png_ptr = png_nonconst_ptr;
924 png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
925
926 /* A warning is only logged if there is no prior warning or error. */
927 if (image->warning_or_error == 0)
928 {
929 png_safecat(image->message, (sizeof image->message), 0, warning_message);
930 image->warning_or_error |= PNG_IMAGE_WARNING;
931 }
932 }
933 #endif
934
935 int /* PRIVATE */
936 png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
937 {
938 volatile png_imagep image = image_in;
939 volatile int result;
940 volatile png_voidp saved_error_buf;
941 jmp_buf safe_jmpbuf;
942
943 /* Safely execute function(arg) with png_error returning to this function. */
944 saved_error_buf = image->opaque->error_buf;
945 result = setjmp(safe_jmpbuf) == 0;
946
947 if (result != 0)
948 {
949
950 image->opaque->error_buf = safe_jmpbuf;
951 result = function(arg);
952 }
953
954 image->opaque->error_buf = saved_error_buf;
955
956 /* And do the cleanup prior to any failure return. */
957 if (result == 0)
958 png_image_free(image);
959
960 return result;
961 }
962 #endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
963 #endif /* READ || WRITE */
OLDNEW
« no previous file with comments | « third_party/libpng/pngdebug.h ('k') | third_party/libpng/pnggccrd.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698