1 |
1 |
2 /* pngrutil.c - utilities to read a PNG file |
2 /* pngrutil.c - utilities to read a PNG file |
3 * |
3 * |
4 * Last changed in libpng 1.2.38 [July 16, 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 |
12 * |
12 * |
13 * This file contains routines that are only called from within |
13 * This file contains routines that are only called from within |
14 * libpng itself during the course of reading an image. |
14 * libpng itself during the course of reading an image. |
15 */ |
15 */ |
16 |
16 |
17 #define PNG_INTERNAL |
17 #define PNG_NO_PEDANTIC_WARNINGS |
18 #include "png.h" |
18 #include "png.h" |
19 #if defined(PNG_READ_SUPPORTED) |
19 #ifdef PNG_READ_SUPPORTED |
20 |
20 #include "pngpriv.h" |
21 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) |
21 |
22 # define WIN32_WCE_OLD |
|
23 #endif |
|
24 |
|
25 #ifdef PNG_FLOATING_POINT_SUPPORTED |
|
26 # if defined(WIN32_WCE_OLD) |
|
27 /* The strtod() function is not supported on WindowsCE */ |
|
28 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr) |
|
29 { |
|
30 double result = 0; |
|
31 int len; |
|
32 wchar_t *str, *end; |
|
33 |
|
34 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); |
|
35 str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t)); |
|
36 if ( NULL != str ) |
|
37 { |
|
38 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); |
|
39 result = wcstod(str, &end); |
|
40 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); |
|
41 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); |
|
42 png_free(png_ptr, str); |
|
43 } |
|
44 return result; |
|
45 } |
|
46 # else |
|
47 # define png_strtod(p,a,b) strtod(a,b) |
22 # define png_strtod(p,a,b) strtod(a,b) |
48 # endif |
|
49 #endif |
|
50 |
|
51 png_uint_32 PNGAPI |
23 png_uint_32 PNGAPI |
52 png_get_uint_31(png_structp png_ptr, png_bytep buf) |
24 png_get_uint_31(png_structp png_ptr, png_bytep buf) |
53 { |
25 { |
54 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED |
|
55 png_uint_32 i = png_get_uint_32(buf); |
26 png_uint_32 i = png_get_uint_32(buf); |
56 #else |
|
57 /* Avoid an extra function call by inlining the result. */ |
|
58 png_uint_32 i = ((png_uint_32)(*buf) << 24) + |
|
59 ((png_uint_32)(*(buf + 1)) << 16) + |
|
60 ((png_uint_32)(*(buf + 2)) << 8) + |
|
61 (png_uint_32)(*(buf + 3)); |
|
62 #endif |
|
63 if (i > PNG_UINT_31_MAX) |
27 if (i > PNG_UINT_31_MAX) |
64 png_error(png_ptr, "PNG unsigned integer out of range."); |
28 png_error(png_ptr, "PNG unsigned integer out of range"); |
65 return (i); |
29 return (i); |
66 } |
30 } |
67 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED |
31 #ifndef PNG_USE_READ_MACROS |
68 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ |
32 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ |
69 png_uint_32 PNGAPI |
33 png_uint_32 PNGAPI |
70 png_get_uint_32(png_bytep buf) |
34 png_get_uint_32(png_bytep buf) |
71 { |
35 { |
72 png_uint_32 i = ((png_uint_32)(*buf) << 24) + |
36 png_uint_32 i = ((png_uint_32)(*buf) << 24) + |
99 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + |
63 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + |
100 (png_uint_16)(*(buf + 1))); |
64 (png_uint_16)(*(buf + 1))); |
101 |
65 |
102 return (i); |
66 return (i); |
103 } |
67 } |
104 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ |
68 #endif /* PNG_USE_READ_MACROS */ |
105 |
69 |
106 /* Read the chunk header (length + type name). |
70 /* Read the chunk header (length + type name). |
107 * Put the type name into png_ptr->chunk_name, and return the length. |
71 * Put the type name into png_ptr->chunk_name, and return the length. |
108 */ |
72 */ |
109 png_uint_32 /* PRIVATE */ |
73 png_uint_32 /* PRIVATE */ |
110 png_read_chunk_header(png_structp png_ptr) |
74 png_read_chunk_header(png_structp png_ptr) |
111 { |
75 { |
112 png_byte buf[8]; |
76 png_byte buf[8]; |
113 png_uint_32 length; |
77 png_uint_32 length; |
114 |
78 |
|
79 #ifdef PNG_IO_STATE_SUPPORTED |
|
80 /* Inform the I/O callback that the chunk header is being read. |
|
81 * PNG_IO_CHUNK_HDR requires a single I/O call. |
|
82 */ |
|
83 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; |
|
84 #endif |
|
85 |
115 /* Read the length and the chunk name */ |
86 /* Read the length and the chunk name */ |
116 png_read_data(png_ptr, buf, 8); |
87 png_read_data(png_ptr, buf, 8); |
117 length = png_get_uint_31(png_ptr, buf); |
88 length = png_get_uint_31(png_ptr, buf); |
118 |
89 |
119 /* Put the chunk name into png_ptr->chunk_name */ |
90 /* Put the chunk name into png_ptr->chunk_name */ |
126 png_reset_crc(png_ptr); |
97 png_reset_crc(png_ptr); |
127 png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); |
98 png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); |
128 |
99 |
129 /* Check to see if chunk name is valid */ |
100 /* Check to see if chunk name is valid */ |
130 png_check_chunk_name(png_ptr, png_ptr->chunk_name); |
101 png_check_chunk_name(png_ptr, png_ptr->chunk_name); |
|
102 |
|
103 #ifdef PNG_IO_STATE_SUPPORTED |
|
104 /* Inform the I/O callback that chunk data will (possibly) be read. |
|
105 * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. |
|
106 */ |
|
107 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; |
|
108 #endif |
131 |
109 |
132 return length; |
110 return length; |
133 } |
111 } |
134 |
112 |
135 /* Read data, and (optionally) run it through the CRC. */ |
113 /* Read data, and (optionally) run it through the CRC. */ |
288 if (text == NULL) |
273 if (text == NULL) |
289 { |
274 { |
290 png_free(png_ptr, png_ptr->chunkdata); |
275 png_free(png_ptr, png_ptr->chunkdata); |
291 png_ptr->chunkdata = NULL; |
276 png_ptr->chunkdata = NULL; |
292 png_error(png_ptr, |
277 png_error(png_ptr, |
293 "Not enough memory to decompress chunk."); |
278 "Not enough memory to decompress chunk"); |
294 } |
279 } |
295 png_memcpy(text + prefix_size, png_ptr->zbuf, |
280 png_memcpy(text + prefix_size, png_ptr->zbuf, |
296 text_size - prefix_size); |
281 text_size - prefix_size); |
297 png_memcpy(text, png_ptr->chunkdata, prefix_size); |
282 png_memcpy(text, png_ptr->chunkdata, prefix_size); |
298 *(text + text_size) = 0x00; |
283 *(text + text_size) = 0x00; |
300 else |
285 else |
301 { |
286 { |
302 png_charp tmp; |
287 png_charp tmp; |
303 |
288 |
304 tmp = text; |
289 tmp = text; |
305 text = (png_charp)png_malloc_warn(png_ptr, |
290 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
306 (png_uint_32)(text_size + |
291 if ((png_ptr->user_chunk_cache_max != 0) && |
307 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); |
292 (--png_ptr->user_chunk_cache_max == 0)) |
|
293 { |
|
294 png_warning(png_ptr, "No space in chunk cache"); |
|
295 text = NULL; |
|
296 } |
|
297 |
|
298 else |
|
299 { |
|
300 #endif |
|
301 text = (png_charp)png_malloc_warn(png_ptr, |
|
302 (png_size_t)(text_size + |
|
303 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); |
|
304 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
305 } |
|
306 #endif |
308 if (text == NULL) |
307 if (text == NULL) |
309 { |
308 { |
310 png_free(png_ptr, tmp); |
309 png_free(png_ptr, tmp); |
311 png_free(png_ptr, png_ptr->chunkdata); |
310 png_free(png_ptr, png_ptr->chunkdata); |
312 png_ptr->chunkdata = NULL; |
311 png_ptr->chunkdata = NULL; |
313 png_error(png_ptr, |
312 png_error(png_ptr, |
314 "Not enough memory to decompress chunk.."); |
313 "Not enough memory to decompress chunk"); |
315 } |
314 } |
316 png_memcpy(text, tmp, text_size); |
315 png_memcpy(text, tmp, text_size); |
317 png_free(png_ptr, tmp); |
316 png_free(png_ptr, tmp); |
318 png_memcpy(text + text_size, png_ptr->zbuf, |
317 png_memcpy(text + text_size, png_ptr->zbuf, |
319 (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); |
318 (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); |
360 text = (png_charp)png_malloc_warn(png_ptr, text_size+1); |
359 text = (png_charp)png_malloc_warn(png_ptr, text_size+1); |
361 if (text == NULL) |
360 if (text == NULL) |
362 { |
361 { |
363 png_free(png_ptr, png_ptr->chunkdata); |
362 png_free(png_ptr, png_ptr->chunkdata); |
364 png_ptr->chunkdata = NULL; |
363 png_ptr->chunkdata = NULL; |
365 png_error(png_ptr, "Not enough memory for text."); |
364 png_error(png_ptr, "Not enough memory for text"); |
366 } |
365 } |
367 png_memcpy(text, png_ptr->chunkdata, prefix_size); |
366 png_memcpy(text, png_ptr->chunkdata, prefix_size); |
368 } |
367 } |
369 *(text + text_size) = 0x00; |
368 *(text + text_size) = 0x00; |
370 } |
369 } |
428 png_ptr->width = width; |
427 png_ptr->width = width; |
429 png_ptr->height = height; |
428 png_ptr->height = height; |
430 png_ptr->bit_depth = (png_byte)bit_depth; |
429 png_ptr->bit_depth = (png_byte)bit_depth; |
431 png_ptr->interlaced = (png_byte)interlace_type; |
430 png_ptr->interlaced = (png_byte)interlace_type; |
432 png_ptr->color_type = (png_byte)color_type; |
431 png_ptr->color_type = (png_byte)color_type; |
433 #if defined(PNG_MNG_FEATURES_SUPPORTED) |
432 #ifdef PNG_MNG_FEATURES_SUPPORTED |
434 png_ptr->filter_type = (png_byte)filter_type; |
433 png_ptr->filter_type = (png_byte)filter_type; |
435 #endif |
434 #endif |
436 png_ptr->compression_type = (png_byte)compression_type; |
435 png_ptr->compression_type = (png_byte)compression_type; |
437 |
436 |
438 /* Find number of channels */ |
437 /* Find number of channels */ |
552 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do |
551 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do |
553 * whatever the normal CRC configuration tells us. However, if we |
552 * whatever the normal CRC configuration tells us. However, if we |
554 * have an RGB image, the PLTE can be considered ancillary, so |
553 * have an RGB image, the PLTE can be considered ancillary, so |
555 * we will act as though it is. |
554 * we will act as though it is. |
556 */ |
555 */ |
557 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) |
556 #ifndef PNG_READ_OPT_PLTE_SUPPORTED |
558 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
557 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
559 #endif |
558 #endif |
560 { |
559 { |
561 png_crc_finish(png_ptr, 0); |
560 png_crc_finish(png_ptr, 0); |
562 } |
561 } |
563 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) |
562 #ifndef PNG_READ_OPT_PLTE_SUPPORTED |
564 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ |
563 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ |
565 { |
564 { |
566 /* If we don't want to use the data from an ancillary chunk, |
565 /* If we don't want to use the data from an ancillary chunk, |
567 we have two options: an error abort, or a warning and we |
566 we have two options: an error abort, or a warning and we |
568 ignore the data in this chunk (which should be OK, since |
567 ignore the data in this chunk (which should be OK, since |
569 it's considered ancillary for a RGB or RGBA image). */ |
568 it's considered ancillary for a RGB or RGBA image). */ |
570 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) |
569 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) |
571 { |
570 { |
572 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) |
571 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) |
573 { |
572 { |
574 png_chunk_error(png_ptr, "CRC error"); |
573 png_chunk_benign_error(png_ptr, "CRC error"); |
575 } |
574 } |
576 else |
575 else |
577 { |
576 { |
578 png_chunk_warning(png_ptr, "CRC error"); |
577 png_chunk_warning(png_ptr, "CRC error"); |
579 return; |
578 return; |
654 else if (png_ptr->mode & PNG_HAVE_PLTE) |
653 else if (png_ptr->mode & PNG_HAVE_PLTE) |
655 /* Should be an error, but we can cope with it */ |
654 /* Should be an error, but we can cope with it */ |
656 png_warning(png_ptr, "Out of place gAMA chunk"); |
655 png_warning(png_ptr, "Out of place gAMA chunk"); |
657 |
656 |
658 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) |
657 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) |
659 #if defined(PNG_READ_sRGB_SUPPORTED) |
658 #ifdef PNG_READ_sRGB_SUPPORTED |
660 && !(info_ptr->valid & PNG_INFO_sRGB) |
659 && !(info_ptr->valid & PNG_INFO_sRGB) |
661 #endif |
660 #endif |
662 ) |
661 ) |
663 { |
662 { |
664 png_warning(png_ptr, "Duplicate gAMA chunk"); |
663 png_warning(png_ptr, "Duplicate gAMA chunk"); |
684 png_warning(png_ptr, |
683 png_warning(png_ptr, |
685 "Ignoring gAMA chunk with gamma=0"); |
684 "Ignoring gAMA chunk with gamma=0"); |
686 return; |
685 return; |
687 } |
686 } |
688 |
687 |
689 #if defined(PNG_READ_sRGB_SUPPORTED) |
688 #ifdef PNG_READ_sRGB_SUPPORTED |
690 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) |
689 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) |
691 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) |
690 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) |
692 { |
691 { |
693 png_warning(png_ptr, |
692 png_warning(png_ptr, |
694 "Ignoring incorrect gAMA value when sRGB is also present"); |
693 "Ignoring incorrect gAMA value when sRGB is also present"); |
695 #ifndef PNG_NO_CONSOLE_IO |
694 #ifdef PNG_CONSOLE_IO_SUPPORTED |
696 fprintf(stderr, "gamma = (%d/100000)", (int)igamma); |
695 fprintf(stderr, "gamma = (%d/100000)", (int)igamma); |
697 #endif |
696 #endif |
698 return; |
697 return; |
699 } |
698 } |
700 #endif /* PNG_READ_sRGB_SUPPORTED */ |
699 #endif /* PNG_READ_sRGB_SUPPORTED */ |
804 else if (png_ptr->mode & PNG_HAVE_PLTE) |
803 else if (png_ptr->mode & PNG_HAVE_PLTE) |
805 /* Should be an error, but we can cope with it */ |
804 /* Should be an error, but we can cope with it */ |
806 png_warning(png_ptr, "Missing PLTE before cHRM"); |
805 png_warning(png_ptr, "Missing PLTE before cHRM"); |
807 |
806 |
808 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) |
807 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) |
809 #if defined(PNG_READ_sRGB_SUPPORTED) |
808 #ifdef PNG_READ_sRGB_SUPPORTED |
810 && !(info_ptr->valid & PNG_INFO_sRGB) |
809 && !(info_ptr->valid & PNG_INFO_sRGB) |
811 #endif |
810 #endif |
812 ) |
811 ) |
813 { |
812 { |
814 png_warning(png_ptr, "Duplicate cHRM chunk"); |
813 png_warning(png_ptr, "Duplicate cHRM chunk"); |
856 green_y = (float)int_y_green / (float)100000.0; |
855 green_y = (float)int_y_green / (float)100000.0; |
857 blue_x = (float)int_x_blue / (float)100000.0; |
856 blue_x = (float)int_x_blue / (float)100000.0; |
858 blue_y = (float)int_y_blue / (float)100000.0; |
857 blue_y = (float)int_y_blue / (float)100000.0; |
859 #endif |
858 #endif |
860 |
859 |
861 #if defined(PNG_READ_sRGB_SUPPORTED) |
860 #ifdef PNG_READ_sRGB_SUPPORTED |
862 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) |
861 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) |
863 { |
862 { |
864 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || |
863 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || |
865 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || |
864 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || |
866 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || |
865 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || |
870 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || |
869 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || |
871 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) |
870 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) |
872 { |
871 { |
873 png_warning(png_ptr, |
872 png_warning(png_ptr, |
874 "Ignoring incorrect cHRM value when sRGB is also present"); |
873 "Ignoring incorrect cHRM value when sRGB is also present"); |
875 #ifndef PNG_NO_CONSOLE_IO |
874 #ifdef PNG_CONSOLE_IO_SUPPORTED |
876 #ifdef PNG_FLOATING_POINT_SUPPORTED |
875 #ifdef PNG_FLOATING_POINT_SUPPORTED |
877 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", |
876 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", |
878 white_x, white_y, red_x, red_y); |
877 white_x, white_y, red_x, red_y); |
879 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", |
878 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", |
880 green_x, green_y, blue_x, blue_y); |
879 green_x, green_y, blue_x, blue_y); |
882 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", |
881 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", |
883 int_x_white, int_y_white, int_x_red, int_y_red); |
882 int_x_white, int_y_white, int_x_red, int_y_red); |
884 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", |
883 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", |
885 int_x_green, int_y_green, int_x_blue, int_y_blue); |
884 int_x_green, int_y_green, int_x_blue, int_y_blue); |
886 #endif |
885 #endif |
887 #endif /* PNG_NO_CONSOLE_IO */ |
886 #endif /* PNG_CONSOLE_IO_SUPPORTED */ |
888 } |
887 } |
889 return; |
888 return; |
890 } |
889 } |
891 #endif /* PNG_READ_sRGB_SUPPORTED */ |
890 #endif /* PNG_READ_sRGB_SUPPORTED */ |
892 |
891 |
962 #endif |
961 #endif |
963 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) |
962 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) |
964 { |
963 { |
965 png_warning(png_ptr, |
964 png_warning(png_ptr, |
966 "Ignoring incorrect gAMA value when sRGB is also present"); |
965 "Ignoring incorrect gAMA value when sRGB is also present"); |
967 #ifndef PNG_NO_CONSOLE_IO |
966 #ifdef PNG_CONSOLE_IO_SUPPORTED |
968 # ifdef PNG_FIXED_POINT_SUPPORTED |
967 # ifdef PNG_FIXED_POINT_SUPPORTED |
969 fprintf(stderr, "incorrect gamma=(%d/100000)\n", |
968 fprintf(stderr, "incorrect gamma=(%d/100000)\n", |
970 (int)png_ptr->int_gamma); |
969 (int)png_ptr->int_gamma); |
971 # else |
970 # else |
972 # ifdef PNG_FLOATING_POINT_SUPPORTED |
971 # ifdef PNG_FLOATING_POINT_SUPPORTED |
1107 |
1106 |
1108 if (profile_size > profile_length) |
1107 if (profile_size > profile_length) |
1109 { |
1108 { |
1110 png_free(png_ptr, png_ptr->chunkdata); |
1109 png_free(png_ptr, png_ptr->chunkdata); |
1111 png_ptr->chunkdata = NULL; |
1110 png_ptr->chunkdata = NULL; |
1112 png_warning(png_ptr, "Ignoring truncated iCCP profile."); |
1111 png_warning(png_ptr, "Ignoring truncated iCCP profile"); |
1113 return; |
1112 return; |
1114 } |
1113 } |
1115 |
1114 |
1116 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, |
1115 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, |
1117 compression_type, png_ptr->chunkdata + prefix_length, profile_length); |
1116 compression_type, png_ptr->chunkdata + prefix_length, profile_length); |
1118 png_free(png_ptr, png_ptr->chunkdata); |
1117 png_free(png_ptr, png_ptr->chunkdata); |
1119 png_ptr->chunkdata = NULL; |
1118 png_ptr->chunkdata = NULL; |
1120 } |
1119 } |
1121 #endif /* PNG_READ_iCCP_SUPPORTED */ |
1120 #endif /* PNG_READ_iCCP_SUPPORTED */ |
1122 |
1121 |
1123 #if defined(PNG_READ_sPLT_SUPPORTED) |
1122 #ifdef PNG_READ_sPLT_SUPPORTED |
1124 void /* PRIVATE */ |
1123 void /* PRIVATE */ |
1125 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) |
1124 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) |
1126 /* Note: this does not properly handle chunks that are > 64K under DOS */ |
1125 /* Note: this does not properly handle chunks that are > 64K under DOS */ |
1127 { |
1126 { |
1128 png_bytep entry_start; |
1127 png_bytep entry_start; |
1129 png_sPLT_t new_palette; |
1128 png_sPLT_t new_palette; |
1130 #ifdef PNG_NO_POINTER_INDEXING |
1129 #ifdef PNG_POINTER_INDEXING_SUPPORTED |
1131 png_sPLT_entryp pp; |
1130 png_sPLT_entryp pp; |
1132 #endif |
1131 #endif |
1133 int data_length, entry_size, i; |
1132 int data_length, entry_size, i; |
1134 png_uint_32 skip = 0; |
1133 png_uint_32 skip = 0; |
1135 png_size_t slength; |
1134 png_size_t slength; |
1136 |
1135 |
1137 png_debug(1, "in png_handle_sPLT"); |
1136 png_debug(1, "in png_handle_sPLT"); |
1138 |
1137 |
|
1138 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
1139 |
|
1140 if (png_ptr->user_chunk_cache_max != 0) |
|
1141 { |
|
1142 if (png_ptr->user_chunk_cache_max == 1) |
|
1143 { |
|
1144 png_crc_finish(png_ptr, length); |
|
1145 return; |
|
1146 } |
|
1147 if (--png_ptr->user_chunk_cache_max == 1) |
|
1148 { |
|
1149 png_warning(png_ptr, "No space in chunk cache for sPLT"); |
|
1150 png_crc_finish(png_ptr, length); |
|
1151 return; |
|
1152 } |
|
1153 } |
|
1154 #endif |
1139 |
1155 |
1140 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
1156 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
1141 png_error(png_ptr, "Missing IHDR before sPLT"); |
1157 png_error(png_ptr, "Missing IHDR before sPLT"); |
1142 else if (png_ptr->mode & PNG_HAVE_IDAT) |
1158 else if (png_ptr->mode & PNG_HAVE_IDAT) |
1143 { |
1159 { |
1313 png_crc_finish(png_ptr, length); |
1329 png_crc_finish(png_ptr, length); |
1314 return; |
1330 return; |
1315 } |
1331 } |
1316 png_crc_read(png_ptr, buf, (png_size_t)length); |
1332 png_crc_read(png_ptr, buf, (png_size_t)length); |
1317 png_ptr->num_trans = 1; |
1333 png_ptr->num_trans = 1; |
1318 png_ptr->trans_values.red = png_get_uint_16(buf); |
1334 png_ptr->trans_color.red = png_get_uint_16(buf); |
1319 png_ptr->trans_values.green = png_get_uint_16(buf + 2); |
1335 png_ptr->trans_color.green = png_get_uint_16(buf + 2); |
1320 png_ptr->trans_values.blue = png_get_uint_16(buf + 4); |
1336 png_ptr->trans_color.blue = png_get_uint_16(buf + 4); |
1321 } |
1337 } |
1322 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
1338 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
1323 { |
1339 { |
1324 if (!(png_ptr->mode & PNG_HAVE_PLTE)) |
1340 if (!(png_ptr->mode & PNG_HAVE_PLTE)) |
1325 { |
1341 { |
1622 length + 1); |
1638 length + 1); |
1623 png_free(png_ptr, png_ptr->chunkdata); |
1639 png_free(png_ptr, png_ptr->chunkdata); |
1624 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
1640 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
1625 if (png_ptr->chunkdata == NULL) |
1641 if (png_ptr->chunkdata == NULL) |
1626 { |
1642 { |
1627 png_warning(png_ptr, "No memory for pCAL purpose."); |
1643 png_warning(png_ptr, "No memory for pCAL purpose"); |
1628 return; |
1644 return; |
1629 } |
1645 } |
1630 slength = (png_size_t)length; |
1646 slength = (png_size_t)length; |
1631 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
1647 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
1632 |
1648 |
1683 for (buf = units; *buf; buf++) |
1699 for (buf = units; *buf; buf++) |
1684 /* Empty loop to move past the units string. */ ; |
1700 /* Empty loop to move past the units string. */ ; |
1685 |
1701 |
1686 png_debug(3, "Allocating pCAL parameters array"); |
1702 png_debug(3, "Allocating pCAL parameters array"); |
1687 params = (png_charpp)png_malloc_warn(png_ptr, |
1703 params = (png_charpp)png_malloc_warn(png_ptr, |
1688 (png_uint_32)(nparams * png_sizeof(png_charp))) ; |
1704 (png_size_t)(nparams * png_sizeof(png_charp))); |
1689 if (params == NULL) |
1705 if (params == NULL) |
1690 { |
1706 { |
1691 png_free(png_ptr, png_ptr->chunkdata); |
1707 png_free(png_ptr, png_ptr->chunkdata); |
1692 png_ptr->chunkdata = NULL; |
1708 png_ptr->chunkdata = NULL; |
1693 png_warning(png_ptr, "No memory for pCAL params."); |
1709 png_warning(png_ptr, "No memory for pCAL params"); |
1694 return; |
1710 return; |
1695 } |
1711 } |
1696 |
1712 |
1697 /* Get pointers to the start of each parameter string. */ |
1713 /* Get pointers to the start of each parameter string. */ |
1698 for (i = 0; i < (int)nparams; i++) |
1714 for (i = 0; i < (int)nparams; i++) |
1921 png_size_t slength; |
1937 png_size_t slength; |
1922 int ret; |
1938 int ret; |
1923 |
1939 |
1924 png_debug(1, "in png_handle_tEXt"); |
1940 png_debug(1, "in png_handle_tEXt"); |
1925 |
1941 |
|
1942 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
1943 if (png_ptr->user_chunk_cache_max != 0) |
|
1944 { |
|
1945 if (png_ptr->user_chunk_cache_max == 1) |
|
1946 { |
|
1947 png_crc_finish(png_ptr, length); |
|
1948 return; |
|
1949 } |
|
1950 if (--png_ptr->user_chunk_cache_max == 1) |
|
1951 { |
|
1952 png_warning(png_ptr, "No space in chunk cache for tEXt"); |
|
1953 png_crc_finish(png_ptr, length); |
|
1954 return; |
|
1955 } |
|
1956 } |
|
1957 #endif |
1926 |
1958 |
1927 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
1959 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
1928 png_error(png_ptr, "Missing IHDR before tEXt"); |
1960 png_error(png_ptr, "Missing IHDR before tEXt"); |
1929 |
1961 |
1930 if (png_ptr->mode & PNG_HAVE_IDAT) |
1962 if (png_ptr->mode & PNG_HAVE_IDAT) |
1942 png_free(png_ptr, png_ptr->chunkdata); |
1974 png_free(png_ptr, png_ptr->chunkdata); |
1943 |
1975 |
1944 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
1976 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
1945 if (png_ptr->chunkdata == NULL) |
1977 if (png_ptr->chunkdata == NULL) |
1946 { |
1978 { |
1947 png_warning(png_ptr, "No memory to process text chunk."); |
1979 png_warning(png_ptr, "No memory to process text chunk"); |
1948 return; |
1980 return; |
1949 } |
1981 } |
1950 slength = (png_size_t)length; |
1982 slength = (png_size_t)length; |
1951 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
1983 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
1952 |
1984 |
1966 |
1998 |
1967 if (text != key + slength) |
1999 if (text != key + slength) |
1968 text++; |
2000 text++; |
1969 |
2001 |
1970 text_ptr = (png_textp)png_malloc_warn(png_ptr, |
2002 text_ptr = (png_textp)png_malloc_warn(png_ptr, |
1971 (png_uint_32)png_sizeof(png_text)); |
2003 png_sizeof(png_text)); |
1972 if (text_ptr == NULL) |
2004 if (text_ptr == NULL) |
1973 { |
2005 { |
1974 png_warning(png_ptr, "Not enough memory to process text chunk."); |
2006 png_warning(png_ptr, "Not enough memory to process text chunk"); |
1975 png_free(png_ptr, png_ptr->chunkdata); |
2007 png_free(png_ptr, png_ptr->chunkdata); |
1976 png_ptr->chunkdata = NULL; |
2008 png_ptr->chunkdata = NULL; |
1977 return; |
2009 return; |
1978 } |
2010 } |
1979 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; |
2011 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; |
1990 |
2022 |
1991 png_free(png_ptr, png_ptr->chunkdata); |
2023 png_free(png_ptr, png_ptr->chunkdata); |
1992 png_ptr->chunkdata = NULL; |
2024 png_ptr->chunkdata = NULL; |
1993 png_free(png_ptr, text_ptr); |
2025 png_free(png_ptr, text_ptr); |
1994 if (ret) |
2026 if (ret) |
1995 png_warning(png_ptr, "Insufficient memory to process text chunk."); |
2027 png_warning(png_ptr, "Insufficient memory to process text chunk"); |
1996 } |
2028 } |
1997 #endif |
2029 #endif |
1998 |
2030 |
1999 #if defined(PNG_READ_zTXt_SUPPORTED) |
2031 #ifdef PNG_READ_zTXt_SUPPORTED |
2000 /* Note: this does not correctly handle chunks that are > 64K under DOS */ |
2032 /* Note: this does not correctly handle chunks that are > 64K under DOS */ |
2001 void /* PRIVATE */ |
2033 void /* PRIVATE */ |
2002 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) |
2034 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) |
2003 { |
2035 { |
2004 png_textp text_ptr; |
2036 png_textp text_ptr; |
2007 int ret; |
2039 int ret; |
2008 png_size_t slength, prefix_len, data_len; |
2040 png_size_t slength, prefix_len, data_len; |
2009 |
2041 |
2010 png_debug(1, "in png_handle_zTXt"); |
2042 png_debug(1, "in png_handle_zTXt"); |
2011 |
2043 |
|
2044 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
2045 if (png_ptr->user_chunk_cache_max != 0) |
|
2046 { |
|
2047 if (png_ptr->user_chunk_cache_max == 1) |
|
2048 { |
|
2049 png_crc_finish(png_ptr, length); |
|
2050 return; |
|
2051 } |
|
2052 if (--png_ptr->user_chunk_cache_max == 1) |
|
2053 { |
|
2054 png_warning(png_ptr, "No space in chunk cache for zTXt"); |
|
2055 png_crc_finish(png_ptr, length); |
|
2056 return; |
|
2057 } |
|
2058 } |
|
2059 #endif |
2012 |
2060 |
2013 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
2061 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
2014 png_error(png_ptr, "Missing IHDR before zTXt"); |
2062 png_error(png_ptr, "Missing IHDR before zTXt"); |
2015 |
2063 |
2016 if (png_ptr->mode & PNG_HAVE_IDAT) |
2064 if (png_ptr->mode & PNG_HAVE_IDAT) |
2029 |
2077 |
2030 png_free(png_ptr, png_ptr->chunkdata); |
2078 png_free(png_ptr, png_ptr->chunkdata); |
2031 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
2079 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
2032 if (png_ptr->chunkdata == NULL) |
2080 if (png_ptr->chunkdata == NULL) |
2033 { |
2081 { |
2034 png_warning(png_ptr, "Out of memory processing zTXt chunk."); |
2082 png_warning(png_ptr, "Out of memory processing zTXt chunk"); |
2035 return; |
2083 return; |
2036 } |
2084 } |
2037 slength = (png_size_t)length; |
2085 slength = (png_size_t)length; |
2038 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
2086 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
2039 if (png_crc_finish(png_ptr, 0)) |
2087 if (png_crc_finish(png_ptr, 0)) |
2070 |
2118 |
2071 png_decompress_chunk(png_ptr, comp_type, |
2119 png_decompress_chunk(png_ptr, comp_type, |
2072 (png_size_t)length, prefix_len, &data_len); |
2120 (png_size_t)length, prefix_len, &data_len); |
2073 |
2121 |
2074 text_ptr = (png_textp)png_malloc_warn(png_ptr, |
2122 text_ptr = (png_textp)png_malloc_warn(png_ptr, |
2075 (png_uint_32)png_sizeof(png_text)); |
2123 png_sizeof(png_text)); |
2076 if (text_ptr == NULL) |
2124 if (text_ptr == NULL) |
2077 { |
2125 { |
2078 png_warning(png_ptr, "Not enough memory to process zTXt chunk."); |
2126 png_warning(png_ptr, "Not enough memory to process zTXt chunk"); |
2079 png_free(png_ptr, png_ptr->chunkdata); |
2127 png_free(png_ptr, png_ptr->chunkdata); |
2080 png_ptr->chunkdata = NULL; |
2128 png_ptr->chunkdata = NULL; |
2081 return; |
2129 return; |
2082 } |
2130 } |
2083 text_ptr->compression = comp_type; |
2131 text_ptr->compression = comp_type; |
2094 |
2142 |
2095 png_free(png_ptr, text_ptr); |
2143 png_free(png_ptr, text_ptr); |
2096 png_free(png_ptr, png_ptr->chunkdata); |
2144 png_free(png_ptr, png_ptr->chunkdata); |
2097 png_ptr->chunkdata = NULL; |
2145 png_ptr->chunkdata = NULL; |
2098 if (ret) |
2146 if (ret) |
2099 png_error(png_ptr, "Insufficient memory to store zTXt chunk."); |
2147 png_error(png_ptr, "Insufficient memory to store zTXt chunk"); |
2100 } |
2148 } |
2101 #endif |
2149 #endif |
2102 |
2150 |
2103 #if defined(PNG_READ_iTXt_SUPPORTED) |
2151 #ifdef PNG_READ_iTXt_SUPPORTED |
2104 /* Note: this does not correctly handle chunks that are > 64K under DOS */ |
2152 /* Note: this does not correctly handle chunks that are > 64K under DOS */ |
2105 void /* PRIVATE */ |
2153 void /* PRIVATE */ |
2106 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) |
2154 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) |
2107 { |
2155 { |
2108 png_textp text_ptr; |
2156 png_textp text_ptr; |
2112 int ret; |
2160 int ret; |
2113 png_size_t slength, prefix_len, data_len; |
2161 png_size_t slength, prefix_len, data_len; |
2114 |
2162 |
2115 png_debug(1, "in png_handle_iTXt"); |
2163 png_debug(1, "in png_handle_iTXt"); |
2116 |
2164 |
|
2165 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
2166 if (png_ptr->user_chunk_cache_max != 0) |
|
2167 { |
|
2168 if (png_ptr->user_chunk_cache_max == 1) |
|
2169 { |
|
2170 png_crc_finish(png_ptr, length); |
|
2171 return; |
|
2172 } |
|
2173 if (--png_ptr->user_chunk_cache_max == 1) |
|
2174 { |
|
2175 png_warning(png_ptr, "No space in chunk cache for iTXt"); |
|
2176 png_crc_finish(png_ptr, length); |
|
2177 return; |
|
2178 } |
|
2179 } |
|
2180 #endif |
2117 |
2181 |
2118 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
2182 if (!(png_ptr->mode & PNG_HAVE_IHDR)) |
2119 png_error(png_ptr, "Missing IHDR before iTXt"); |
2183 png_error(png_ptr, "Missing IHDR before iTXt"); |
2120 |
2184 |
2121 if (png_ptr->mode & PNG_HAVE_IDAT) |
2185 if (png_ptr->mode & PNG_HAVE_IDAT) |
2134 |
2198 |
2135 png_free(png_ptr, png_ptr->chunkdata); |
2199 png_free(png_ptr, png_ptr->chunkdata); |
2136 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
2200 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); |
2137 if (png_ptr->chunkdata == NULL) |
2201 if (png_ptr->chunkdata == NULL) |
2138 { |
2202 { |
2139 png_warning(png_ptr, "No memory to process iTXt chunk."); |
2203 png_warning(png_ptr, "No memory to process iTXt chunk"); |
2140 return; |
2204 return; |
2141 } |
2205 } |
2142 slength = (png_size_t)length; |
2206 slength = (png_size_t)length; |
2143 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
2207 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); |
2144 if (png_crc_finish(png_ptr, 0)) |
2208 if (png_crc_finish(png_ptr, 0)) |
2202 png_decompress_chunk(png_ptr, comp_type, |
2266 png_decompress_chunk(png_ptr, comp_type, |
2203 (size_t)length, prefix_len, &data_len); |
2267 (size_t)length, prefix_len, &data_len); |
2204 else |
2268 else |
2205 data_len = png_strlen(png_ptr->chunkdata + prefix_len); |
2269 data_len = png_strlen(png_ptr->chunkdata + prefix_len); |
2206 text_ptr = (png_textp)png_malloc_warn(png_ptr, |
2270 text_ptr = (png_textp)png_malloc_warn(png_ptr, |
2207 (png_uint_32)png_sizeof(png_text)); |
2271 png_sizeof(png_text)); |
2208 if (text_ptr == NULL) |
2272 if (text_ptr == NULL) |
2209 { |
2273 { |
2210 png_warning(png_ptr, "Not enough memory to process iTXt chunk."); |
2274 png_warning(png_ptr, "Not enough memory to process iTXt chunk"); |
2211 png_free(png_ptr, png_ptr->chunkdata); |
2275 png_free(png_ptr, png_ptr->chunkdata); |
2212 png_ptr->chunkdata = NULL; |
2276 png_ptr->chunkdata = NULL; |
2213 return; |
2277 return; |
2214 } |
2278 } |
2215 text_ptr->compression = (int)comp_flag + 1; |
2279 text_ptr->compression = (int)comp_flag + 1; |
2240 { |
2304 { |
2241 png_uint_32 skip = 0; |
2305 png_uint_32 skip = 0; |
2242 |
2306 |
2243 png_debug(1, "in png_handle_unknown"); |
2307 png_debug(1, "in png_handle_unknown"); |
2244 |
2308 |
|
2309 #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
|
2310 if (png_ptr->user_chunk_cache_max != 0) |
|
2311 { |
|
2312 if (png_ptr->user_chunk_cache_max == 1) |
|
2313 { |
|
2314 png_crc_finish(png_ptr, length); |
|
2315 return; |
|
2316 } |
|
2317 if (--png_ptr->user_chunk_cache_max == 1) |
|
2318 { |
|
2319 png_warning(png_ptr, "No space in chunk cache for unknown chunk"); |
|
2320 png_crc_finish(png_ptr, length); |
|
2321 return; |
|
2322 } |
|
2323 } |
|
2324 #endif |
2245 |
2325 |
2246 if (png_ptr->mode & PNG_HAVE_IDAT) |
2326 if (png_ptr->mode & PNG_HAVE_IDAT) |
2247 { |
2327 { |
2248 #ifdef PNG_USE_LOCAL_ARRAYS |
2328 PNG_IDAT; |
2249 PNG_CONST PNG_IDAT; |
|
2250 #endif |
|
2251 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ |
2329 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ |
2252 png_ptr->mode |= PNG_AFTER_IDAT; |
2330 png_ptr->mode |= PNG_AFTER_IDAT; |
2253 } |
2331 } |
2254 |
2332 |
2255 if (!(png_ptr->chunk_name[0] & 0x20)) |
2333 if (!(png_ptr->chunk_name[0] & 0x20)) |
2256 { |
2334 { |
2257 #if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) |
2335 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
2258 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != |
2336 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != |
2259 PNG_HANDLE_CHUNK_ALWAYS |
2337 PNG_HANDLE_CHUNK_ALWAYS |
2260 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) |
2338 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED |
2261 && png_ptr->read_user_chunk_fn == NULL |
2339 && png_ptr->read_user_chunk_fn == NULL |
2262 #endif |
2340 #endif |
2263 ) |
2341 ) |
2264 #endif |
2342 #endif |
2265 png_chunk_error(png_ptr, "unknown critical chunk"); |
2343 png_chunk_error(png_ptr, "unknown critical chunk"); |
2266 } |
2344 } |
2267 |
2345 |
2268 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) |
2346 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED |
2269 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) |
2347 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) |
2270 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) |
2348 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED |
2271 || (png_ptr->read_user_chunk_fn != NULL) |
2349 || (png_ptr->read_user_chunk_fn != NULL) |
2272 #endif |
2350 #endif |
2273 ) |
2351 ) |
2274 { |
2352 { |
2275 #ifdef PNG_MAX_MALLOC_64K |
2353 #ifdef PNG_MAX_MALLOC_64K |
2302 if (ret < 0) |
2380 if (ret < 0) |
2303 png_chunk_error(png_ptr, "error in user chunk"); |
2381 png_chunk_error(png_ptr, "error in user chunk"); |
2304 if (ret == 0) |
2382 if (ret == 0) |
2305 { |
2383 { |
2306 if (!(png_ptr->chunk_name[0] & 0x20)) |
2384 if (!(png_ptr->chunk_name[0] & 0x20)) |
2307 #if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) |
2385 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
2308 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != |
2386 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != |
2309 PNG_HANDLE_CHUNK_ALWAYS) |
2387 PNG_HANDLE_CHUNK_ALWAYS) |
2310 #endif |
2388 #endif |
2311 png_chunk_error(png_ptr, "unknown critical chunk"); |
2389 png_chunk_error(png_ptr, "unknown critical chunk"); |
2312 png_set_unknown_chunks(png_ptr, info_ptr, |
2390 png_set_unknown_chunks(png_ptr, info_ptr, |
2571 { |
2649 { |
2572 png_row_infop row_info = &(png_ptr->row_info); |
2650 png_row_infop row_info = &(png_ptr->row_info); |
2573 png_bytep row = png_ptr->row_buf + 1; |
2651 png_bytep row = png_ptr->row_buf + 1; |
2574 int pass = png_ptr->pass; |
2652 int pass = png_ptr->pass; |
2575 png_uint_32 transformations = png_ptr->transformations; |
2653 png_uint_32 transformations = png_ptr->transformations; |
2576 #ifdef PNG_USE_LOCAL_ARRAYS |
|
2577 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
2654 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
2578 /* Offset to next interlace block */ |
2655 /* Offset to next interlace block */ |
2579 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; |
2656 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; |
2580 #endif |
|
2581 |
2657 |
2582 png_debug(1, "in png_do_read_interlace"); |
2658 png_debug(1, "in png_do_read_interlace"); |
2583 if (row != NULL && row_info != NULL) |
2659 if (row != NULL && row_info != NULL) |
2584 { |
2660 { |
2585 png_uint_32 final_width; |
2661 png_uint_32 final_width; |
2909 *row = 0; |
2985 *row = 0; |
2910 break; |
2986 break; |
2911 } |
2987 } |
2912 } |
2988 } |
2913 |
2989 |
2914 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED |
2990 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED |
2915 void /* PRIVATE */ |
2991 void /* PRIVATE */ |
2916 png_read_finish_row(png_structp png_ptr) |
2992 png_read_finish_row(png_structp png_ptr) |
2917 { |
2993 { |
2918 #ifdef PNG_USE_LOCAL_ARRAYS |
|
2919 #ifdef PNG_READ_INTERLACING_SUPPORTED |
2994 #ifdef PNG_READ_INTERLACING_SUPPORTED |
2920 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
2995 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
2921 |
2996 |
2922 /* Start of interlace block */ |
2997 /* Start of interlace block */ |
2923 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; |
2998 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; |
2929 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
3004 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
2930 |
3005 |
2931 /* Offset to next interlace block in the y direction */ |
3006 /* Offset to next interlace block in the y direction */ |
2932 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
3007 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
2933 #endif /* PNG_READ_INTERLACING_SUPPORTED */ |
3008 #endif /* PNG_READ_INTERLACING_SUPPORTED */ |
2934 #endif |
|
2935 |
3009 |
2936 png_debug(1, "in png_read_finish_row"); |
3010 png_debug(1, "in png_read_finish_row"); |
2937 png_ptr->row_number++; |
3011 png_ptr->row_number++; |
2938 if (png_ptr->row_number < png_ptr->num_rows) |
3012 if (png_ptr->row_number < png_ptr->num_rows) |
2939 return; |
3013 return; |
2940 |
3014 |
2941 #ifdef PNG_READ_INTERLACING_SUPPORTED |
3015 #ifdef PNG_READ_INTERLACING_SUPPORTED |
2942 if (png_ptr->interlaced) |
3016 if (png_ptr->interlaced) |
2943 { |
3017 { |
2944 png_ptr->row_number = 0; |
3018 png_ptr->row_number = 0; |
2945 png_memset_check(png_ptr, png_ptr->prev_row, 0, |
3019 png_memset(png_ptr->prev_row, 0, |
2946 png_ptr->rowbytes + 1); |
3020 png_ptr->rowbytes + 1); |
2947 do |
3021 do |
2948 { |
3022 { |
2949 png_ptr->pass++; |
3023 png_ptr->pass++; |
2950 if (png_ptr->pass >= 7) |
3024 if (png_ptr->pass >= 7) |
3041 |
3113 |
3042 inflateReset(&png_ptr->zstream); |
3114 inflateReset(&png_ptr->zstream); |
3043 |
3115 |
3044 png_ptr->mode |= PNG_AFTER_IDAT; |
3116 png_ptr->mode |= PNG_AFTER_IDAT; |
3045 } |
3117 } |
3046 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ |
3118 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ |
3047 |
3119 |
3048 void /* PRIVATE */ |
3120 void /* PRIVATE */ |
3049 png_read_start_row(png_structp png_ptr) |
3121 png_read_start_row(png_structp png_ptr) |
3050 { |
3122 { |
3051 #ifdef PNG_USE_LOCAL_ARRAYS |
|
3052 #ifdef PNG_READ_INTERLACING_SUPPORTED |
3123 #ifdef PNG_READ_INTERLACING_SUPPORTED |
3053 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
3124 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
3054 |
3125 |
3055 /* Start of interlace block */ |
3126 /* Start of interlace block */ |
3056 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; |
3127 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; |
3061 /* Start of interlace block in the y direction */ |
3132 /* Start of interlace block in the y direction */ |
3062 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
3133 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
3063 |
3134 |
3064 /* Offset to next interlace block in the y direction */ |
3135 /* Offset to next interlace block in the y direction */ |
3065 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
3136 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
3066 #endif |
|
3067 #endif |
3137 #endif |
3068 |
3138 |
3069 int max_pixel_depth; |
3139 int max_pixel_depth; |
3070 png_size_t row_bytes; |
3140 png_size_t row_bytes; |
3071 |
3141 |
3096 png_ptr->iwidth = png_ptr->width; |
3166 png_ptr->iwidth = png_ptr->width; |
3097 png_ptr->irowbytes = png_ptr->rowbytes + 1; |
3167 png_ptr->irowbytes = png_ptr->rowbytes + 1; |
3098 } |
3168 } |
3099 max_pixel_depth = png_ptr->pixel_depth; |
3169 max_pixel_depth = png_ptr->pixel_depth; |
3100 |
3170 |
3101 #if defined(PNG_READ_PACK_SUPPORTED) |
3171 #ifdef PNG_READ_PACK_SUPPORTED |
3102 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) |
3172 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) |
3103 max_pixel_depth = 8; |
3173 max_pixel_depth = 8; |
3104 #endif |
3174 #endif |
3105 |
3175 |
3106 #if defined(PNG_READ_EXPAND_SUPPORTED) |
3176 #ifdef PNG_READ_EXPAND_SUPPORTED |
3107 if (png_ptr->transformations & PNG_EXPAND) |
3177 if (png_ptr->transformations & PNG_EXPAND) |
3108 { |
3178 { |
3109 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
3179 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
3110 { |
3180 { |
3111 if (png_ptr->num_trans) |
3181 if (png_ptr->num_trans) |
3151 max_pixel_depth = 64; |
3221 max_pixel_depth = 64; |
3152 } |
3222 } |
3153 } |
3223 } |
3154 #endif |
3224 #endif |
3155 |
3225 |
3156 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) |
3226 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED |
3157 if (png_ptr->transformations & PNG_GRAY_TO_RGB) |
3227 if (png_ptr->transformations & PNG_GRAY_TO_RGB) |
3158 { |
3228 { |
3159 if ( |
3229 if ( |
3160 #if defined(PNG_READ_EXPAND_SUPPORTED) |
3230 #ifdef PNG_READ_EXPAND_SUPPORTED |
3161 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || |
3231 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || |
3162 #endif |
3232 #endif |
3163 #if defined(PNG_READ_FILLER_SUPPORTED) |
3233 #ifdef PNG_READ_FILLER_SUPPORTED |
3164 (png_ptr->transformations & (PNG_FILLER)) || |
3234 (png_ptr->transformations & (PNG_FILLER)) || |
3165 #endif |
3235 #endif |
3166 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
3236 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
3167 { |
3237 { |
3168 if (max_pixel_depth <= 16) |
3238 if (max_pixel_depth <= 16) |
3210 #ifdef PNG_MAX_MALLOC_64K |
3280 #ifdef PNG_MAX_MALLOC_64K |
3211 if (row_bytes > (png_uint_32)65536L) |
3281 if (row_bytes > (png_uint_32)65536L) |
3212 png_error(png_ptr, "This image requires a row greater than 64KB"); |
3282 png_error(png_ptr, "This image requires a row greater than 64KB"); |
3213 #endif |
3283 #endif |
3214 |
3284 |
3215 if (row_bytes + 64 > png_ptr->old_big_row_buf_size) |
3285 if (row_bytes + 48 > png_ptr->old_big_row_buf_size) |
3216 { |
3286 { |
3217 png_free(png_ptr, png_ptr->big_row_buf); |
3287 png_free(png_ptr, png_ptr->big_row_buf); |
3218 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 64); |
|
3219 if (png_ptr->interlaced) |
3288 if (png_ptr->interlaced) |
3220 png_memset(png_ptr->big_row_buf, 0, row_bytes + 64); |
3289 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, |
|
3290 row_bytes + 48); |
|
3291 else |
|
3292 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, |
|
3293 row_bytes + 48); |
|
3294 png_ptr->old_big_row_buf_size = row_bytes + 48; |
|
3295 |
|
3296 #ifdef PNG_ALIGNED_MEMORY_SUPPORTED |
|
3297 /* Use 16-byte aligned memory for row_buf with at least 16 bytes |
|
3298 * of padding before and after row_buf. |
|
3299 */ |
|
3300 png_ptr->row_buf = png_ptr->big_row_buf + 32 |
|
3301 - (((png_alloc_size_t)&(png_ptr->big_row_buf[0]) + 15) % 16); |
|
3302 png_ptr->old_big_row_buf_size = row_bytes + 48; |
|
3303 #else |
|
3304 /* Use 32 bytes of padding before and 16 bytes after row_buf. */ |
3221 png_ptr->row_buf = png_ptr->big_row_buf + 32; |
3305 png_ptr->row_buf = png_ptr->big_row_buf + 32; |
3222 png_ptr->old_big_row_buf_size = row_bytes + 64; |
3306 #endif |
|
3307 png_ptr->old_big_row_buf_size = row_bytes + 48; |
3223 } |
3308 } |
3224 |
3309 |
3225 #ifdef PNG_MAX_MALLOC_64K |
3310 #ifdef PNG_MAX_MALLOC_64K |
3226 if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L) |
3311 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) |
3227 png_error(png_ptr, "This image requires a row greater than 64KB"); |
3312 png_error(png_ptr, "This image requires a row greater than 64KB"); |
3228 #endif |
3313 #endif |
3229 if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1)) |
3314 if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1)) |
3230 png_error(png_ptr, "Row has too many bytes to allocate in memory."); |
3315 png_error(png_ptr, "Row has too many bytes to allocate in memory"); |
3231 |
3316 |
3232 if (row_bytes + 1 > png_ptr->old_prev_row_size) |
3317 if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size) |
3233 { |
3318 { |
3234 png_free(png_ptr, png_ptr->prev_row); |
3319 png_free(png_ptr, png_ptr->prev_row); |
3235 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( |
3320 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( |
3236 row_bytes + 1)); |
3321 png_ptr->rowbytes + 1)); |
3237 png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1); |
3322 png_ptr->old_prev_row_size = png_ptr->rowbytes + 1; |
3238 png_ptr->old_prev_row_size = row_bytes + 1; |
3323 } |
3239 } |
3324 |
3240 |
3325 png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); |
3241 png_ptr->rowbytes = row_bytes; |
|
3242 |
3326 |
3243 png_debug1(3, "width = %lu,", png_ptr->width); |
3327 png_debug1(3, "width = %lu,", png_ptr->width); |
3244 png_debug1(3, "height = %lu,", png_ptr->height); |
3328 png_debug1(3, "height = %lu,", png_ptr->height); |
3245 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); |
3329 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); |
3246 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); |
3330 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); |