1 |
1 |
2 /* png.c - location for general purpose libpng functions |
2 /* png.c - location for general purpose libpng functions |
3 * |
3 * |
4 * Last changed in libpng 1.2.39 [August 13, 2009] |
4 * Last changed in libpng 1.4.0 [January 3, 2010] |
5 * Copyright (c) 1998-2009 Glenn Randers-Pehrson |
5 * Copyright (c) 1998-2010 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 |
13 |
14 #define PNG_INTERNAL |
|
15 #define PNG_NO_EXTERN |
14 #define PNG_NO_EXTERN |
|
15 #define PNG_NO_PEDANTIC_WARNINGS |
16 #include "png.h" |
16 #include "png.h" |
|
17 #include "pngpriv.h" |
17 |
18 |
18 /* Generate a compiler error if there is an old png.h in the search path. */ |
19 /* Generate a compiler error if there is an old png.h in the search path. */ |
19 typedef version_1_2_40 Your_png_h_is_not_version_1_2_40; |
20 typedef version_1_4_0 Your_png_h_is_not_version_1_4_0; |
20 |
21 |
21 /* Version information for C files. This had better match the version |
22 /* Version information for C files. This had better match the version |
22 * string defined in png.h. */ |
23 * string defined in png.h. |
23 |
24 */ |
24 #ifdef PNG_USE_GLOBAL_ARRAYS |
|
25 /* png_libpng_ver was changed to a function in version 1.0.5c */ |
|
26 PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING; |
|
27 |
|
28 #ifdef PNG_READ_SUPPORTED |
|
29 |
|
30 /* png_sig was changed to a function in version 1.0.5c */ |
|
31 /* Place to hold the signature string for a PNG file. */ |
|
32 PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; |
|
33 #endif /* PNG_READ_SUPPORTED */ |
|
34 |
|
35 /* Invoke global declarations for constant strings for known chunk types */ |
|
36 PNG_IHDR; |
|
37 PNG_IDAT; |
|
38 PNG_IEND; |
|
39 PNG_PLTE; |
|
40 PNG_bKGD; |
|
41 PNG_cHRM; |
|
42 PNG_gAMA; |
|
43 PNG_hIST; |
|
44 PNG_iCCP; |
|
45 PNG_iTXt; |
|
46 PNG_oFFs; |
|
47 PNG_pCAL; |
|
48 PNG_sCAL; |
|
49 PNG_pHYs; |
|
50 PNG_sBIT; |
|
51 PNG_sPLT; |
|
52 PNG_sRGB; |
|
53 PNG_tEXt; |
|
54 PNG_tIME; |
|
55 PNG_tRNS; |
|
56 PNG_zTXt; |
|
57 |
|
58 #ifdef PNG_READ_SUPPORTED |
|
59 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
|
60 |
|
61 /* Start of interlace block */ |
|
62 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; |
|
63 |
|
64 /* Offset to next interlace block */ |
|
65 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; |
|
66 |
|
67 /* Start of interlace block in the y direction */ |
|
68 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; |
|
69 |
|
70 /* Offset to next interlace block in the y direction */ |
|
71 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; |
|
72 |
|
73 /* Height of interlace block. This is not currently used - if you need |
|
74 * it, uncomment it here and in png.h |
|
75 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; |
|
76 */ |
|
77 |
|
78 /* Mask to determine which pixels are valid in a pass */ |
|
79 PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; |
|
80 |
|
81 /* Mask to determine which pixels to overwrite while displaying */ |
|
82 PNG_CONST int FARDATA png_pass_dsp_mask[] |
|
83 = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; |
|
84 |
|
85 #endif /* PNG_READ_SUPPORTED */ |
|
86 #endif /* PNG_USE_GLOBAL_ARRAYS */ |
|
87 |
25 |
88 /* Tells libpng that we have already handled the first "num_bytes" bytes |
26 /* Tells libpng that we have already handled the first "num_bytes" bytes |
89 * of the PNG file signature. If the PNG data is embedded into another |
27 * of the PNG file signature. If the PNG data is embedded into another |
90 * stream we can set num_bytes = 8 so that libpng will not attempt to read |
28 * stream we can set num_bytes = 8 so that libpng will not attempt to read |
91 * or write any of the magic bytes before it starts on the IHDR. |
29 * or write any of the magic bytes before it starts on the IHDR. |
128 num_to_check = 8 - start; |
68 num_to_check = 8 - start; |
129 |
69 |
130 return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); |
70 return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); |
131 } |
71 } |
132 |
72 |
133 #if defined(PNG_1_0_X) || defined(PNG_1_2_X) |
|
134 /* (Obsolete) function to check signature bytes. It does not allow one |
|
135 * to check a partial signature. This function might be removed in the |
|
136 * future - use png_sig_cmp(). Returns true (nonzero) if the file is PNG. |
|
137 */ |
|
138 int PNGAPI |
|
139 png_check_sig(png_bytep sig, int num) |
|
140 { |
|
141 return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num)); |
|
142 } |
|
143 #endif |
|
144 #endif /* PNG_READ_SUPPORTED */ |
73 #endif /* PNG_READ_SUPPORTED */ |
145 |
74 |
146 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
75 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
147 /* Function to allocate memory for zlib and clear it to 0. */ |
76 /* Function to allocate memory for zlib and clear it to 0. */ |
148 #ifdef PNG_1_0_X |
|
149 voidpf PNGAPI |
|
150 #else |
|
151 voidpf /* PRIVATE */ |
77 voidpf /* PRIVATE */ |
152 #endif |
|
153 png_zalloc(voidpf png_ptr, uInt items, uInt size) |
78 png_zalloc(voidpf png_ptr, uInt items, uInt size) |
154 { |
79 { |
155 png_voidp ptr; |
80 png_voidp ptr; |
156 png_structp p=(png_structp)png_ptr; |
81 png_structp p=(png_structp)png_ptr; |
157 png_uint_32 save_flags=p->flags; |
82 png_uint_32 save_flags=p->flags; |
158 png_uint_32 num_bytes; |
83 png_alloc_size_t num_bytes; |
159 |
84 |
160 if (png_ptr == NULL) |
85 if (png_ptr == NULL) |
161 return (NULL); |
86 return (NULL); |
162 if (items > PNG_UINT_32_MAX/size) |
87 if (items > PNG_UINT_32_MAX/size) |
163 { |
88 { |
164 png_warning (p, "Potential overflow in png_zalloc()"); |
89 png_warning (p, "Potential overflow in png_zalloc()"); |
165 return (NULL); |
90 return (NULL); |
166 } |
91 } |
167 num_bytes = (png_uint_32)items * size; |
92 num_bytes = (png_alloc_size_t)items * size; |
168 |
93 |
169 p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; |
94 p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; |
170 ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); |
95 ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); |
171 p->flags=save_flags; |
96 p->flags=save_flags; |
172 |
97 |
173 #if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO) |
|
174 if (ptr == NULL) |
|
175 return ((voidpf)ptr); |
|
176 |
|
177 if (num_bytes > (png_uint_32)0x8000L) |
|
178 { |
|
179 png_memset(ptr, 0, (png_size_t)0x8000L); |
|
180 png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0, |
|
181 (png_size_t)(num_bytes - (png_uint_32)0x8000L)); |
|
182 } |
|
183 else |
|
184 { |
|
185 png_memset(ptr, 0, (png_size_t)num_bytes); |
|
186 } |
|
187 #endif |
|
188 return ((voidpf)ptr); |
98 return ((voidpf)ptr); |
189 } |
99 } |
190 |
100 |
191 /* Function to free memory for zlib */ |
101 /* Function to free memory for zlib */ |
192 #ifdef PNG_1_0_X |
|
193 void PNGAPI |
|
194 #else |
|
195 void /* PRIVATE */ |
102 void /* PRIVATE */ |
196 #endif |
|
197 png_zfree(voidpf png_ptr, voidpf ptr) |
103 png_zfree(voidpf png_ptr, voidpf ptr) |
198 { |
104 { |
199 png_free((png_structp)png_ptr, (png_voidp)ptr); |
105 png_free((png_structp)png_ptr, (png_voidp)ptr); |
200 } |
106 } |
201 |
107 |
292 |
202 |
293 /* Initialize the info structure. This is now an internal function (0.89) |
203 /* Initialize the info structure. This is now an internal function (0.89) |
294 * and applications using it are urged to use png_create_info_struct() |
204 * and applications using it are urged to use png_create_info_struct() |
295 * instead. |
205 * instead. |
296 */ |
206 */ |
297 #if defined(PNG_1_0_X) || defined(PNG_1_2_X) |
|
298 #undef png_info_init |
|
299 void PNGAPI |
|
300 png_info_init(png_infop info_ptr) |
|
301 { |
|
302 /* We only come here via pre-1.0.12-compiled applications */ |
|
303 png_info_init_3(&info_ptr, 0); |
|
304 } |
|
305 #endif |
|
306 |
207 |
307 void PNGAPI |
208 void PNGAPI |
308 png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) |
209 png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) |
309 { |
210 { |
310 png_infop info_ptr = *ptr_ptr; |
211 png_infop info_ptr = *ptr_ptr; |
311 |
212 |
|
213 png_debug(1, "in png_info_init_3"); |
|
214 |
312 if (info_ptr == NULL) |
215 if (info_ptr == NULL) |
313 return; |
216 return; |
314 |
|
315 png_debug(1, "in png_info_init_3"); |
|
316 |
217 |
317 if (png_sizeof(png_info) > png_info_struct_size) |
218 if (png_sizeof(png_info) > png_info_struct_size) |
318 { |
219 { |
319 png_destroy_struct(info_ptr); |
220 png_destroy_struct(info_ptr); |
320 info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); |
221 info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); |
323 |
224 |
324 /* Set everything to 0 */ |
225 /* Set everything to 0 */ |
325 png_memset(info_ptr, 0, png_sizeof(png_info)); |
226 png_memset(info_ptr, 0, png_sizeof(png_info)); |
326 } |
227 } |
327 |
228 |
328 #ifdef PNG_FREE_ME_SUPPORTED |
|
329 void PNGAPI |
229 void PNGAPI |
330 png_data_freer(png_structp png_ptr, png_infop info_ptr, |
230 png_data_freer(png_structp png_ptr, png_infop info_ptr, |
331 int freer, png_uint_32 mask) |
231 int freer, png_uint_32 mask) |
332 { |
232 { |
333 png_debug(1, "in png_data_freer"); |
233 png_debug(1, "in png_data_freer"); |
|
234 |
334 if (png_ptr == NULL || info_ptr == NULL) |
235 if (png_ptr == NULL || info_ptr == NULL) |
335 return; |
236 return; |
|
237 |
336 if (freer == PNG_DESTROY_WILL_FREE_DATA) |
238 if (freer == PNG_DESTROY_WILL_FREE_DATA) |
337 info_ptr->free_me |= mask; |
239 info_ptr->free_me |= mask; |
338 else if (freer == PNG_USER_WILL_FREE_DATA) |
240 else if (freer == PNG_USER_WILL_FREE_DATA) |
339 info_ptr->free_me &= ~mask; |
241 info_ptr->free_me &= ~mask; |
340 else |
242 else |
341 png_warning(png_ptr, |
243 png_warning(png_ptr, |
342 "Unknown freer parameter in png_data_freer."); |
244 "Unknown freer parameter in png_data_freer"); |
343 } |
245 } |
344 #endif |
|
345 |
246 |
346 void PNGAPI |
247 void PNGAPI |
347 png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, |
248 png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, |
348 int num) |
249 int num) |
349 { |
250 { |
350 png_debug(1, "in png_free_data"); |
251 png_debug(1, "in png_free_data"); |
|
252 |
351 if (png_ptr == NULL || info_ptr == NULL) |
253 if (png_ptr == NULL || info_ptr == NULL) |
352 return; |
254 return; |
353 |
255 |
354 #if defined(PNG_TEXT_SUPPORTED) |
256 #ifdef PNG_TEXT_SUPPORTED |
355 /* Free text item num or (if num == -1) all text items */ |
257 /* Free text item num or (if num == -1) all text items */ |
356 #ifdef PNG_FREE_ME_SUPPORTED |
|
357 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) |
258 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) |
358 #else |
|
359 if (mask & PNG_FREE_TEXT) |
|
360 #endif |
|
361 { |
259 { |
362 if (num != -1) |
260 if (num != -1) |
363 { |
261 { |
364 if (info_ptr->text && info_ptr->text[num].key) |
262 if (info_ptr->text && info_ptr->text[num].key) |
365 { |
263 { |
377 info_ptr->num_text=0; |
275 info_ptr->num_text=0; |
378 } |
276 } |
379 } |
277 } |
380 #endif |
278 #endif |
381 |
279 |
382 #if defined(PNG_tRNS_SUPPORTED) |
280 #ifdef PNG_tRNS_SUPPORTED |
383 /* Free any tRNS entry */ |
281 /* Free any tRNS entry */ |
384 #ifdef PNG_FREE_ME_SUPPORTED |
|
385 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) |
282 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) |
386 #else |
283 { |
387 if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS)) |
284 png_free(png_ptr, info_ptr->trans_alpha); |
388 #endif |
285 info_ptr->trans_alpha = NULL; |
389 { |
|
390 png_free(png_ptr, info_ptr->trans); |
|
391 info_ptr->trans = NULL; |
|
392 info_ptr->valid &= ~PNG_INFO_tRNS; |
286 info_ptr->valid &= ~PNG_INFO_tRNS; |
393 #ifndef PNG_FREE_ME_SUPPORTED |
287 } |
394 png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; |
288 #endif |
395 #endif |
289 |
396 } |
290 #ifdef PNG_sCAL_SUPPORTED |
397 #endif |
|
398 |
|
399 #if defined(PNG_sCAL_SUPPORTED) |
|
400 /* Free any sCAL entry */ |
291 /* Free any sCAL entry */ |
401 #ifdef PNG_FREE_ME_SUPPORTED |
|
402 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) |
292 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) |
403 #else |
|
404 if (mask & PNG_FREE_SCAL) |
|
405 #endif |
|
406 { |
293 { |
407 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) |
294 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) |
408 png_free(png_ptr, info_ptr->scal_s_width); |
295 png_free(png_ptr, info_ptr->scal_s_width); |
409 png_free(png_ptr, info_ptr->scal_s_height); |
296 png_free(png_ptr, info_ptr->scal_s_height); |
410 info_ptr->scal_s_width = NULL; |
297 info_ptr->scal_s_width = NULL; |
430 { |
313 { |
431 int i; |
314 int i; |
432 for (i = 0; i < (int)info_ptr->pcal_nparams; i++) |
315 for (i = 0; i < (int)info_ptr->pcal_nparams; i++) |
433 { |
316 { |
434 png_free(png_ptr, info_ptr->pcal_params[i]); |
317 png_free(png_ptr, info_ptr->pcal_params[i]); |
435 info_ptr->pcal_params[i]=NULL; |
318 info_ptr->pcal_params[i] = NULL; |
436 } |
319 } |
437 png_free(png_ptr, info_ptr->pcal_params); |
320 png_free(png_ptr, info_ptr->pcal_params); |
438 info_ptr->pcal_params = NULL; |
321 info_ptr->pcal_params = NULL; |
439 } |
322 } |
440 info_ptr->valid &= ~PNG_INFO_pCAL; |
323 info_ptr->valid &= ~PNG_INFO_pCAL; |
441 } |
324 } |
442 #endif |
325 #endif |
443 |
326 |
444 #if defined(PNG_iCCP_SUPPORTED) |
327 #ifdef PNG_iCCP_SUPPORTED |
445 /* Free any iCCP entry */ |
328 /* Free any iCCP entry */ |
446 #ifdef PNG_FREE_ME_SUPPORTED |
|
447 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) |
329 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) |
448 #else |
|
449 if (mask & PNG_FREE_ICCP) |
|
450 #endif |
|
451 { |
330 { |
452 png_free(png_ptr, info_ptr->iccp_name); |
331 png_free(png_ptr, info_ptr->iccp_name); |
453 png_free(png_ptr, info_ptr->iccp_profile); |
332 png_free(png_ptr, info_ptr->iccp_profile); |
454 info_ptr->iccp_name = NULL; |
333 info_ptr->iccp_name = NULL; |
455 info_ptr->iccp_profile = NULL; |
334 info_ptr->iccp_profile = NULL; |
456 info_ptr->valid &= ~PNG_INFO_iCCP; |
335 info_ptr->valid &= ~PNG_INFO_iCCP; |
457 } |
336 } |
458 #endif |
337 #endif |
459 |
338 |
460 #if defined(PNG_sPLT_SUPPORTED) |
339 #ifdef PNG_sPLT_SUPPORTED |
461 /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ |
340 /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ |
462 #ifdef PNG_FREE_ME_SUPPORTED |
|
463 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) |
341 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) |
464 #else |
|
465 if (mask & PNG_FREE_SPLT) |
|
466 #endif |
|
467 { |
342 { |
468 if (num != -1) |
343 if (num != -1) |
469 { |
344 { |
470 if (info_ptr->splt_palettes) |
345 if (info_ptr->splt_palettes) |
471 { |
346 { |
528 } |
399 } |
529 } |
400 } |
530 } |
401 } |
531 #endif |
402 #endif |
532 |
403 |
533 #if defined(PNG_hIST_SUPPORTED) |
404 #ifdef PNG_hIST_SUPPORTED |
534 /* Free any hIST entry */ |
405 /* Free any hIST entry */ |
535 #ifdef PNG_FREE_ME_SUPPORTED |
|
536 if ((mask & PNG_FREE_HIST) & info_ptr->free_me) |
406 if ((mask & PNG_FREE_HIST) & info_ptr->free_me) |
537 #else |
|
538 if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST)) |
|
539 #endif |
|
540 { |
407 { |
541 png_free(png_ptr, info_ptr->hist); |
408 png_free(png_ptr, info_ptr->hist); |
542 info_ptr->hist = NULL; |
409 info_ptr->hist = NULL; |
543 info_ptr->valid &= ~PNG_INFO_hIST; |
410 info_ptr->valid &= ~PNG_INFO_hIST; |
544 #ifndef PNG_FREE_ME_SUPPORTED |
|
545 png_ptr->flags &= ~PNG_FLAG_FREE_HIST; |
|
546 #endif |
|
547 } |
411 } |
548 #endif |
412 #endif |
549 |
413 |
550 /* Free any PLTE entry that was internally allocated */ |
414 /* Free any PLTE entry that was internally allocated */ |
551 #ifdef PNG_FREE_ME_SUPPORTED |
|
552 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) |
415 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) |
553 #else |
|
554 if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE)) |
|
555 #endif |
|
556 { |
416 { |
557 png_zfree(png_ptr, info_ptr->palette); |
417 png_zfree(png_ptr, info_ptr->palette); |
558 info_ptr->palette = NULL; |
418 info_ptr->palette = NULL; |
559 info_ptr->valid &= ~PNG_INFO_PLTE; |
419 info_ptr->valid &= ~PNG_INFO_PLTE; |
560 #ifndef PNG_FREE_ME_SUPPORTED |
|
561 png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; |
|
562 #endif |
|
563 info_ptr->num_palette = 0; |
420 info_ptr->num_palette = 0; |
564 } |
421 } |
565 |
422 |
566 #if defined(PNG_INFO_IMAGE_SUPPORTED) |
423 #ifdef PNG_INFO_IMAGE_SUPPORTED |
567 /* Free any image bits attached to the info structure */ |
424 /* Free any image bits attached to the info structure */ |
568 #ifdef PNG_FREE_ME_SUPPORTED |
|
569 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) |
425 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) |
570 #else |
|
571 if (mask & PNG_FREE_ROWS) |
|
572 #endif |
|
573 { |
426 { |
574 if (info_ptr->row_pointers) |
427 if (info_ptr->row_pointers) |
575 { |
428 { |
576 int row; |
429 int row; |
577 for (row = 0; row < (int)info_ptr->height; row++) |
430 for (row = 0; row < (int)info_ptr->height; row++) |
578 { |
431 { |
579 png_free(png_ptr, info_ptr->row_pointers[row]); |
432 png_free(png_ptr, info_ptr->row_pointers[row]); |
580 info_ptr->row_pointers[row]=NULL; |
433 info_ptr->row_pointers[row] = NULL; |
581 } |
434 } |
582 png_free(png_ptr, info_ptr->row_pointers); |
435 png_free(png_ptr, info_ptr->row_pointers); |
583 info_ptr->row_pointers=NULL; |
436 info_ptr->row_pointers = NULL; |
584 } |
437 } |
585 info_ptr->valid &= ~PNG_INFO_IDAT; |
438 info_ptr->valid &= ~PNG_INFO_IDAT; |
586 } |
439 } |
587 #endif |
440 #endif |
588 |
441 |
589 #ifdef PNG_FREE_ME_SUPPORTED |
|
590 if (num == -1) |
442 if (num == -1) |
591 info_ptr->free_me &= ~mask; |
443 info_ptr->free_me &= ~mask; |
592 else |
444 else |
593 info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); |
445 info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); |
594 #endif |
|
595 } |
446 } |
596 |
447 |
597 /* This is an internal routine to free any memory that the info struct is |
448 /* This is an internal routine to free any memory that the info struct is |
598 * pointing to before re-using it or freeing the struct itself. Recall |
449 * pointing to before re-using it or freeing the struct itself. Recall |
599 * that png_free() checks for NULL pointers for us. |
450 * that png_free() checks for NULL pointers for us. |
603 { |
454 { |
604 png_debug(1, "in png_info_destroy"); |
455 png_debug(1, "in png_info_destroy"); |
605 |
456 |
606 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); |
457 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); |
607 |
458 |
608 #if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) |
459 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
609 if (png_ptr->num_chunk_list) |
460 if (png_ptr->num_chunk_list) |
610 { |
461 { |
611 png_free(png_ptr, png_ptr->chunk_list); |
462 png_free(png_ptr, png_ptr->chunk_list); |
612 png_ptr->chunk_list=NULL; |
463 png_ptr->chunk_list = NULL; |
613 png_ptr->num_chunk_list = 0; |
464 png_ptr->num_chunk_list = 0; |
614 } |
465 } |
615 #endif |
466 #endif |
616 |
467 |
617 png_info_init_3(&info_ptr, png_sizeof(png_info)); |
468 png_info_init_3(&info_ptr, png_sizeof(png_info)); |
629 return (NULL); |
480 return (NULL); |
630 return (png_ptr->io_ptr); |
481 return (png_ptr->io_ptr); |
631 } |
482 } |
632 |
483 |
633 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
484 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
634 #if !defined(PNG_NO_STDIO) |
485 #ifdef PNG_STDIO_SUPPORTED |
635 /* Initialize the default input/output functions for the PNG file. If you |
486 /* Initialize the default input/output functions for the PNG file. If you |
636 * use your own read or write routines, you can call either png_set_read_fn() |
487 * use your own read or write routines, you can call either png_set_read_fn() |
637 * or png_set_write_fn() instead of png_init_io(). If you have defined |
488 * or png_set_write_fn() instead of png_init_io(). If you have defined |
638 * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't |
489 * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't |
639 * necessarily available. |
490 * necessarily available. |
640 */ |
491 */ |
641 void PNGAPI |
492 void PNGAPI |
642 png_init_io(png_structp png_ptr, png_FILE_p fp) |
493 png_init_io(png_structp png_ptr, png_FILE_p fp) |
643 { |
494 { |
644 png_debug(1, "in png_init_io"); |
495 png_debug(1, "in png_init_io"); |
|
496 |
645 if (png_ptr == NULL) |
497 if (png_ptr == NULL) |
646 return; |
498 return; |
|
499 |
647 png_ptr->io_ptr = (png_voidp)fp; |
500 png_ptr->io_ptr = (png_voidp)fp; |
648 } |
501 } |
649 #endif |
502 #endif |
650 |
503 |
651 #if defined(PNG_TIME_RFC1123_SUPPORTED) |
504 #ifdef PNG_TIME_RFC1123_SUPPORTED |
652 /* Convert the supplied time into an RFC 1123 string suitable for use in |
505 /* Convert the supplied time into an RFC 1123 string suitable for use in |
653 * a "Creation Time" or other text-based time string. |
506 * a "Creation Time" or other text-based time string. |
654 */ |
507 */ |
655 png_charp PNGAPI |
508 png_charp PNGAPI |
656 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) |
509 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) |
665 { |
518 { |
666 png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* |
519 png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* |
667 png_sizeof(char))); |
520 png_sizeof(char))); |
668 } |
521 } |
669 |
522 |
670 #if defined(_WIN32_WCE) |
|
671 { |
|
672 wchar_t time_buf[29]; |
|
673 wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"), |
|
674 ptime->day % 32, short_months[(ptime->month - 1) % 12], |
|
675 ptime->year, ptime->hour % 24, ptime->minute % 60, |
|
676 ptime->second % 61); |
|
677 WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29, |
|
678 NULL, NULL); |
|
679 } |
|
680 #else |
|
681 #ifdef USE_FAR_KEYWORD |
523 #ifdef USE_FAR_KEYWORD |
682 { |
524 { |
683 char near_time_buf[29]; |
525 char near_time_buf[29]; |
684 png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000", |
526 png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000", |
685 ptime->day % 32, short_months[(ptime->month - 1) % 12], |
527 ptime->day % 32, short_months[(ptime->month - 1) % 12], |
692 png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000", |
534 png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000", |
693 ptime->day % 32, short_months[(ptime->month - 1) % 12], |
535 ptime->day % 32, short_months[(ptime->month - 1) % 12], |
694 ptime->year, ptime->hour % 24, ptime->minute % 60, |
536 ptime->year, ptime->hour % 24, ptime->minute % 60, |
695 ptime->second % 61); |
537 ptime->second % 61); |
696 #endif |
538 #endif |
697 #endif /* _WIN32_WCE */ |
|
698 return ((png_charp)png_ptr->time_buffer); |
539 return ((png_charp)png_ptr->time_buffer); |
699 } |
540 } |
700 #endif /* PNG_TIME_RFC1123_SUPPORTED */ |
541 #endif /* PNG_TIME_RFC1123_SUPPORTED */ |
701 |
542 |
702 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ |
543 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ |
703 |
544 |
704 png_charp PNGAPI |
545 png_charp PNGAPI |
705 png_get_copyright(png_structp png_ptr) |
546 png_get_copyright(png_structp png_ptr) |
706 { |
547 { |
707 png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ |
548 png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ |
708 return ((png_charp) "\n libpng version 1.2.40 - September 10, 2009\n\ |
549 #ifdef PNG_STRING_COPYRIGHT |
709 Copyright (c) 1998-2009 Glenn Randers-Pehrson\n\ |
550 return PNG_STRING_COPYRIGHT |
710 Copyright (c) 1996-1997 Andreas Dilger\n\ |
551 #else |
711 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n"); |
552 #ifdef __STDC__ |
|
553 return ((png_charp) PNG_STRING_NEWLINE \ |
|
554 "libpng version 1.4.0 - January 3, 2010" PNG_STRING_NEWLINE \ |
|
555 "Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ |
|
556 "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ |
|
557 "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ |
|
558 PNG_STRING_NEWLINE); |
|
559 #else |
|
560 return ((png_charp) "libpng version 1.4.0 - January 3, 2010\ |
|
561 Copyright (c) 1998-2010 Glenn Randers-Pehrson\ |
|
562 Copyright (c) 1996-1997 Andreas Dilger\ |
|
563 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."); |
|
564 #endif |
|
565 #endif |
712 } |
566 } |
713 |
567 |
714 /* The following return the library version as a short string in the |
568 /* The following return the library version as a short string in the |
715 * format 1.0.0 through 99.99.99zz. To get the version of *.h files |
569 * format 1.0.0 through 99.99.99zz. To get the version of *.h files |
716 * used with your application, print out PNG_LIBPNG_VER_STRING, which |
570 * used with your application, print out PNG_LIBPNG_VER_STRING, which |
919 ret = 0; |
767 ret = 0; |
920 } |
768 } |
921 |
769 |
922 return ret; |
770 return ret; |
923 } |
771 } |
924 #endif /* NO_PNG_CHECK_cHRM */ |
772 #endif /* PNG_CHECK_cHRM_SUPPORTED */ |
925 #endif /* PNG_cHRM_SUPPORTED */ |
773 #endif /* PNG_cHRM_SUPPORTED */ |
|
774 |
|
775 void /* PRIVATE */ |
|
776 png_check_IHDR(png_structp png_ptr, |
|
777 png_uint_32 width, png_uint_32 height, int bit_depth, |
|
778 int color_type, int interlace_type, int compression_type, |
|
779 int filter_type) |
|
780 { |
|
781 int error = 0; |
|
782 |
|
783 /* Check for width and height valid values */ |
|
784 if (width == 0) |
|
785 { |
|
786 png_warning(png_ptr, "Image width is zero in IHDR"); |
|
787 error = 1; |
|
788 } |
|
789 |
|
790 if (height == 0) |
|
791 { |
|
792 png_warning(png_ptr, "Image height is zero in IHDR"); |
|
793 error = 1; |
|
794 } |
|
795 |
|
796 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
797 if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX) |
|
798 #else |
|
799 if (width > PNG_USER_WIDTH_MAX) |
|
800 #endif |
|
801 { |
|
802 png_warning(png_ptr, "Image width exceeds user limit in IHDR"); |
|
803 error = 1; |
|
804 } |
|
805 |
|
806 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
807 if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX) |
|
808 #else |
|
809 if (height > PNG_USER_HEIGHT_MAX) |
|
810 #endif |
|
811 { |
|
812 png_warning(png_ptr, "Image height exceeds user limit in IHDR"); |
|
813 error = 1; |
|
814 } |
|
815 |
|
816 if (width > PNG_UINT_31_MAX) |
|
817 { |
|
818 png_warning(png_ptr, "Invalid image width in IHDR"); |
|
819 error = 1; |
|
820 } |
|
821 |
|
822 if ( height > PNG_UINT_31_MAX) |
|
823 { |
|
824 png_warning(png_ptr, "Invalid image height in IHDR"); |
|
825 error = 1; |
|
826 } |
|
827 |
|
828 if ( width > (PNG_UINT_32_MAX |
|
829 >> 3) /* 8-byte RGBA pixels */ |
|
830 - 64 /* bigrowbuf hack */ |
|
831 - 1 /* filter byte */ |
|
832 - 7*8 /* rounding of width to multiple of 8 pixels */ |
|
833 - 8) /* extra max_pixel_depth pad */ |
|
834 png_warning(png_ptr, "Width is too large for libpng to process pixels"); |
|
835 |
|
836 /* Check other values */ |
|
837 if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && |
|
838 bit_depth != 8 && bit_depth != 16) |
|
839 { |
|
840 png_warning(png_ptr, "Invalid bit depth in IHDR"); |
|
841 error = 1; |
|
842 } |
|
843 |
|
844 if (color_type < 0 || color_type == 1 || |
|
845 color_type == 5 || color_type > 6) |
|
846 { |
|
847 png_warning(png_ptr, "Invalid color type in IHDR"); |
|
848 error = 1; |
|
849 } |
|
850 |
|
851 if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || |
|
852 ((color_type == PNG_COLOR_TYPE_RGB || |
|
853 color_type == PNG_COLOR_TYPE_GRAY_ALPHA || |
|
854 color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) |
|
855 { |
|
856 png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); |
|
857 error = 1; |
|
858 } |
|
859 |
|
860 if (interlace_type >= PNG_INTERLACE_LAST) |
|
861 { |
|
862 png_warning(png_ptr, "Unknown interlace method in IHDR"); |
|
863 error = 1; |
|
864 } |
|
865 |
|
866 if (compression_type != PNG_COMPRESSION_TYPE_BASE) |
|
867 { |
|
868 png_warning(png_ptr, "Unknown compression method in IHDR"); |
|
869 error = 1; |
|
870 } |
|
871 |
|
872 #ifdef PNG_MNG_FEATURES_SUPPORTED |
|
873 /* Accept filter_method 64 (intrapixel differencing) only if |
|
874 * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and |
|
875 * 2. Libpng did not read a PNG signature (this filter_method is only |
|
876 * used in PNG datastreams that are embedded in MNG datastreams) and |
|
877 * 3. The application called png_permit_mng_features with a mask that |
|
878 * included PNG_FLAG_MNG_FILTER_64 and |
|
879 * 4. The filter_method is 64 and |
|
880 * 5. The color_type is RGB or RGBA |
|
881 */ |
|
882 if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && |
|
883 png_ptr->mng_features_permitted) |
|
884 png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); |
|
885 |
|
886 if (filter_type != PNG_FILTER_TYPE_BASE) |
|
887 { |
|
888 if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && |
|
889 (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && |
|
890 ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && |
|
891 (color_type == PNG_COLOR_TYPE_RGB || |
|
892 color_type == PNG_COLOR_TYPE_RGB_ALPHA))) |
|
893 { |
|
894 png_warning(png_ptr, "Unknown filter method in IHDR"); |
|
895 error = 1; |
|
896 } |
|
897 |
|
898 if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) |
|
899 { |
|
900 png_warning(png_ptr, "Invalid filter method in IHDR"); |
|
901 error = 1; |
|
902 } |
|
903 } |
|
904 |
|
905 #else |
|
906 if (filter_type != PNG_FILTER_TYPE_BASE) |
|
907 { |
|
908 png_warning(png_ptr, "Unknown filter method in IHDR"); |
|
909 error = 1; |
|
910 } |
|
911 #endif |
|
912 |
|
913 if (error == 1) |
|
914 png_error(png_ptr, "Invalid IHDR data"); |
|
915 } |
926 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ |
916 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ |