annotate lib/libpng/pngerror.c @ 2575:a76d408c5132 tip

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