2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.34 [December 18, 2008]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2008 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.
16 #if defined(PNG_READ_SUPPORTED)
18 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
19 # define WIN32_WCE_OLD
22 #ifdef PNG_FLOATING_POINT_SUPPORTED
23 # if defined(WIN32_WCE_OLD)
24 /* strtod() function is not supported on WindowsCE */
25 __inline
double png_strtod(png_structp png_ptr
, PNG_CONST
char *nptr
, char **endptr
)
31 len
= MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, NULL
, 0);
32 str
= (wchar_t *)png_malloc(png_ptr
, len
* png_sizeof(wchar_t));
35 MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, str
, len
);
36 result
= wcstod(str
, &end
);
37 len
= WideCharToMultiByte(CP_ACP
, 0, end
, -1, NULL
, 0, NULL
, NULL
);
38 *endptr
= (char *)nptr
+ (png_strlen(nptr
) - len
+ 1);
39 png_free(png_ptr
, str
);
44 # define png_strtod(p,a,b) strtod(a,b)
49 png_get_uint_31(png_structp png_ptr
, png_bytep buf
)
51 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
52 png_uint_32 i
= png_get_uint_32(buf
);
54 /* Avoid an extra function call by inlining the result. */
55 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
56 ((png_uint_32
)(*(buf
+ 1)) << 16) +
57 ((png_uint_32
)(*(buf
+ 2)) << 8) +
58 (png_uint_32
)(*(buf
+ 3));
60 if (i
> PNG_UINT_31_MAX
)
61 png_error(png_ptr
, "PNG unsigned integer out of range.");
64 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
65 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
67 png_get_uint_32(png_bytep buf
)
69 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
70 ((png_uint_32
)(*(buf
+ 1)) << 16) +
71 ((png_uint_32
)(*(buf
+ 2)) << 8) +
72 (png_uint_32
)(*(buf
+ 3));
77 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
78 * data is stored in the PNG file in two's complement format, and it is
79 * assumed that the machine format for signed integers is the same. */
81 png_get_int_32(png_bytep buf
)
83 png_int_32 i
= ((png_int_32
)(*buf
) << 24) +
84 ((png_int_32
)(*(buf
+ 1)) << 16) +
85 ((png_int_32
)(*(buf
+ 2)) << 8) +
86 (png_int_32
)(*(buf
+ 3));
91 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
93 png_get_uint_16(png_bytep buf
)
95 png_uint_16 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
96 (png_uint_16
)(*(buf
+ 1)));
100 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
102 /* Read the chunk header (length + type name).
103 * Put the type name into png_ptr->chunk_name, and return the length.
105 png_uint_32
/* PRIVATE */
106 png_read_chunk_header(png_structp png_ptr
)
111 /* read the length and the chunk name */
112 png_read_data(png_ptr
, buf
, 8);
113 length
= png_get_uint_31(png_ptr
, buf
);
115 /* put the chunk name into png_ptr->chunk_name */
116 png_memcpy(png_ptr
->chunk_name
, buf
+ 4, 4);
118 png_debug2(0, "Reading %s chunk, length = %lu",
119 png_ptr
->chunk_name
, length
);
121 /* reset the crc and run it over the chunk name */
122 png_reset_crc(png_ptr
);
123 png_calculate_crc(png_ptr
, png_ptr
->chunk_name
, 4);
125 /* check to see if chunk name is valid */
126 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
131 /* Read data, and (optionally) run it through the CRC. */
133 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
135 if (png_ptr
== NULL
) return;
136 png_read_data(png_ptr
, buf
, length
);
137 png_calculate_crc(png_ptr
, buf
, length
);
140 /* Optionally skip data and then check the CRC. Depending on whether we
141 are reading a ancillary or critical chunk, and how the program has set
142 things up, we may calculate the CRC on the data and print a message.
143 Returns '1' if there was a CRC error, '0' otherwise. */
145 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
148 png_size_t istop
= png_ptr
->zbuf_size
;
150 for (i
= (png_size_t
)skip
; i
> istop
; i
-= istop
)
152 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
156 png_crc_read(png_ptr
, png_ptr
->zbuf
, i
);
159 if (png_crc_error(png_ptr
))
161 if (((png_ptr
->chunk_name
[0] & 0x20) && /* Ancillary */
162 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
163 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
164 (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
)))
166 png_chunk_warning(png_ptr
, "CRC error");
170 png_chunk_error(png_ptr
, "CRC error");
178 /* Compare the CRC stored in the PNG file with that calculated by libpng from
179 the data it has read thus far. */
181 png_crc_error(png_structp png_ptr
)
183 png_byte crc_bytes
[4];
187 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
189 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
190 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
195 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
199 png_read_data(png_ptr
, crc_bytes
, 4);
203 crc
= png_get_uint_32(crc_bytes
);
204 return ((int)(crc
!= png_ptr
->crc
));
210 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
211 defined(PNG_READ_iCCP_SUPPORTED)
213 * Decompress trailing data in a chunk. The assumption is that chunkdata
214 * points at an allocated area holding the contents of a chunk with a
215 * trailing compressed part. What we get back is an allocated area
216 * holding the original prefix part and an uncompressed version of the
217 * trailing part (the malloc area passed in is freed).
220 png_decompress_chunk(png_structp png_ptr
, int comp_type
,
221 png_size_t chunklength
,
222 png_size_t prefix_size
, png_size_t
*newlength
)
224 static PNG_CONST
char msg
[] = "Error decoding compressed text";
226 png_size_t text_size
;
228 if (comp_type
== PNG_COMPRESSION_TYPE_BASE
)
231 png_ptr
->zstream
.next_in
= (png_bytep
)(png_ptr
->chunkdata
+ prefix_size
);
232 png_ptr
->zstream
.avail_in
= (uInt
)(chunklength
- prefix_size
);
233 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
234 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
239 while (png_ptr
->zstream
.avail_in
)
241 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
242 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
)
244 if (png_ptr
->zstream
.msg
!= NULL
)
245 png_warning(png_ptr
, png_ptr
->zstream
.msg
);
247 png_warning(png_ptr
, msg
);
248 inflateReset(&png_ptr
->zstream
);
249 png_ptr
->zstream
.avail_in
= 0;
253 text_size
= prefix_size
+ png_sizeof(msg
) + 1;
254 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
);
257 png_free(png_ptr
, png_ptr
->chunkdata
);
258 png_ptr
->chunkdata
= NULL
;
259 png_error(png_ptr
, "Not enough memory to decompress chunk");
261 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
264 text
[text_size
- 1] = 0x00;
266 /* Copy what we can of the error message into the text chunk */
267 text_size
= (png_size_t
)(chunklength
-
268 (text
- png_ptr
->chunkdata
) - 1);
269 if (text_size
> png_sizeof(msg
))
270 text_size
= png_sizeof(msg
);
271 png_memcpy(text
+ prefix_size
, msg
, text_size
);
274 if (!png_ptr
->zstream
.avail_out
|| ret
== Z_STREAM_END
)
278 text_size
= prefix_size
+
279 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
280 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+ 1);
283 png_free(png_ptr
, png_ptr
->chunkdata
);
284 png_ptr
->chunkdata
= NULL
;
286 "Not enough memory to decompress chunk.");
288 png_memcpy(text
+ prefix_size
, png_ptr
->zbuf
,
289 text_size
- prefix_size
);
290 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
291 *(text
+ text_size
) = 0x00;
298 text
= (png_charp
)png_malloc_warn(png_ptr
,
299 (png_uint_32
)(text_size
+
300 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
+ 1));
303 png_free(png_ptr
, tmp
);
304 png_free(png_ptr
, png_ptr
->chunkdata
);
305 png_ptr
->chunkdata
= NULL
;
307 "Not enough memory to decompress chunk..");
309 png_memcpy(text
, tmp
, text_size
);
310 png_free(png_ptr
, tmp
);
311 png_memcpy(text
+ text_size
, png_ptr
->zbuf
,
312 (png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
));
313 text_size
+= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
314 *(text
+ text_size
) = 0x00;
316 if (ret
== Z_STREAM_END
)
320 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
321 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
325 if (ret
!= Z_STREAM_END
)
327 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
330 if (ret
== Z_BUF_ERROR
)
331 png_snprintf(umsg
, 52,
332 "Buffer error in compressed datastream in %s chunk",
333 png_ptr
->chunk_name
);
334 else if (ret
== Z_DATA_ERROR
)
335 png_snprintf(umsg
, 52,
336 "Data error in compressed datastream in %s chunk",
337 png_ptr
->chunk_name
);
339 png_snprintf(umsg
, 52,
340 "Incomplete compressed datastream in %s chunk",
341 png_ptr
->chunk_name
);
342 png_warning(png_ptr
, umsg
);
345 "Incomplete compressed datastream in chunk other than IDAT");
347 text_size
= prefix_size
;
350 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+1);
353 png_free(png_ptr
, png_ptr
->chunkdata
);
354 png_ptr
->chunkdata
= NULL
;
355 png_error(png_ptr
, "Not enough memory for text.");
357 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
359 *(text
+ text_size
) = 0x00;
362 inflateReset(&png_ptr
->zstream
);
363 png_ptr
->zstream
.avail_in
= 0;
365 png_free(png_ptr
, png_ptr
->chunkdata
);
366 png_ptr
->chunkdata
= text
;
367 *newlength
=text_size
;
369 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
371 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
374 png_snprintf(umsg
, 50, "Unknown zTXt compression type %d", comp_type
);
375 png_warning(png_ptr
, umsg
);
377 png_warning(png_ptr
, "Unknown zTXt compression type");
380 *(png_ptr
->chunkdata
+ prefix_size
) = 0x00;
381 *newlength
= prefix_size
;
386 /* read and check the IDHR chunk */
388 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
391 png_uint_32 width
, height
;
392 int bit_depth
, color_type
, compression_type
, filter_type
;
395 png_debug(1, "in png_handle_IHDR");
397 if (png_ptr
->mode
& PNG_HAVE_IHDR
)
398 png_error(png_ptr
, "Out of place IHDR");
400 /* check the length */
402 png_error(png_ptr
, "Invalid IHDR chunk");
404 png_ptr
->mode
|= PNG_HAVE_IHDR
;
406 png_crc_read(png_ptr
, buf
, 13);
407 png_crc_finish(png_ptr
, 0);
409 width
= png_get_uint_31(png_ptr
, buf
);
410 height
= png_get_uint_31(png_ptr
, buf
+ 4);
413 compression_type
= buf
[10];
414 filter_type
= buf
[11];
415 interlace_type
= buf
[12];
417 /* set internal variables */
418 png_ptr
->width
= width
;
419 png_ptr
->height
= height
;
420 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
421 png_ptr
->interlaced
= (png_byte
)interlace_type
;
422 png_ptr
->color_type
= (png_byte
)color_type
;
423 #if defined(PNG_MNG_FEATURES_SUPPORTED)
424 png_ptr
->filter_type
= (png_byte
)filter_type
;
426 png_ptr
->compression_type
= (png_byte
)compression_type
;
428 /* find number of channels */
429 switch (png_ptr
->color_type
)
431 case PNG_COLOR_TYPE_GRAY
:
432 case PNG_COLOR_TYPE_PALETTE
:
433 png_ptr
->channels
= 1;
435 case PNG_COLOR_TYPE_RGB
:
436 png_ptr
->channels
= 3;
438 case PNG_COLOR_TYPE_GRAY_ALPHA
:
439 png_ptr
->channels
= 2;
441 case PNG_COLOR_TYPE_RGB_ALPHA
:
442 png_ptr
->channels
= 4;
446 /* set up other useful info */
447 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
449 png_ptr
->rowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
, png_ptr
->width
);
450 png_debug1(3, "bit_depth = %d", png_ptr
->bit_depth
);
451 png_debug1(3, "channels = %d", png_ptr
->channels
);
452 png_debug1(3, "rowbytes = %lu", png_ptr
->rowbytes
);
453 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
454 color_type
, interlace_type
, compression_type
, filter_type
);
457 /* read and check the palette */
459 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
461 png_color palette
[PNG_MAX_PALETTE_LENGTH
];
463 #ifndef PNG_NO_POINTER_INDEXING
467 png_debug(1, "in png_handle_PLTE");
469 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
470 png_error(png_ptr
, "Missing IHDR before PLTE");
471 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
473 png_warning(png_ptr
, "Invalid PLTE after IDAT");
474 png_crc_finish(png_ptr
, length
);
477 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
478 png_error(png_ptr
, "Duplicate PLTE chunk");
480 png_ptr
->mode
|= PNG_HAVE_PLTE
;
482 if (!(png_ptr
->color_type
&PNG_COLOR_MASK_COLOR
))
485 "Ignoring PLTE chunk in grayscale PNG");
486 png_crc_finish(png_ptr
, length
);
489 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
490 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
492 png_crc_finish(png_ptr
, length
);
497 if (length
> 3*PNG_MAX_PALETTE_LENGTH
|| length
% 3)
499 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
501 png_warning(png_ptr
, "Invalid palette chunk");
502 png_crc_finish(png_ptr
, length
);
507 png_error(png_ptr
, "Invalid palette chunk");
511 num
= (int)length
/ 3;
513 #ifndef PNG_NO_POINTER_INDEXING
514 for (i
= 0, pal_ptr
= palette
; i
< num
; i
++, pal_ptr
++)
518 png_crc_read(png_ptr
, buf
, 3);
519 pal_ptr
->red
= buf
[0];
520 pal_ptr
->green
= buf
[1];
521 pal_ptr
->blue
= buf
[2];
524 for (i
= 0; i
< num
; i
++)
528 png_crc_read(png_ptr
, buf
, 3);
529 /* don't depend upon png_color being any order */
530 palette
[i
].red
= buf
[0];
531 palette
[i
].green
= buf
[1];
532 palette
[i
].blue
= buf
[2];
536 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
537 whatever the normal CRC configuration tells us. However, if we
538 have an RGB image, the PLTE can be considered ancillary, so
539 we will act as though it is. */
540 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
541 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
544 png_crc_finish(png_ptr
, 0);
546 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
547 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
549 /* If we don't want to use the data from an ancillary chunk,
550 we have two options: an error abort, or a warning and we
551 ignore the data in this chunk (which should be OK, since
552 it's considered ancillary for a RGB or RGBA image). */
553 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
555 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
557 png_chunk_error(png_ptr
, "CRC error");
561 png_chunk_warning(png_ptr
, "CRC error");
565 /* Otherwise, we (optionally) emit a warning and use the chunk. */
566 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
568 png_chunk_warning(png_ptr
, "CRC error");
573 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
575 #if defined(PNG_READ_tRNS_SUPPORTED)
576 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
578 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
580 if (png_ptr
->num_trans
> (png_uint_16
)num
)
582 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
583 png_ptr
->num_trans
= (png_uint_16
)num
;
585 if (info_ptr
->num_trans
> (png_uint_16
)num
)
587 png_warning(png_ptr
, "Truncating incorrect info tRNS chunk length");
588 info_ptr
->num_trans
= (png_uint_16
)num
;
597 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
599 png_debug(1, "in png_handle_IEND");
601 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
603 png_error(png_ptr
, "No image in file");
606 png_ptr
->mode
|= (PNG_AFTER_IDAT
| PNG_HAVE_IEND
);
610 png_warning(png_ptr
, "Incorrect IEND chunk length");
612 png_crc_finish(png_ptr
, length
);
614 info_ptr
= info_ptr
; /* quiet compiler warnings about unused info_ptr */
617 #if defined(PNG_READ_gAMA_SUPPORTED)
619 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
621 png_fixed_point igamma
;
622 #ifdef PNG_FLOATING_POINT_SUPPORTED
627 png_debug(1, "in png_handle_gAMA");
629 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
630 png_error(png_ptr
, "Missing IHDR before gAMA");
631 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
633 png_warning(png_ptr
, "Invalid gAMA after IDAT");
634 png_crc_finish(png_ptr
, length
);
637 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
638 /* Should be an error, but we can cope with it */
639 png_warning(png_ptr
, "Out of place gAMA chunk");
641 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
)
642 #if defined(PNG_READ_sRGB_SUPPORTED)
643 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
647 png_warning(png_ptr
, "Duplicate gAMA chunk");
648 png_crc_finish(png_ptr
, length
);
654 png_warning(png_ptr
, "Incorrect gAMA chunk length");
655 png_crc_finish(png_ptr
, length
);
659 png_crc_read(png_ptr
, buf
, 4);
660 if (png_crc_finish(png_ptr
, 0))
663 igamma
= (png_fixed_point
)png_get_uint_32(buf
);
664 /* check for zero gamma */
668 "Ignoring gAMA chunk with gamma=0");
672 #if defined(PNG_READ_sRGB_SUPPORTED)
673 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
674 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
677 "Ignoring incorrect gAMA value when sRGB is also present");
678 #ifndef PNG_NO_CONSOLE_IO
679 fprintf(stderr
, "gamma = (%d/100000)", (int)igamma
);
683 #endif /* PNG_READ_sRGB_SUPPORTED */
685 #ifdef PNG_FLOATING_POINT_SUPPORTED
686 file_gamma
= (float)igamma
/ (float)100000.0;
687 # ifdef PNG_READ_GAMMA_SUPPORTED
688 png_ptr
->gamma
= file_gamma
;
690 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
692 #ifdef PNG_FIXED_POINT_SUPPORTED
693 png_set_gAMA_fixed(png_ptr
, info_ptr
, igamma
);
698 #if defined(PNG_READ_sBIT_SUPPORTED)
700 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
705 png_debug(1, "in png_handle_sBIT");
707 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
709 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
710 png_error(png_ptr
, "Missing IHDR before sBIT");
711 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
713 png_warning(png_ptr
, "Invalid sBIT after IDAT");
714 png_crc_finish(png_ptr
, length
);
717 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
719 /* Should be an error, but we can cope with it */
720 png_warning(png_ptr
, "Out of place sBIT chunk");
722 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sBIT
))
724 png_warning(png_ptr
, "Duplicate sBIT chunk");
725 png_crc_finish(png_ptr
, length
);
729 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
732 truelen
= (png_size_t
)png_ptr
->channels
;
734 if (length
!= truelen
|| length
> 4)
736 png_warning(png_ptr
, "Incorrect sBIT chunk length");
737 png_crc_finish(png_ptr
, length
);
741 png_crc_read(png_ptr
, buf
, truelen
);
742 if (png_crc_finish(png_ptr
, 0))
745 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
747 png_ptr
->sig_bit
.red
= buf
[0];
748 png_ptr
->sig_bit
.green
= buf
[1];
749 png_ptr
->sig_bit
.blue
= buf
[2];
750 png_ptr
->sig_bit
.alpha
= buf
[3];
754 png_ptr
->sig_bit
.gray
= buf
[0];
755 png_ptr
->sig_bit
.red
= buf
[0];
756 png_ptr
->sig_bit
.green
= buf
[0];
757 png_ptr
->sig_bit
.blue
= buf
[0];
758 png_ptr
->sig_bit
.alpha
= buf
[1];
760 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
764 #if defined(PNG_READ_cHRM_SUPPORTED)
766 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
769 #ifdef PNG_FLOATING_POINT_SUPPORTED
770 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
772 png_fixed_point int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
773 int_y_green
, int_x_blue
, int_y_blue
;
775 png_uint_32 uint_x
, uint_y
;
777 png_debug(1, "in png_handle_cHRM");
779 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
780 png_error(png_ptr
, "Missing IHDR before cHRM");
781 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
783 png_warning(png_ptr
, "Invalid cHRM after IDAT");
784 png_crc_finish(png_ptr
, length
);
787 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
788 /* Should be an error, but we can cope with it */
789 png_warning(png_ptr
, "Missing PLTE before cHRM");
791 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
)
792 #if defined(PNG_READ_sRGB_SUPPORTED)
793 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
797 png_warning(png_ptr
, "Duplicate cHRM chunk");
798 png_crc_finish(png_ptr
, length
);
804 png_warning(png_ptr
, "Incorrect cHRM chunk length");
805 png_crc_finish(png_ptr
, length
);
809 png_crc_read(png_ptr
, buf
, 32);
810 if (png_crc_finish(png_ptr
, 0))
813 uint_x
= png_get_uint_32(buf
);
814 uint_y
= png_get_uint_32(buf
+ 4);
815 int_x_white
= (png_fixed_point
)uint_x
;
816 int_y_white
= (png_fixed_point
)uint_y
;
818 uint_x
= png_get_uint_32(buf
+ 8);
819 uint_y
= png_get_uint_32(buf
+ 12);
820 int_x_red
= (png_fixed_point
)uint_x
;
821 int_y_red
= (png_fixed_point
)uint_y
;
823 uint_x
= png_get_uint_32(buf
+ 16);
824 uint_y
= png_get_uint_32(buf
+ 20);
825 int_x_green
= (png_fixed_point
)uint_x
;
826 int_y_green
= (png_fixed_point
)uint_y
;
828 uint_x
= png_get_uint_32(buf
+ 24);
829 uint_y
= png_get_uint_32(buf
+ 28);
830 int_x_blue
= (png_fixed_point
)uint_x
;
831 int_y_blue
= (png_fixed_point
)uint_y
;
833 #ifdef PNG_FLOATING_POINT_SUPPORTED
834 white_x
= (float)int_x_white
/ (float)100000.0;
835 white_y
= (float)int_y_white
/ (float)100000.0;
836 red_x
= (float)int_x_red
/ (float)100000.0;
837 red_y
= (float)int_y_red
/ (float)100000.0;
838 green_x
= (float)int_x_green
/ (float)100000.0;
839 green_y
= (float)int_y_green
/ (float)100000.0;
840 blue_x
= (float)int_x_blue
/ (float)100000.0;
841 blue_y
= (float)int_y_blue
/ (float)100000.0;
844 #if defined(PNG_READ_sRGB_SUPPORTED)
845 if ((info_ptr
!= NULL
) && (info_ptr
->valid
& PNG_INFO_sRGB
))
847 if (PNG_OUT_OF_RANGE(int_x_white
, 31270, 1000) ||
848 PNG_OUT_OF_RANGE(int_y_white
, 32900, 1000) ||
849 PNG_OUT_OF_RANGE(int_x_red
, 64000L, 1000) ||
850 PNG_OUT_OF_RANGE(int_y_red
, 33000, 1000) ||
851 PNG_OUT_OF_RANGE(int_x_green
, 30000, 1000) ||
852 PNG_OUT_OF_RANGE(int_y_green
, 60000L, 1000) ||
853 PNG_OUT_OF_RANGE(int_x_blue
, 15000, 1000) ||
854 PNG_OUT_OF_RANGE(int_y_blue
, 6000, 1000))
857 "Ignoring incorrect cHRM value when sRGB is also present");
858 #ifndef PNG_NO_CONSOLE_IO
859 #ifdef PNG_FLOATING_POINT_SUPPORTED
860 fprintf(stderr
, "wx=%f, wy=%f, rx=%f, ry=%f\n",
861 white_x
, white_y
, red_x
, red_y
);
862 fprintf(stderr
, "gx=%f, gy=%f, bx=%f, by=%f\n",
863 green_x
, green_y
, blue_x
, blue_y
);
865 fprintf(stderr
, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
866 int_x_white
, int_y_white
, int_x_red
, int_y_red
);
867 fprintf(stderr
, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
868 int_x_green
, int_y_green
, int_x_blue
, int_y_blue
);
870 #endif /* PNG_NO_CONSOLE_IO */
874 #endif /* PNG_READ_sRGB_SUPPORTED */
876 #ifdef PNG_FLOATING_POINT_SUPPORTED
877 png_set_cHRM(png_ptr
, info_ptr
,
878 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
880 #ifdef PNG_FIXED_POINT_SUPPORTED
881 png_set_cHRM_fixed(png_ptr
, info_ptr
,
882 int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
883 int_y_green
, int_x_blue
, int_y_blue
);
888 #if defined(PNG_READ_sRGB_SUPPORTED)
890 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
895 png_debug(1, "in png_handle_sRGB");
897 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
898 png_error(png_ptr
, "Missing IHDR before sRGB");
899 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
901 png_warning(png_ptr
, "Invalid sRGB after IDAT");
902 png_crc_finish(png_ptr
, length
);
905 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
906 /* Should be an error, but we can cope with it */
907 png_warning(png_ptr
, "Out of place sRGB chunk");
909 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
911 png_warning(png_ptr
, "Duplicate sRGB chunk");
912 png_crc_finish(png_ptr
, length
);
918 png_warning(png_ptr
, "Incorrect sRGB chunk length");
919 png_crc_finish(png_ptr
, length
);
923 png_crc_read(png_ptr
, buf
, 1);
924 if (png_crc_finish(png_ptr
, 0))
928 /* check for bad intent */
929 if (intent
>= PNG_sRGB_INTENT_LAST
)
931 png_warning(png_ptr
, "Unknown sRGB intent");
935 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
936 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
))
938 png_fixed_point igamma
;
939 #ifdef PNG_FIXED_POINT_SUPPORTED
940 igamma
=info_ptr
->int_gamma
;
942 # ifdef PNG_FLOATING_POINT_SUPPORTED
943 igamma
=(png_fixed_point
)(info_ptr
->gamma
* 100000.);
946 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
949 "Ignoring incorrect gAMA value when sRGB is also present");
950 #ifndef PNG_NO_CONSOLE_IO
951 # ifdef PNG_FIXED_POINT_SUPPORTED
952 fprintf(stderr
, "incorrect gamma=(%d/100000)\n",
953 (int)png_ptr
->int_gamma
);
955 # ifdef PNG_FLOATING_POINT_SUPPORTED
956 fprintf(stderr
, "incorrect gamma=%f\n", png_ptr
->gamma
);
962 #endif /* PNG_READ_gAMA_SUPPORTED */
964 #ifdef PNG_READ_cHRM_SUPPORTED
965 #ifdef PNG_FIXED_POINT_SUPPORTED
966 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
))
967 if (PNG_OUT_OF_RANGE(info_ptr
->int_x_white
, 31270, 1000) ||
968 PNG_OUT_OF_RANGE(info_ptr
->int_y_white
, 32900, 1000) ||
969 PNG_OUT_OF_RANGE(info_ptr
->int_x_red
, 64000L, 1000) ||
970 PNG_OUT_OF_RANGE(info_ptr
->int_y_red
, 33000, 1000) ||
971 PNG_OUT_OF_RANGE(info_ptr
->int_x_green
, 30000, 1000) ||
972 PNG_OUT_OF_RANGE(info_ptr
->int_y_green
, 60000L, 1000) ||
973 PNG_OUT_OF_RANGE(info_ptr
->int_x_blue
, 15000, 1000) ||
974 PNG_OUT_OF_RANGE(info_ptr
->int_y_blue
, 6000, 1000))
977 "Ignoring incorrect cHRM value when sRGB is also present");
979 #endif /* PNG_FIXED_POINT_SUPPORTED */
980 #endif /* PNG_READ_cHRM_SUPPORTED */
982 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
984 #endif /* PNG_READ_sRGB_SUPPORTED */
986 #if defined(PNG_READ_iCCP_SUPPORTED)
988 png_handle_iCCP(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
989 /* Note: this does not properly handle chunks that are > 64K under DOS */
991 png_byte compression_type
;
994 png_uint_32 skip
= 0;
995 png_uint_32 profile_size
, profile_length
;
996 png_size_t slength
, prefix_length
, data_length
;
998 png_debug(1, "in png_handle_iCCP");
1000 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1001 png_error(png_ptr
, "Missing IHDR before iCCP");
1002 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1004 png_warning(png_ptr
, "Invalid iCCP after IDAT");
1005 png_crc_finish(png_ptr
, length
);
1008 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
1009 /* Should be an error, but we can cope with it */
1010 png_warning(png_ptr
, "Out of place iCCP chunk");
1012 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_iCCP
))
1014 png_warning(png_ptr
, "Duplicate iCCP chunk");
1015 png_crc_finish(png_ptr
, length
);
1019 #ifdef PNG_MAX_MALLOC_64K
1020 if (length
> (png_uint_32
)65535L)
1022 png_warning(png_ptr
, "iCCP chunk too large to fit in memory");
1023 skip
= length
- (png_uint_32
)65535L;
1024 length
= (png_uint_32
)65535L;
1028 png_free(png_ptr
, png_ptr
->chunkdata
);
1029 png_ptr
->chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1030 slength
= (png_size_t
)length
;
1031 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1033 if (png_crc_finish(png_ptr
, skip
))
1035 png_free(png_ptr
, png_ptr
->chunkdata
);
1036 png_ptr
->chunkdata
= NULL
;
1040 png_ptr
->chunkdata
[slength
] = 0x00;
1042 for (profile
= png_ptr
->chunkdata
; *profile
; profile
++)
1043 /* empty loop to find end of name */ ;
1047 /* there should be at least one zero (the compression type byte)
1048 following the separator, and we should be on it */
1049 if ( profile
>= png_ptr
->chunkdata
+ slength
- 1)
1051 png_free(png_ptr
, png_ptr
->chunkdata
);
1052 png_ptr
->chunkdata
= NULL
;
1053 png_warning(png_ptr
, "Malformed iCCP chunk");
1057 /* compression_type should always be zero */
1058 compression_type
= *profile
++;
1059 if (compression_type
)
1061 png_warning(png_ptr
, "Ignoring nonzero compression type in iCCP chunk");
1062 compression_type
= 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1066 prefix_length
= profile
- png_ptr
->chunkdata
;
1067 png_decompress_chunk(png_ptr
, compression_type
,
1068 slength
, prefix_length
, &data_length
);
1070 profile_length
= data_length
- prefix_length
;
1072 if ( prefix_length
> data_length
|| profile_length
< 4)
1074 png_free(png_ptr
, png_ptr
->chunkdata
);
1075 png_ptr
->chunkdata
= NULL
;
1076 png_warning(png_ptr
, "Profile size field missing from iCCP chunk");
1080 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1081 pC
= (png_bytep
)(png_ptr
->chunkdata
+ prefix_length
);
1082 profile_size
= ((*(pC
))<<24) |
1087 if (profile_size
< profile_length
)
1088 profile_length
= profile_size
;
1090 if (profile_size
> profile_length
)
1092 png_free(png_ptr
, png_ptr
->chunkdata
);
1093 png_ptr
->chunkdata
= NULL
;
1094 png_warning(png_ptr
, "Ignoring truncated iCCP profile.");
1098 png_set_iCCP(png_ptr
, info_ptr
, png_ptr
->chunkdata
,
1099 compression_type
, png_ptr
->chunkdata
+ prefix_length
, profile_length
);
1100 png_free(png_ptr
, png_ptr
->chunkdata
);
1101 png_ptr
->chunkdata
= NULL
;
1103 #endif /* PNG_READ_iCCP_SUPPORTED */
1105 #if defined(PNG_READ_sPLT_SUPPORTED)
1107 png_handle_sPLT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1108 /* Note: this does not properly handle chunks that are > 64K under DOS */
1110 png_bytep entry_start
;
1111 png_sPLT_t new_palette
;
1112 #ifdef PNG_NO_POINTER_INDEXING
1115 int data_length
, entry_size
, i
;
1116 png_uint_32 skip
= 0;
1119 png_debug(1, "in png_handle_sPLT");
1121 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1122 png_error(png_ptr
, "Missing IHDR before sPLT");
1123 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1125 png_warning(png_ptr
, "Invalid sPLT after IDAT");
1126 png_crc_finish(png_ptr
, length
);
1130 #ifdef PNG_MAX_MALLOC_64K
1131 if (length
> (png_uint_32
)65535L)
1133 png_warning(png_ptr
, "sPLT chunk too large to fit in memory");
1134 skip
= length
- (png_uint_32
)65535L;
1135 length
= (png_uint_32
)65535L;
1139 png_free(png_ptr
, png_ptr
->chunkdata
);
1140 png_ptr
->chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1141 slength
= (png_size_t
)length
;
1142 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1144 if (png_crc_finish(png_ptr
, skip
))
1146 png_free(png_ptr
, png_ptr
->chunkdata
);
1147 png_ptr
->chunkdata
= NULL
;
1151 png_ptr
->chunkdata
[slength
] = 0x00;
1153 for (entry_start
= (png_bytep
)png_ptr
->chunkdata
; *entry_start
; entry_start
++)
1154 /* empty loop to find end of name */ ;
1157 /* a sample depth should follow the separator, and we should be on it */
1158 if (entry_start
> (png_bytep
)png_ptr
->chunkdata
+ slength
- 2)
1160 png_free(png_ptr
, png_ptr
->chunkdata
);
1161 png_ptr
->chunkdata
= NULL
;
1162 png_warning(png_ptr
, "malformed sPLT chunk");
1166 new_palette
.depth
= *entry_start
++;
1167 entry_size
= (new_palette
.depth
== 8 ? 6 : 10);
1168 data_length
= (slength
- (entry_start
- (png_bytep
)png_ptr
->chunkdata
));
1170 /* integrity-check the data length */
1171 if (data_length
% entry_size
)
1173 png_free(png_ptr
, png_ptr
->chunkdata
);
1174 png_ptr
->chunkdata
= NULL
;
1175 png_warning(png_ptr
, "sPLT chunk has bad length");
1179 new_palette
.nentries
= (png_int_32
) ( data_length
/ entry_size
);
1180 if ((png_uint_32
) new_palette
.nentries
>
1181 (png_uint_32
) (PNG_SIZE_MAX
/ png_sizeof(png_sPLT_entry
)))
1183 png_warning(png_ptr
, "sPLT chunk too long");
1186 new_palette
.entries
= (png_sPLT_entryp
)png_malloc_warn(
1187 png_ptr
, new_palette
.nentries
* png_sizeof(png_sPLT_entry
));
1188 if (new_palette
.entries
== NULL
)
1190 png_warning(png_ptr
, "sPLT chunk requires too much memory");
1194 #ifndef PNG_NO_POINTER_INDEXING
1195 for (i
= 0; i
< new_palette
.nentries
; i
++)
1197 png_sPLT_entryp pp
= new_palette
.entries
+ i
;
1199 if (new_palette
.depth
== 8)
1201 pp
->red
= *entry_start
++;
1202 pp
->green
= *entry_start
++;
1203 pp
->blue
= *entry_start
++;
1204 pp
->alpha
= *entry_start
++;
1208 pp
->red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1209 pp
->green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1210 pp
->blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1211 pp
->alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1213 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1216 pp
= new_palette
.entries
;
1217 for (i
= 0; i
< new_palette
.nentries
; i
++)
1220 if (new_palette
.depth
== 8)
1222 pp
[i
].red
= *entry_start
++;
1223 pp
[i
].green
= *entry_start
++;
1224 pp
[i
].blue
= *entry_start
++;
1225 pp
[i
].alpha
= *entry_start
++;
1229 pp
[i
].red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1230 pp
[i
].green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1231 pp
[i
].blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1232 pp
[i
].alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1234 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1238 /* discard all chunk data except the name and stash that */
1239 new_palette
.name
= png_ptr
->chunkdata
;
1241 png_set_sPLT(png_ptr
, info_ptr
, &new_palette
, 1);
1243 png_free(png_ptr
, png_ptr
->chunkdata
);
1244 png_ptr
->chunkdata
= NULL
;
1245 png_free(png_ptr
, new_palette
.entries
);
1247 #endif /* PNG_READ_sPLT_SUPPORTED */
1249 #if defined(PNG_READ_tRNS_SUPPORTED)
1251 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1253 png_byte readbuf
[PNG_MAX_PALETTE_LENGTH
];
1255 png_debug(1, "in png_handle_tRNS");
1257 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1258 png_error(png_ptr
, "Missing IHDR before tRNS");
1259 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1261 png_warning(png_ptr
, "Invalid tRNS after IDAT");
1262 png_crc_finish(png_ptr
, length
);
1265 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
1267 png_warning(png_ptr
, "Duplicate tRNS chunk");
1268 png_crc_finish(png_ptr
, length
);
1272 if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
1278 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1279 png_crc_finish(png_ptr
, length
);
1283 png_crc_read(png_ptr
, buf
, 2);
1284 png_ptr
->num_trans
= 1;
1285 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
);
1287 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
1293 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1294 png_crc_finish(png_ptr
, length
);
1297 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
1298 png_ptr
->num_trans
= 1;
1299 png_ptr
->trans_values
.red
= png_get_uint_16(buf
);
1300 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2);
1301 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4);
1303 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1305 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1307 /* Should be an error, but we can cope with it. */
1308 png_warning(png_ptr
, "Missing PLTE before tRNS");
1310 if (length
> (png_uint_32
)png_ptr
->num_palette
||
1311 length
> PNG_MAX_PALETTE_LENGTH
)
1313 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1314 png_crc_finish(png_ptr
, length
);
1319 png_warning(png_ptr
, "Zero length tRNS chunk");
1320 png_crc_finish(png_ptr
, length
);
1323 png_crc_read(png_ptr
, readbuf
, (png_size_t
)length
);
1324 png_ptr
->num_trans
= (png_uint_16
)length
;
1328 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
1329 png_crc_finish(png_ptr
, length
);
1333 if (png_crc_finish(png_ptr
, 0))
1335 png_ptr
->num_trans
= 0;
1339 png_set_tRNS(png_ptr
, info_ptr
, readbuf
, png_ptr
->num_trans
,
1340 &(png_ptr
->trans_values
));
1344 #if defined(PNG_READ_bKGD_SUPPORTED)
1346 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1351 png_debug(1, "in png_handle_bKGD");
1353 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1354 png_error(png_ptr
, "Missing IHDR before bKGD");
1355 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1357 png_warning(png_ptr
, "Invalid bKGD after IDAT");
1358 png_crc_finish(png_ptr
, length
);
1361 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
1362 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
1364 png_warning(png_ptr
, "Missing PLTE before bKGD");
1365 png_crc_finish(png_ptr
, length
);
1368 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_bKGD
))
1370 png_warning(png_ptr
, "Duplicate bKGD chunk");
1371 png_crc_finish(png_ptr
, length
);
1375 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1377 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1382 if (length
!= truelen
)
1384 png_warning(png_ptr
, "Incorrect bKGD chunk length");
1385 png_crc_finish(png_ptr
, length
);
1389 png_crc_read(png_ptr
, buf
, truelen
);
1390 if (png_crc_finish(png_ptr
, 0))
1393 /* We convert the index value into RGB components so that we can allow
1394 * arbitrary RGB values for background when we have transparency, and
1395 * so it is easy to determine the RGB values of the background color
1396 * from the info_ptr struct. */
1397 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1399 png_ptr
->background
.index
= buf
[0];
1400 if (info_ptr
&& info_ptr
->num_palette
)
1402 if (buf
[0] >= info_ptr
->num_palette
)
1404 png_warning(png_ptr
, "Incorrect bKGD chunk index value");
1407 png_ptr
->background
.red
=
1408 (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
1409 png_ptr
->background
.green
=
1410 (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
1411 png_ptr
->background
.blue
=
1412 (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
1415 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
1417 png_ptr
->background
.red
=
1418 png_ptr
->background
.green
=
1419 png_ptr
->background
.blue
=
1420 png_ptr
->background
.gray
= png_get_uint_16(buf
);
1424 png_ptr
->background
.red
= png_get_uint_16(buf
);
1425 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
1426 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
1429 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
1433 #if defined(PNG_READ_hIST_SUPPORTED)
1435 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1437 unsigned int num
, i
;
1438 png_uint_16 readbuf
[PNG_MAX_PALETTE_LENGTH
];
1440 png_debug(1, "in png_handle_hIST");
1442 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1443 png_error(png_ptr
, "Missing IHDR before hIST");
1444 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1446 png_warning(png_ptr
, "Invalid hIST after IDAT");
1447 png_crc_finish(png_ptr
, length
);
1450 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1452 png_warning(png_ptr
, "Missing PLTE before hIST");
1453 png_crc_finish(png_ptr
, length
);
1456 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_hIST
))
1458 png_warning(png_ptr
, "Duplicate hIST chunk");
1459 png_crc_finish(png_ptr
, length
);
1464 if (num
!= (unsigned int) png_ptr
->num_palette
|| num
>
1465 (unsigned int) PNG_MAX_PALETTE_LENGTH
)
1467 png_warning(png_ptr
, "Incorrect hIST chunk length");
1468 png_crc_finish(png_ptr
, length
);
1472 for (i
= 0; i
< num
; i
++)
1476 png_crc_read(png_ptr
, buf
, 2);
1477 readbuf
[i
] = png_get_uint_16(buf
);
1480 if (png_crc_finish(png_ptr
, 0))
1483 png_set_hIST(png_ptr
, info_ptr
, readbuf
);
1487 #if defined(PNG_READ_pHYs_SUPPORTED)
1489 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1492 png_uint_32 res_x
, res_y
;
1495 png_debug(1, "in png_handle_pHYs");
1497 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1498 png_error(png_ptr
, "Missing IHDR before pHYs");
1499 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1501 png_warning(png_ptr
, "Invalid pHYs after IDAT");
1502 png_crc_finish(png_ptr
, length
);
1505 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pHYs
))
1507 png_warning(png_ptr
, "Duplicate pHYs chunk");
1508 png_crc_finish(png_ptr
, length
);
1514 png_warning(png_ptr
, "Incorrect pHYs chunk length");
1515 png_crc_finish(png_ptr
, length
);
1519 png_crc_read(png_ptr
, buf
, 9);
1520 if (png_crc_finish(png_ptr
, 0))
1523 res_x
= png_get_uint_32(buf
);
1524 res_y
= png_get_uint_32(buf
+ 4);
1526 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
1530 #if defined(PNG_READ_oFFs_SUPPORTED)
1532 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1535 png_int_32 offset_x
, offset_y
;
1538 png_debug(1, "in png_handle_oFFs");
1540 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1541 png_error(png_ptr
, "Missing IHDR before oFFs");
1542 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1544 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1545 png_crc_finish(png_ptr
, length
);
1548 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_oFFs
))
1550 png_warning(png_ptr
, "Duplicate oFFs chunk");
1551 png_crc_finish(png_ptr
, length
);
1557 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1558 png_crc_finish(png_ptr
, length
);
1562 png_crc_read(png_ptr
, buf
, 9);
1563 if (png_crc_finish(png_ptr
, 0))
1566 offset_x
= png_get_int_32(buf
);
1567 offset_y
= png_get_int_32(buf
+ 4);
1569 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1573 #if defined(PNG_READ_pCAL_SUPPORTED)
1574 /* read the pCAL chunk (described in the PNG Extensions document) */
1576 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1579 png_byte type
, nparams
;
1580 png_charp buf
, units
, endptr
;
1585 png_debug(1, "in png_handle_pCAL");
1587 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1588 png_error(png_ptr
, "Missing IHDR before pCAL");
1589 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1591 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1592 png_crc_finish(png_ptr
, length
);
1595 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pCAL
))
1597 png_warning(png_ptr
, "Duplicate pCAL chunk");
1598 png_crc_finish(png_ptr
, length
);
1602 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1604 png_free(png_ptr
, png_ptr
->chunkdata
);
1605 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1606 if (png_ptr
->chunkdata
== NULL
)
1608 png_warning(png_ptr
, "No memory for pCAL purpose.");
1611 slength
= (png_size_t
)length
;
1612 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1614 if (png_crc_finish(png_ptr
, 0))
1616 png_free(png_ptr
, png_ptr
->chunkdata
);
1617 png_ptr
->chunkdata
= NULL
;
1621 png_ptr
->chunkdata
[slength
] = 0x00; /* null terminate the last string */
1623 png_debug(3, "Finding end of pCAL purpose string");
1624 for (buf
= png_ptr
->chunkdata
; *buf
; buf
++)
1627 endptr
= png_ptr
->chunkdata
+ slength
;
1629 /* We need to have at least 12 bytes after the purpose string
1630 in order to get the parameter information. */
1631 if (endptr
<= buf
+ 12)
1633 png_warning(png_ptr
, "Invalid pCAL data");
1634 png_free(png_ptr
, png_ptr
->chunkdata
);
1635 png_ptr
->chunkdata
= NULL
;
1639 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1640 X0
= png_get_int_32((png_bytep
)buf
+1);
1641 X1
= png_get_int_32((png_bytep
)buf
+5);
1646 png_debug(3, "Checking pCAL equation type and number of parameters");
1647 /* Check that we have the right number of parameters for known
1649 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1650 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1651 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1652 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1654 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1655 png_free(png_ptr
, png_ptr
->chunkdata
);
1656 png_ptr
->chunkdata
= NULL
;
1659 else if (type
>= PNG_EQUATION_LAST
)
1661 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1664 for (buf
= units
; *buf
; buf
++)
1665 /* Empty loop to move past the units string. */ ;
1667 png_debug(3, "Allocating pCAL parameters array");
1668 params
= (png_charpp
)png_malloc_warn(png_ptr
,
1669 (png_uint_32
)(nparams
* png_sizeof(png_charp
))) ;
1672 png_free(png_ptr
, png_ptr
->chunkdata
);
1673 png_ptr
->chunkdata
= NULL
;
1674 png_warning(png_ptr
, "No memory for pCAL params.");
1678 /* Get pointers to the start of each parameter string. */
1679 for (i
= 0; i
< (int)nparams
; i
++)
1681 buf
++; /* Skip the null string terminator from previous parameter. */
1683 png_debug1(3, "Reading pCAL parameter %d", i
);
1684 for (params
[i
] = buf
; buf
<= endptr
&& *buf
!= 0x00; buf
++)
1685 /* Empty loop to move past each parameter string */ ;
1687 /* Make sure we haven't run out of data yet */
1690 png_warning(png_ptr
, "Invalid pCAL data");
1691 png_free(png_ptr
, png_ptr
->chunkdata
);
1692 png_ptr
->chunkdata
= NULL
;
1693 png_free(png_ptr
, params
);
1698 png_set_pCAL(png_ptr
, info_ptr
, png_ptr
->chunkdata
, X0
, X1
, type
, nparams
,
1701 png_free(png_ptr
, png_ptr
->chunkdata
);
1702 png_ptr
->chunkdata
= NULL
;
1703 png_free(png_ptr
, params
);
1707 #if defined(PNG_READ_sCAL_SUPPORTED)
1708 /* read the sCAL chunk */
1710 png_handle_sCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1713 #ifdef PNG_FLOATING_POINT_SUPPORTED
1714 double width
, height
;
1717 #ifdef PNG_FIXED_POINT_SUPPORTED
1718 png_charp swidth
, sheight
;
1723 png_debug(1, "in png_handle_sCAL");
1725 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1726 png_error(png_ptr
, "Missing IHDR before sCAL");
1727 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1729 png_warning(png_ptr
, "Invalid sCAL after IDAT");
1730 png_crc_finish(png_ptr
, length
);
1733 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sCAL
))
1735 png_warning(png_ptr
, "Duplicate sCAL chunk");
1736 png_crc_finish(png_ptr
, length
);
1740 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1742 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1743 if (png_ptr
->chunkdata
== NULL
)
1745 png_warning(png_ptr
, "Out of memory while processing sCAL chunk");
1748 slength
= (png_size_t
)length
;
1749 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1751 if (png_crc_finish(png_ptr
, 0))
1753 png_free(png_ptr
, png_ptr
->chunkdata
);
1754 png_ptr
->chunkdata
= NULL
;
1758 png_ptr
->chunkdata
[slength
] = 0x00; /* null terminate the last string */
1760 ep
= png_ptr
->chunkdata
+ 1; /* skip unit byte */
1762 #ifdef PNG_FLOATING_POINT_SUPPORTED
1763 width
= png_strtod(png_ptr
, ep
, &vp
);
1766 png_warning(png_ptr
, "malformed width string in sCAL chunk");
1770 #ifdef PNG_FIXED_POINT_SUPPORTED
1771 swidth
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1774 png_warning(png_ptr
, "Out of memory while processing sCAL chunk width");
1777 png_memcpy(swidth
, ep
, (png_size_t
)png_strlen(ep
));
1781 for (ep
= png_ptr
->chunkdata
; *ep
; ep
++)
1785 if (png_ptr
->chunkdata
+ slength
< ep
)
1787 png_warning(png_ptr
, "Truncated sCAL chunk");
1788 #if defined(PNG_FIXED_POINT_SUPPORTED) && \
1789 !defined(PNG_FLOATING_POINT_SUPPORTED)
1790 png_free(png_ptr
, swidth
);
1792 png_free(png_ptr
, png_ptr
->chunkdata
);
1793 png_ptr
->chunkdata
= NULL
;
1797 #ifdef PNG_FLOATING_POINT_SUPPORTED
1798 height
= png_strtod(png_ptr
, ep
, &vp
);
1801 png_warning(png_ptr
, "malformed height string in sCAL chunk");
1805 #ifdef PNG_FIXED_POINT_SUPPORTED
1806 sheight
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1807 if (sheight
== NULL
)
1809 png_warning(png_ptr
, "Out of memory while processing sCAL chunk height");
1812 png_memcpy(sheight
, ep
, (png_size_t
)png_strlen(ep
));
1816 if (png_ptr
->chunkdata
+ slength
< ep
1817 #ifdef PNG_FLOATING_POINT_SUPPORTED
1818 || width
<= 0. || height
<= 0.
1822 png_warning(png_ptr
, "Invalid sCAL data");
1823 png_free(png_ptr
, png_ptr
->chunkdata
);
1824 png_ptr
->chunkdata
= NULL
;
1825 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1826 png_free(png_ptr
, swidth
);
1827 png_free(png_ptr
, sheight
);
1833 #ifdef PNG_FLOATING_POINT_SUPPORTED
1834 png_set_sCAL(png_ptr
, info_ptr
, png_ptr
->chunkdata
[0], width
, height
);
1836 #ifdef PNG_FIXED_POINT_SUPPORTED
1837 png_set_sCAL_s(png_ptr
, info_ptr
, png_ptr
->chunkdata
[0], swidth
, sheight
);
1841 png_free(png_ptr
, png_ptr
->chunkdata
);
1842 png_ptr
->chunkdata
= NULL
;
1843 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1844 png_free(png_ptr
, swidth
);
1845 png_free(png_ptr
, sheight
);
1850 #if defined(PNG_READ_tIME_SUPPORTED)
1852 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1857 png_debug(1, "in png_handle_tIME");
1859 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1860 png_error(png_ptr
, "Out of place tIME chunk");
1861 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tIME
))
1863 png_warning(png_ptr
, "Duplicate tIME chunk");
1864 png_crc_finish(png_ptr
, length
);
1868 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1869 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1873 png_warning(png_ptr
, "Incorrect tIME chunk length");
1874 png_crc_finish(png_ptr
, length
);
1878 png_crc_read(png_ptr
, buf
, 7);
1879 if (png_crc_finish(png_ptr
, 0))
1882 mod_time
.second
= buf
[6];
1883 mod_time
.minute
= buf
[5];
1884 mod_time
.hour
= buf
[4];
1885 mod_time
.day
= buf
[3];
1886 mod_time
.month
= buf
[2];
1887 mod_time
.year
= png_get_uint_16(buf
);
1889 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1893 #if defined(PNG_READ_tEXt_SUPPORTED)
1894 /* Note: this does not properly handle chunks that are > 64K under DOS */
1896 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1901 png_uint_32 skip
= 0;
1905 png_debug(1, "in png_handle_tEXt");
1907 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1908 png_error(png_ptr
, "Missing IHDR before tEXt");
1910 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1911 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1913 #ifdef PNG_MAX_MALLOC_64K
1914 if (length
> (png_uint_32
)65535L)
1916 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
1917 skip
= length
- (png_uint_32
)65535L;
1918 length
= (png_uint_32
)65535L;
1922 png_free(png_ptr
, png_ptr
->chunkdata
);
1923 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1924 if (png_ptr
->chunkdata
== NULL
)
1926 png_warning(png_ptr
, "No memory to process text chunk.");
1929 slength
= (png_size_t
)length
;
1930 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1932 if (png_crc_finish(png_ptr
, skip
))
1934 png_free(png_ptr
, png_ptr
->chunkdata
);
1935 png_ptr
->chunkdata
= NULL
;
1939 key
= png_ptr
->chunkdata
;
1940 key
[slength
] = 0x00;
1942 for (text
= key
; *text
; text
++)
1943 /* empty loop to find end of key */ ;
1945 if (text
!= key
+ slength
)
1948 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
1949 (png_uint_32
)png_sizeof(png_text
));
1950 if (text_ptr
== NULL
)
1952 png_warning(png_ptr
, "Not enough memory to process text chunk.");
1953 png_free(png_ptr
, png_ptr
->chunkdata
);
1954 png_ptr
->chunkdata
= NULL
;
1957 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
1958 text_ptr
->key
= key
;
1959 #ifdef PNG_iTXt_SUPPORTED
1960 text_ptr
->lang
= NULL
;
1961 text_ptr
->lang_key
= NULL
;
1962 text_ptr
->itxt_length
= 0;
1964 text_ptr
->text
= text
;
1965 text_ptr
->text_length
= png_strlen(text
);
1967 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
1969 png_free(png_ptr
, png_ptr
->chunkdata
);
1970 png_ptr
->chunkdata
= NULL
;
1971 png_free(png_ptr
, text_ptr
);
1973 png_warning(png_ptr
, "Insufficient memory to process text chunk.");
1977 #if defined(PNG_READ_zTXt_SUPPORTED)
1978 /* note: this does not correctly handle chunks that are > 64K under DOS */
1980 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1986 png_size_t slength
, prefix_len
, data_len
;
1988 png_debug(1, "in png_handle_zTXt");
1989 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1990 png_error(png_ptr
, "Missing IHDR before zTXt");
1992 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1993 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1995 #ifdef PNG_MAX_MALLOC_64K
1996 /* We will no doubt have problems with chunks even half this size, but
1997 there is no hard and fast rule to tell us where to stop. */
1998 if (length
> (png_uint_32
)65535L)
2000 png_warning(png_ptr
, "zTXt chunk too large to fit in memory");
2001 png_crc_finish(png_ptr
, length
);
2006 png_free(png_ptr
, png_ptr
->chunkdata
);
2007 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2008 if (png_ptr
->chunkdata
== NULL
)
2010 png_warning(png_ptr
, "Out of memory processing zTXt chunk.");
2013 slength
= (png_size_t
)length
;
2014 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
2015 if (png_crc_finish(png_ptr
, 0))
2017 png_free(png_ptr
, png_ptr
->chunkdata
);
2018 png_ptr
->chunkdata
= NULL
;
2022 png_ptr
->chunkdata
[slength
] = 0x00;
2024 for (text
= png_ptr
->chunkdata
; *text
; text
++)
2027 /* zTXt must have some text after the chunkdataword */
2028 if (text
>= png_ptr
->chunkdata
+ slength
- 2)
2030 png_warning(png_ptr
, "Truncated zTXt chunk");
2031 png_free(png_ptr
, png_ptr
->chunkdata
);
2032 png_ptr
->chunkdata
= NULL
;
2037 comp_type
= *(++text
);
2038 if (comp_type
!= PNG_TEXT_COMPRESSION_zTXt
)
2040 png_warning(png_ptr
, "Unknown compression type in zTXt chunk");
2041 comp_type
= PNG_TEXT_COMPRESSION_zTXt
;
2043 text
++; /* skip the compression_method byte */
2045 prefix_len
= text
- png_ptr
->chunkdata
;
2047 png_decompress_chunk(png_ptr
, comp_type
,
2048 (png_size_t
)length
, prefix_len
, &data_len
);
2050 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2051 (png_uint_32
)png_sizeof(png_text
));
2052 if (text_ptr
== NULL
)
2054 png_warning(png_ptr
, "Not enough memory to process zTXt chunk.");
2055 png_free(png_ptr
, png_ptr
->chunkdata
);
2056 png_ptr
->chunkdata
= NULL
;
2059 text_ptr
->compression
= comp_type
;
2060 text_ptr
->key
= png_ptr
->chunkdata
;
2061 #ifdef PNG_iTXt_SUPPORTED
2062 text_ptr
->lang
= NULL
;
2063 text_ptr
->lang_key
= NULL
;
2064 text_ptr
->itxt_length
= 0;
2066 text_ptr
->text
= png_ptr
->chunkdata
+ prefix_len
;
2067 text_ptr
->text_length
= data_len
;
2069 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2071 png_free(png_ptr
, text_ptr
);
2072 png_free(png_ptr
, png_ptr
->chunkdata
);
2073 png_ptr
->chunkdata
= NULL
;
2075 png_error(png_ptr
, "Insufficient memory to store zTXt chunk.");
2079 #if defined(PNG_READ_iTXt_SUPPORTED)
2080 /* note: this does not correctly handle chunks that are > 64K under DOS */
2082 png_handle_iTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2085 png_charp key
, lang
, text
, lang_key
;
2089 png_size_t slength
, prefix_len
, data_len
;
2091 png_debug(1, "in png_handle_iTXt");
2093 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2094 png_error(png_ptr
, "Missing IHDR before iTXt");
2096 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2097 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2099 #ifdef PNG_MAX_MALLOC_64K
2100 /* We will no doubt have problems with chunks even half this size, but
2101 there is no hard and fast rule to tell us where to stop. */
2102 if (length
> (png_uint_32
)65535L)
2104 png_warning(png_ptr
, "iTXt chunk too large to fit in memory");
2105 png_crc_finish(png_ptr
, length
);
2110 png_free(png_ptr
, png_ptr
->chunkdata
);
2111 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2112 if (png_ptr
->chunkdata
== NULL
)
2114 png_warning(png_ptr
, "No memory to process iTXt chunk.");
2117 slength
= (png_size_t
)length
;
2118 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
2119 if (png_crc_finish(png_ptr
, 0))
2121 png_free(png_ptr
, png_ptr
->chunkdata
);
2122 png_ptr
->chunkdata
= NULL
;
2126 png_ptr
->chunkdata
[slength
] = 0x00;
2128 for (lang
= png_ptr
->chunkdata
; *lang
; lang
++)
2130 lang
++; /* skip NUL separator */
2132 /* iTXt must have a language tag (possibly empty), two compression bytes,
2133 translated keyword (possibly empty), and possibly some text after the
2136 if (lang
>= png_ptr
->chunkdata
+ slength
- 3)
2138 png_warning(png_ptr
, "Truncated iTXt chunk");
2139 png_free(png_ptr
, png_ptr
->chunkdata
);
2140 png_ptr
->chunkdata
= NULL
;
2145 comp_flag
= *lang
++;
2146 comp_type
= *lang
++;
2149 for (lang_key
= lang
; *lang_key
; lang_key
++)
2151 lang_key
++; /* skip NUL separator */
2153 if (lang_key
>= png_ptr
->chunkdata
+ slength
)
2155 png_warning(png_ptr
, "Truncated iTXt chunk");
2156 png_free(png_ptr
, png_ptr
->chunkdata
);
2157 png_ptr
->chunkdata
= NULL
;
2161 for (text
= lang_key
; *text
; text
++)
2163 text
++; /* skip NUL separator */
2164 if (text
>= png_ptr
->chunkdata
+ slength
)
2166 png_warning(png_ptr
, "Malformed iTXt chunk");
2167 png_free(png_ptr
, png_ptr
->chunkdata
);
2168 png_ptr
->chunkdata
= NULL
;
2172 prefix_len
= text
- png_ptr
->chunkdata
;
2174 key
=png_ptr
->chunkdata
;
2176 png_decompress_chunk(png_ptr
, comp_type
,
2177 (size_t)length
, prefix_len
, &data_len
);
2179 data_len
= png_strlen(png_ptr
->chunkdata
+ prefix_len
);
2180 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2181 (png_uint_32
)png_sizeof(png_text
));
2182 if (text_ptr
== NULL
)
2184 png_warning(png_ptr
, "Not enough memory to process iTXt chunk.");
2185 png_free(png_ptr
, png_ptr
->chunkdata
);
2186 png_ptr
->chunkdata
= NULL
;
2189 text_ptr
->compression
= (int)comp_flag
+ 1;
2190 text_ptr
->lang_key
= png_ptr
->chunkdata
+ (lang_key
- key
);
2191 text_ptr
->lang
= png_ptr
->chunkdata
+ (lang
- key
);
2192 text_ptr
->itxt_length
= data_len
;
2193 text_ptr
->text_length
= 0;
2194 text_ptr
->key
= png_ptr
->chunkdata
;
2195 text_ptr
->text
= png_ptr
->chunkdata
+ prefix_len
;
2197 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2199 png_free(png_ptr
, text_ptr
);
2200 png_free(png_ptr
, png_ptr
->chunkdata
);
2201 png_ptr
->chunkdata
= NULL
;
2203 png_error(png_ptr
, "Insufficient memory to store iTXt chunk.");
2207 /* This function is called when we haven't found a handler for a
2208 chunk. If there isn't a problem with the chunk itself (ie bad
2209 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2210 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2211 case it will be saved away to be written out later. */
2213 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2215 png_uint_32 skip
= 0;
2217 png_debug(1, "in png_handle_unknown");
2219 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2221 #ifdef PNG_USE_LOCAL_ARRAYS
2224 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4)) /* not an IDAT */
2225 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2228 if (!(png_ptr
->chunk_name
[0] & 0x20))
2230 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2231 if (png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2232 PNG_HANDLE_CHUNK_ALWAYS
2233 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2234 && png_ptr
->read_user_chunk_fn
== NULL
2238 png_chunk_error(png_ptr
, "unknown critical chunk");
2241 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2242 if ((png_ptr
->flags
& PNG_FLAG_KEEP_UNKNOWN_CHUNKS
) ||
2243 (png_ptr
->read_user_chunk_fn
!= NULL
))
2245 #ifdef PNG_MAX_MALLOC_64K
2246 if (length
> (png_uint_32
)65535L)
2248 png_warning(png_ptr
, "unknown chunk too large to fit in memory");
2249 skip
= length
- (png_uint_32
)65535L;
2250 length
= (png_uint_32
)65535L;
2253 png_memcpy((png_charp
)png_ptr
->unknown_chunk
.name
,
2254 (png_charp
)png_ptr
->chunk_name
,
2255 png_sizeof(png_ptr
->unknown_chunk
.name
));
2256 png_ptr
->unknown_chunk
.name
[png_sizeof(png_ptr
->unknown_chunk
.name
)-1] = '\0';
2257 png_ptr
->unknown_chunk
.size
= (png_size_t
)length
;
2259 png_ptr
->unknown_chunk
.data
= NULL
;
2262 png_ptr
->unknown_chunk
.data
= (png_bytep
)png_malloc(png_ptr
, length
);
2263 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->unknown_chunk
.data
, length
);
2265 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2266 if (png_ptr
->read_user_chunk_fn
!= NULL
)
2268 /* callback to user unknown chunk handler */
2270 ret
= (*(png_ptr
->read_user_chunk_fn
))
2271 (png_ptr
, &png_ptr
->unknown_chunk
);
2273 png_chunk_error(png_ptr
, "error in user chunk");
2276 if (!(png_ptr
->chunk_name
[0] & 0x20))
2277 if (png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2278 PNG_HANDLE_CHUNK_ALWAYS
)
2279 png_chunk_error(png_ptr
, "unknown critical chunk");
2280 png_set_unknown_chunks(png_ptr
, info_ptr
,
2281 &png_ptr
->unknown_chunk
, 1);
2286 png_set_unknown_chunks(png_ptr
, info_ptr
, &png_ptr
->unknown_chunk
, 1);
2287 png_free(png_ptr
, png_ptr
->unknown_chunk
.data
);
2288 png_ptr
->unknown_chunk
.data
= NULL
;
2294 png_crc_finish(png_ptr
, skip
);
2296 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2297 info_ptr
= info_ptr
; /* quiet compiler warnings about unused info_ptr */
2301 /* This function is called to verify that a chunk name is valid.
2302 This function can't have the "critical chunk check" incorporated
2303 into it, since in the future we will need to be able to call user
2304 functions to handle unknown critical chunks after we check that
2305 the chunk name itself is valid. */
2307 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2310 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
2312 png_debug(1, "in png_check_chunk_name");
2313 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
2314 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
2316 png_chunk_error(png_ptr
, "invalid chunk type");
2320 /* Combines the row recently read in with the existing pixels in the
2321 row. This routine takes care of alpha and transparency if requested.
2322 This routine also handles the two methods of progressive display
2323 of interlaced images, depending on the mask value.
2324 The mask value describes which pixels are to be combined with
2325 the row. The pattern always repeats every 8 pixels, so just 8
2326 bits are needed. A one indicates the pixel is to be combined,
2327 a zero indicates the pixel is to be skipped. This is in addition
2328 to any alpha or transparency value associated with the pixel. If
2329 you want all pixels to be combined, pass 0xff (255) in mask. */
2332 png_combine_row(png_structp png_ptr
, png_bytep row
, int mask
)
2334 png_debug(1, "in png_combine_row");
2337 png_memcpy(row
, png_ptr
->row_buf
+ 1,
2338 PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
, png_ptr
->width
));
2342 switch (png_ptr
->row_info
.pixel_depth
)
2346 png_bytep sp
= png_ptr
->row_buf
+ 1;
2348 int s_inc
, s_start
, s_end
;
2352 png_uint_32 row_width
= png_ptr
->width
;
2354 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2355 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2371 for (i
= 0; i
< row_width
; i
++)
2377 value
= (*sp
>> shift
) & 0x01;
2378 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2379 *dp
|= (png_byte
)(value
<< shift
);
2400 png_bytep sp
= png_ptr
->row_buf
+ 1;
2402 int s_start
, s_end
, s_inc
;
2406 png_uint_32 row_width
= png_ptr
->width
;
2409 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2410 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2426 for (i
= 0; i
< row_width
; i
++)
2430 value
= (*sp
>> shift
) & 0x03;
2431 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2432 *dp
|= (png_byte
)(value
<< shift
);
2452 png_bytep sp
= png_ptr
->row_buf
+ 1;
2454 int s_start
, s_end
, s_inc
;
2458 png_uint_32 row_width
= png_ptr
->width
;
2461 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2462 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2477 for (i
= 0; i
< row_width
; i
++)
2481 value
= (*sp
>> shift
) & 0xf;
2482 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2483 *dp
|= (png_byte
)(value
<< shift
);
2503 png_bytep sp
= png_ptr
->row_buf
+ 1;
2505 png_size_t pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
2507 png_uint_32 row_width
= png_ptr
->width
;
2511 for (i
= 0; i
< row_width
; i
++)
2515 png_memcpy(dp
, sp
, pixel_bytes
);
2532 #ifdef PNG_READ_INTERLACING_SUPPORTED
2533 /* OLD pre-1.0.9 interface:
2534 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2535 png_uint_32 transformations)
2538 png_do_read_interlace(png_structp png_ptr
)
2540 png_row_infop row_info
= &(png_ptr
->row_info
);
2541 png_bytep row
= png_ptr
->row_buf
+ 1;
2542 int pass
= png_ptr
->pass
;
2543 png_uint_32 transformations
= png_ptr
->transformations
;
2544 #ifdef PNG_USE_LOCAL_ARRAYS
2545 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2546 /* offset to next interlace block */
2547 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2550 png_debug(1, "in png_do_read_interlace");
2551 if (row
!= NULL
&& row_info
!= NULL
)
2553 png_uint_32 final_width
;
2555 final_width
= row_info
->width
* png_pass_inc
[pass
];
2557 switch (row_info
->pixel_depth
)
2561 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2562 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
2564 int s_start
, s_end
, s_inc
;
2565 int jstop
= png_pass_inc
[pass
];
2570 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2571 if (transformations
& PNG_PACKSWAP
)
2573 sshift
= (int)((row_info
->width
+ 7) & 0x07);
2574 dshift
= (int)((final_width
+ 7) & 0x07);
2582 sshift
= 7 - (int)((row_info
->width
+ 7) & 0x07);
2583 dshift
= 7 - (int)((final_width
+ 7) & 0x07);
2589 for (i
= 0; i
< row_info
->width
; i
++)
2591 v
= (png_byte
)((*sp
>> sshift
) & 0x01);
2592 for (j
= 0; j
< jstop
; j
++)
2594 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
2595 *dp
|= (png_byte
)(v
<< dshift
);
2596 if (dshift
== s_end
)
2604 if (sshift
== s_end
)
2616 png_bytep sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
2617 png_bytep dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
2619 int s_start
, s_end
, s_inc
;
2620 int jstop
= png_pass_inc
[pass
];
2623 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2624 if (transformations
& PNG_PACKSWAP
)
2626 sshift
= (int)(((row_info
->width
+ 3) & 0x03) << 1);
2627 dshift
= (int)(((final_width
+ 3) & 0x03) << 1);
2635 sshift
= (int)((3 - ((row_info
->width
+ 3) & 0x03)) << 1);
2636 dshift
= (int)((3 - ((final_width
+ 3) & 0x03)) << 1);
2642 for (i
= 0; i
< row_info
->width
; i
++)
2647 v
= (png_byte
)((*sp
>> sshift
) & 0x03);
2648 for (j
= 0; j
< jstop
; j
++)
2650 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
2651 *dp
|= (png_byte
)(v
<< dshift
);
2652 if (dshift
== s_end
)
2660 if (sshift
== s_end
)
2672 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2673 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
2675 int s_start
, s_end
, s_inc
;
2677 int jstop
= png_pass_inc
[pass
];
2679 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2680 if (transformations
& PNG_PACKSWAP
)
2682 sshift
= (int)(((row_info
->width
+ 1) & 0x01) << 2);
2683 dshift
= (int)(((final_width
+ 1) & 0x01) << 2);
2691 sshift
= (int)((1 - ((row_info
->width
+ 1) & 0x01)) << 2);
2692 dshift
= (int)((1 - ((final_width
+ 1) & 0x01)) << 2);
2698 for (i
= 0; i
< row_info
->width
; i
++)
2700 png_byte v
= (png_byte
)((*sp
>> sshift
) & 0xf);
2703 for (j
= 0; j
< jstop
; j
++)
2705 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
2706 *dp
|= (png_byte
)(v
<< dshift
);
2707 if (dshift
== s_end
)
2715 if (sshift
== s_end
)
2727 png_size_t pixel_bytes
= (row_info
->pixel_depth
>> 3);
2728 png_bytep sp
= row
+ (png_size_t
)(row_info
->width
- 1) * pixel_bytes
;
2729 png_bytep dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
2731 int jstop
= png_pass_inc
[pass
];
2734 for (i
= 0; i
< row_info
->width
; i
++)
2739 png_memcpy(v
, sp
, pixel_bytes
);
2740 for (j
= 0; j
< jstop
; j
++)
2742 png_memcpy(dp
, v
, pixel_bytes
);
2750 row_info
->width
= final_width
;
2751 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, final_width
);
2753 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2754 transformations
= transformations
; /* silence compiler warning */
2757 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2760 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
2761 png_bytep prev_row
, int filter
)
2763 png_debug(1, "in png_read_filter_row");
2764 png_debug2(2, "row = %lu, filter = %d", png_ptr
->row_number
, filter
);
2767 case PNG_FILTER_VALUE_NONE
:
2769 case PNG_FILTER_VALUE_SUB
:
2772 png_uint_32 istop
= row_info
->rowbytes
;
2773 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2774 png_bytep rp
= row
+ bpp
;
2777 for (i
= bpp
; i
< istop
; i
++)
2779 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
++)) & 0xff);
2784 case PNG_FILTER_VALUE_UP
:
2787 png_uint_32 istop
= row_info
->rowbytes
;
2789 png_bytep pp
= prev_row
;
2791 for (i
= 0; i
< istop
; i
++)
2793 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2798 case PNG_FILTER_VALUE_AVG
:
2802 png_bytep pp
= prev_row
;
2804 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2805 png_uint_32 istop
= row_info
->rowbytes
- bpp
;
2807 for (i
= 0; i
< bpp
; i
++)
2809 *rp
= (png_byte
)(((int)(*rp
) +
2810 ((int)(*pp
++) / 2 )) & 0xff);
2814 for (i
= 0; i
< istop
; i
++)
2816 *rp
= (png_byte
)(((int)(*rp
) +
2817 (int)(*pp
++ + *lp
++) / 2 ) & 0xff);
2822 case PNG_FILTER_VALUE_PAETH
:
2826 png_bytep pp
= prev_row
;
2828 png_bytep cp
= prev_row
;
2829 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2830 png_uint_32 istop
=row_info
->rowbytes
- bpp
;
2832 for (i
= 0; i
< bpp
; i
++)
2834 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2838 for (i
= 0; i
< istop
; i
++) /* use leftover rp,pp */
2840 int a
, b
, c
, pa
, pb
, pc
, p
;
2854 pa
= p
< 0 ? -p
: p
;
2855 pb
= pc
< 0 ? -pc
: pc
;
2856 pc
= (p
+ pc
) < 0 ? -(p
+ pc
) : p
+ pc
;
2860 if (pa <= pb && pa <= pc)
2868 p
= (pa
<= pb
&& pa
<= pc
) ? a
: (pb
<= pc
) ? b
: c
;
2870 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
2876 png_warning(png_ptr
, "Ignoring bad adaptive filter type");
2883 png_read_finish_row(png_structp png_ptr
)
2885 #ifdef PNG_USE_LOCAL_ARRAYS
2886 #ifdef PNG_READ_INTERLACING_SUPPORTED
2887 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2889 /* start of interlace block */
2890 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2892 /* offset to next interlace block */
2893 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2895 /* start of interlace block in the y direction */
2896 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2898 /* offset to next interlace block in the y direction */
2899 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2900 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2903 png_debug(1, "in png_read_finish_row");
2904 png_ptr
->row_number
++;
2905 if (png_ptr
->row_number
< png_ptr
->num_rows
)
2908 #ifdef PNG_READ_INTERLACING_SUPPORTED
2909 if (png_ptr
->interlaced
)
2911 png_ptr
->row_number
= 0;
2912 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0,
2913 png_ptr
->rowbytes
+ 1);
2917 if (png_ptr
->pass
>= 7)
2919 png_ptr
->iwidth
= (png_ptr
->width
+
2920 png_pass_inc
[png_ptr
->pass
] - 1 -
2921 png_pass_start
[png_ptr
->pass
]) /
2922 png_pass_inc
[png_ptr
->pass
];
2924 png_ptr
->irowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,
2925 png_ptr
->iwidth
) + 1;
2927 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2929 png_ptr
->num_rows
= (png_ptr
->height
+
2930 png_pass_yinc
[png_ptr
->pass
] - 1 -
2931 png_pass_ystart
[png_ptr
->pass
]) /
2932 png_pass_yinc
[png_ptr
->pass
];
2933 if (!(png_ptr
->num_rows
))
2936 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2938 } while (png_ptr
->iwidth
== 0);
2940 if (png_ptr
->pass
< 7)
2943 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2945 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
2947 #ifdef PNG_USE_LOCAL_ARRAYS
2953 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
2954 png_ptr
->zstream
.avail_out
= (uInt
)1;
2957 if (!(png_ptr
->zstream
.avail_in
))
2959 while (!png_ptr
->idat_size
)
2961 png_byte chunk_length
[4];
2963 png_crc_finish(png_ptr
, 0);
2965 png_read_data(png_ptr
, chunk_length
, 4);
2966 png_ptr
->idat_size
= png_get_uint_31(png_ptr
, chunk_length
);
2967 png_reset_crc(png_ptr
);
2968 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
2969 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4))
2970 png_error(png_ptr
, "Not enough image data");
2973 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
2974 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
2975 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
2976 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
2977 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
2978 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
2980 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
2981 if (ret
== Z_STREAM_END
)
2983 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
2985 png_warning(png_ptr
, "Extra compressed data");
2986 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2987 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2991 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
2992 "Decompression Error");
2994 if (!(png_ptr
->zstream
.avail_out
))
2996 png_warning(png_ptr
, "Extra compressed data.");
2997 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2998 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
3003 png_ptr
->zstream
.avail_out
= 0;
3006 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
3007 png_warning(png_ptr
, "Extra compression data");
3009 inflateReset(&png_ptr
->zstream
);
3011 png_ptr
->mode
|= PNG_AFTER_IDAT
;
3015 png_read_start_row(png_structp png_ptr
)
3017 #ifdef PNG_USE_LOCAL_ARRAYS
3018 #ifdef PNG_READ_INTERLACING_SUPPORTED
3019 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3021 /* start of interlace block */
3022 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
3024 /* offset to next interlace block */
3025 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
3027 /* start of interlace block in the y direction */
3028 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
3030 /* offset to next interlace block in the y direction */
3031 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
3035 int max_pixel_depth
;
3036 png_size_t row_bytes
;
3038 png_debug(1, "in png_read_start_row");
3039 png_ptr
->zstream
.avail_in
= 0;
3040 png_init_read_transformations(png_ptr
);
3041 #ifdef PNG_READ_INTERLACING_SUPPORTED
3042 if (png_ptr
->interlaced
)
3044 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
3045 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
3046 png_pass_ystart
[0]) / png_pass_yinc
[0];
3048 png_ptr
->num_rows
= png_ptr
->height
;
3050 png_ptr
->iwidth
= (png_ptr
->width
+
3051 png_pass_inc
[png_ptr
->pass
] - 1 -
3052 png_pass_start
[png_ptr
->pass
]) /
3053 png_pass_inc
[png_ptr
->pass
];
3055 png_ptr
->irowbytes
=
3056 PNG_ROWBYTES(png_ptr
->pixel_depth
, png_ptr
->iwidth
) + 1;
3059 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3061 png_ptr
->num_rows
= png_ptr
->height
;
3062 png_ptr
->iwidth
= png_ptr
->width
;
3063 png_ptr
->irowbytes
= png_ptr
->rowbytes
+ 1;
3065 max_pixel_depth
= png_ptr
->pixel_depth
;
3067 #if defined(PNG_READ_PACK_SUPPORTED)
3068 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
3069 max_pixel_depth
= 8;
3072 #if defined(PNG_READ_EXPAND_SUPPORTED)
3073 if (png_ptr
->transformations
& PNG_EXPAND
)
3075 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3077 if (png_ptr
->num_trans
)
3078 max_pixel_depth
= 32;
3080 max_pixel_depth
= 24;
3082 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3084 if (max_pixel_depth
< 8)
3085 max_pixel_depth
= 8;
3086 if (png_ptr
->num_trans
)
3087 max_pixel_depth
*= 2;
3089 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3091 if (png_ptr
->num_trans
)
3093 max_pixel_depth
*= 4;
3094 max_pixel_depth
/= 3;
3100 #if defined(PNG_READ_FILLER_SUPPORTED)
3101 if (png_ptr
->transformations
& (PNG_FILLER
))
3103 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3104 max_pixel_depth
= 32;
3105 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3107 if (max_pixel_depth
<= 8)
3108 max_pixel_depth
= 16;
3110 max_pixel_depth
= 32;
3112 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3114 if (max_pixel_depth
<= 32)
3115 max_pixel_depth
= 32;
3117 max_pixel_depth
= 64;
3122 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3123 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
3126 #if defined(PNG_READ_EXPAND_SUPPORTED)
3127 (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
3129 #if defined(PNG_READ_FILLER_SUPPORTED)
3130 (png_ptr
->transformations
& (PNG_FILLER
)) ||
3132 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
3134 if (max_pixel_depth
<= 16)
3135 max_pixel_depth
= 32;
3137 max_pixel_depth
= 64;
3141 if (max_pixel_depth
<= 8)
3143 if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3144 max_pixel_depth
= 32;
3146 max_pixel_depth
= 24;
3148 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3149 max_pixel_depth
= 64;
3151 max_pixel_depth
= 48;
3156 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3157 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3158 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
3160 int user_pixel_depth
= png_ptr
->user_transform_depth
*
3161 png_ptr
->user_transform_channels
;
3162 if (user_pixel_depth
> max_pixel_depth
)
3163 max_pixel_depth
=user_pixel_depth
;
3167 /* align the width on the next larger 8 pixels. Mainly used
3169 row_bytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
3170 /* calculate the maximum bytes needed, adding a byte and a pixel
3171 for safety's sake */
3172 row_bytes
= PNG_ROWBYTES(max_pixel_depth
, row_bytes
) +
3173 1 + ((max_pixel_depth
+ 7) >> 3);
3174 #ifdef PNG_MAX_MALLOC_64K
3175 if (row_bytes
> (png_uint_32
)65536L)
3176 png_error(png_ptr
, "This image requires a row greater than 64KB");
3179 if (row_bytes
+ 64 > png_ptr
->old_big_row_buf_size
)
3181 png_free(png_ptr
, png_ptr
->big_row_buf
);
3182 png_ptr
->big_row_buf
= (png_bytep
)png_malloc(png_ptr
, row_bytes
+64);
3183 png_ptr
->row_buf
= png_ptr
->big_row_buf
+32;
3184 png_ptr
->old_big_row_buf_size
= row_bytes
+64;
3187 #ifdef PNG_MAX_MALLOC_64K
3188 if ((png_uint_32
)png_ptr
->rowbytes
+ 1 > (png_uint_32
)65536L)
3189 png_error(png_ptr
, "This image requires a row greater than 64KB");
3191 if ((png_uint_32
)png_ptr
->rowbytes
> (png_uint_32
)(PNG_SIZE_MAX
- 1))
3192 png_error(png_ptr
, "Row has too many bytes to allocate in memory.");
3194 if (png_ptr
->rowbytes
+1 > png_ptr
->old_prev_row_size
)
3196 png_free(png_ptr
, png_ptr
->prev_row
);
3197 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
3198 png_ptr
->rowbytes
+ 1));
3199 png_ptr
->old_prev_row_size
= png_ptr
->rowbytes
+1;
3202 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
3204 png_debug1(3, "width = %lu,", png_ptr
->width
);
3205 png_debug1(3, "height = %lu,", png_ptr
->height
);
3206 png_debug1(3, "iwidth = %lu,", png_ptr
->iwidth
);
3207 png_debug1(3, "num_rows = %lu", png_ptr
->num_rows
);
3208 png_debug1(3, "rowbytes = %lu,", png_ptr
->rowbytes
);
3209 png_debug1(3, "irowbytes = %lu,", png_ptr
->irowbytes
);
3211 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;
3213 #endif /* PNG_READ_SUPPORTED */