2 /* pngrutil.c - utilities to read a PNG file
4 * libpng 1.0.10 - March 30, 2001
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2001 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This file contains routines that are only called from within
11 * libpng itself during the course of reading an image.
17 #if defined(_WIN32_WCE)
18 /* strtod() function is not supported on WindowsCE */
19 # ifdef PNG_FLOATING_POINT_SUPPORTED
20 __inline
double strtod(const char *nptr
, char **endptr
)
26 len
= MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, NULL
, 0);
27 str
= (wchar_t *)malloc(len
* sizeof(wchar_t));
30 MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, str
, len
);
31 result
= wcstod(str
, &end
);
32 len
= WideCharToMultiByte(CP_ACP
, 0, end
, -1, NULL
, 0, NULL
, NULL
);
33 *endptr
= (char *)nptr
+ (png_strlen(nptr
) - len
+ 1);
41 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
42 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
43 png_uint_32
/* PRIVATE */
44 png_get_uint_32(png_bytep buf
)
46 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
47 ((png_uint_32
)(*(buf
+ 1)) << 16) +
48 ((png_uint_32
)(*(buf
+ 2)) << 8) +
49 (png_uint_32
)(*(buf
+ 3));
54 #if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
55 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
56 * data is stored in the PNG file in two's complement format, and it is
57 * assumed that the machine format for signed integers is the same. */
58 png_int_32
/* PRIVATE */
59 png_get_int_32(png_bytep buf
)
61 png_int_32 i
= ((png_int_32
)(*buf
) << 24) +
62 ((png_int_32
)(*(buf
+ 1)) << 16) +
63 ((png_int_32
)(*(buf
+ 2)) << 8) +
64 (png_int_32
)(*(buf
+ 3));
68 #endif /* PNG_READ_pCAL_SUPPORTED */
70 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
71 png_uint_16
/* PRIVATE */
72 png_get_uint_16(png_bytep buf
)
74 png_uint_16 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
75 (png_uint_16
)(*(buf
+ 1)));
79 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
81 /* Read data, and (optionally) run it through the CRC. */
83 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
85 png_read_data(png_ptr
, buf
, length
);
86 png_calculate_crc(png_ptr
, buf
, length
);
89 /* Optionally skip data and then check the CRC. Depending on whether we
90 are reading a ancillary or critical chunk, and how the program has set
91 things up, we may calculate the CRC on the data and print a message.
92 Returns '1' if there was a CRC error, '0' otherwise. */
94 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
97 png_size_t istop
= png_ptr
->zbuf_size
;
99 for (i
= (png_size_t
)skip
; i
> istop
; i
-= istop
)
101 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
105 png_crc_read(png_ptr
, png_ptr
->zbuf
, i
);
108 if (png_crc_error(png_ptr
))
110 if (((png_ptr
->chunk_name
[0] & 0x20) && /* Ancillary */
111 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
112 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
113 (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
)))
115 png_chunk_warning(png_ptr
, "CRC error");
119 png_chunk_error(png_ptr
, "CRC error");
127 /* Compare the CRC stored in the PNG file with that calculated by libpng from
128 the data it has read thus far. */
130 png_crc_error(png_structp png_ptr
)
132 png_byte crc_bytes
[4];
136 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
138 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
139 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
144 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
148 png_read_data(png_ptr
, crc_bytes
, 4);
152 crc
= png_get_uint_32(crc_bytes
);
153 return ((int)(crc
!= png_ptr
->crc
));
159 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
160 defined(PNG_READ_iCCP_SUPPORTED)
162 * Decompress trailing data in a chunk. The assumption is that chunkdata
163 * points at an allocated area holding the contents of a chunk with a
164 * trailing compressed part. What we get back is an allocated area
165 * holding the original prefix part and an uncompressed version of the
166 * trailing part (the malloc area passed in is freed).
168 png_charp
/* PRIVATE */
169 png_decompress_chunk(png_structp png_ptr
, int comp_type
,
170 png_charp chunkdata
, png_size_t chunklength
,
171 png_size_t prefix_size
, png_size_t
*newlength
)
173 static char msg
[] = "Error decoding compressed text";
174 png_charp text
= NULL
;
175 png_size_t text_size
;
177 if (comp_type
== PNG_COMPRESSION_TYPE_BASE
)
180 png_ptr
->zstream
.next_in
= (png_bytep
)(chunkdata
+ prefix_size
);
181 png_ptr
->zstream
.avail_in
= (uInt
)(chunklength
- prefix_size
);
182 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
183 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
188 while (png_ptr
->zstream
.avail_in
)
190 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
191 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
)
193 if (png_ptr
->zstream
.msg
!= NULL
)
194 png_warning(png_ptr
, png_ptr
->zstream
.msg
);
196 png_warning(png_ptr
, msg
);
197 inflateReset(&png_ptr
->zstream
);
198 png_ptr
->zstream
.avail_in
= 0;
202 text_size
= prefix_size
+ sizeof(msg
) + 1;
203 text
= (png_charp
)png_malloc(png_ptr
, text_size
);
204 png_memcpy(text
, chunkdata
, prefix_size
);
207 text
[text_size
- 1] = 0x00;
209 /* Copy what we can of the error message into the text chunk */
210 text_size
= (png_size_t
)(chunklength
- (text
- chunkdata
) - 1);
211 text_size
= sizeof(msg
) > text_size
? text_size
: sizeof(msg
);
212 png_memcpy(text
+ prefix_size
, msg
, text_size
+ 1);
215 if (!png_ptr
->zstream
.avail_out
|| ret
== Z_STREAM_END
)
219 text_size
= prefix_size
+
220 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
221 text
= (png_charp
)png_malloc(png_ptr
, text_size
+ 1);
222 png_memcpy(text
+ prefix_size
, png_ptr
->zbuf
,
223 text_size
- prefix_size
);
224 png_memcpy(text
, chunkdata
, prefix_size
);
225 *(text
+ text_size
) = 0x00;
232 text
= (png_charp
)png_malloc(png_ptr
, (png_uint_32
)(text_size
+
233 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
+ 1));
234 png_memcpy(text
, tmp
, text_size
);
235 png_free(png_ptr
, tmp
);
236 png_memcpy(text
+ text_size
, png_ptr
->zbuf
,
237 (png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
));
238 text_size
+= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
239 *(text
+ text_size
) = 0x00;
241 if (ret
== Z_STREAM_END
)
245 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
246 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
250 if (ret
!= Z_STREAM_END
)
252 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
255 if (ret
== Z_BUF_ERROR
)
256 sprintf(umsg
,"Buffer error in compressed datastream in %s chunk",
257 png_ptr
->chunk_name
);
258 else if (ret
== Z_DATA_ERROR
)
259 sprintf(umsg
,"Data error in compressed datastream in %s chunk",
260 png_ptr
->chunk_name
);
262 sprintf(umsg
,"Incomplete compressed datastream in %s chunk",
263 png_ptr
->chunk_name
);
264 png_warning(png_ptr
, umsg
);
267 "Incomplete compressed datastream in chunk other than IDAT");
269 text_size
=prefix_size
;
272 text
= (png_charp
)png_malloc(png_ptr
, text_size
+1);
273 png_memcpy(text
, chunkdata
, prefix_size
);
275 *(text
+ text_size
) = 0x00;
278 inflateReset(&png_ptr
->zstream
);
279 png_ptr
->zstream
.avail_in
= 0;
281 png_free(png_ptr
, chunkdata
);
283 *newlength
=text_size
;
285 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
287 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
290 sprintf(umsg
, "Unknown zTXt compression type %d", comp_type
);
291 png_warning(png_ptr
, umsg
);
293 png_warning(png_ptr
, "Unknown zTXt compression type");
296 *(chunkdata
+ prefix_size
) = 0x00;
297 *newlength
=prefix_size
;
304 /* read and check the IDHR chunk */
306 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
309 png_uint_32 width
, height
;
310 int bit_depth
, color_type
, compression_type
, filter_type
;
313 png_debug(1, "in png_handle_IHDR\n");
315 if (png_ptr
->mode
& PNG_HAVE_IHDR
)
316 png_error(png_ptr
, "Out of place IHDR");
318 /* check the length */
320 png_error(png_ptr
, "Invalid IHDR chunk");
322 png_ptr
->mode
|= PNG_HAVE_IHDR
;
324 png_crc_read(png_ptr
, buf
, 13);
325 png_crc_finish(png_ptr
, 0);
327 width
= png_get_uint_32(buf
);
328 height
= png_get_uint_32(buf
+ 4);
331 compression_type
= buf
[10];
332 filter_type
= buf
[11];
333 interlace_type
= buf
[12];
336 /* set internal variables */
337 png_ptr
->width
= width
;
338 png_ptr
->height
= height
;
339 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
340 png_ptr
->interlaced
= (png_byte
)interlace_type
;
341 png_ptr
->color_type
= (png_byte
)color_type
;
342 png_ptr
->filter_type
= (png_byte
)filter_type
;
344 /* find number of channels */
345 switch (png_ptr
->color_type
)
347 case PNG_COLOR_TYPE_GRAY
:
348 case PNG_COLOR_TYPE_PALETTE
:
349 png_ptr
->channels
= 1;
351 case PNG_COLOR_TYPE_RGB
:
352 png_ptr
->channels
= 3;
354 case PNG_COLOR_TYPE_GRAY_ALPHA
:
355 png_ptr
->channels
= 2;
357 case PNG_COLOR_TYPE_RGB_ALPHA
:
358 png_ptr
->channels
= 4;
362 /* set up other useful info */
363 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
365 png_ptr
->rowbytes
= ((png_ptr
->width
*
366 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3);
367 png_debug1(3,"bit_depth = %d\n", png_ptr
->bit_depth
);
368 png_debug1(3,"channels = %d\n", png_ptr
->channels
);
369 png_debug1(3,"rowbytes = %lu\n", png_ptr
->rowbytes
);
370 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
371 color_type
, interlace_type
, compression_type
, filter_type
);
374 /* read and check the palette */
376 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
378 png_color palette
[PNG_MAX_PALETTE_LENGTH
];
380 #ifndef PNG_NO_POINTER_INDEXING
384 png_debug(1, "in png_handle_PLTE\n");
386 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
387 png_error(png_ptr
, "Missing IHDR before PLTE");
388 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
390 png_warning(png_ptr
, "Invalid PLTE after IDAT");
391 png_crc_finish(png_ptr
, length
);
394 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
395 png_error(png_ptr
, "Duplicate PLTE chunk");
397 png_ptr
->mode
|= PNG_HAVE_PLTE
;
399 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
400 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
402 png_crc_finish(png_ptr
, length
);
407 if (length
> 3*PNG_MAX_PALETTE_LENGTH
|| length
% 3)
409 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
411 png_warning(png_ptr
, "Invalid palette chunk");
412 png_crc_finish(png_ptr
, length
);
417 png_error(png_ptr
, "Invalid palette chunk");
421 num
= (int)length
/ 3;
423 #ifndef PNG_NO_POINTER_INDEXING
424 for (i
= 0, pal_ptr
= palette
; i
< num
; i
++, pal_ptr
++)
428 png_crc_read(png_ptr
, buf
, 3);
429 pal_ptr
->red
= buf
[0];
430 pal_ptr
->green
= buf
[1];
431 pal_ptr
->blue
= buf
[2];
434 for (i
= 0; i
< num
; i
++)
438 png_crc_read(png_ptr
, buf
, 3);
439 /* don't depend upon png_color being any order */
440 palette
[i
].red
= buf
[0];
441 palette
[i
].green
= buf
[1];
442 palette
[i
].blue
= buf
[2];
446 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
447 whatever the normal CRC configuration tells us. However, if we
448 have an RGB image, the PLTE can be considered ancillary, so
449 we will act as though it is. */
450 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
451 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
454 png_crc_finish(png_ptr
, 0);
456 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
457 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
459 /* If we don't want to use the data from an ancillary chunk,
460 we have two options: an error abort, or a warning and we
461 ignore the data in this chunk (which should be OK, since
462 it's considered ancillary for a RGB or RGBA image). */
463 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
465 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
467 png_chunk_error(png_ptr
, "CRC error");
471 png_chunk_warning(png_ptr
, "CRC error");
475 /* Otherwise, we (optionally) emit a warning and use the chunk. */
476 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
478 png_chunk_warning(png_ptr
, "CRC error");
483 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
485 #if defined(PNG_READ_tRNS_SUPPORTED)
486 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
488 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
490 if (png_ptr
->num_trans
> (png_uint_16
)num
)
492 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
493 png_ptr
->num_trans
= (png_uint_16
)num
;
495 if (info_ptr
->num_trans
> (png_uint_16
)num
)
497 png_warning(png_ptr
, "Truncating incorrect info tRNS chunk length");
498 info_ptr
->num_trans
= (png_uint_16
)num
;
507 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
509 png_debug(1, "in png_handle_IEND\n");
511 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
513 png_error(png_ptr
, "No image in file");
515 /* to quiet compiler warnings about unused info_ptr */
516 if (info_ptr
== NULL
)
520 png_ptr
->mode
|= (PNG_AFTER_IDAT
| PNG_HAVE_IEND
);
524 png_warning(png_ptr
, "Incorrect IEND chunk length");
526 png_crc_finish(png_ptr
, length
);
529 #if defined(PNG_READ_gAMA_SUPPORTED)
531 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
533 png_fixed_point igamma
;
534 #ifdef PNG_FLOATING_POINT_SUPPORTED
539 png_debug(1, "in png_handle_gAMA\n");
541 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
542 png_error(png_ptr
, "Missing IHDR before gAMA");
543 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
545 png_warning(png_ptr
, "Invalid gAMA after IDAT");
546 png_crc_finish(png_ptr
, length
);
549 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
550 /* Should be an error, but we can cope with it */
551 png_warning(png_ptr
, "Out of place gAMA chunk");
553 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
)
554 #if defined(PNG_READ_sRGB_SUPPORTED)
555 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
559 png_warning(png_ptr
, "Duplicate gAMA chunk");
560 png_crc_finish(png_ptr
, length
);
566 png_warning(png_ptr
, "Incorrect gAMA chunk length");
567 png_crc_finish(png_ptr
, length
);
571 png_crc_read(png_ptr
, buf
, 4);
572 if (png_crc_finish(png_ptr
, 0))
575 igamma
= (png_fixed_point
)png_get_uint_32(buf
);
576 /* check for zero gamma */
580 "Ignoring gAMA chunk with gamma=0");
584 #if defined(PNG_READ_sRGB_SUPPORTED)
585 if (info_ptr
->valid
& PNG_INFO_sRGB
)
586 if(igamma
< 45000L || igamma
> 46000L)
589 "Ignoring incorrect gAMA value when sRGB is also present");
590 #ifndef PNG_NO_CONSOLE_IO
591 fprintf(stderr
, "gamma = (%d/100000)\n", (int)igamma
);
595 #endif /* PNG_READ_sRGB_SUPPORTED */
597 #ifdef PNG_FLOATING_POINT_SUPPORTED
598 file_gamma
= (float)igamma
/ (float)100000.0;
599 # ifdef PNG_READ_GAMMA_SUPPORTED
600 png_ptr
->gamma
= file_gamma
;
602 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
604 #ifdef PNG_FIXED_POINT_SUPPORTED
605 png_set_gAMA_fixed(png_ptr
, info_ptr
, igamma
);
610 #if defined(PNG_READ_sBIT_SUPPORTED)
612 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
617 png_debug(1, "in png_handle_sBIT\n");
619 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
621 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
622 png_error(png_ptr
, "Missing IHDR before sBIT");
623 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
625 png_warning(png_ptr
, "Invalid sBIT after IDAT");
626 png_crc_finish(png_ptr
, length
);
629 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
631 /* Should be an error, but we can cope with it */
632 png_warning(png_ptr
, "Out of place sBIT chunk");
634 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sBIT
))
636 png_warning(png_ptr
, "Duplicate sBIT chunk");
637 png_crc_finish(png_ptr
, length
);
641 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
644 truelen
= (png_size_t
)png_ptr
->channels
;
646 if (length
!= truelen
)
648 png_warning(png_ptr
, "Incorrect sBIT chunk length");
649 png_crc_finish(png_ptr
, length
);
653 png_crc_read(png_ptr
, buf
, truelen
);
654 if (png_crc_finish(png_ptr
, 0))
657 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
659 png_ptr
->sig_bit
.red
= buf
[0];
660 png_ptr
->sig_bit
.green
= buf
[1];
661 png_ptr
->sig_bit
.blue
= buf
[2];
662 png_ptr
->sig_bit
.alpha
= buf
[3];
666 png_ptr
->sig_bit
.gray
= buf
[0];
667 png_ptr
->sig_bit
.red
= buf
[0];
668 png_ptr
->sig_bit
.green
= buf
[0];
669 png_ptr
->sig_bit
.blue
= buf
[0];
670 png_ptr
->sig_bit
.alpha
= buf
[1];
672 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
676 #if defined(PNG_READ_cHRM_SUPPORTED)
678 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
681 #ifdef PNG_FLOATING_POINT_SUPPORTED
682 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
684 png_fixed_point int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
685 int_y_green
, int_x_blue
, int_y_blue
;
687 png_debug(1, "in png_handle_cHRM\n");
689 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
690 png_error(png_ptr
, "Missing IHDR before cHRM");
691 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
693 png_warning(png_ptr
, "Invalid cHRM after IDAT");
694 png_crc_finish(png_ptr
, length
);
697 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
698 /* Should be an error, but we can cope with it */
699 png_warning(png_ptr
, "Missing PLTE before cHRM");
701 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
)
702 #if defined(PNG_READ_sRGB_SUPPORTED)
703 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
707 png_warning(png_ptr
, "Duplicate cHRM chunk");
708 png_crc_finish(png_ptr
, length
);
714 png_warning(png_ptr
, "Incorrect cHRM chunk length");
715 png_crc_finish(png_ptr
, length
);
719 png_crc_read(png_ptr
, buf
, 4);
720 int_x_white
= (png_fixed_point
)png_get_uint_32(buf
);
722 png_crc_read(png_ptr
, buf
, 4);
723 int_y_white
= (png_fixed_point
)png_get_uint_32(buf
);
725 if (int_x_white
> 80000L || int_y_white
> 80000L ||
726 int_x_white
+ int_y_white
> 100000L)
728 png_warning(png_ptr
, "Invalid cHRM white point");
729 png_crc_finish(png_ptr
, 24);
733 png_crc_read(png_ptr
, buf
, 4);
734 int_x_red
= (png_fixed_point
)png_get_uint_32(buf
);
736 png_crc_read(png_ptr
, buf
, 4);
737 int_y_red
= (png_fixed_point
)png_get_uint_32(buf
);
739 if (int_x_red
> 80000L || int_y_red
> 80000L ||
740 int_x_red
+ int_y_red
> 100000L)
742 png_warning(png_ptr
, "Invalid cHRM red point");
743 png_crc_finish(png_ptr
, 16);
747 png_crc_read(png_ptr
, buf
, 4);
748 int_x_green
= (png_fixed_point
)png_get_uint_32(buf
);
750 png_crc_read(png_ptr
, buf
, 4);
751 int_y_green
= (png_fixed_point
)png_get_uint_32(buf
);
753 if (int_x_green
> 80000L || int_y_green
> 80000L ||
754 int_x_green
+ int_y_green
> 100000L)
756 png_warning(png_ptr
, "Invalid cHRM green point");
757 png_crc_finish(png_ptr
, 8);
761 png_crc_read(png_ptr
, buf
, 4);
762 int_x_blue
= (png_fixed_point
)png_get_uint_32(buf
);
764 png_crc_read(png_ptr
, buf
, 4);
765 int_y_blue
= (png_fixed_point
)png_get_uint_32(buf
);
767 if (int_x_blue
> 80000L || int_y_blue
> 80000L ||
768 int_x_blue
+ int_y_blue
> 100000L)
770 png_warning(png_ptr
, "Invalid cHRM blue point");
771 png_crc_finish(png_ptr
, 0);
774 #ifdef PNG_FLOATING_POINT_SUPPORTED
775 white_x
= (float)int_x_white
/ (float)100000.0;
776 white_y
= (float)int_y_white
/ (float)100000.0;
777 red_x
= (float)int_x_red
/ (float)100000.0;
778 red_y
= (float)int_y_red
/ (float)100000.0;
779 green_x
= (float)int_x_green
/ (float)100000.0;
780 green_y
= (float)int_y_green
/ (float)100000.0;
781 blue_x
= (float)int_x_blue
/ (float)100000.0;
782 blue_y
= (float)int_y_blue
/ (float)100000.0;
785 #if defined(PNG_READ_sRGB_SUPPORTED)
786 if (info_ptr
->valid
& PNG_INFO_sRGB
)
788 if (abs(int_x_white
- 31270L) > 1000 ||
789 abs(int_y_white
- 32900L) > 1000 ||
790 abs( int_x_red
- 64000L) > 1000 ||
791 abs( int_y_red
- 33000L) > 1000 ||
792 abs(int_x_green
- 30000L) > 1000 ||
793 abs(int_y_green
- 60000L) > 1000 ||
794 abs( int_x_blue
- 15000L) > 1000 ||
795 abs( int_y_blue
- 6000L) > 1000)
799 "Ignoring incorrect cHRM value when sRGB is also present");
800 #ifndef PNG_NO_CONSOLE_IO
801 #ifdef PNG_FLOATING_POINT_SUPPORTED
802 fprintf(stderr
,"wx=%f, wy=%f, rx=%f, ry=%f\n",
803 white_x
, white_y
, red_x
, red_y
);
804 fprintf(stderr
,"gx=%f, gy=%f, bx=%f, by=%f\n",
805 green_x
, green_y
, blue_x
, blue_y
);
807 fprintf(stderr
,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
808 int_x_white
, int_y_white
, int_x_red
, int_y_red
);
809 fprintf(stderr
,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
810 int_x_green
, int_y_green
, int_x_blue
, int_y_blue
);
812 #endif /* PNG_NO_CONSOLE_IO */
814 png_crc_finish(png_ptr
, 0);
817 #endif /* PNG_READ_sRGB_SUPPORTED */
819 #ifdef PNG_FLOATING_POINT_SUPPORTED
820 png_set_cHRM(png_ptr
, info_ptr
,
821 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
823 #ifdef PNG_FIXED_POINT_SUPPORTED
824 png_set_cHRM_fixed(png_ptr
, info_ptr
,
825 int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
826 int_y_green
, int_x_blue
, int_y_blue
);
828 if (png_crc_finish(png_ptr
, 0))
833 #if defined(PNG_READ_sRGB_SUPPORTED)
835 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
840 png_debug(1, "in png_handle_sRGB\n");
842 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
843 png_error(png_ptr
, "Missing IHDR before sRGB");
844 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
846 png_warning(png_ptr
, "Invalid sRGB after IDAT");
847 png_crc_finish(png_ptr
, length
);
850 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
851 /* Should be an error, but we can cope with it */
852 png_warning(png_ptr
, "Out of place sRGB chunk");
854 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
856 png_warning(png_ptr
, "Duplicate sRGB chunk");
857 png_crc_finish(png_ptr
, length
);
863 png_warning(png_ptr
, "Incorrect sRGB chunk length");
864 png_crc_finish(png_ptr
, length
);
868 png_crc_read(png_ptr
, buf
, 1);
869 if (png_crc_finish(png_ptr
, 0))
873 /* check for bad intent */
874 if (intent
>= PNG_sRGB_INTENT_LAST
)
876 png_warning(png_ptr
, "Unknown sRGB intent");
880 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
881 if ((info_ptr
->valid
& PNG_INFO_gAMA
))
884 #ifdef PNG_FIXED_POINT_SUPPORTED
885 igamma
=(int)info_ptr
->int_gamma
;
887 # ifdef PNG_FLOATING_POINT_SUPPORTED
888 igamma
=(int)(info_ptr
->gamma
* 100000.);
891 #if 0 && defined(PNG_cHRM_SUPPORTED) && !defined(PNG_FIXED_POINT_SUPPORTED)
892 /* We need to define these here because they aren't in png.h */
893 png_fixed_point int_x_white
;
894 png_fixed_point int_y_white
;
895 png_fixed_point int_x_red
;
896 png_fixed_point int_y_red
;
897 png_fixed_point int_x_green
;
898 png_fixed_point int_y_green
;
899 png_fixed_point int_x_blue
;
900 png_fixed_point int_y_blue
;
902 if(igamma
< 45000L || igamma
> 46000L)
905 "Ignoring incorrect gAMA value when sRGB is also present");
906 #ifndef PNG_NO_CONSOLE_IO
907 # ifdef PNG_FIXED_POINT_SUPPORTED
908 fprintf(stderr
,"incorrect gamma=(%d/100000)\n",(int)png_ptr
->int_gamma
);
910 # ifdef PNG_FLOATING_POINT_SUPPORTED
911 fprintf(stderr
,"incorrect gamma=%f\n",png_ptr
->gamma
);
917 #endif /* PNG_READ_gAMA_SUPPORTED */
919 #ifdef PNG_READ_cHRM_SUPPORTED
920 #ifdef PNG_FIXED_POINT_SUPPORTED
921 if (info_ptr
->valid
& PNG_INFO_cHRM
)
922 if (abs(info_ptr
->int_x_white
- 31270L) > 1000 ||
923 abs(info_ptr
->int_y_white
- 32900L) > 1000 ||
924 abs( info_ptr
->int_x_red
- 64000L) > 1000 ||
925 abs( info_ptr
->int_y_red
- 33000L) > 1000 ||
926 abs(info_ptr
->int_x_green
- 30000L) > 1000 ||
927 abs(info_ptr
->int_y_green
- 60000L) > 1000 ||
928 abs( info_ptr
->int_x_blue
- 15000L) > 1000 ||
929 abs( info_ptr
->int_y_blue
- 6000L) > 1000)
932 "Ignoring incorrect cHRM value when sRGB is also present");
934 #endif /* PNG_FIXED_POINT_SUPPORTED */
935 #endif /* PNG_READ_cHRM_SUPPORTED */
937 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
939 #endif /* PNG_READ_sRGB_SUPPORTED */
941 #if defined(PNG_READ_iCCP_SUPPORTED)
943 png_handle_iCCP(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
944 /* Note: this does not properly handle chunks that are > 64K under DOS */
947 png_byte compression_type
;
949 png_uint_32 skip
= 0;
950 png_uint_32 profile_size
= 0;
951 png_uint_32 profile_length
= 0;
952 png_size_t slength
, prefix_length
, data_length
;
954 png_debug(1, "in png_handle_iCCP\n");
956 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
957 png_error(png_ptr
, "Missing IHDR before iCCP");
958 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
960 png_warning(png_ptr
, "Invalid iCCP after IDAT");
961 png_crc_finish(png_ptr
, length
);
964 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
965 /* Should be an error, but we can cope with it */
966 png_warning(png_ptr
, "Out of place iCCP chunk");
968 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_iCCP
))
970 png_warning(png_ptr
, "Duplicate iCCP chunk");
971 png_crc_finish(png_ptr
, length
);
975 #ifdef PNG_MAX_MALLOC_64K
976 if (length
> (png_uint_32
)65535L)
978 png_warning(png_ptr
, "iCCP chunk too large to fit in memory");
979 skip
= length
- (png_uint_32
)65535L;
980 length
= (png_uint_32
)65535L;
984 chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
985 slength
= (png_size_t
)length
;
986 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
988 if (png_crc_finish(png_ptr
, skip
))
990 png_free(png_ptr
, chunkdata
);
994 chunkdata
[slength
] = 0x00;
996 for (profile
= chunkdata
; *profile
; profile
++)
997 /* empty loop to find end of name */ ;
1001 /* there should be at least one zero (the compression type byte)
1002 following the separator, and we should be on it */
1003 if ( profile
>= chunkdata
+ slength
)
1005 png_free(png_ptr
, chunkdata
);
1006 png_warning(png_ptr
, "Malformed iCCP chunk");
1010 /* compression_type should always be zero */
1011 compression_type
= *profile
++;
1012 if (compression_type
)
1014 png_warning(png_ptr
, "Ignoring nonzero compression type in iCCP chunk");
1015 compression_type
=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1019 prefix_length
= profile
- chunkdata
;
1020 chunkdata
= png_decompress_chunk(png_ptr
, compression_type
, chunkdata
,
1021 slength
, prefix_length
, &data_length
);
1023 profile_length
= data_length
- prefix_length
;
1025 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1026 profile_size
= ((*(chunkdata
+prefix_length
))<<24) |
1027 ((*(chunkdata
+prefix_length
+1))<<16) |
1028 ((*(chunkdata
+prefix_length
+2))<< 8) |
1029 ((*(chunkdata
+prefix_length
+3)) );
1031 if(profile_size
< profile_length
)
1032 profile_length
= profile_size
;
1034 if(profile_size
> profile_length
)
1036 png_warning(png_ptr
, "Ignoring truncated iCCP profile.\n");
1040 png_set_iCCP(png_ptr
, info_ptr
, chunkdata
, compression_type
,
1041 chunkdata
+ prefix_length
, profile_length
);
1042 png_free(png_ptr
, chunkdata
);
1044 #endif /* PNG_READ_iCCP_SUPPORTED */
1046 #if defined(PNG_READ_sPLT_SUPPORTED)
1048 png_handle_sPLT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1049 /* Note: this does not properly handle chunks that are > 64K under DOS */
1051 png_bytep chunkdata
;
1052 png_bytep entry_start
;
1053 png_sPLT_t new_palette
;
1054 #ifdef PNG_NO_POINTER_INDEXING
1057 int data_length
, entry_size
, i
;
1058 png_uint_32 skip
= 0;
1061 png_debug(1, "in png_handle_sPLT\n");
1063 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1064 png_error(png_ptr
, "Missing IHDR before sPLT");
1065 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1067 png_warning(png_ptr
, "Invalid sPLT after IDAT");
1068 png_crc_finish(png_ptr
, length
);
1072 #ifdef PNG_MAX_MALLOC_64K
1073 if (length
> (png_uint_32
)65535L)
1075 png_warning(png_ptr
, "sPLT chunk too large to fit in memory");
1076 skip
= length
- (png_uint_32
)65535L;
1077 length
= (png_uint_32
)65535L;
1081 chunkdata
= (png_bytep
)png_malloc(png_ptr
, length
+ 1);
1082 slength
= (png_size_t
)length
;
1083 png_crc_read(png_ptr
, chunkdata
, slength
);
1085 if (png_crc_finish(png_ptr
, skip
))
1087 png_free(png_ptr
, chunkdata
);
1091 chunkdata
[slength
] = 0x00;
1093 for (entry_start
= chunkdata
; *entry_start
; entry_start
++)
1094 /* empty loop to find end of name */ ;
1097 /* a sample depth should follow the separator, and we should be on it */
1098 if (entry_start
> chunkdata
+ slength
)
1100 png_free(png_ptr
, chunkdata
);
1101 png_warning(png_ptr
, "malformed sPLT chunk");
1105 new_palette
.depth
= *entry_start
++;
1106 entry_size
= (new_palette
.depth
== 8 ? 6 : 10);
1107 data_length
= (slength
- (entry_start
- chunkdata
));
1109 /* integrity-check the data length */
1110 if (data_length
% entry_size
)
1112 png_free(png_ptr
, chunkdata
);
1113 png_error(png_ptr
, "sPLT chunk has bad length");
1116 new_palette
.nentries
= data_length
/ entry_size
;
1117 new_palette
.entries
= (png_sPLT_entryp
)png_malloc(
1118 png_ptr
, new_palette
.nentries
* sizeof(png_sPLT_entry
));
1120 #ifndef PNG_NO_POINTER_INDEXING
1121 for (i
= 0; i
< new_palette
.nentries
; i
++)
1123 png_sPLT_entryp pp
= new_palette
.entries
+ i
;
1125 if (new_palette
.depth
== 8)
1127 pp
->red
= *entry_start
++;
1128 pp
->green
= *entry_start
++;
1129 pp
->blue
= *entry_start
++;
1130 pp
->alpha
= *entry_start
++;
1134 pp
->red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1135 pp
->green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1136 pp
->blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1137 pp
->alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1139 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1142 pp
= new_palette
.entries
;
1143 for (i
= 0; i
< new_palette
.nentries
; i
++)
1146 if (new_palette
.depth
== 8)
1148 pp
[i
].red
= *entry_start
++;
1149 pp
[i
].green
= *entry_start
++;
1150 pp
[i
].blue
= *entry_start
++;
1151 pp
[i
].alpha
= *entry_start
++;
1155 pp
[i
].red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1156 pp
[i
].green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1157 pp
[i
].blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1158 pp
[i
].alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1160 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1164 /* discard all chunk data except the name and stash that */
1165 new_palette
.name
= (png_charp
)chunkdata
;
1167 png_set_sPLT(png_ptr
, info_ptr
, &new_palette
, 1);
1169 png_free(png_ptr
, chunkdata
);
1170 png_free(png_ptr
, new_palette
.entries
);
1172 #endif /* PNG_READ_sPLT_SUPPORTED */
1174 #if defined(PNG_READ_tRNS_SUPPORTED)
1176 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1178 png_byte readbuf
[PNG_MAX_PALETTE_LENGTH
];
1180 png_debug(1, "in png_handle_tRNS\n");
1182 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1183 png_error(png_ptr
, "Missing IHDR before tRNS");
1184 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1186 png_warning(png_ptr
, "Invalid tRNS after IDAT");
1187 png_crc_finish(png_ptr
, length
);
1190 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
1192 png_warning(png_ptr
, "Duplicate tRNS chunk");
1193 png_crc_finish(png_ptr
, length
);
1197 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1199 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1201 /* Should be an error, but we can cope with it */
1202 png_warning(png_ptr
, "Missing PLTE before tRNS");
1204 else if (length
> (png_uint_32
)png_ptr
->num_palette
)
1206 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1207 png_crc_finish(png_ptr
, length
);
1212 png_warning(png_ptr
, "Zero length tRNS chunk");
1213 png_crc_finish(png_ptr
, length
);
1217 png_crc_read(png_ptr
, readbuf
, (png_size_t
)length
);
1218 png_ptr
->num_trans
= (png_uint_16
)length
;
1220 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
1226 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1227 png_crc_finish(png_ptr
, length
);
1231 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
1232 png_ptr
->num_trans
= 1;
1233 png_ptr
->trans_values
.red
= png_get_uint_16(buf
);
1234 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2);
1235 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4);
1237 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
1243 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1244 png_crc_finish(png_ptr
, length
);
1248 png_crc_read(png_ptr
, buf
, 2);
1249 png_ptr
->num_trans
= 1;
1250 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
);
1254 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
1255 png_crc_finish(png_ptr
, length
);
1259 if (png_crc_finish(png_ptr
, 0))
1262 png_set_tRNS(png_ptr
, info_ptr
, readbuf
, png_ptr
->num_trans
,
1263 &(png_ptr
->trans_values
));
1267 #if defined(PNG_READ_bKGD_SUPPORTED)
1269 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1274 png_debug(1, "in png_handle_bKGD\n");
1276 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1277 png_error(png_ptr
, "Missing IHDR before bKGD");
1278 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1280 png_warning(png_ptr
, "Invalid bKGD after IDAT");
1281 png_crc_finish(png_ptr
, length
);
1284 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
1285 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
1287 png_warning(png_ptr
, "Missing PLTE before bKGD");
1288 png_crc_finish(png_ptr
, length
);
1291 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_bKGD
))
1293 png_warning(png_ptr
, "Duplicate bKGD chunk");
1294 png_crc_finish(png_ptr
, length
);
1298 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1300 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1305 if (length
!= truelen
)
1307 png_warning(png_ptr
, "Incorrect bKGD chunk length");
1308 png_crc_finish(png_ptr
, length
);
1312 png_crc_read(png_ptr
, buf
, truelen
);
1313 if (png_crc_finish(png_ptr
, 0))
1316 /* We convert the index value into RGB components so that we can allow
1317 * arbitrary RGB values for background when we have transparency, and
1318 * so it is easy to determine the RGB values of the background color
1319 * from the info_ptr struct. */
1320 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1322 png_ptr
->background
.index
= buf
[0];
1323 if(info_ptr
->num_palette
)
1325 if(buf
[0] > info_ptr
->num_palette
)
1327 png_warning(png_ptr
, "Incorrect bKGD chunk index value");
1330 png_ptr
->background
.red
=
1331 (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
1332 png_ptr
->background
.green
=
1333 (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
1334 png_ptr
->background
.blue
=
1335 (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
1338 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
1340 png_ptr
->background
.red
=
1341 png_ptr
->background
.green
=
1342 png_ptr
->background
.blue
=
1343 png_ptr
->background
.gray
= png_get_uint_16(buf
);
1347 png_ptr
->background
.red
= png_get_uint_16(buf
);
1348 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
1349 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
1352 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
1356 #if defined(PNG_READ_hIST_SUPPORTED)
1358 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1361 png_uint_16 readbuf
[PNG_MAX_PALETTE_LENGTH
];
1363 png_debug(1, "in png_handle_hIST\n");
1365 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1366 png_error(png_ptr
, "Missing IHDR before hIST");
1367 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1369 png_warning(png_ptr
, "Invalid hIST after IDAT");
1370 png_crc_finish(png_ptr
, length
);
1373 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1375 png_warning(png_ptr
, "Missing PLTE before hIST");
1376 png_crc_finish(png_ptr
, length
);
1379 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_hIST
))
1381 png_warning(png_ptr
, "Duplicate hIST chunk");
1382 png_crc_finish(png_ptr
, length
);
1386 num
= (int)length
/ 2 ;
1387 if (num
!= png_ptr
->num_palette
)
1389 png_warning(png_ptr
, "Incorrect hIST chunk length");
1390 png_crc_finish(png_ptr
, length
);
1394 for (i
= 0; i
< num
; i
++)
1398 png_crc_read(png_ptr
, buf
, 2);
1399 readbuf
[i
] = png_get_uint_16(buf
);
1402 if (png_crc_finish(png_ptr
, 0))
1405 png_set_hIST(png_ptr
, info_ptr
, readbuf
);
1409 #if defined(PNG_READ_pHYs_SUPPORTED)
1411 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1414 png_uint_32 res_x
, res_y
;
1417 png_debug(1, "in png_handle_pHYs\n");
1419 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1420 png_error(png_ptr
, "Missing IHDR before pHYs");
1421 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1423 png_warning(png_ptr
, "Invalid pHYs after IDAT");
1424 png_crc_finish(png_ptr
, length
);
1427 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pHYs
))
1429 png_warning(png_ptr
, "Duplicate pHYs chunk");
1430 png_crc_finish(png_ptr
, length
);
1436 png_warning(png_ptr
, "Incorrect pHYs chunk length");
1437 png_crc_finish(png_ptr
, length
);
1441 png_crc_read(png_ptr
, buf
, 9);
1442 if (png_crc_finish(png_ptr
, 0))
1445 res_x
= png_get_uint_32(buf
);
1446 res_y
= png_get_uint_32(buf
+ 4);
1448 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
1452 #if defined(PNG_READ_oFFs_SUPPORTED)
1454 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1457 png_int_32 offset_x
, offset_y
;
1460 png_debug(1, "in png_handle_oFFs\n");
1462 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1463 png_error(png_ptr
, "Missing IHDR before oFFs");
1464 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1466 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1467 png_crc_finish(png_ptr
, length
);
1470 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_oFFs
))
1472 png_warning(png_ptr
, "Duplicate oFFs chunk");
1473 png_crc_finish(png_ptr
, length
);
1479 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1480 png_crc_finish(png_ptr
, length
);
1484 png_crc_read(png_ptr
, buf
, 9);
1485 if (png_crc_finish(png_ptr
, 0))
1488 offset_x
= png_get_int_32(buf
);
1489 offset_y
= png_get_int_32(buf
+ 4);
1491 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1495 #if defined(PNG_READ_pCAL_SUPPORTED)
1496 /* read the pCAL chunk (described in the PNG Extensions document) */
1498 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1502 png_byte type
, nparams
;
1503 png_charp buf
, units
, endptr
;
1508 png_debug(1, "in png_handle_pCAL\n");
1510 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1511 png_error(png_ptr
, "Missing IHDR before pCAL");
1512 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1514 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1515 png_crc_finish(png_ptr
, length
);
1518 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pCAL
))
1520 png_warning(png_ptr
, "Duplicate pCAL chunk");
1521 png_crc_finish(png_ptr
, length
);
1525 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1527 purpose
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1528 slength
= (png_size_t
)length
;
1529 png_crc_read(png_ptr
, (png_bytep
)purpose
, slength
);
1531 if (png_crc_finish(png_ptr
, 0))
1533 png_free(png_ptr
, purpose
);
1537 purpose
[slength
] = 0x00; /* null terminate the last string */
1539 png_debug(3, "Finding end of pCAL purpose string\n");
1540 for (buf
= purpose
; *buf
; buf
++)
1543 endptr
= purpose
+ slength
;
1545 /* We need to have at least 12 bytes after the purpose string
1546 in order to get the parameter information. */
1547 if (endptr
<= buf
+ 12)
1549 png_warning(png_ptr
, "Invalid pCAL data");
1550 png_free(png_ptr
, purpose
);
1554 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1555 X0
= png_get_int_32((png_bytep
)buf
+1);
1556 X1
= png_get_int_32((png_bytep
)buf
+5);
1561 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1562 /* Check that we have the right number of parameters for known
1564 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1565 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1566 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1567 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1569 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1570 png_free(png_ptr
, purpose
);
1573 else if (type
>= PNG_EQUATION_LAST
)
1575 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1578 for (buf
= units
; *buf
; buf
++)
1579 /* Empty loop to move past the units string. */ ;
1581 png_debug(3, "Allocating pCAL parameters array\n");
1582 params
= (png_charpp
)png_malloc(png_ptr
, (png_uint_32
)(nparams
1583 *sizeof(png_charp
))) ;
1585 /* Get pointers to the start of each parameter string. */
1586 for (i
= 0; i
< (int)nparams
; i
++)
1588 buf
++; /* Skip the null string terminator from previous parameter. */
1590 png_debug1(3, "Reading pCAL parameter %d\n", i
);
1591 for (params
[i
] = buf
; *buf
!= 0x00 && buf
<= endptr
; buf
++)
1592 /* Empty loop to move past each parameter string */ ;
1594 /* Make sure we haven't run out of data yet */
1597 png_warning(png_ptr
, "Invalid pCAL data");
1598 png_free(png_ptr
, purpose
);
1599 png_free(png_ptr
, params
);
1604 png_set_pCAL(png_ptr
, info_ptr
, purpose
, X0
, X1
, type
, nparams
,
1607 png_free(png_ptr
, purpose
);
1608 png_free(png_ptr
, params
);
1612 #if defined(PNG_READ_sCAL_SUPPORTED)
1613 /* read the sCAL chunk */
1615 png_handle_sCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1617 png_charp buffer
, ep
;
1618 #ifdef PNG_FLOATING_POINT_SUPPORTED
1619 double width
, height
;
1622 #ifdef PNG_FIXED_POINT_SUPPORTED
1623 png_charp swidth
, sheight
;
1628 png_debug(1, "in png_handle_sCAL\n");
1630 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1631 png_error(png_ptr
, "Missing IHDR before sCAL");
1632 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1634 png_warning(png_ptr
, "Invalid sCAL after IDAT");
1635 png_crc_finish(png_ptr
, length
);
1638 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sCAL
))
1640 png_warning(png_ptr
, "Duplicate sCAL chunk");
1641 png_crc_finish(png_ptr
, length
);
1645 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1647 buffer
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1648 slength
= (png_size_t
)length
;
1649 png_crc_read(png_ptr
, (png_bytep
)buffer
, slength
);
1651 if (png_crc_finish(png_ptr
, 0))
1653 png_free(png_ptr
, buffer
);
1657 buffer
[slength
] = 0x00; /* null terminate the last string */
1659 ep
= buffer
+ 1; /* skip unit byte */
1661 #ifdef PNG_FLOATING_POINT_SUPPORTED
1662 width
= strtod(ep
, &vp
);
1665 png_warning(png_ptr
, "malformed width string in sCAL chunk");
1669 #ifdef PNG_FIXED_POINT_SUPPORTED
1670 swidth
= (png_charp
)png_malloc(png_ptr
, png_strlen(ep
) + 1);
1671 png_memcpy(swidth
, ep
, (png_size_t
)png_strlen(ep
));
1675 for (ep
= buffer
; *ep
; ep
++)
1679 #ifdef PNG_FLOATING_POINT_SUPPORTED
1680 height
= strtod(ep
, &vp
);
1683 png_warning(png_ptr
, "malformed height string in sCAL chunk");
1687 #ifdef PNG_FIXED_POINT_SUPPORTED
1688 sheight
= (png_charp
)png_malloc(png_ptr
, png_strlen(ep
) + 1);
1689 png_memcpy(sheight
, ep
, (png_size_t
)png_strlen(ep
));
1693 if (buffer
+ slength
< ep
1694 #ifdef PNG_FLOATING_POINT_SUPPORTED
1695 || width
<= 0. || height
<= 0.
1699 png_warning(png_ptr
, "Invalid sCAL data");
1700 png_free(png_ptr
, buffer
);
1701 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1702 png_free(png_ptr
, swidth
);
1703 png_free(png_ptr
, sheight
);
1709 #ifdef PNG_FLOATING_POINT_SUPPORTED
1710 png_set_sCAL(png_ptr
, info_ptr
, buffer
[0], width
, height
);
1712 #ifdef PNG_FIXED_POINT_SUPPORTED
1713 png_set_sCAL_s(png_ptr
, info_ptr
, buffer
[0], swidth
, sheight
);
1717 png_free(png_ptr
, buffer
);
1718 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1719 png_free(png_ptr
, swidth
);
1720 png_free(png_ptr
, sheight
);
1725 #if defined(PNG_READ_tIME_SUPPORTED)
1727 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1732 png_debug(1, "in png_handle_tIME\n");
1734 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1735 png_error(png_ptr
, "Out of place tIME chunk");
1736 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tIME
))
1738 png_warning(png_ptr
, "Duplicate tIME chunk");
1739 png_crc_finish(png_ptr
, length
);
1743 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1744 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1748 png_warning(png_ptr
, "Incorrect tIME chunk length");
1749 png_crc_finish(png_ptr
, length
);
1753 png_crc_read(png_ptr
, buf
, 7);
1754 if (png_crc_finish(png_ptr
, 0))
1757 mod_time
.second
= buf
[6];
1758 mod_time
.minute
= buf
[5];
1759 mod_time
.hour
= buf
[4];
1760 mod_time
.day
= buf
[3];
1761 mod_time
.month
= buf
[2];
1762 mod_time
.year
= png_get_uint_16(buf
);
1764 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1768 #if defined(PNG_READ_tEXt_SUPPORTED)
1769 /* Note: this does not properly handle chunks that are > 64K under DOS */
1771 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1776 png_uint_32 skip
= 0;
1779 png_debug(1, "in png_handle_tEXt\n");
1781 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1782 png_error(png_ptr
, "Missing IHDR before tEXt");
1784 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1785 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1787 #ifdef PNG_MAX_MALLOC_64K
1788 if (length
> (png_uint_32
)65535L)
1790 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
1791 skip
= length
- (png_uint_32
)65535L;
1792 length
= (png_uint_32
)65535L;
1796 key
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1797 slength
= (png_size_t
)length
;
1798 png_crc_read(png_ptr
, (png_bytep
)key
, slength
);
1800 if (png_crc_finish(png_ptr
, skip
))
1802 png_free(png_ptr
, key
);
1806 key
[slength
] = 0x00;
1808 for (text
= key
; *text
; text
++)
1809 /* empty loop to find end of key */ ;
1811 if (text
!= key
+ slength
)
1814 text_ptr
= (png_textp
)png_malloc(png_ptr
, (png_uint_32
)sizeof(png_text
));
1815 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
1816 text_ptr
->key
= key
;
1817 #ifdef PNG_iTXt_SUPPORTED
1818 text_ptr
->lang
= NULL
;
1819 text_ptr
->lang_key
= NULL
;
1820 text_ptr
->itxt_length
= 0;
1822 text_ptr
->text
= text
;
1823 text_ptr
->text_length
= png_strlen(text
);
1825 png_set_text(png_ptr
, info_ptr
, text_ptr
, 1);
1827 png_free(png_ptr
, key
);
1828 png_free(png_ptr
, text_ptr
);
1832 #if defined(PNG_READ_zTXt_SUPPORTED)
1833 /* note: this does not correctly handle chunks that are > 64K under DOS */
1835 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1838 png_charp chunkdata
;
1841 png_size_t slength
, prefix_len
, data_len
;
1843 png_debug(1, "in png_handle_zTXt\n");
1844 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1845 png_error(png_ptr
, "Missing IHDR before zTXt");
1847 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1848 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1850 #ifdef PNG_MAX_MALLOC_64K
1851 /* We will no doubt have problems with chunks even half this size, but
1852 there is no hard and fast rule to tell us where to stop. */
1853 if (length
> (png_uint_32
)65535L)
1855 png_warning(png_ptr
,"zTXt chunk too large to fit in memory");
1856 png_crc_finish(png_ptr
, length
);
1861 chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1862 slength
= (png_size_t
)length
;
1863 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1864 if (png_crc_finish(png_ptr
, 0))
1866 png_free(png_ptr
, chunkdata
);
1870 chunkdata
[slength
] = 0x00;
1872 for (text
= chunkdata
; *text
; text
++)
1875 /* zTXt must have some text after the chunkdataword */
1876 if (text
== chunkdata
+ slength
)
1878 comp_type
= PNG_TEXT_COMPRESSION_NONE
;
1879 png_warning(png_ptr
, "Zero length zTXt chunk");
1883 comp_type
= *(++text
);
1884 if (comp_type
!= PNG_TEXT_COMPRESSION_zTXt
)
1886 png_warning(png_ptr
, "Unknown compression type in zTXt chunk");
1887 comp_type
= PNG_TEXT_COMPRESSION_zTXt
;
1889 text
++; /* skip the compression_method byte */
1891 prefix_len
= text
- chunkdata
;
1893 chunkdata
= (png_charp
)png_decompress_chunk(png_ptr
, comp_type
, chunkdata
,
1894 (png_size_t
)length
, prefix_len
, &data_len
);
1896 text_ptr
= (png_textp
)png_malloc(png_ptr
, (png_uint_32
)sizeof(png_text
));
1897 text_ptr
->compression
= comp_type
;
1898 text_ptr
->key
= chunkdata
;
1899 #ifdef PNG_iTXt_SUPPORTED
1900 text_ptr
->lang
= NULL
;
1901 text_ptr
->lang_key
= NULL
;
1902 text_ptr
->itxt_length
= 0;
1904 text_ptr
->text
= chunkdata
+ prefix_len
;
1905 text_ptr
->text_length
= data_len
;
1907 png_set_text(png_ptr
, info_ptr
, text_ptr
, 1);
1909 png_free(png_ptr
, text_ptr
);
1910 png_free(png_ptr
, chunkdata
);
1914 #if defined(PNG_READ_iTXt_SUPPORTED)
1915 /* note: this does not correctly handle chunks that are > 64K under DOS */
1917 png_handle_iTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1920 png_charp chunkdata
;
1921 png_charp key
, lang
, text
, lang_key
;
1924 png_size_t slength
, prefix_len
, data_len
;
1926 png_debug(1, "in png_handle_iTXt\n");
1928 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1929 png_error(png_ptr
, "Missing IHDR before iTXt");
1931 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1932 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1934 #ifdef PNG_MAX_MALLOC_64K
1935 /* We will no doubt have problems with chunks even half this size, but
1936 there is no hard and fast rule to tell us where to stop. */
1937 if (length
> (png_uint_32
)65535L)
1939 png_warning(png_ptr
,"iTXt chunk too large to fit in memory");
1940 png_crc_finish(png_ptr
, length
);
1945 chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1946 slength
= (png_size_t
)length
;
1947 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1948 if (png_crc_finish(png_ptr
, 0))
1950 png_free(png_ptr
, chunkdata
);
1954 chunkdata
[slength
] = 0x00;
1956 for (lang
= chunkdata
; *lang
; lang
++)
1958 lang
++; /* skip NUL separator */
1960 /* iTXt must have a language tag (possibly empty), two compression bytes,
1961 translated keyword (possibly empty), and possibly some text after the
1964 if (lang
>= chunkdata
+ slength
)
1966 comp_flag
= PNG_TEXT_COMPRESSION_NONE
;
1967 png_warning(png_ptr
, "Zero length iTXt chunk");
1971 comp_flag
= *lang
++;
1972 comp_type
= *lang
++;
1975 for (lang_key
= lang
; *lang_key
; lang_key
++)
1977 lang_key
++; /* skip NUL separator */
1979 for (text
= lang_key
; *text
; text
++)
1981 text
++; /* skip NUL separator */
1983 prefix_len
= text
- chunkdata
;
1987 chunkdata
= png_decompress_chunk(png_ptr
, comp_type
, chunkdata
,
1988 (size_t)length
, prefix_len
, &data_len
);
1990 data_len
=png_strlen(chunkdata
+ prefix_len
);
1991 text_ptr
= (png_textp
)png_malloc(png_ptr
, (png_uint_32
)sizeof(png_text
));
1992 text_ptr
->compression
= (int)comp_flag
+ 1;
1993 text_ptr
->lang_key
= chunkdata
+(lang_key
-key
);
1994 text_ptr
->lang
= chunkdata
+(lang
-key
);
1995 text_ptr
->itxt_length
= data_len
;
1996 text_ptr
->text_length
= 0;
1997 text_ptr
->key
= chunkdata
;
1998 text_ptr
->text
= chunkdata
+ prefix_len
;
2000 png_set_text(png_ptr
, info_ptr
, text_ptr
, 1);
2002 png_free(png_ptr
, text_ptr
);
2003 png_free(png_ptr
, chunkdata
);
2007 /* This function is called when we haven't found a handler for a
2008 chunk. If there isn't a problem with the chunk itself (ie bad
2009 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2010 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2011 case it will be saved away to be written out later. */
2013 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2015 png_uint_32 skip
= 0;
2017 png_debug(1, "in png_handle_unknown\n");
2019 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2021 #ifdef PNG_USE_LOCAL_ARRAYS
2024 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4)) /* not an IDAT */
2025 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2028 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
2030 if (!(png_ptr
->chunk_name
[0] & 0x20))
2032 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2033 if(png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2035 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2036 && png_ptr
->read_user_chunk_fn
== (png_user_chunk_ptr
)NULL
2040 png_chunk_error(png_ptr
, "unknown critical chunk");
2043 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2044 if (png_ptr
->flags
& PNG_FLAG_KEEP_UNKNOWN_CHUNKS
)
2046 png_unknown_chunk chunk
;
2048 #ifdef PNG_MAX_MALLOC_64K
2049 if (length
> (png_uint_32
)65535L)
2051 png_warning(png_ptr
, "unknown chunk too large to fit in memory");
2052 skip
= length
- (png_uint_32
)65535L;
2053 length
= (png_uint_32
)65535L;
2056 png_strcpy((png_charp
)chunk
.name
, (png_charp
)png_ptr
->chunk_name
);
2057 chunk
.data
= (png_bytep
)png_malloc(png_ptr
, length
);
2058 png_crc_read(png_ptr
, chunk
.data
, length
);
2059 chunk
.size
= length
;
2060 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2061 if(png_ptr
->read_user_chunk_fn
!= (png_user_chunk_ptr
)NULL
)
2063 /* callback to user unknown chunk handler */
2064 if ((*(png_ptr
->read_user_chunk_fn
)) (png_ptr
, &chunk
) <= 0)
2066 if (!(png_ptr
->chunk_name
[0] & 0x20))
2067 if(png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2068 HANDLE_CHUNK_ALWAYS
)
2069 png_chunk_error(png_ptr
, "unknown critical chunk");
2070 png_set_unknown_chunks(png_ptr
, info_ptr
, &chunk
, 1);
2075 png_set_unknown_chunks(png_ptr
, info_ptr
, &chunk
, 1);
2076 png_free(png_ptr
, chunk
.data
);
2082 png_crc_finish(png_ptr
, skip
);
2084 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2085 if (info_ptr
== NULL
)
2086 /* quiet compiler warnings about unused info_ptr */ ;
2090 /* This function is called to verify that a chunk name is valid.
2091 This function can't have the "critical chunk check" incorporated
2092 into it, since in the future we will need to be able to call user
2093 functions to handle unknown critical chunks after we check that
2094 the chunk name itself is valid. */
2096 #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
2099 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
2101 png_debug(1, "in png_check_chunk_name\n");
2102 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
2103 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
2105 png_chunk_error(png_ptr
, "invalid chunk type");
2109 /* Combines the row recently read in with the existing pixels in the
2110 row. This routine takes care of alpha and transparency if requested.
2111 This routine also handles the two methods of progressive display
2112 of interlaced images, depending on the mask value.
2113 The mask value describes which pixels are to be combined with
2114 the row. The pattern always repeats every 8 pixels, so just 8
2115 bits are needed. A one indicates the pixel is to be combined,
2116 a zero indicates the pixel is to be skipped. This is in addition
2117 to any alpha or transparency value associated with the pixel. If
2118 you want all pixels to be combined, pass 0xff (255) in mask. */
2119 #ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
2121 png_combine_row(png_structp png_ptr
, png_bytep row
, int mask
)
2123 png_debug(1,"in png_combine_row\n");
2126 png_memcpy(row
, png_ptr
->row_buf
+ 1,
2127 (png_size_t
)((png_ptr
->width
*
2128 png_ptr
->row_info
.pixel_depth
+ 7) >> 3));
2132 switch (png_ptr
->row_info
.pixel_depth
)
2136 png_bytep sp
= png_ptr
->row_buf
+ 1;
2138 int s_inc
, s_start
, s_end
;
2142 png_uint_32 row_width
= png_ptr
->width
;
2144 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2145 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2161 for (i
= 0; i
< row_width
; i
++)
2167 value
= (*sp
>> shift
) & 0x01;
2168 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2169 *dp
|= (png_byte
)(value
<< shift
);
2190 png_bytep sp
= png_ptr
->row_buf
+ 1;
2192 int s_start
, s_end
, s_inc
;
2196 png_uint_32 row_width
= png_ptr
->width
;
2199 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2200 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2216 for (i
= 0; i
< row_width
; i
++)
2220 value
= (*sp
>> shift
) & 0x03;
2221 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2222 *dp
|= (png_byte
)(value
<< shift
);
2242 png_bytep sp
= png_ptr
->row_buf
+ 1;
2244 int s_start
, s_end
, s_inc
;
2248 png_uint_32 row_width
= png_ptr
->width
;
2251 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2252 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2267 for (i
= 0; i
< row_width
; i
++)
2271 value
= (*sp
>> shift
) & 0xf;
2272 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2273 *dp
|= (png_byte
)(value
<< shift
);
2293 png_bytep sp
= png_ptr
->row_buf
+ 1;
2295 png_size_t pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
2297 png_uint_32 row_width
= png_ptr
->width
;
2301 for (i
= 0; i
< row_width
; i
++)
2305 png_memcpy(dp
, sp
, pixel_bytes
);
2321 #endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
2323 #ifdef PNG_READ_INTERLACING_SUPPORTED
2324 #ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
2325 /* OLD pre-1.0.9 interface:
2326 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2327 png_uint_32 transformations)
2330 png_do_read_interlace(png_structp png_ptr
)
2332 png_row_infop row_info
= &(png_ptr
->row_info
);
2333 png_bytep row
= png_ptr
->row_buf
+ 1;
2334 int pass
= png_ptr
->pass
;
2335 png_uint_32 transformations
= png_ptr
->transformations
;
2336 #ifdef PNG_USE_LOCAL_ARRAYS
2337 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2338 /* offset to next interlace block */
2339 const int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2342 png_debug(1,"in png_do_read_interlace (stock C version)\n");
2343 if (row
!= NULL
&& row_info
!= NULL
)
2345 png_uint_32 final_width
;
2347 final_width
= row_info
->width
* png_pass_inc
[pass
];
2349 switch (row_info
->pixel_depth
)
2353 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2354 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
2356 int s_start
, s_end
, s_inc
;
2357 int jstop
= png_pass_inc
[pass
];
2362 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2363 if (transformations
& PNG_PACKSWAP
)
2365 sshift
= (int)((row_info
->width
+ 7) & 0x07);
2366 dshift
= (int)((final_width
+ 7) & 0x07);
2374 sshift
= 7 - (int)((row_info
->width
+ 7) & 0x07);
2375 dshift
= 7 - (int)((final_width
+ 7) & 0x07);
2381 for (i
= 0; i
< row_info
->width
; i
++)
2383 v
= (png_byte
)((*sp
>> sshift
) & 0x01);
2384 for (j
= 0; j
< jstop
; j
++)
2386 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
2387 *dp
|= (png_byte
)(v
<< dshift
);
2388 if (dshift
== s_end
)
2396 if (sshift
== s_end
)
2408 png_bytep sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
2409 png_bytep dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
2411 int s_start
, s_end
, s_inc
;
2412 int jstop
= png_pass_inc
[pass
];
2415 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2416 if (transformations
& PNG_PACKSWAP
)
2418 sshift
= (int)(((row_info
->width
+ 3) & 0x03) << 1);
2419 dshift
= (int)(((final_width
+ 3) & 0x03) << 1);
2427 sshift
= (int)((3 - ((row_info
->width
+ 3) & 0x03)) << 1);
2428 dshift
= (int)((3 - ((final_width
+ 3) & 0x03)) << 1);
2434 for (i
= 0; i
< row_info
->width
; i
++)
2439 v
= (png_byte
)((*sp
>> sshift
) & 0x03);
2440 for (j
= 0; j
< jstop
; j
++)
2442 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
2443 *dp
|= (png_byte
)(v
<< dshift
);
2444 if (dshift
== s_end
)
2452 if (sshift
== s_end
)
2464 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2465 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
2467 int s_start
, s_end
, s_inc
;
2469 int jstop
= png_pass_inc
[pass
];
2471 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2472 if (transformations
& PNG_PACKSWAP
)
2474 sshift
= (int)(((row_info
->width
+ 1) & 0x01) << 2);
2475 dshift
= (int)(((final_width
+ 1) & 0x01) << 2);
2483 sshift
= (int)((1 - ((row_info
->width
+ 1) & 0x01)) << 2);
2484 dshift
= (int)((1 - ((final_width
+ 1) & 0x01)) << 2);
2490 for (i
= 0; i
< row_info
->width
; i
++)
2492 png_byte v
= (png_byte
)((*sp
>> sshift
) & 0xf);
2495 for (j
= 0; j
< jstop
; j
++)
2497 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
2498 *dp
|= (png_byte
)(v
<< dshift
);
2499 if (dshift
== s_end
)
2507 if (sshift
== s_end
)
2519 png_size_t pixel_bytes
= (row_info
->pixel_depth
>> 3);
2520 png_bytep sp
= row
+ (png_size_t
)(row_info
->width
- 1) * pixel_bytes
;
2521 png_bytep dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
2523 int jstop
= png_pass_inc
[pass
];
2526 for (i
= 0; i
< row_info
->width
; i
++)
2531 png_memcpy(v
, sp
, pixel_bytes
);
2532 for (j
= 0; j
< jstop
; j
++)
2534 png_memcpy(dp
, v
, pixel_bytes
);
2542 row_info
->width
= final_width
;
2543 row_info
->rowbytes
= ((final_width
*
2544 (png_uint_32
)row_info
->pixel_depth
+ 7) >> 3);
2546 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2547 /* silence compiler warning */
2548 if (transformations
)
2552 #endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
2553 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2555 #ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
2557 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
2558 png_bytep prev_row
, int filter
)
2560 png_debug(1, "in png_read_filter_row\n");
2561 png_debug2(2,"row = %lu, filter = %d\n", png_ptr
->row_number
, filter
);
2564 case PNG_FILTER_VALUE_NONE
:
2566 case PNG_FILTER_VALUE_SUB
:
2569 png_uint_32 istop
= row_info
->rowbytes
;
2570 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2571 png_bytep rp
= row
+ bpp
;
2574 for (i
= bpp
; i
< istop
; i
++)
2576 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
++)) & 0xff);
2581 case PNG_FILTER_VALUE_UP
:
2584 png_uint_32 istop
= row_info
->rowbytes
;
2586 png_bytep pp
= prev_row
;
2588 for (i
= 0; i
< istop
; i
++)
2590 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2595 case PNG_FILTER_VALUE_AVG
:
2599 png_bytep pp
= prev_row
;
2601 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2602 png_uint_32 istop
= row_info
->rowbytes
- bpp
;
2604 for (i
= 0; i
< bpp
; i
++)
2606 *rp
= (png_byte
)(((int)(*rp
) +
2607 ((int)(*pp
++) / 2 )) & 0xff);
2611 for (i
= 0; i
< istop
; i
++)
2613 *rp
= (png_byte
)(((int)(*rp
) +
2614 (int)(*pp
++ + *lp
++) / 2 ) & 0xff);
2619 case PNG_FILTER_VALUE_PAETH
:
2623 png_bytep pp
= prev_row
;
2625 png_bytep cp
= prev_row
;
2626 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2627 png_uint_32 istop
=row_info
->rowbytes
- bpp
;
2629 for (i
= 0; i
< bpp
; i
++)
2631 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2635 for (i
= 0; i
< istop
; i
++) /* use leftover rp,pp */
2637 int a
, b
, c
, pa
, pb
, pc
, p
;
2651 pa
= p
< 0 ? -p
: p
;
2652 pb
= pc
< 0 ? -pc
: pc
;
2653 pc
= (p
+ pc
) < 0 ? -(p
+ pc
) : p
+ pc
;
2657 if (pa <= pb && pa <= pc)
2665 p
= (pa
<= pb
&& pa
<=pc
) ? a
: (pb
<= pc
) ? b
: c
;
2667 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
2673 png_warning(png_ptr
, "Ignoring bad adaptive filter type");
2678 #endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
2681 png_read_finish_row(png_structp png_ptr
)
2683 #ifdef PNG_USE_LOCAL_ARRAYS
2684 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2686 /* start of interlace block */
2687 const int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2689 /* offset to next interlace block */
2690 const int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2692 /* start of interlace block in the y direction */
2693 const int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2695 /* offset to next interlace block in the y direction */
2696 const int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2699 png_debug(1, "in png_read_finish_row\n");
2700 png_ptr
->row_number
++;
2701 if (png_ptr
->row_number
< png_ptr
->num_rows
)
2704 if (png_ptr
->interlaced
)
2706 png_ptr
->row_number
= 0;
2707 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
2711 if (png_ptr
->pass
>= 7)
2713 png_ptr
->iwidth
= (png_ptr
->width
+
2714 png_pass_inc
[png_ptr
->pass
] - 1 -
2715 png_pass_start
[png_ptr
->pass
]) /
2716 png_pass_inc
[png_ptr
->pass
];
2717 png_ptr
->irowbytes
= ((png_ptr
->iwidth
*
2718 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3) +1;
2720 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2722 png_ptr
->num_rows
= (png_ptr
->height
+
2723 png_pass_yinc
[png_ptr
->pass
] - 1 -
2724 png_pass_ystart
[png_ptr
->pass
]) /
2725 png_pass_yinc
[png_ptr
->pass
];
2726 if (!(png_ptr
->num_rows
))
2729 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2731 } while (png_ptr
->iwidth
== 0);
2733 if (png_ptr
->pass
< 7)
2737 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
2739 #ifdef PNG_USE_LOCAL_ARRAYS
2745 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
2746 png_ptr
->zstream
.avail_out
= (uInt
)1;
2749 if (!(png_ptr
->zstream
.avail_in
))
2751 while (!png_ptr
->idat_size
)
2753 png_byte chunk_length
[4];
2755 png_crc_finish(png_ptr
, 0);
2757 png_read_data(png_ptr
, chunk_length
, 4);
2758 png_ptr
->idat_size
= png_get_uint_32(chunk_length
);
2760 png_reset_crc(png_ptr
);
2761 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
2762 if (png_memcmp(png_ptr
->chunk_name
, (png_bytep
)png_IDAT
, 4))
2763 png_error(png_ptr
, "Not enough image data");
2766 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
2767 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
2768 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
2769 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
2770 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
2771 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
2773 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
2774 if (ret
== Z_STREAM_END
)
2776 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
2778 png_error(png_ptr
, "Extra compressed data");
2779 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2780 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2784 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
2785 "Decompression Error");
2787 if (!(png_ptr
->zstream
.avail_out
))
2788 png_error(png_ptr
, "Extra compressed data");
2791 png_ptr
->zstream
.avail_out
= 0;
2794 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
2795 png_error(png_ptr
, "Extra compression data");
2797 inflateReset(&png_ptr
->zstream
);
2799 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2803 png_read_start_row(png_structp png_ptr
)
2805 #ifdef PNG_USE_LOCAL_ARRAYS
2806 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2808 /* start of interlace block */
2809 const int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2811 /* offset to next interlace block */
2812 const int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2814 /* start of interlace block in the y direction */
2815 const int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2817 /* offset to next interlace block in the y direction */
2818 const int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2821 int max_pixel_depth
;
2822 png_uint_32 row_bytes
;
2824 png_debug(1, "in png_read_start_row\n");
2825 png_ptr
->zstream
.avail_in
= 0;
2826 png_init_read_transformations(png_ptr
);
2827 if (png_ptr
->interlaced
)
2829 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2830 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
2831 png_pass_ystart
[0]) / png_pass_yinc
[0];
2833 png_ptr
->num_rows
= png_ptr
->height
;
2835 png_ptr
->iwidth
= (png_ptr
->width
+
2836 png_pass_inc
[png_ptr
->pass
] - 1 -
2837 png_pass_start
[png_ptr
->pass
]) /
2838 png_pass_inc
[png_ptr
->pass
];
2840 row_bytes
= ((png_ptr
->iwidth
*
2841 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3) +1;
2842 png_ptr
->irowbytes
= (png_size_t
)row_bytes
;
2843 if((png_uint_32
)png_ptr
->irowbytes
!= row_bytes
)
2844 png_error(png_ptr
, "Rowbytes overflow in png_read_start_row");
2848 png_ptr
->num_rows
= png_ptr
->height
;
2849 png_ptr
->iwidth
= png_ptr
->width
;
2850 png_ptr
->irowbytes
= png_ptr
->rowbytes
+ 1;
2852 max_pixel_depth
= png_ptr
->pixel_depth
;
2854 #if defined(PNG_READ_PACK_SUPPORTED)
2855 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
2856 max_pixel_depth
= 8;
2859 #if defined(PNG_READ_EXPAND_SUPPORTED)
2860 if (png_ptr
->transformations
& PNG_EXPAND
)
2862 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2864 if (png_ptr
->num_trans
)
2865 max_pixel_depth
= 32;
2867 max_pixel_depth
= 24;
2869 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
2871 if (max_pixel_depth
< 8)
2872 max_pixel_depth
= 8;
2873 if (png_ptr
->num_trans
)
2874 max_pixel_depth
*= 2;
2876 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
2878 if (png_ptr
->num_trans
)
2880 max_pixel_depth
*= 4;
2881 max_pixel_depth
/= 3;
2887 #if defined(PNG_READ_FILLER_SUPPORTED)
2888 if (png_ptr
->transformations
& (PNG_FILLER
))
2890 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2891 max_pixel_depth
= 32;
2892 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
2894 if (max_pixel_depth
<= 8)
2895 max_pixel_depth
= 16;
2897 max_pixel_depth
= 32;
2899 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
2901 if (max_pixel_depth
<= 32)
2902 max_pixel_depth
= 32;
2904 max_pixel_depth
= 64;
2909 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2910 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
2913 #if defined(PNG_READ_EXPAND_SUPPORTED)
2914 (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
2916 #if defined(PNG_READ_FILLER_SUPPORTED)
2917 (png_ptr
->transformations
& (PNG_FILLER
)) ||
2919 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2921 if (max_pixel_depth
<= 16)
2922 max_pixel_depth
= 32;
2924 max_pixel_depth
= 64;
2928 if (max_pixel_depth
<= 8)
2930 if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2931 max_pixel_depth
= 32;
2933 max_pixel_depth
= 24;
2935 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
2936 max_pixel_depth
= 64;
2938 max_pixel_depth
= 48;
2943 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
2944 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
2945 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
2947 int user_pixel_depth
=png_ptr
->user_transform_depth
*
2948 png_ptr
->user_transform_channels
;
2949 if(user_pixel_depth
> max_pixel_depth
)
2950 max_pixel_depth
=user_pixel_depth
;
2954 /* align the width on the next larger 8 pixels. Mainly used
2956 row_bytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
2957 /* calculate the maximum bytes needed, adding a byte and a pixel
2958 for safety's sake */
2959 row_bytes
= ((row_bytes
* (png_uint_32
)max_pixel_depth
+ 7) >> 3) +
2960 1 + ((max_pixel_depth
+ 7) >> 3);
2961 #ifdef PNG_MAX_MALLOC_64K
2962 if (row_bytes
> (png_uint_32
)65536L)
2963 png_error(png_ptr
, "This image requires a row greater than 64KB");
2965 png_ptr
->row_buf
= (png_bytep
)png_malloc(png_ptr
, row_bytes
);
2966 png_ptr
->row_buf_size
= row_bytes
;
2968 #ifdef PNG_MAX_MALLOC_64K
2969 if ((png_uint_32
)png_ptr
->rowbytes
+ 1 > (png_uint_32
)65536L)
2970 png_error(png_ptr
, "This image requires a row greater than 64KB");
2972 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
2973 png_ptr
->rowbytes
+ 1));
2975 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
2977 png_debug1(3, "width = %lu,\n", png_ptr
->width
);
2978 png_debug1(3, "height = %lu,\n", png_ptr
->height
);
2979 png_debug1(3, "iwidth = %lu,\n", png_ptr
->iwidth
);
2980 png_debug1(3, "num_rows = %lu\n", png_ptr
->num_rows
);
2981 png_debug1(3, "rowbytes = %lu,\n", png_ptr
->rowbytes
);
2982 png_debug1(3, "irowbytes = %lu,\n", png_ptr
->irowbytes
);
2984 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;