2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.37 [June 4, 2009]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2009 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 /* The 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.
82 png_get_int_32(png_bytep buf
)
84 png_int_32 i
= ((png_int_32
)(*buf
) << 24) +
85 ((png_int_32
)(*(buf
+ 1)) << 16) +
86 ((png_int_32
)(*(buf
+ 2)) << 8) +
87 (png_int_32
)(*(buf
+ 3));
92 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
94 png_get_uint_16(png_bytep buf
)
96 png_uint_16 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
97 (png_uint_16
)(*(buf
+ 1)));
101 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
103 /* Read the chunk header (length + type name).
104 * Put the type name into png_ptr->chunk_name, and return the length.
106 png_uint_32
/* PRIVATE */
107 png_read_chunk_header(png_structp png_ptr
)
112 /* Read the length and the chunk name */
113 png_read_data(png_ptr
, buf
, 8);
114 length
= png_get_uint_31(png_ptr
, buf
);
116 /* Put the chunk name into png_ptr->chunk_name */
117 png_memcpy(png_ptr
->chunk_name
, buf
+ 4, 4);
119 png_debug2(0, "Reading %s chunk, length = %lu",
120 png_ptr
->chunk_name
, length
);
122 /* Reset the crc and run it over the chunk name */
123 png_reset_crc(png_ptr
);
124 png_calculate_crc(png_ptr
, png_ptr
->chunk_name
, 4);
126 /* Check to see if chunk name is valid */
127 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
132 /* Read data, and (optionally) run it through the CRC. */
134 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
138 png_read_data(png_ptr
, buf
, length
);
139 png_calculate_crc(png_ptr
, buf
, length
);
142 /* Optionally skip data and then check the CRC. Depending on whether we
143 * are reading a ancillary or critical chunk, and how the program has set
144 * things up, we may calculate the CRC on the data and print a message.
145 * Returns '1' if there was a CRC error, '0' otherwise.
148 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
151 png_size_t istop
= png_ptr
->zbuf_size
;
153 for (i
= (png_size_t
)skip
; i
> istop
; i
-= istop
)
155 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
159 png_crc_read(png_ptr
, png_ptr
->zbuf
, i
);
162 if (png_crc_error(png_ptr
))
164 if (((png_ptr
->chunk_name
[0] & 0x20) && /* Ancillary */
165 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
166 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
167 (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
)))
169 png_chunk_warning(png_ptr
, "CRC error");
173 png_chunk_error(png_ptr
, "CRC error");
181 /* Compare the CRC stored in the PNG file with that calculated by libpng from
182 * the data it has read thus far.
185 png_crc_error(png_structp png_ptr
)
187 png_byte crc_bytes
[4];
191 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
193 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
194 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
199 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
203 png_read_data(png_ptr
, crc_bytes
, 4);
207 crc
= png_get_uint_32(crc_bytes
);
208 return ((int)(crc
!= png_ptr
->crc
));
214 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
215 defined(PNG_READ_iCCP_SUPPORTED)
217 * Decompress trailing data in a chunk. The assumption is that chunkdata
218 * points at an allocated area holding the contents of a chunk with a
219 * trailing compressed part. What we get back is an allocated area
220 * holding the original prefix part and an uncompressed version of the
221 * trailing part (the malloc area passed in is freed).
224 png_decompress_chunk(png_structp png_ptr
, int comp_type
,
225 png_size_t chunklength
,
226 png_size_t prefix_size
, png_size_t
*newlength
)
228 static PNG_CONST
char msg
[] = "Error decoding compressed text";
230 png_size_t text_size
;
232 if (comp_type
== PNG_COMPRESSION_TYPE_BASE
)
235 png_ptr
->zstream
.next_in
= (png_bytep
)(png_ptr
->chunkdata
+ prefix_size
);
236 png_ptr
->zstream
.avail_in
= (uInt
)(chunklength
- prefix_size
);
237 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
238 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
243 while (png_ptr
->zstream
.avail_in
)
245 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
246 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
)
248 if (png_ptr
->zstream
.msg
!= NULL
)
249 png_warning(png_ptr
, png_ptr
->zstream
.msg
);
251 png_warning(png_ptr
, msg
);
252 inflateReset(&png_ptr
->zstream
);
253 png_ptr
->zstream
.avail_in
= 0;
257 text_size
= prefix_size
+ png_sizeof(msg
) + 1;
258 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
);
261 png_free(png_ptr
, png_ptr
->chunkdata
);
262 png_ptr
->chunkdata
= NULL
;
263 png_error(png_ptr
, "Not enough memory to decompress chunk");
265 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
268 text
[text_size
- 1] = 0x00;
270 /* Copy what we can of the error message into the text chunk */
271 text_size
= (png_size_t
)(chunklength
-
272 (text
- png_ptr
->chunkdata
) - 1);
273 if (text_size
> png_sizeof(msg
))
274 text_size
= png_sizeof(msg
);
275 png_memcpy(text
+ prefix_size
, msg
, text_size
);
278 if (!png_ptr
->zstream
.avail_out
|| ret
== Z_STREAM_END
)
282 text_size
= prefix_size
+
283 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
284 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+ 1);
287 png_free(png_ptr
, png_ptr
->chunkdata
);
288 png_ptr
->chunkdata
= NULL
;
290 "Not enough memory to decompress chunk.");
292 png_memcpy(text
+ prefix_size
, png_ptr
->zbuf
,
293 text_size
- prefix_size
);
294 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
295 *(text
+ text_size
) = 0x00;
302 text
= (png_charp
)png_malloc_warn(png_ptr
,
303 (png_uint_32
)(text_size
+
304 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
+ 1));
307 png_free(png_ptr
, tmp
);
308 png_free(png_ptr
, png_ptr
->chunkdata
);
309 png_ptr
->chunkdata
= NULL
;
311 "Not enough memory to decompress chunk..");
313 png_memcpy(text
, tmp
, text_size
);
314 png_free(png_ptr
, tmp
);
315 png_memcpy(text
+ text_size
, png_ptr
->zbuf
,
316 (png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
));
317 text_size
+= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
318 *(text
+ text_size
) = 0x00;
320 if (ret
== Z_STREAM_END
)
324 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
325 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
329 if (ret
!= Z_STREAM_END
)
331 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
334 if (ret
== Z_BUF_ERROR
)
335 png_snprintf(umsg
, 52,
336 "Buffer error in compressed datastream in %s chunk",
337 png_ptr
->chunk_name
);
339 else if (ret
== Z_DATA_ERROR
)
340 png_snprintf(umsg
, 52,
341 "Data error in compressed datastream in %s chunk",
342 png_ptr
->chunk_name
);
345 png_snprintf(umsg
, 52,
346 "Incomplete compressed datastream in %s chunk",
347 png_ptr
->chunk_name
);
349 png_warning(png_ptr
, umsg
);
352 "Incomplete compressed datastream in chunk other than IDAT");
354 text_size
= prefix_size
;
357 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+1);
360 png_free(png_ptr
, png_ptr
->chunkdata
);
361 png_ptr
->chunkdata
= NULL
;
362 png_error(png_ptr
, "Not enough memory for text.");
364 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
366 *(text
+ text_size
) = 0x00;
369 inflateReset(&png_ptr
->zstream
);
370 png_ptr
->zstream
.avail_in
= 0;
372 png_free(png_ptr
, png_ptr
->chunkdata
);
373 png_ptr
->chunkdata
= text
;
374 *newlength
=text_size
;
376 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
378 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
381 png_snprintf(umsg
, 50, "Unknown zTXt compression type %d", comp_type
);
382 png_warning(png_ptr
, umsg
);
384 png_warning(png_ptr
, "Unknown zTXt compression type");
387 *(png_ptr
->chunkdata
+ prefix_size
) = 0x00;
388 *newlength
= prefix_size
;
393 /* Read and check the IDHR chunk */
395 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
398 png_uint_32 width
, height
;
399 int bit_depth
, color_type
, compression_type
, filter_type
;
402 png_debug(1, "in png_handle_IHDR");
404 if (png_ptr
->mode
& PNG_HAVE_IHDR
)
405 png_error(png_ptr
, "Out of place IHDR");
407 /* Check the length */
409 png_error(png_ptr
, "Invalid IHDR chunk");
411 png_ptr
->mode
|= PNG_HAVE_IHDR
;
413 png_crc_read(png_ptr
, buf
, 13);
414 png_crc_finish(png_ptr
, 0);
416 width
= png_get_uint_31(png_ptr
, buf
);
417 height
= png_get_uint_31(png_ptr
, buf
+ 4);
420 compression_type
= buf
[10];
421 filter_type
= buf
[11];
422 interlace_type
= buf
[12];
424 /* Set internal variables */
425 png_ptr
->width
= width
;
426 png_ptr
->height
= height
;
427 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
428 png_ptr
->interlaced
= (png_byte
)interlace_type
;
429 png_ptr
->color_type
= (png_byte
)color_type
;
430 #if defined(PNG_MNG_FEATURES_SUPPORTED)
431 png_ptr
->filter_type
= (png_byte
)filter_type
;
433 png_ptr
->compression_type
= (png_byte
)compression_type
;
435 /* Find number of channels */
436 switch (png_ptr
->color_type
)
438 case PNG_COLOR_TYPE_GRAY
:
439 case PNG_COLOR_TYPE_PALETTE
:
440 png_ptr
->channels
= 1;
443 case PNG_COLOR_TYPE_RGB
:
444 png_ptr
->channels
= 3;
447 case PNG_COLOR_TYPE_GRAY_ALPHA
:
448 png_ptr
->channels
= 2;
451 case PNG_COLOR_TYPE_RGB_ALPHA
:
452 png_ptr
->channels
= 4;
456 /* Set up other useful info */
457 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
459 png_ptr
->rowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
, png_ptr
->width
);
460 png_debug1(3, "bit_depth = %d", png_ptr
->bit_depth
);
461 png_debug1(3, "channels = %d", png_ptr
->channels
);
462 png_debug1(3, "rowbytes = %lu", png_ptr
->rowbytes
);
463 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
464 color_type
, interlace_type
, compression_type
, filter_type
);
467 /* Read and check the palette */
469 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
471 png_color palette
[PNG_MAX_PALETTE_LENGTH
];
473 #ifndef PNG_NO_POINTER_INDEXING
477 png_debug(1, "in png_handle_PLTE");
479 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
480 png_error(png_ptr
, "Missing IHDR before PLTE");
482 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
484 png_warning(png_ptr
, "Invalid PLTE after IDAT");
485 png_crc_finish(png_ptr
, length
);
489 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
490 png_error(png_ptr
, "Duplicate PLTE chunk");
492 png_ptr
->mode
|= PNG_HAVE_PLTE
;
494 if (!(png_ptr
->color_type
&PNG_COLOR_MASK_COLOR
))
497 "Ignoring PLTE chunk in grayscale PNG");
498 png_crc_finish(png_ptr
, length
);
501 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
502 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
504 png_crc_finish(png_ptr
, length
);
509 if (length
> 3*PNG_MAX_PALETTE_LENGTH
|| length
% 3)
511 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
513 png_warning(png_ptr
, "Invalid palette chunk");
514 png_crc_finish(png_ptr
, length
);
520 png_error(png_ptr
, "Invalid palette chunk");
524 num
= (int)length
/ 3;
526 #ifndef PNG_NO_POINTER_INDEXING
527 for (i
= 0, pal_ptr
= palette
; i
< num
; i
++, pal_ptr
++)
531 png_crc_read(png_ptr
, buf
, 3);
532 pal_ptr
->red
= buf
[0];
533 pal_ptr
->green
= buf
[1];
534 pal_ptr
->blue
= buf
[2];
537 for (i
= 0; i
< num
; i
++)
541 png_crc_read(png_ptr
, buf
, 3);
542 /* Don't depend upon png_color being any order */
543 palette
[i
].red
= buf
[0];
544 palette
[i
].green
= buf
[1];
545 palette
[i
].blue
= buf
[2];
549 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
550 * whatever the normal CRC configuration tells us. However, if we
551 * have an RGB image, the PLTE can be considered ancillary, so
552 * we will act as though it is.
554 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
555 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
558 png_crc_finish(png_ptr
, 0);
560 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
561 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
563 /* If we don't want to use the data from an ancillary chunk,
564 we have two options: an error abort, or a warning and we
565 ignore the data in this chunk (which should be OK, since
566 it's considered ancillary for a RGB or RGBA image). */
567 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
569 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
571 png_chunk_error(png_ptr
, "CRC error");
575 png_chunk_warning(png_ptr
, "CRC error");
579 /* Otherwise, we (optionally) emit a warning and use the chunk. */
580 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
582 png_chunk_warning(png_ptr
, "CRC error");
587 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
589 #if defined(PNG_READ_tRNS_SUPPORTED)
590 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
592 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
594 if (png_ptr
->num_trans
> (png_uint_16
)num
)
596 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
597 png_ptr
->num_trans
= (png_uint_16
)num
;
599 if (info_ptr
->num_trans
> (png_uint_16
)num
)
601 png_warning(png_ptr
, "Truncating incorrect info tRNS chunk length");
602 info_ptr
->num_trans
= (png_uint_16
)num
;
611 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
613 png_debug(1, "in png_handle_IEND");
615 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
617 png_error(png_ptr
, "No image in file");
620 png_ptr
->mode
|= (PNG_AFTER_IDAT
| PNG_HAVE_IEND
);
624 png_warning(png_ptr
, "Incorrect IEND chunk length");
626 png_crc_finish(png_ptr
, length
);
628 info_ptr
= info_ptr
; /* Quiet compiler warnings about unused info_ptr */
631 #if defined(PNG_READ_gAMA_SUPPORTED)
633 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
635 png_fixed_point igamma
;
636 #ifdef PNG_FLOATING_POINT_SUPPORTED
641 png_debug(1, "in png_handle_gAMA");
643 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
644 png_error(png_ptr
, "Missing IHDR before gAMA");
645 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
647 png_warning(png_ptr
, "Invalid gAMA after IDAT");
648 png_crc_finish(png_ptr
, length
);
651 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
652 /* Should be an error, but we can cope with it */
653 png_warning(png_ptr
, "Out of place gAMA chunk");
655 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
)
656 #if defined(PNG_READ_sRGB_SUPPORTED)
657 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
661 png_warning(png_ptr
, "Duplicate gAMA chunk");
662 png_crc_finish(png_ptr
, length
);
668 png_warning(png_ptr
, "Incorrect gAMA chunk length");
669 png_crc_finish(png_ptr
, length
);
673 png_crc_read(png_ptr
, buf
, 4);
674 if (png_crc_finish(png_ptr
, 0))
677 igamma
= (png_fixed_point
)png_get_uint_32(buf
);
678 /* Check for zero gamma */
682 "Ignoring gAMA chunk with gamma=0");
686 #if defined(PNG_READ_sRGB_SUPPORTED)
687 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
688 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
691 "Ignoring incorrect gAMA value when sRGB is also present");
692 #ifndef PNG_NO_CONSOLE_IO
693 fprintf(stderr
, "gamma = (%d/100000)", (int)igamma
);
697 #endif /* PNG_READ_sRGB_SUPPORTED */
699 #ifdef PNG_FLOATING_POINT_SUPPORTED
700 file_gamma
= (float)igamma
/ (float)100000.0;
701 # ifdef PNG_READ_GAMMA_SUPPORTED
702 png_ptr
->gamma
= file_gamma
;
704 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
706 #ifdef PNG_FIXED_POINT_SUPPORTED
707 png_set_gAMA_fixed(png_ptr
, info_ptr
, igamma
);
712 #if defined(PNG_READ_sBIT_SUPPORTED)
714 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
719 png_debug(1, "in png_handle_sBIT");
721 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
723 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
724 png_error(png_ptr
, "Missing IHDR before sBIT");
725 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
727 png_warning(png_ptr
, "Invalid sBIT after IDAT");
728 png_crc_finish(png_ptr
, length
);
731 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
733 /* Should be an error, but we can cope with it */
734 png_warning(png_ptr
, "Out of place sBIT chunk");
736 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sBIT
))
738 png_warning(png_ptr
, "Duplicate sBIT chunk");
739 png_crc_finish(png_ptr
, length
);
743 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
746 truelen
= (png_size_t
)png_ptr
->channels
;
748 if (length
!= truelen
|| length
> 4)
750 png_warning(png_ptr
, "Incorrect sBIT chunk length");
751 png_crc_finish(png_ptr
, length
);
755 png_crc_read(png_ptr
, buf
, truelen
);
756 if (png_crc_finish(png_ptr
, 0))
759 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
761 png_ptr
->sig_bit
.red
= buf
[0];
762 png_ptr
->sig_bit
.green
= buf
[1];
763 png_ptr
->sig_bit
.blue
= buf
[2];
764 png_ptr
->sig_bit
.alpha
= buf
[3];
768 png_ptr
->sig_bit
.gray
= buf
[0];
769 png_ptr
->sig_bit
.red
= buf
[0];
770 png_ptr
->sig_bit
.green
= buf
[0];
771 png_ptr
->sig_bit
.blue
= buf
[0];
772 png_ptr
->sig_bit
.alpha
= buf
[1];
774 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
778 #if defined(PNG_READ_cHRM_SUPPORTED)
780 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
783 #ifdef PNG_FLOATING_POINT_SUPPORTED
784 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
786 png_fixed_point int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
787 int_y_green
, int_x_blue
, int_y_blue
;
789 png_uint_32 uint_x
, uint_y
;
791 png_debug(1, "in png_handle_cHRM");
793 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
794 png_error(png_ptr
, "Missing IHDR before cHRM");
795 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
797 png_warning(png_ptr
, "Invalid cHRM after IDAT");
798 png_crc_finish(png_ptr
, length
);
801 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
802 /* Should be an error, but we can cope with it */
803 png_warning(png_ptr
, "Missing PLTE before cHRM");
805 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
)
806 #if defined(PNG_READ_sRGB_SUPPORTED)
807 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
811 png_warning(png_ptr
, "Duplicate cHRM chunk");
812 png_crc_finish(png_ptr
, length
);
818 png_warning(png_ptr
, "Incorrect cHRM chunk length");
819 png_crc_finish(png_ptr
, length
);
823 png_crc_read(png_ptr
, buf
, 32);
824 if (png_crc_finish(png_ptr
, 0))
827 uint_x
= png_get_uint_32(buf
);
828 uint_y
= png_get_uint_32(buf
+ 4);
829 int_x_white
= (png_fixed_point
)uint_x
;
830 int_y_white
= (png_fixed_point
)uint_y
;
832 uint_x
= png_get_uint_32(buf
+ 8);
833 uint_y
= png_get_uint_32(buf
+ 12);
834 int_x_red
= (png_fixed_point
)uint_x
;
835 int_y_red
= (png_fixed_point
)uint_y
;
837 uint_x
= png_get_uint_32(buf
+ 16);
838 uint_y
= png_get_uint_32(buf
+ 20);
839 int_x_green
= (png_fixed_point
)uint_x
;
840 int_y_green
= (png_fixed_point
)uint_y
;
842 uint_x
= png_get_uint_32(buf
+ 24);
843 uint_y
= png_get_uint_32(buf
+ 28);
844 int_x_blue
= (png_fixed_point
)uint_x
;
845 int_y_blue
= (png_fixed_point
)uint_y
;
847 #ifdef PNG_FLOATING_POINT_SUPPORTED
848 white_x
= (float)int_x_white
/ (float)100000.0;
849 white_y
= (float)int_y_white
/ (float)100000.0;
850 red_x
= (float)int_x_red
/ (float)100000.0;
851 red_y
= (float)int_y_red
/ (float)100000.0;
852 green_x
= (float)int_x_green
/ (float)100000.0;
853 green_y
= (float)int_y_green
/ (float)100000.0;
854 blue_x
= (float)int_x_blue
/ (float)100000.0;
855 blue_y
= (float)int_y_blue
/ (float)100000.0;
858 #if defined(PNG_READ_sRGB_SUPPORTED)
859 if ((info_ptr
!= NULL
) && (info_ptr
->valid
& PNG_INFO_sRGB
))
861 if (PNG_OUT_OF_RANGE(int_x_white
, 31270, 1000) ||
862 PNG_OUT_OF_RANGE(int_y_white
, 32900, 1000) ||
863 PNG_OUT_OF_RANGE(int_x_red
, 64000L, 1000) ||
864 PNG_OUT_OF_RANGE(int_y_red
, 33000, 1000) ||
865 PNG_OUT_OF_RANGE(int_x_green
, 30000, 1000) ||
866 PNG_OUT_OF_RANGE(int_y_green
, 60000L, 1000) ||
867 PNG_OUT_OF_RANGE(int_x_blue
, 15000, 1000) ||
868 PNG_OUT_OF_RANGE(int_y_blue
, 6000, 1000))
871 "Ignoring incorrect cHRM value when sRGB is also present");
872 #ifndef PNG_NO_CONSOLE_IO
873 #ifdef PNG_FLOATING_POINT_SUPPORTED
874 fprintf(stderr
, "wx=%f, wy=%f, rx=%f, ry=%f\n",
875 white_x
, white_y
, red_x
, red_y
);
876 fprintf(stderr
, "gx=%f, gy=%f, bx=%f, by=%f\n",
877 green_x
, green_y
, blue_x
, blue_y
);
879 fprintf(stderr
, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
880 int_x_white
, int_y_white
, int_x_red
, int_y_red
);
881 fprintf(stderr
, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
882 int_x_green
, int_y_green
, int_x_blue
, int_y_blue
);
884 #endif /* PNG_NO_CONSOLE_IO */
888 #endif /* PNG_READ_sRGB_SUPPORTED */
890 #ifdef PNG_FLOATING_POINT_SUPPORTED
891 png_set_cHRM(png_ptr
, info_ptr
,
892 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
894 #ifdef PNG_FIXED_POINT_SUPPORTED
895 png_set_cHRM_fixed(png_ptr
, info_ptr
,
896 int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
897 int_y_green
, int_x_blue
, int_y_blue
);
902 #if defined(PNG_READ_sRGB_SUPPORTED)
904 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
909 png_debug(1, "in png_handle_sRGB");
911 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
912 png_error(png_ptr
, "Missing IHDR before sRGB");
913 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
915 png_warning(png_ptr
, "Invalid sRGB after IDAT");
916 png_crc_finish(png_ptr
, length
);
919 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
920 /* Should be an error, but we can cope with it */
921 png_warning(png_ptr
, "Out of place sRGB chunk");
923 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
925 png_warning(png_ptr
, "Duplicate sRGB chunk");
926 png_crc_finish(png_ptr
, length
);
932 png_warning(png_ptr
, "Incorrect sRGB chunk length");
933 png_crc_finish(png_ptr
, length
);
937 png_crc_read(png_ptr
, buf
, 1);
938 if (png_crc_finish(png_ptr
, 0))
942 /* Check for bad intent */
943 if (intent
>= PNG_sRGB_INTENT_LAST
)
945 png_warning(png_ptr
, "Unknown sRGB intent");
949 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
950 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
))
952 png_fixed_point igamma
;
953 #ifdef PNG_FIXED_POINT_SUPPORTED
954 igamma
=info_ptr
->int_gamma
;
956 # ifdef PNG_FLOATING_POINT_SUPPORTED
957 igamma
=(png_fixed_point
)(info_ptr
->gamma
* 100000.);
960 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
963 "Ignoring incorrect gAMA value when sRGB is also present");
964 #ifndef PNG_NO_CONSOLE_IO
965 # ifdef PNG_FIXED_POINT_SUPPORTED
966 fprintf(stderr
, "incorrect gamma=(%d/100000)\n",
967 (int)png_ptr
->int_gamma
);
969 # ifdef PNG_FLOATING_POINT_SUPPORTED
970 fprintf(stderr
, "incorrect gamma=%f\n", png_ptr
->gamma
);
976 #endif /* PNG_READ_gAMA_SUPPORTED */
978 #ifdef PNG_READ_cHRM_SUPPORTED
979 #ifdef PNG_FIXED_POINT_SUPPORTED
980 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
))
981 if (PNG_OUT_OF_RANGE(info_ptr
->int_x_white
, 31270, 1000) ||
982 PNG_OUT_OF_RANGE(info_ptr
->int_y_white
, 32900, 1000) ||
983 PNG_OUT_OF_RANGE(info_ptr
->int_x_red
, 64000L, 1000) ||
984 PNG_OUT_OF_RANGE(info_ptr
->int_y_red
, 33000, 1000) ||
985 PNG_OUT_OF_RANGE(info_ptr
->int_x_green
, 30000, 1000) ||
986 PNG_OUT_OF_RANGE(info_ptr
->int_y_green
, 60000L, 1000) ||
987 PNG_OUT_OF_RANGE(info_ptr
->int_x_blue
, 15000, 1000) ||
988 PNG_OUT_OF_RANGE(info_ptr
->int_y_blue
, 6000, 1000))
991 "Ignoring incorrect cHRM value when sRGB is also present");
993 #endif /* PNG_FIXED_POINT_SUPPORTED */
994 #endif /* PNG_READ_cHRM_SUPPORTED */
996 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
998 #endif /* PNG_READ_sRGB_SUPPORTED */
1000 #if defined(PNG_READ_iCCP_SUPPORTED)
1002 png_handle_iCCP(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1003 /* Note: this does not properly handle chunks that are > 64K under DOS */
1005 png_byte compression_type
;
1008 png_uint_32 skip
= 0;
1009 png_uint_32 profile_size
, profile_length
;
1010 png_size_t slength
, prefix_length
, data_length
;
1012 png_debug(1, "in png_handle_iCCP");
1014 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1015 png_error(png_ptr
, "Missing IHDR before iCCP");
1016 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1018 png_warning(png_ptr
, "Invalid iCCP after IDAT");
1019 png_crc_finish(png_ptr
, length
);
1022 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
1023 /* Should be an error, but we can cope with it */
1024 png_warning(png_ptr
, "Out of place iCCP chunk");
1026 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_iCCP
))
1028 png_warning(png_ptr
, "Duplicate iCCP chunk");
1029 png_crc_finish(png_ptr
, length
);
1033 #ifdef PNG_MAX_MALLOC_64K
1034 if (length
> (png_uint_32
)65535L)
1036 png_warning(png_ptr
, "iCCP chunk too large to fit in memory");
1037 skip
= length
- (png_uint_32
)65535L;
1038 length
= (png_uint_32
)65535L;
1042 png_free(png_ptr
, png_ptr
->chunkdata
);
1043 png_ptr
->chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1044 slength
= (png_size_t
)length
;
1045 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1047 if (png_crc_finish(png_ptr
, skip
))
1049 png_free(png_ptr
, png_ptr
->chunkdata
);
1050 png_ptr
->chunkdata
= NULL
;
1054 png_ptr
->chunkdata
[slength
] = 0x00;
1056 for (profile
= png_ptr
->chunkdata
; *profile
; profile
++)
1057 /* Empty loop to find end of name */ ;
1061 /* There should be at least one zero (the compression type byte)
1062 * following the separator, and we should be on it
1064 if ( profile
>= png_ptr
->chunkdata
+ slength
- 1)
1066 png_free(png_ptr
, png_ptr
->chunkdata
);
1067 png_ptr
->chunkdata
= NULL
;
1068 png_warning(png_ptr
, "Malformed iCCP chunk");
1072 /* Compression_type should always be zero */
1073 compression_type
= *profile
++;
1074 if (compression_type
)
1076 png_warning(png_ptr
, "Ignoring nonzero compression type in iCCP chunk");
1077 compression_type
= 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1081 prefix_length
= profile
- png_ptr
->chunkdata
;
1082 png_decompress_chunk(png_ptr
, compression_type
,
1083 slength
, prefix_length
, &data_length
);
1085 profile_length
= data_length
- prefix_length
;
1087 if ( prefix_length
> data_length
|| profile_length
< 4)
1089 png_free(png_ptr
, png_ptr
->chunkdata
);
1090 png_ptr
->chunkdata
= NULL
;
1091 png_warning(png_ptr
, "Profile size field missing from iCCP chunk");
1095 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1096 pC
= (png_bytep
)(png_ptr
->chunkdata
+ prefix_length
);
1097 profile_size
= ((*(pC
))<<24) |
1102 if (profile_size
< profile_length
)
1103 profile_length
= profile_size
;
1105 if (profile_size
> profile_length
)
1107 png_free(png_ptr
, png_ptr
->chunkdata
);
1108 png_ptr
->chunkdata
= NULL
;
1109 png_warning(png_ptr
, "Ignoring truncated iCCP profile.");
1113 png_set_iCCP(png_ptr
, info_ptr
, png_ptr
->chunkdata
,
1114 compression_type
, png_ptr
->chunkdata
+ prefix_length
, profile_length
);
1115 png_free(png_ptr
, png_ptr
->chunkdata
);
1116 png_ptr
->chunkdata
= NULL
;
1118 #endif /* PNG_READ_iCCP_SUPPORTED */
1120 #if defined(PNG_READ_sPLT_SUPPORTED)
1122 png_handle_sPLT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1123 /* Note: this does not properly handle chunks that are > 64K under DOS */
1125 png_bytep entry_start
;
1126 png_sPLT_t new_palette
;
1127 #ifdef PNG_NO_POINTER_INDEXING
1130 int data_length
, entry_size
, i
;
1131 png_uint_32 skip
= 0;
1134 png_debug(1, "in png_handle_sPLT");
1137 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1138 png_error(png_ptr
, "Missing IHDR before sPLT");
1139 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1141 png_warning(png_ptr
, "Invalid sPLT after IDAT");
1142 png_crc_finish(png_ptr
, length
);
1146 #ifdef PNG_MAX_MALLOC_64K
1147 if (length
> (png_uint_32
)65535L)
1149 png_warning(png_ptr
, "sPLT chunk too large to fit in memory");
1150 skip
= length
- (png_uint_32
)65535L;
1151 length
= (png_uint_32
)65535L;
1155 png_free(png_ptr
, png_ptr
->chunkdata
);
1156 png_ptr
->chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1157 slength
= (png_size_t
)length
;
1158 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1160 if (png_crc_finish(png_ptr
, skip
))
1162 png_free(png_ptr
, png_ptr
->chunkdata
);
1163 png_ptr
->chunkdata
= NULL
;
1167 png_ptr
->chunkdata
[slength
] = 0x00;
1169 for (entry_start
= (png_bytep
)png_ptr
->chunkdata
; *entry_start
; entry_start
++)
1170 /* Empty loop to find end of name */ ;
1173 /* A sample depth should follow the separator, and we should be on it */
1174 if (entry_start
> (png_bytep
)png_ptr
->chunkdata
+ slength
- 2)
1176 png_free(png_ptr
, png_ptr
->chunkdata
);
1177 png_ptr
->chunkdata
= NULL
;
1178 png_warning(png_ptr
, "malformed sPLT chunk");
1182 new_palette
.depth
= *entry_start
++;
1183 entry_size
= (new_palette
.depth
== 8 ? 6 : 10);
1184 data_length
= (slength
- (entry_start
- (png_bytep
)png_ptr
->chunkdata
));
1186 /* Integrity-check the data length */
1187 if (data_length
% entry_size
)
1189 png_free(png_ptr
, png_ptr
->chunkdata
);
1190 png_ptr
->chunkdata
= NULL
;
1191 png_warning(png_ptr
, "sPLT chunk has bad length");
1195 new_palette
.nentries
= (png_int_32
) ( data_length
/ entry_size
);
1196 if ((png_uint_32
) new_palette
.nentries
>
1197 (png_uint_32
) (PNG_SIZE_MAX
/ png_sizeof(png_sPLT_entry
)))
1199 png_warning(png_ptr
, "sPLT chunk too long");
1202 new_palette
.entries
= (png_sPLT_entryp
)png_malloc_warn(
1203 png_ptr
, new_palette
.nentries
* png_sizeof(png_sPLT_entry
));
1204 if (new_palette
.entries
== NULL
)
1206 png_warning(png_ptr
, "sPLT chunk requires too much memory");
1210 #ifndef PNG_NO_POINTER_INDEXING
1211 for (i
= 0; i
< new_palette
.nentries
; i
++)
1213 png_sPLT_entryp pp
= new_palette
.entries
+ i
;
1215 if (new_palette
.depth
== 8)
1217 pp
->red
= *entry_start
++;
1218 pp
->green
= *entry_start
++;
1219 pp
->blue
= *entry_start
++;
1220 pp
->alpha
= *entry_start
++;
1224 pp
->red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1225 pp
->green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1226 pp
->blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1227 pp
->alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1229 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1232 pp
= new_palette
.entries
;
1233 for (i
= 0; i
< new_palette
.nentries
; i
++)
1236 if (new_palette
.depth
== 8)
1238 pp
[i
].red
= *entry_start
++;
1239 pp
[i
].green
= *entry_start
++;
1240 pp
[i
].blue
= *entry_start
++;
1241 pp
[i
].alpha
= *entry_start
++;
1245 pp
[i
].red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1246 pp
[i
].green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1247 pp
[i
].blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1248 pp
[i
].alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1250 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1254 /* Discard all chunk data except the name and stash that */
1255 new_palette
.name
= png_ptr
->chunkdata
;
1257 png_set_sPLT(png_ptr
, info_ptr
, &new_palette
, 1);
1259 png_free(png_ptr
, png_ptr
->chunkdata
);
1260 png_ptr
->chunkdata
= NULL
;
1261 png_free(png_ptr
, new_palette
.entries
);
1263 #endif /* PNG_READ_sPLT_SUPPORTED */
1265 #if defined(PNG_READ_tRNS_SUPPORTED)
1267 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1269 png_byte readbuf
[PNG_MAX_PALETTE_LENGTH
];
1271 png_debug(1, "in png_handle_tRNS");
1273 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1274 png_error(png_ptr
, "Missing IHDR before tRNS");
1275 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1277 png_warning(png_ptr
, "Invalid tRNS after IDAT");
1278 png_crc_finish(png_ptr
, length
);
1281 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
1283 png_warning(png_ptr
, "Duplicate tRNS chunk");
1284 png_crc_finish(png_ptr
, length
);
1288 if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
1294 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1295 png_crc_finish(png_ptr
, length
);
1299 png_crc_read(png_ptr
, buf
, 2);
1300 png_ptr
->num_trans
= 1;
1301 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
);
1303 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
1309 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1310 png_crc_finish(png_ptr
, length
);
1313 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
1314 png_ptr
->num_trans
= 1;
1315 png_ptr
->trans_values
.red
= png_get_uint_16(buf
);
1316 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2);
1317 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4);
1319 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1321 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1323 /* Should be an error, but we can cope with it. */
1324 png_warning(png_ptr
, "Missing PLTE before tRNS");
1326 if (length
> (png_uint_32
)png_ptr
->num_palette
||
1327 length
> PNG_MAX_PALETTE_LENGTH
)
1329 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1330 png_crc_finish(png_ptr
, length
);
1335 png_warning(png_ptr
, "Zero length tRNS chunk");
1336 png_crc_finish(png_ptr
, length
);
1339 png_crc_read(png_ptr
, readbuf
, (png_size_t
)length
);
1340 png_ptr
->num_trans
= (png_uint_16
)length
;
1344 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
1345 png_crc_finish(png_ptr
, length
);
1349 if (png_crc_finish(png_ptr
, 0))
1351 png_ptr
->num_trans
= 0;
1355 png_set_tRNS(png_ptr
, info_ptr
, readbuf
, png_ptr
->num_trans
,
1356 &(png_ptr
->trans_values
));
1360 #if defined(PNG_READ_bKGD_SUPPORTED)
1362 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1367 png_debug(1, "in png_handle_bKGD");
1369 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1370 png_error(png_ptr
, "Missing IHDR before bKGD");
1371 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1373 png_warning(png_ptr
, "Invalid bKGD after IDAT");
1374 png_crc_finish(png_ptr
, length
);
1377 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
1378 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
1380 png_warning(png_ptr
, "Missing PLTE before bKGD");
1381 png_crc_finish(png_ptr
, length
);
1384 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_bKGD
))
1386 png_warning(png_ptr
, "Duplicate bKGD chunk");
1387 png_crc_finish(png_ptr
, length
);
1391 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1393 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1398 if (length
!= truelen
)
1400 png_warning(png_ptr
, "Incorrect bKGD chunk length");
1401 png_crc_finish(png_ptr
, length
);
1405 png_crc_read(png_ptr
, buf
, truelen
);
1406 if (png_crc_finish(png_ptr
, 0))
1409 /* We convert the index value into RGB components so that we can allow
1410 * arbitrary RGB values for background when we have transparency, and
1411 * so it is easy to determine the RGB values of the background color
1412 * from the info_ptr struct. */
1413 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1415 png_ptr
->background
.index
= buf
[0];
1416 if (info_ptr
&& info_ptr
->num_palette
)
1418 if (buf
[0] >= info_ptr
->num_palette
)
1420 png_warning(png_ptr
, "Incorrect bKGD chunk index value");
1423 png_ptr
->background
.red
=
1424 (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
1425 png_ptr
->background
.green
=
1426 (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
1427 png_ptr
->background
.blue
=
1428 (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
1431 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
1433 png_ptr
->background
.red
=
1434 png_ptr
->background
.green
=
1435 png_ptr
->background
.blue
=
1436 png_ptr
->background
.gray
= png_get_uint_16(buf
);
1440 png_ptr
->background
.red
= png_get_uint_16(buf
);
1441 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
1442 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
1445 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
1449 #if defined(PNG_READ_hIST_SUPPORTED)
1451 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1453 unsigned int num
, i
;
1454 png_uint_16 readbuf
[PNG_MAX_PALETTE_LENGTH
];
1456 png_debug(1, "in png_handle_hIST");
1458 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1459 png_error(png_ptr
, "Missing IHDR before hIST");
1460 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1462 png_warning(png_ptr
, "Invalid hIST after IDAT");
1463 png_crc_finish(png_ptr
, length
);
1466 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1468 png_warning(png_ptr
, "Missing PLTE before hIST");
1469 png_crc_finish(png_ptr
, length
);
1472 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_hIST
))
1474 png_warning(png_ptr
, "Duplicate hIST chunk");
1475 png_crc_finish(png_ptr
, length
);
1480 if (num
!= (unsigned int) png_ptr
->num_palette
|| num
>
1481 (unsigned int) PNG_MAX_PALETTE_LENGTH
)
1483 png_warning(png_ptr
, "Incorrect hIST chunk length");
1484 png_crc_finish(png_ptr
, length
);
1488 for (i
= 0; i
< num
; i
++)
1492 png_crc_read(png_ptr
, buf
, 2);
1493 readbuf
[i
] = png_get_uint_16(buf
);
1496 if (png_crc_finish(png_ptr
, 0))
1499 png_set_hIST(png_ptr
, info_ptr
, readbuf
);
1503 #if defined(PNG_READ_pHYs_SUPPORTED)
1505 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1508 png_uint_32 res_x
, res_y
;
1511 png_debug(1, "in png_handle_pHYs");
1513 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1514 png_error(png_ptr
, "Missing IHDR before pHYs");
1515 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1517 png_warning(png_ptr
, "Invalid pHYs after IDAT");
1518 png_crc_finish(png_ptr
, length
);
1521 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pHYs
))
1523 png_warning(png_ptr
, "Duplicate pHYs chunk");
1524 png_crc_finish(png_ptr
, length
);
1530 png_warning(png_ptr
, "Incorrect pHYs chunk length");
1531 png_crc_finish(png_ptr
, length
);
1535 png_crc_read(png_ptr
, buf
, 9);
1536 if (png_crc_finish(png_ptr
, 0))
1539 res_x
= png_get_uint_32(buf
);
1540 res_y
= png_get_uint_32(buf
+ 4);
1542 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
1546 #if defined(PNG_READ_oFFs_SUPPORTED)
1548 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1551 png_int_32 offset_x
, offset_y
;
1554 png_debug(1, "in png_handle_oFFs");
1556 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1557 png_error(png_ptr
, "Missing IHDR before oFFs");
1558 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1560 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1561 png_crc_finish(png_ptr
, length
);
1564 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_oFFs
))
1566 png_warning(png_ptr
, "Duplicate oFFs chunk");
1567 png_crc_finish(png_ptr
, length
);
1573 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1574 png_crc_finish(png_ptr
, length
);
1578 png_crc_read(png_ptr
, buf
, 9);
1579 if (png_crc_finish(png_ptr
, 0))
1582 offset_x
= png_get_int_32(buf
);
1583 offset_y
= png_get_int_32(buf
+ 4);
1585 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1589 #if defined(PNG_READ_pCAL_SUPPORTED)
1590 /* Read the pCAL chunk (described in the PNG Extensions document) */
1592 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1595 png_byte type
, nparams
;
1596 png_charp buf
, units
, endptr
;
1601 png_debug(1, "in png_handle_pCAL");
1603 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1604 png_error(png_ptr
, "Missing IHDR before pCAL");
1605 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1607 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1608 png_crc_finish(png_ptr
, length
);
1611 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pCAL
))
1613 png_warning(png_ptr
, "Duplicate pCAL chunk");
1614 png_crc_finish(png_ptr
, length
);
1618 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1620 png_free(png_ptr
, png_ptr
->chunkdata
);
1621 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1622 if (png_ptr
->chunkdata
== NULL
)
1624 png_warning(png_ptr
, "No memory for pCAL purpose.");
1627 slength
= (png_size_t
)length
;
1628 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1630 if (png_crc_finish(png_ptr
, 0))
1632 png_free(png_ptr
, png_ptr
->chunkdata
);
1633 png_ptr
->chunkdata
= NULL
;
1637 png_ptr
->chunkdata
[slength
] = 0x00; /* Null terminate the last string */
1639 png_debug(3, "Finding end of pCAL purpose string");
1640 for (buf
= png_ptr
->chunkdata
; *buf
; buf
++)
1643 endptr
= png_ptr
->chunkdata
+ slength
;
1645 /* We need to have at least 12 bytes after the purpose string
1646 in order to get the parameter information. */
1647 if (endptr
<= buf
+ 12)
1649 png_warning(png_ptr
, "Invalid pCAL data");
1650 png_free(png_ptr
, png_ptr
->chunkdata
);
1651 png_ptr
->chunkdata
= NULL
;
1655 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1656 X0
= png_get_int_32((png_bytep
)buf
+1);
1657 X1
= png_get_int_32((png_bytep
)buf
+5);
1662 png_debug(3, "Checking pCAL equation type and number of parameters");
1663 /* Check that we have the right number of parameters for known
1665 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1666 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1667 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1668 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1670 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1671 png_free(png_ptr
, png_ptr
->chunkdata
);
1672 png_ptr
->chunkdata
= NULL
;
1675 else if (type
>= PNG_EQUATION_LAST
)
1677 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1680 for (buf
= units
; *buf
; buf
++)
1681 /* Empty loop to move past the units string. */ ;
1683 png_debug(3, "Allocating pCAL parameters array");
1684 params
= (png_charpp
)png_malloc_warn(png_ptr
,
1685 (png_uint_32
)(nparams
* png_sizeof(png_charp
))) ;
1688 png_free(png_ptr
, png_ptr
->chunkdata
);
1689 png_ptr
->chunkdata
= NULL
;
1690 png_warning(png_ptr
, "No memory for pCAL params.");
1694 /* Get pointers to the start of each parameter string. */
1695 for (i
= 0; i
< (int)nparams
; i
++)
1697 buf
++; /* Skip the null string terminator from previous parameter. */
1699 png_debug1(3, "Reading pCAL parameter %d", i
);
1700 for (params
[i
] = buf
; buf
<= endptr
&& *buf
!= 0x00; buf
++)
1701 /* Empty loop to move past each parameter string */ ;
1703 /* Make sure we haven't run out of data yet */
1706 png_warning(png_ptr
, "Invalid pCAL data");
1707 png_free(png_ptr
, png_ptr
->chunkdata
);
1708 png_ptr
->chunkdata
= NULL
;
1709 png_free(png_ptr
, params
);
1714 png_set_pCAL(png_ptr
, info_ptr
, png_ptr
->chunkdata
, X0
, X1
, type
, nparams
,
1717 png_free(png_ptr
, png_ptr
->chunkdata
);
1718 png_ptr
->chunkdata
= NULL
;
1719 png_free(png_ptr
, params
);
1723 #if defined(PNG_READ_sCAL_SUPPORTED)
1724 /* Read the sCAL chunk */
1726 png_handle_sCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1729 #ifdef PNG_FLOATING_POINT_SUPPORTED
1730 double width
, height
;
1733 #ifdef PNG_FIXED_POINT_SUPPORTED
1734 png_charp swidth
, sheight
;
1739 png_debug(1, "in png_handle_sCAL");
1741 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1742 png_error(png_ptr
, "Missing IHDR before sCAL");
1743 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1745 png_warning(png_ptr
, "Invalid sCAL after IDAT");
1746 png_crc_finish(png_ptr
, length
);
1749 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sCAL
))
1751 png_warning(png_ptr
, "Duplicate sCAL chunk");
1752 png_crc_finish(png_ptr
, length
);
1756 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1758 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1759 if (png_ptr
->chunkdata
== NULL
)
1761 png_warning(png_ptr
, "Out of memory while processing sCAL chunk");
1764 slength
= (png_size_t
)length
;
1765 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1767 if (png_crc_finish(png_ptr
, 0))
1769 png_free(png_ptr
, png_ptr
->chunkdata
);
1770 png_ptr
->chunkdata
= NULL
;
1774 png_ptr
->chunkdata
[slength
] = 0x00; /* Null terminate the last string */
1776 ep
= png_ptr
->chunkdata
+ 1; /* Skip unit byte */
1778 #ifdef PNG_FLOATING_POINT_SUPPORTED
1779 width
= png_strtod(png_ptr
, ep
, &vp
);
1782 png_warning(png_ptr
, "malformed width string in sCAL chunk");
1786 #ifdef PNG_FIXED_POINT_SUPPORTED
1787 swidth
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1790 png_warning(png_ptr
, "Out of memory while processing sCAL chunk width");
1793 png_memcpy(swidth
, ep
, (png_size_t
)png_strlen(ep
));
1797 for (ep
= png_ptr
->chunkdata
; *ep
; ep
++)
1801 if (png_ptr
->chunkdata
+ slength
< ep
)
1803 png_warning(png_ptr
, "Truncated sCAL chunk");
1804 #if defined(PNG_FIXED_POINT_SUPPORTED) && \
1805 !defined(PNG_FLOATING_POINT_SUPPORTED)
1806 png_free(png_ptr
, swidth
);
1808 png_free(png_ptr
, png_ptr
->chunkdata
);
1809 png_ptr
->chunkdata
= NULL
;
1813 #ifdef PNG_FLOATING_POINT_SUPPORTED
1814 height
= png_strtod(png_ptr
, ep
, &vp
);
1817 png_warning(png_ptr
, "malformed height string in sCAL chunk");
1821 #ifdef PNG_FIXED_POINT_SUPPORTED
1822 sheight
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1823 if (sheight
== NULL
)
1825 png_warning(png_ptr
, "Out of memory while processing sCAL chunk height");
1828 png_memcpy(sheight
, ep
, (png_size_t
)png_strlen(ep
));
1832 if (png_ptr
->chunkdata
+ slength
< ep
1833 #ifdef PNG_FLOATING_POINT_SUPPORTED
1834 || width
<= 0. || height
<= 0.
1838 png_warning(png_ptr
, "Invalid sCAL data");
1839 png_free(png_ptr
, png_ptr
->chunkdata
);
1840 png_ptr
->chunkdata
= NULL
;
1841 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1842 png_free(png_ptr
, swidth
);
1843 png_free(png_ptr
, sheight
);
1849 #ifdef PNG_FLOATING_POINT_SUPPORTED
1850 png_set_sCAL(png_ptr
, info_ptr
, png_ptr
->chunkdata
[0], width
, height
);
1852 #ifdef PNG_FIXED_POINT_SUPPORTED
1853 png_set_sCAL_s(png_ptr
, info_ptr
, png_ptr
->chunkdata
[0], swidth
, sheight
);
1857 png_free(png_ptr
, png_ptr
->chunkdata
);
1858 png_ptr
->chunkdata
= NULL
;
1859 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1860 png_free(png_ptr
, swidth
);
1861 png_free(png_ptr
, sheight
);
1866 #if defined(PNG_READ_tIME_SUPPORTED)
1868 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1873 png_debug(1, "in png_handle_tIME");
1875 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1876 png_error(png_ptr
, "Out of place tIME chunk");
1877 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tIME
))
1879 png_warning(png_ptr
, "Duplicate tIME chunk");
1880 png_crc_finish(png_ptr
, length
);
1884 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1885 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1889 png_warning(png_ptr
, "Incorrect tIME chunk length");
1890 png_crc_finish(png_ptr
, length
);
1894 png_crc_read(png_ptr
, buf
, 7);
1895 if (png_crc_finish(png_ptr
, 0))
1898 mod_time
.second
= buf
[6];
1899 mod_time
.minute
= buf
[5];
1900 mod_time
.hour
= buf
[4];
1901 mod_time
.day
= buf
[3];
1902 mod_time
.month
= buf
[2];
1903 mod_time
.year
= png_get_uint_16(buf
);
1905 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1909 #if defined(PNG_READ_tEXt_SUPPORTED)
1910 /* Note: this does not properly handle chunks that are > 64K under DOS */
1912 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1917 png_uint_32 skip
= 0;
1921 png_debug(1, "in png_handle_tEXt");
1924 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1925 png_error(png_ptr
, "Missing IHDR before tEXt");
1927 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1928 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1930 #ifdef PNG_MAX_MALLOC_64K
1931 if (length
> (png_uint_32
)65535L)
1933 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
1934 skip
= length
- (png_uint_32
)65535L;
1935 length
= (png_uint_32
)65535L;
1939 png_free(png_ptr
, png_ptr
->chunkdata
);
1941 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1942 if (png_ptr
->chunkdata
== NULL
)
1944 png_warning(png_ptr
, "No memory to process text chunk.");
1947 slength
= (png_size_t
)length
;
1948 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1950 if (png_crc_finish(png_ptr
, skip
))
1952 png_free(png_ptr
, png_ptr
->chunkdata
);
1953 png_ptr
->chunkdata
= NULL
;
1957 key
= png_ptr
->chunkdata
;
1959 key
[slength
] = 0x00;
1961 for (text
= key
; *text
; text
++)
1962 /* Empty loop to find end of key */ ;
1964 if (text
!= key
+ slength
)
1967 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
1968 (png_uint_32
)png_sizeof(png_text
));
1969 if (text_ptr
== NULL
)
1971 png_warning(png_ptr
, "Not enough memory to process text chunk.");
1972 png_free(png_ptr
, png_ptr
->chunkdata
);
1973 png_ptr
->chunkdata
= NULL
;
1976 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
1977 text_ptr
->key
= key
;
1978 #ifdef PNG_iTXt_SUPPORTED
1979 text_ptr
->lang
= NULL
;
1980 text_ptr
->lang_key
= NULL
;
1981 text_ptr
->itxt_length
= 0;
1983 text_ptr
->text
= text
;
1984 text_ptr
->text_length
= png_strlen(text
);
1986 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
1988 png_free(png_ptr
, png_ptr
->chunkdata
);
1989 png_ptr
->chunkdata
= NULL
;
1990 png_free(png_ptr
, text_ptr
);
1992 png_warning(png_ptr
, "Insufficient memory to process text chunk.");
1996 #if defined(PNG_READ_zTXt_SUPPORTED)
1997 /* Note: this does not correctly handle chunks that are > 64K under DOS */
1999 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2005 png_size_t slength
, prefix_len
, data_len
;
2007 png_debug(1, "in png_handle_zTXt");
2010 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2011 png_error(png_ptr
, "Missing IHDR before zTXt");
2013 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2014 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2016 #ifdef PNG_MAX_MALLOC_64K
2017 /* We will no doubt have problems with chunks even half this size, but
2018 there is no hard and fast rule to tell us where to stop. */
2019 if (length
> (png_uint_32
)65535L)
2021 png_warning(png_ptr
, "zTXt chunk too large to fit in memory");
2022 png_crc_finish(png_ptr
, length
);
2027 png_free(png_ptr
, png_ptr
->chunkdata
);
2028 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2029 if (png_ptr
->chunkdata
== NULL
)
2031 png_warning(png_ptr
, "Out of memory processing zTXt chunk.");
2034 slength
= (png_size_t
)length
;
2035 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
2036 if (png_crc_finish(png_ptr
, 0))
2038 png_free(png_ptr
, png_ptr
->chunkdata
);
2039 png_ptr
->chunkdata
= NULL
;
2043 png_ptr
->chunkdata
[slength
] = 0x00;
2045 for (text
= png_ptr
->chunkdata
; *text
; text
++)
2048 /* zTXt must have some text after the chunkdataword */
2049 if (text
>= png_ptr
->chunkdata
+ slength
- 2)
2051 png_warning(png_ptr
, "Truncated zTXt chunk");
2052 png_free(png_ptr
, png_ptr
->chunkdata
);
2053 png_ptr
->chunkdata
= NULL
;
2058 comp_type
= *(++text
);
2059 if (comp_type
!= PNG_TEXT_COMPRESSION_zTXt
)
2061 png_warning(png_ptr
, "Unknown compression type in zTXt chunk");
2062 comp_type
= PNG_TEXT_COMPRESSION_zTXt
;
2064 text
++; /* Skip the compression_method byte */
2066 prefix_len
= text
- png_ptr
->chunkdata
;
2068 png_decompress_chunk(png_ptr
, comp_type
,
2069 (png_size_t
)length
, prefix_len
, &data_len
);
2071 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2072 (png_uint_32
)png_sizeof(png_text
));
2073 if (text_ptr
== NULL
)
2075 png_warning(png_ptr
, "Not enough memory to process zTXt chunk.");
2076 png_free(png_ptr
, png_ptr
->chunkdata
);
2077 png_ptr
->chunkdata
= NULL
;
2080 text_ptr
->compression
= comp_type
;
2081 text_ptr
->key
= png_ptr
->chunkdata
;
2082 #ifdef PNG_iTXt_SUPPORTED
2083 text_ptr
->lang
= NULL
;
2084 text_ptr
->lang_key
= NULL
;
2085 text_ptr
->itxt_length
= 0;
2087 text_ptr
->text
= png_ptr
->chunkdata
+ prefix_len
;
2088 text_ptr
->text_length
= data_len
;
2090 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2092 png_free(png_ptr
, text_ptr
);
2093 png_free(png_ptr
, png_ptr
->chunkdata
);
2094 png_ptr
->chunkdata
= NULL
;
2096 png_error(png_ptr
, "Insufficient memory to store zTXt chunk.");
2100 #if defined(PNG_READ_iTXt_SUPPORTED)
2101 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2103 png_handle_iTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2106 png_charp key
, lang
, text
, lang_key
;
2110 png_size_t slength
, prefix_len
, data_len
;
2112 png_debug(1, "in png_handle_iTXt");
2115 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2116 png_error(png_ptr
, "Missing IHDR before iTXt");
2118 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2119 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2121 #ifdef PNG_MAX_MALLOC_64K
2122 /* We will no doubt have problems with chunks even half this size, but
2123 there is no hard and fast rule to tell us where to stop. */
2124 if (length
> (png_uint_32
)65535L)
2126 png_warning(png_ptr
, "iTXt chunk too large to fit in memory");
2127 png_crc_finish(png_ptr
, length
);
2132 png_free(png_ptr
, png_ptr
->chunkdata
);
2133 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2134 if (png_ptr
->chunkdata
== NULL
)
2136 png_warning(png_ptr
, "No memory to process iTXt chunk.");
2139 slength
= (png_size_t
)length
;
2140 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
2141 if (png_crc_finish(png_ptr
, 0))
2143 png_free(png_ptr
, png_ptr
->chunkdata
);
2144 png_ptr
->chunkdata
= NULL
;
2148 png_ptr
->chunkdata
[slength
] = 0x00;
2150 for (lang
= png_ptr
->chunkdata
; *lang
; lang
++)
2152 lang
++; /* Skip NUL separator */
2154 /* iTXt must have a language tag (possibly empty), two compression bytes,
2155 * translated keyword (possibly empty), and possibly some text after the
2159 if (lang
>= png_ptr
->chunkdata
+ slength
- 3)
2161 png_warning(png_ptr
, "Truncated iTXt chunk");
2162 png_free(png_ptr
, png_ptr
->chunkdata
);
2163 png_ptr
->chunkdata
= NULL
;
2168 comp_flag
= *lang
++;
2169 comp_type
= *lang
++;
2172 for (lang_key
= lang
; *lang_key
; lang_key
++)
2174 lang_key
++; /* Skip NUL separator */
2176 if (lang_key
>= png_ptr
->chunkdata
+ slength
)
2178 png_warning(png_ptr
, "Truncated iTXt chunk");
2179 png_free(png_ptr
, png_ptr
->chunkdata
);
2180 png_ptr
->chunkdata
= NULL
;
2184 for (text
= lang_key
; *text
; text
++)
2186 text
++; /* Skip NUL separator */
2187 if (text
>= png_ptr
->chunkdata
+ slength
)
2189 png_warning(png_ptr
, "Malformed iTXt chunk");
2190 png_free(png_ptr
, png_ptr
->chunkdata
);
2191 png_ptr
->chunkdata
= NULL
;
2195 prefix_len
= text
- png_ptr
->chunkdata
;
2197 key
=png_ptr
->chunkdata
;
2199 png_decompress_chunk(png_ptr
, comp_type
,
2200 (size_t)length
, prefix_len
, &data_len
);
2202 data_len
= png_strlen(png_ptr
->chunkdata
+ prefix_len
);
2203 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2204 (png_uint_32
)png_sizeof(png_text
));
2205 if (text_ptr
== NULL
)
2207 png_warning(png_ptr
, "Not enough memory to process iTXt chunk.");
2208 png_free(png_ptr
, png_ptr
->chunkdata
);
2209 png_ptr
->chunkdata
= NULL
;
2212 text_ptr
->compression
= (int)comp_flag
+ 1;
2213 text_ptr
->lang_key
= png_ptr
->chunkdata
+ (lang_key
- key
);
2214 text_ptr
->lang
= png_ptr
->chunkdata
+ (lang
- key
);
2215 text_ptr
->itxt_length
= data_len
;
2216 text_ptr
->text_length
= 0;
2217 text_ptr
->key
= png_ptr
->chunkdata
;
2218 text_ptr
->text
= png_ptr
->chunkdata
+ prefix_len
;
2220 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2222 png_free(png_ptr
, text_ptr
);
2223 png_free(png_ptr
, png_ptr
->chunkdata
);
2224 png_ptr
->chunkdata
= NULL
;
2226 png_error(png_ptr
, "Insufficient memory to store iTXt chunk.");
2230 /* This function is called when we haven't found a handler for a
2231 chunk. If there isn't a problem with the chunk itself (ie bad
2232 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2233 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2234 case it will be saved away to be written out later. */
2236 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2238 png_uint_32 skip
= 0;
2240 png_debug(1, "in png_handle_unknown");
2243 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2245 #ifdef PNG_USE_LOCAL_ARRAYS
2248 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4)) /* Not an IDAT */
2249 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2252 if (!(png_ptr
->chunk_name
[0] & 0x20))
2254 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2255 if (png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2256 PNG_HANDLE_CHUNK_ALWAYS
2257 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2258 && png_ptr
->read_user_chunk_fn
== NULL
2262 png_chunk_error(png_ptr
, "unknown critical chunk");
2265 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2266 if ((png_ptr
->flags
& PNG_FLAG_KEEP_UNKNOWN_CHUNKS
) ||
2267 (png_ptr
->read_user_chunk_fn
!= NULL
))
2269 #ifdef PNG_MAX_MALLOC_64K
2270 if (length
> (png_uint_32
)65535L)
2272 png_warning(png_ptr
, "unknown chunk too large to fit in memory");
2273 skip
= length
- (png_uint_32
)65535L;
2274 length
= (png_uint_32
)65535L;
2277 png_memcpy((png_charp
)png_ptr
->unknown_chunk
.name
,
2278 (png_charp
)png_ptr
->chunk_name
,
2279 png_sizeof(png_ptr
->unknown_chunk
.name
));
2280 png_ptr
->unknown_chunk
.name
[png_sizeof(png_ptr
->unknown_chunk
.name
)-1] = '\0';
2281 png_ptr
->unknown_chunk
.size
= (png_size_t
)length
;
2283 png_ptr
->unknown_chunk
.data
= NULL
;
2286 png_ptr
->unknown_chunk
.data
= (png_bytep
)png_malloc(png_ptr
, length
);
2287 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->unknown_chunk
.data
, length
);
2289 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2290 if (png_ptr
->read_user_chunk_fn
!= NULL
)
2292 /* Callback to user unknown chunk handler */
2294 ret
= (*(png_ptr
->read_user_chunk_fn
))
2295 (png_ptr
, &png_ptr
->unknown_chunk
);
2297 png_chunk_error(png_ptr
, "error in user chunk");
2300 if (!(png_ptr
->chunk_name
[0] & 0x20))
2301 if (png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2302 PNG_HANDLE_CHUNK_ALWAYS
)
2303 png_chunk_error(png_ptr
, "unknown critical chunk");
2304 png_set_unknown_chunks(png_ptr
, info_ptr
,
2305 &png_ptr
->unknown_chunk
, 1);
2310 png_set_unknown_chunks(png_ptr
, info_ptr
, &png_ptr
->unknown_chunk
, 1);
2311 png_free(png_ptr
, png_ptr
->unknown_chunk
.data
);
2312 png_ptr
->unknown_chunk
.data
= NULL
;
2318 png_crc_finish(png_ptr
, skip
);
2320 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2321 info_ptr
= info_ptr
; /* Quiet compiler warnings about unused info_ptr */
2325 /* This function is called to verify that a chunk name is valid.
2326 This function can't have the "critical chunk check" incorporated
2327 into it, since in the future we will need to be able to call user
2328 functions to handle unknown critical chunks after we check that
2329 the chunk name itself is valid. */
2331 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2334 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
2336 png_debug(1, "in png_check_chunk_name");
2337 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
2338 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
2340 png_chunk_error(png_ptr
, "invalid chunk type");
2344 /* Combines the row recently read in with the existing pixels in the
2345 row. This routine takes care of alpha and transparency if requested.
2346 This routine also handles the two methods of progressive display
2347 of interlaced images, depending on the mask value.
2348 The mask value describes which pixels are to be combined with
2349 the row. The pattern always repeats every 8 pixels, so just 8
2350 bits are needed. A one indicates the pixel is to be combined,
2351 a zero indicates the pixel is to be skipped. This is in addition
2352 to any alpha or transparency value associated with the pixel. If
2353 you want all pixels to be combined, pass 0xff (255) in mask. */
2356 png_combine_row(png_structp png_ptr
, png_bytep row
, int mask
)
2358 png_debug(1, "in png_combine_row");
2361 png_memcpy(row
, png_ptr
->row_buf
+ 1,
2362 PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
, png_ptr
->width
));
2366 switch (png_ptr
->row_info
.pixel_depth
)
2370 png_bytep sp
= png_ptr
->row_buf
+ 1;
2372 int s_inc
, s_start
, s_end
;
2376 png_uint_32 row_width
= png_ptr
->width
;
2378 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2379 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2395 for (i
= 0; i
< row_width
; i
++)
2401 value
= (*sp
>> shift
) & 0x01;
2402 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2403 *dp
|= (png_byte
)(value
<< shift
);
2424 png_bytep sp
= png_ptr
->row_buf
+ 1;
2426 int s_start
, s_end
, s_inc
;
2430 png_uint_32 row_width
= png_ptr
->width
;
2433 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2434 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2450 for (i
= 0; i
< row_width
; i
++)
2454 value
= (*sp
>> shift
) & 0x03;
2455 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2456 *dp
|= (png_byte
)(value
<< shift
);
2476 png_bytep sp
= png_ptr
->row_buf
+ 1;
2478 int s_start
, s_end
, s_inc
;
2482 png_uint_32 row_width
= png_ptr
->width
;
2485 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2486 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2501 for (i
= 0; i
< row_width
; i
++)
2505 value
= (*sp
>> shift
) & 0xf;
2506 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2507 *dp
|= (png_byte
)(value
<< shift
);
2527 png_bytep sp
= png_ptr
->row_buf
+ 1;
2529 png_size_t pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
2531 png_uint_32 row_width
= png_ptr
->width
;
2535 for (i
= 0; i
< row_width
; i
++)
2539 png_memcpy(dp
, sp
, pixel_bytes
);
2556 #ifdef PNG_READ_INTERLACING_SUPPORTED
2557 /* OLD pre-1.0.9 interface:
2558 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2559 png_uint_32 transformations)
2562 png_do_read_interlace(png_structp png_ptr
)
2564 png_row_infop row_info
= &(png_ptr
->row_info
);
2565 png_bytep row
= png_ptr
->row_buf
+ 1;
2566 int pass
= png_ptr
->pass
;
2567 png_uint_32 transformations
= png_ptr
->transformations
;
2568 #ifdef PNG_USE_LOCAL_ARRAYS
2569 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2570 /* Offset to next interlace block */
2571 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2574 png_debug(1, "in png_do_read_interlace");
2575 if (row
!= NULL
&& row_info
!= NULL
)
2577 png_uint_32 final_width
;
2579 final_width
= row_info
->width
* png_pass_inc
[pass
];
2581 switch (row_info
->pixel_depth
)
2585 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2586 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
2588 int s_start
, s_end
, s_inc
;
2589 int jstop
= png_pass_inc
[pass
];
2594 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2595 if (transformations
& PNG_PACKSWAP
)
2597 sshift
= (int)((row_info
->width
+ 7) & 0x07);
2598 dshift
= (int)((final_width
+ 7) & 0x07);
2606 sshift
= 7 - (int)((row_info
->width
+ 7) & 0x07);
2607 dshift
= 7 - (int)((final_width
+ 7) & 0x07);
2613 for (i
= 0; i
< row_info
->width
; i
++)
2615 v
= (png_byte
)((*sp
>> sshift
) & 0x01);
2616 for (j
= 0; j
< jstop
; j
++)
2618 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
2619 *dp
|= (png_byte
)(v
<< dshift
);
2620 if (dshift
== s_end
)
2628 if (sshift
== s_end
)
2640 png_bytep sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
2641 png_bytep dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
2643 int s_start
, s_end
, s_inc
;
2644 int jstop
= png_pass_inc
[pass
];
2647 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2648 if (transformations
& PNG_PACKSWAP
)
2650 sshift
= (int)(((row_info
->width
+ 3) & 0x03) << 1);
2651 dshift
= (int)(((final_width
+ 3) & 0x03) << 1);
2659 sshift
= (int)((3 - ((row_info
->width
+ 3) & 0x03)) << 1);
2660 dshift
= (int)((3 - ((final_width
+ 3) & 0x03)) << 1);
2666 for (i
= 0; i
< row_info
->width
; i
++)
2671 v
= (png_byte
)((*sp
>> sshift
) & 0x03);
2672 for (j
= 0; j
< jstop
; j
++)
2674 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
2675 *dp
|= (png_byte
)(v
<< dshift
);
2676 if (dshift
== s_end
)
2684 if (sshift
== s_end
)
2696 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2697 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
2699 int s_start
, s_end
, s_inc
;
2701 int jstop
= png_pass_inc
[pass
];
2703 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2704 if (transformations
& PNG_PACKSWAP
)
2706 sshift
= (int)(((row_info
->width
+ 1) & 0x01) << 2);
2707 dshift
= (int)(((final_width
+ 1) & 0x01) << 2);
2715 sshift
= (int)((1 - ((row_info
->width
+ 1) & 0x01)) << 2);
2716 dshift
= (int)((1 - ((final_width
+ 1) & 0x01)) << 2);
2722 for (i
= 0; i
< row_info
->width
; i
++)
2724 png_byte v
= (png_byte
)((*sp
>> sshift
) & 0xf);
2727 for (j
= 0; j
< jstop
; j
++)
2729 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
2730 *dp
|= (png_byte
)(v
<< dshift
);
2731 if (dshift
== s_end
)
2739 if (sshift
== s_end
)
2751 png_size_t pixel_bytes
= (row_info
->pixel_depth
>> 3);
2752 png_bytep sp
= row
+ (png_size_t
)(row_info
->width
- 1) * pixel_bytes
;
2753 png_bytep dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
2755 int jstop
= png_pass_inc
[pass
];
2758 for (i
= 0; i
< row_info
->width
; i
++)
2763 png_memcpy(v
, sp
, pixel_bytes
);
2764 for (j
= 0; j
< jstop
; j
++)
2766 png_memcpy(dp
, v
, pixel_bytes
);
2774 row_info
->width
= final_width
;
2775 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, final_width
);
2777 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2778 transformations
= transformations
; /* Silence compiler warning */
2781 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2784 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
2785 png_bytep prev_row
, int filter
)
2787 png_debug(1, "in png_read_filter_row");
2788 png_debug2(2, "row = %lu, filter = %d", png_ptr
->row_number
, filter
);
2791 case PNG_FILTER_VALUE_NONE
:
2793 case PNG_FILTER_VALUE_SUB
:
2796 png_uint_32 istop
= row_info
->rowbytes
;
2797 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2798 png_bytep rp
= row
+ bpp
;
2801 for (i
= bpp
; i
< istop
; i
++)
2803 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
++)) & 0xff);
2808 case PNG_FILTER_VALUE_UP
:
2811 png_uint_32 istop
= row_info
->rowbytes
;
2813 png_bytep pp
= prev_row
;
2815 for (i
= 0; i
< istop
; i
++)
2817 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2822 case PNG_FILTER_VALUE_AVG
:
2826 png_bytep pp
= prev_row
;
2828 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2829 png_uint_32 istop
= row_info
->rowbytes
- bpp
;
2831 for (i
= 0; i
< bpp
; i
++)
2833 *rp
= (png_byte
)(((int)(*rp
) +
2834 ((int)(*pp
++) / 2 )) & 0xff);
2838 for (i
= 0; i
< istop
; i
++)
2840 *rp
= (png_byte
)(((int)(*rp
) +
2841 (int)(*pp
++ + *lp
++) / 2 ) & 0xff);
2846 case PNG_FILTER_VALUE_PAETH
:
2850 png_bytep pp
= prev_row
;
2852 png_bytep cp
= prev_row
;
2853 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2854 png_uint_32 istop
=row_info
->rowbytes
- bpp
;
2856 for (i
= 0; i
< bpp
; i
++)
2858 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2862 for (i
= 0; i
< istop
; i
++) /* Use leftover rp,pp */
2864 int a
, b
, c
, pa
, pb
, pc
, p
;
2878 pa
= p
< 0 ? -p
: p
;
2879 pb
= pc
< 0 ? -pc
: pc
;
2880 pc
= (p
+ pc
) < 0 ? -(p
+ pc
) : p
+ pc
;
2884 if (pa <= pb && pa <= pc)
2892 p
= (pa
<= pb
&& pa
<= pc
) ? a
: (pb
<= pc
) ? b
: c
;
2894 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
2900 png_warning(png_ptr
, "Ignoring bad adaptive filter type");
2906 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
2908 png_read_finish_row(png_structp png_ptr
)
2910 #ifdef PNG_USE_LOCAL_ARRAYS
2911 #ifdef PNG_READ_INTERLACING_SUPPORTED
2912 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2914 /* Start of interlace block */
2915 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2917 /* Offset to next interlace block */
2918 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2920 /* Start of interlace block in the y direction */
2921 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2923 /* Offset to next interlace block in the y direction */
2924 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2925 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2928 png_debug(1, "in png_read_finish_row");
2929 png_ptr
->row_number
++;
2930 if (png_ptr
->row_number
< png_ptr
->num_rows
)
2933 #ifdef PNG_READ_INTERLACING_SUPPORTED
2934 if (png_ptr
->interlaced
)
2936 png_ptr
->row_number
= 0;
2937 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0,
2938 png_ptr
->rowbytes
+ 1);
2942 if (png_ptr
->pass
>= 7)
2944 png_ptr
->iwidth
= (png_ptr
->width
+
2945 png_pass_inc
[png_ptr
->pass
] - 1 -
2946 png_pass_start
[png_ptr
->pass
]) /
2947 png_pass_inc
[png_ptr
->pass
];
2949 png_ptr
->irowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,
2950 png_ptr
->iwidth
) + 1;
2952 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2954 png_ptr
->num_rows
= (png_ptr
->height
+
2955 png_pass_yinc
[png_ptr
->pass
] - 1 -
2956 png_pass_ystart
[png_ptr
->pass
]) /
2957 png_pass_yinc
[png_ptr
->pass
];
2958 if (!(png_ptr
->num_rows
))
2961 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2963 } while (png_ptr
->iwidth
== 0);
2965 if (png_ptr
->pass
< 7)
2968 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2970 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
2972 #ifdef PNG_USE_LOCAL_ARRAYS
2978 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
2979 png_ptr
->zstream
.avail_out
= (uInt
)1;
2982 if (!(png_ptr
->zstream
.avail_in
))
2984 while (!png_ptr
->idat_size
)
2986 png_byte chunk_length
[4];
2988 png_crc_finish(png_ptr
, 0);
2990 png_read_data(png_ptr
, chunk_length
, 4);
2991 png_ptr
->idat_size
= png_get_uint_31(png_ptr
, chunk_length
);
2992 png_reset_crc(png_ptr
);
2993 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
2994 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4))
2995 png_error(png_ptr
, "Not enough image data");
2998 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
2999 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
3000 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
3001 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
3002 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
3003 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
3005 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
3006 if (ret
== Z_STREAM_END
)
3008 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
3010 png_warning(png_ptr
, "Extra compressed data");
3011 png_ptr
->mode
|= PNG_AFTER_IDAT
;
3012 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
3016 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
3017 "Decompression Error");
3019 if (!(png_ptr
->zstream
.avail_out
))
3021 png_warning(png_ptr
, "Extra compressed data.");
3022 png_ptr
->mode
|= PNG_AFTER_IDAT
;
3023 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
3028 png_ptr
->zstream
.avail_out
= 0;
3031 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
3032 png_warning(png_ptr
, "Extra compression data");
3034 inflateReset(&png_ptr
->zstream
);
3036 png_ptr
->mode
|= PNG_AFTER_IDAT
;
3038 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
3041 png_read_start_row(png_structp png_ptr
)
3043 #ifdef PNG_USE_LOCAL_ARRAYS
3044 #ifdef PNG_READ_INTERLACING_SUPPORTED
3045 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3047 /* Start of interlace block */
3048 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
3050 /* Offset to next interlace block */
3051 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
3053 /* Start of interlace block in the y direction */
3054 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
3056 /* Offset to next interlace block in the y direction */
3057 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
3061 int max_pixel_depth
;
3062 png_size_t row_bytes
;
3064 png_debug(1, "in png_read_start_row");
3065 png_ptr
->zstream
.avail_in
= 0;
3066 png_init_read_transformations(png_ptr
);
3067 #ifdef PNG_READ_INTERLACING_SUPPORTED
3068 if (png_ptr
->interlaced
)
3070 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
3071 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
3072 png_pass_ystart
[0]) / png_pass_yinc
[0];
3074 png_ptr
->num_rows
= png_ptr
->height
;
3076 png_ptr
->iwidth
= (png_ptr
->width
+
3077 png_pass_inc
[png_ptr
->pass
] - 1 -
3078 png_pass_start
[png_ptr
->pass
]) /
3079 png_pass_inc
[png_ptr
->pass
];
3081 png_ptr
->irowbytes
=
3082 PNG_ROWBYTES(png_ptr
->pixel_depth
, png_ptr
->iwidth
) + 1;
3085 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3087 png_ptr
->num_rows
= png_ptr
->height
;
3088 png_ptr
->iwidth
= png_ptr
->width
;
3089 png_ptr
->irowbytes
= png_ptr
->rowbytes
+ 1;
3091 max_pixel_depth
= png_ptr
->pixel_depth
;
3093 #if defined(PNG_READ_PACK_SUPPORTED)
3094 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
3095 max_pixel_depth
= 8;
3098 #if defined(PNG_READ_EXPAND_SUPPORTED)
3099 if (png_ptr
->transformations
& PNG_EXPAND
)
3101 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3103 if (png_ptr
->num_trans
)
3104 max_pixel_depth
= 32;
3106 max_pixel_depth
= 24;
3108 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3110 if (max_pixel_depth
< 8)
3111 max_pixel_depth
= 8;
3112 if (png_ptr
->num_trans
)
3113 max_pixel_depth
*= 2;
3115 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3117 if (png_ptr
->num_trans
)
3119 max_pixel_depth
*= 4;
3120 max_pixel_depth
/= 3;
3126 #if defined(PNG_READ_FILLER_SUPPORTED)
3127 if (png_ptr
->transformations
& (PNG_FILLER
))
3129 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3130 max_pixel_depth
= 32;
3131 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3133 if (max_pixel_depth
<= 8)
3134 max_pixel_depth
= 16;
3136 max_pixel_depth
= 32;
3138 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3140 if (max_pixel_depth
<= 32)
3141 max_pixel_depth
= 32;
3143 max_pixel_depth
= 64;
3148 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3149 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
3152 #if defined(PNG_READ_EXPAND_SUPPORTED)
3153 (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
3155 #if defined(PNG_READ_FILLER_SUPPORTED)
3156 (png_ptr
->transformations
& (PNG_FILLER
)) ||
3158 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
3160 if (max_pixel_depth
<= 16)
3161 max_pixel_depth
= 32;
3163 max_pixel_depth
= 64;
3167 if (max_pixel_depth
<= 8)
3169 if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3170 max_pixel_depth
= 32;
3172 max_pixel_depth
= 24;
3174 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3175 max_pixel_depth
= 64;
3177 max_pixel_depth
= 48;
3182 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3183 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3184 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
3186 int user_pixel_depth
= png_ptr
->user_transform_depth
*
3187 png_ptr
->user_transform_channels
;
3188 if (user_pixel_depth
> max_pixel_depth
)
3189 max_pixel_depth
=user_pixel_depth
;
3193 /* Align the width on the next larger 8 pixels. Mainly used
3196 row_bytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
3197 /* Calculate the maximum bytes needed, adding a byte and a pixel
3200 row_bytes
= PNG_ROWBYTES(max_pixel_depth
, row_bytes
) +
3201 1 + ((max_pixel_depth
+ 7) >> 3);
3202 #ifdef PNG_MAX_MALLOC_64K
3203 if (row_bytes
> (png_uint_32
)65536L)
3204 png_error(png_ptr
, "This image requires a row greater than 64KB");
3207 if (row_bytes
+ 64 > png_ptr
->old_big_row_buf_size
)
3209 png_free(png_ptr
, png_ptr
->big_row_buf
);
3210 png_ptr
->big_row_buf
= (png_bytep
)png_malloc(png_ptr
, row_bytes
+ 64);
3211 if (png_ptr
->interlaced
)
3212 png_memset(png_ptr
->big_row_buf
, 0, row_bytes
+ 64);
3213 png_ptr
->row_buf
= png_ptr
->big_row_buf
+ 32;
3214 png_ptr
->old_big_row_buf_size
= row_bytes
+ 64;
3217 #ifdef PNG_MAX_MALLOC_64K
3218 if ((png_uint_32
)row_bytes
+ 1 > (png_uint_32
)65536L)
3219 png_error(png_ptr
, "This image requires a row greater than 64KB");
3221 if ((png_uint_32
)row_bytes
> (png_uint_32
)(PNG_SIZE_MAX
- 1))
3222 png_error(png_ptr
, "Row has too many bytes to allocate in memory.");
3224 if (row_bytes
+ 1 > png_ptr
->old_prev_row_size
)
3226 png_free(png_ptr
, png_ptr
->prev_row
);
3227 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
3229 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, row_bytes
+ 1);
3230 png_ptr
->old_prev_row_size
= row_bytes
+ 1;
3233 png_ptr
->rowbytes
= row_bytes
;
3235 png_debug1(3, "width = %lu,", png_ptr
->width
);
3236 png_debug1(3, "height = %lu,", png_ptr
->height
);
3237 png_debug1(3, "iwidth = %lu,", png_ptr
->iwidth
);
3238 png_debug1(3, "num_rows = %lu,", png_ptr
->num_rows
);
3239 png_debug1(3, "rowbytes = %lu,", png_ptr
->rowbytes
);
3240 png_debug1(3, "irowbytes = %lu", png_ptr
->irowbytes
);
3242 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;
3244 #endif /* PNG_READ_SUPPORTED */