2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.51 [February 6, 2014]
5 * Copyright (c) 1998-2014 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
13 * This file contains routines that are only called from within
14 * libpng itself during the course of reading an image.
18 #define PNG_NO_PEDANTIC_WARNINGS
20 #ifdef PNG_READ_SUPPORTED
22 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
23 # define WIN32_WCE_OLD
26 #ifdef PNG_FLOATING_POINT_SUPPORTED
28 /* The strtod() function is not supported on WindowsCE */
29 __inline
double png_strtod(png_structp png_ptr
, PNG_CONST
char *nptr
,
36 len
= MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, NULL
, 0);
37 str
= (wchar_t *)png_malloc(png_ptr
, len
* png_sizeof(wchar_t));
40 MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, str
, len
);
41 result
= wcstod(str
, &end
);
42 len
= WideCharToMultiByte(CP_ACP
, 0, end
, -1, NULL
, 0, NULL
, NULL
);
43 *endptr
= (char *)nptr
+ (png_strlen(nptr
) - len
+ 1);
44 png_free(png_ptr
, str
);
49 # define png_strtod(p,a,b) strtod(a,b)
54 png_get_uint_31(png_structp png_ptr
, png_bytep buf
)
56 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
57 png_uint_32 i
= png_get_uint_32(buf
);
59 /* Avoid an extra function call by inlining the result. */
60 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
61 ((png_uint_32
)(*(buf
+ 1)) << 16) +
62 ((png_uint_32
)(*(buf
+ 2)) << 8) +
63 (png_uint_32
)(*(buf
+ 3));
65 if (i
> PNG_UINT_31_MAX
)
66 png_error(png_ptr
, "PNG unsigned integer out of range.");
69 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
70 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
72 png_get_uint_32(png_bytep buf
)
74 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
75 ((png_uint_32
)(*(buf
+ 1)) << 16) +
76 ((png_uint_32
)(*(buf
+ 2)) << 8) +
77 (png_uint_32
)(*(buf
+ 3));
82 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
83 * data is stored in the PNG file in two's complement format, and it is
84 * assumed that the machine format for signed integers is the same.
87 png_get_int_32(png_bytep buf
)
89 png_int_32 i
= ((png_int_32
)(*buf
) << 24) +
90 ((png_int_32
)(*(buf
+ 1)) << 16) +
91 ((png_int_32
)(*(buf
+ 2)) << 8) +
92 (png_int_32
)(*(buf
+ 3));
97 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
99 png_get_uint_16(png_bytep buf
)
101 png_uint_16 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
102 (png_uint_16
)(*(buf
+ 1)));
106 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
108 /* Read the chunk header (length + type name).
109 * Put the type name into png_ptr->chunk_name, and return the length.
111 png_uint_32
/* PRIVATE */
112 png_read_chunk_header(png_structp png_ptr
)
117 /* Read the length and the chunk name */
118 png_read_data(png_ptr
, buf
, 8);
119 length
= png_get_uint_31(png_ptr
, buf
);
121 /* Put the chunk name into png_ptr->chunk_name */
122 png_memcpy(png_ptr
->chunk_name
, buf
+ 4, 4);
124 png_debug2(0, "Reading %s chunk, length = %lu",
125 png_ptr
->chunk_name
, length
);
127 /* Reset the crc and run it over the chunk name */
128 png_reset_crc(png_ptr
);
129 png_calculate_crc(png_ptr
, png_ptr
->chunk_name
, 4);
131 /* Check to see if chunk name is valid */
132 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
137 /* Read data, and (optionally) run it through the CRC. */
139 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
143 png_read_data(png_ptr
, buf
, length
);
144 png_calculate_crc(png_ptr
, buf
, length
);
147 /* Optionally skip data and then check the CRC. Depending on whether we
148 * are reading a ancillary or critical chunk, and how the program has set
149 * things up, we may calculate the CRC on the data and print a message.
150 * Returns '1' if there was a CRC error, '0' otherwise.
153 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
156 png_size_t istop
= png_ptr
->zbuf_size
;
158 for (i
= (png_size_t
)skip
; i
> istop
; i
-= istop
)
160 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
164 png_crc_read(png_ptr
, png_ptr
->zbuf
, i
);
167 if (png_crc_error(png_ptr
))
169 if (((png_ptr
->chunk_name
[0] & 0x20) && /* Ancillary */
170 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
171 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
172 (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
)))
174 png_chunk_warning(png_ptr
, "CRC error");
178 png_chunk_error(png_ptr
, "CRC error");
186 /* Compare the CRC stored in the PNG file with that calculated by libpng from
187 * the data it has read thus far.
190 png_crc_error(png_structp png_ptr
)
192 png_byte crc_bytes
[4];
196 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
198 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
199 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
204 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
208 png_read_data(png_ptr
, crc_bytes
, 4);
212 crc
= png_get_uint_32(crc_bytes
);
213 return ((int)(crc
!= png_ptr
->crc
));
219 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
220 defined(PNG_READ_iCCP_SUPPORTED)
222 png_inflate(png_structp png_ptr
, const png_byte
*data
, png_size_t size
,
223 png_bytep output
, png_size_t output_size
)
225 png_size_t count
= 0;
227 png_ptr
->zstream
.next_in
= (png_bytep
)data
; /* const_cast: VALID */
228 png_ptr
->zstream
.avail_in
= size
;
234 /* Reset the output buffer each time round - we empty it
235 * after every inflate call.
237 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
238 png_ptr
->zstream
.avail_out
= png_ptr
->zbuf_size
;
240 ret
= inflate(&png_ptr
->zstream
, Z_NO_FLUSH
);
241 avail
= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
243 /* First copy/count any new output - but only if we didn't
246 if ((ret
== Z_OK
|| ret
== Z_STREAM_END
) && avail
> 0)
248 if (output
!= 0 && output_size
> count
)
250 png_size_t copy
= output_size
- count
;
251 if ((png_size_t
) avail
< copy
) copy
= (png_size_t
) avail
;
252 png_memcpy(output
+ count
, png_ptr
->zbuf
, copy
);
260 /* Termination conditions - always reset the zstream, it
261 * must be left in inflateInit state.
263 png_ptr
->zstream
.avail_in
= 0;
264 inflateReset(&png_ptr
->zstream
);
266 if (ret
== Z_STREAM_END
)
267 return count
; /* NOTE: may be zero. */
269 /* Now handle the error codes - the API always returns 0
270 * and the error message is dumped into the uncompressed
271 * buffer if available.
275 if (png_ptr
->zstream
.msg
!= 0)
276 msg
= png_ptr
->zstream
.msg
;
279 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
285 msg
= "Buffer error in compressed datastream in %s chunk";
288 msg
= "Data error in compressed datastream in %s chunk";
291 msg
= "Incomplete compressed datastream in %s chunk";
295 png_snprintf(umsg
, sizeof umsg
, msg
, png_ptr
->chunk_name
);
298 msg
= "Damaged compressed datastream in chunk other than IDAT";
302 png_warning(png_ptr
, msg
);
305 /* 0 means an error - notice that this code simple ignores
306 * zero length compressed chunks as a result.
313 * Decompress trailing data in a chunk. The assumption is that chunkdata
314 * points at an allocated area holding the contents of a chunk with a
315 * trailing compressed part. What we get back is an allocated area
316 * holding the original prefix part and an uncompressed version of the
317 * trailing part (the malloc area passed in is freed).
320 png_decompress_chunk(png_structp png_ptr
, int comp_type
,
321 png_size_t chunklength
,
322 png_size_t prefix_size
, png_size_t
*newlength
)
324 /* The caller should guarantee this */
325 if (prefix_size
> chunklength
)
327 /* The recovery is to delete the chunk. */
328 png_warning(png_ptr
, "invalid chunklength");
329 prefix_size
= 0; /* To delete everything */
332 else if (comp_type
== PNG_COMPRESSION_TYPE_BASE
)
334 png_size_t expanded_size
= png_inflate(png_ptr
,
335 (png_bytep
)(png_ptr
->chunkdata
+ prefix_size
),
336 chunklength
- prefix_size
,
337 0/*output*/, 0/*output size*/);
339 /* Now check the limits on this chunk - if the limit fails the
340 * compressed data will be removed, the prefix will remain.
342 if (prefix_size
>= (~(png_size_t
)0) - 1 ||
343 expanded_size
>= (~(png_size_t
)0) - 1 - prefix_size
344 #ifdef PNG_USER_CHUNK_MALLOC_MAX
345 || ((PNG_USER_CHUNK_MALLOC_MAX
> 0) &&
346 prefix_size
+ expanded_size
>= PNG_USER_CHUNK_MALLOC_MAX
- 1)
349 png_warning(png_ptr
, "Exceeded size limit while expanding chunk");
351 /* If the size is zero either there was an error and a message
352 * has already been output (warning) or the size really is zero
353 * and we have nothing to do - the code will exit through the
356 else if (expanded_size
> 0)
358 /* Success (maybe) - really uncompress the chunk. */
359 png_size_t new_size
= 0;
361 png_charp text
= png_malloc_warn(png_ptr
,
362 prefix_size
+ expanded_size
+ 1);
366 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
367 new_size
= png_inflate(png_ptr
,
368 (png_bytep
)(png_ptr
->chunkdata
+ prefix_size
),
369 chunklength
- prefix_size
,
370 (png_bytep
)(text
+ prefix_size
), expanded_size
);
371 text
[prefix_size
+ expanded_size
] = 0; /* just in case */
373 if (new_size
== expanded_size
)
375 png_free(png_ptr
, png_ptr
->chunkdata
);
376 png_ptr
->chunkdata
= text
;
377 *newlength
= prefix_size
+ expanded_size
;
378 return; /* The success return! */
381 png_warning(png_ptr
, "png_inflate logic error");
382 png_free(png_ptr
, text
);
385 png_warning(png_ptr
, "Not enough memory to decompress chunk.");
389 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
391 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
394 png_snprintf(umsg
, sizeof umsg
, "Unknown zTXt compression type %d",
396 png_warning(png_ptr
, umsg
);
398 png_warning(png_ptr
, "Unknown zTXt compression type");
401 /* The recovery is to simply drop the data. */
404 /* Generic error return - leave the prefix, delete the compressed
405 * data, reallocate the chunkdata to remove the potentially large
406 * amount of compressed data.
409 png_charp text
= png_malloc_warn(png_ptr
, prefix_size
+ 1);
413 png_memcpy(text
, png_ptr
->chunkdata
, prefix_size
);
414 png_free(png_ptr
, png_ptr
->chunkdata
);
415 png_ptr
->chunkdata
= text
;
417 /* This is an extra zero in the 'uncompressed' part. */
418 *(png_ptr
->chunkdata
+ prefix_size
) = 0x00;
420 /* Ignore a malloc error here - it is safe. */
423 *newlength
= prefix_size
;
427 /* Read and check the IDHR chunk */
429 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
432 png_uint_32 width
, height
;
433 int bit_depth
, color_type
, compression_type
, filter_type
;
436 png_debug(1, "in png_handle_IHDR");
438 if (png_ptr
->mode
& PNG_HAVE_IHDR
)
439 png_error(png_ptr
, "Out of place IHDR");
441 /* Check the length */
443 png_error(png_ptr
, "Invalid IHDR chunk");
445 png_ptr
->mode
|= PNG_HAVE_IHDR
;
447 png_crc_read(png_ptr
, buf
, 13);
448 png_crc_finish(png_ptr
, 0);
450 width
= png_get_uint_31(png_ptr
, buf
);
451 height
= png_get_uint_31(png_ptr
, buf
+ 4);
454 compression_type
= buf
[10];
455 filter_type
= buf
[11];
456 interlace_type
= buf
[12];
458 /* Set internal variables */
459 png_ptr
->width
= width
;
460 png_ptr
->height
= height
;
461 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
462 png_ptr
->interlaced
= (png_byte
)interlace_type
;
463 png_ptr
->color_type
= (png_byte
)color_type
;
464 #ifdef PNG_MNG_FEATURES_SUPPORTED
465 png_ptr
->filter_type
= (png_byte
)filter_type
;
467 png_ptr
->compression_type
= (png_byte
)compression_type
;
469 /* Find number of channels */
470 switch (png_ptr
->color_type
)
472 case PNG_COLOR_TYPE_GRAY
:
473 case PNG_COLOR_TYPE_PALETTE
:
474 png_ptr
->channels
= 1;
477 case PNG_COLOR_TYPE_RGB
:
478 png_ptr
->channels
= 3;
481 case PNG_COLOR_TYPE_GRAY_ALPHA
:
482 png_ptr
->channels
= 2;
485 case PNG_COLOR_TYPE_RGB_ALPHA
:
486 png_ptr
->channels
= 4;
490 /* Set up other useful info */
491 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
493 png_ptr
->rowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
, png_ptr
->width
);
494 png_debug1(3, "bit_depth = %d", png_ptr
->bit_depth
);
495 png_debug1(3, "channels = %d", png_ptr
->channels
);
496 png_debug1(3, "rowbytes = %lu", png_ptr
->rowbytes
);
497 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
498 color_type
, interlace_type
, compression_type
, filter_type
);
501 /* Read and check the palette */
503 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
505 png_color palette
[PNG_MAX_PALETTE_LENGTH
];
507 #ifdef PNG_POINTER_INDEXING_SUPPORTED
511 png_debug(1, "in png_handle_PLTE");
513 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
514 png_error(png_ptr
, "Missing IHDR before PLTE");
516 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
518 png_warning(png_ptr
, "Invalid PLTE after IDAT");
519 png_crc_finish(png_ptr
, length
);
523 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
524 png_error(png_ptr
, "Duplicate PLTE chunk");
526 png_ptr
->mode
|= PNG_HAVE_PLTE
;
528 if (!(png_ptr
->color_type
&PNG_COLOR_MASK_COLOR
))
531 "Ignoring PLTE chunk in grayscale PNG");
532 png_crc_finish(png_ptr
, length
);
535 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
536 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
538 png_crc_finish(png_ptr
, length
);
543 if (length
> 3*PNG_MAX_PALETTE_LENGTH
|| length
% 3)
545 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
547 png_warning(png_ptr
, "Invalid palette chunk");
548 png_crc_finish(png_ptr
, length
);
554 png_error(png_ptr
, "Invalid palette chunk");
558 num
= (int)length
/ 3;
560 #ifdef PNG_POINTER_INDEXING_SUPPORTED
561 for (i
= 0, pal_ptr
= palette
; i
< num
; i
++, pal_ptr
++)
565 png_crc_read(png_ptr
, buf
, 3);
566 pal_ptr
->red
= buf
[0];
567 pal_ptr
->green
= buf
[1];
568 pal_ptr
->blue
= buf
[2];
571 for (i
= 0; i
< num
; i
++)
575 png_crc_read(png_ptr
, buf
, 3);
576 /* Don't depend upon png_color being any order */
577 palette
[i
].red
= buf
[0];
578 palette
[i
].green
= buf
[1];
579 palette
[i
].blue
= buf
[2];
583 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
584 * whatever the normal CRC configuration tells us. However, if we
585 * have an RGB image, the PLTE can be considered ancillary, so
586 * we will act as though it is.
588 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
589 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
592 png_crc_finish(png_ptr
, 0);
594 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
595 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
597 /* If we don't want to use the data from an ancillary chunk,
598 we have two options: an error abort, or a warning and we
599 ignore the data in this chunk (which should be OK, since
600 it's considered ancillary for a RGB or RGBA image). */
601 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
603 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
605 png_chunk_error(png_ptr
, "CRC error");
609 png_chunk_warning(png_ptr
, "CRC error");
613 /* Otherwise, we (optionally) emit a warning and use the chunk. */
614 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
616 png_chunk_warning(png_ptr
, "CRC error");
621 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
623 #ifdef PNG_READ_tRNS_SUPPORTED
624 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
626 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
628 if (png_ptr
->num_trans
> (png_uint_16
)num
)
630 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
631 png_ptr
->num_trans
= (png_uint_16
)num
;
633 if (info_ptr
->num_trans
> (png_uint_16
)num
)
635 png_warning(png_ptr
, "Truncating incorrect info tRNS chunk length");
636 info_ptr
->num_trans
= (png_uint_16
)num
;
645 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
647 png_debug(1, "in png_handle_IEND");
649 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
651 png_error(png_ptr
, "No image in file");
654 png_ptr
->mode
|= (PNG_AFTER_IDAT
| PNG_HAVE_IEND
);
658 png_warning(png_ptr
, "Incorrect IEND chunk length");
660 png_crc_finish(png_ptr
, length
);
662 PNG_UNUSED(info_ptr
) /* Quiet compiler warnings about unused info_ptr */
665 #ifdef PNG_READ_gAMA_SUPPORTED
667 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
669 png_fixed_point igamma
;
670 #ifdef PNG_FLOATING_POINT_SUPPORTED
675 png_debug(1, "in png_handle_gAMA");
677 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
678 png_error(png_ptr
, "Missing IHDR before gAMA");
679 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
681 png_warning(png_ptr
, "Invalid gAMA after IDAT");
682 png_crc_finish(png_ptr
, length
);
685 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
686 /* Should be an error, but we can cope with it */
687 png_warning(png_ptr
, "Out of place gAMA chunk");
689 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
)
690 #ifdef PNG_READ_sRGB_SUPPORTED
691 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
695 png_warning(png_ptr
, "Duplicate gAMA chunk");
696 png_crc_finish(png_ptr
, length
);
702 png_warning(png_ptr
, "Incorrect gAMA chunk length");
703 png_crc_finish(png_ptr
, length
);
707 png_crc_read(png_ptr
, buf
, 4);
708 if (png_crc_finish(png_ptr
, 0))
711 igamma
= (png_fixed_point
)png_get_uint_32(buf
);
712 /* Check for zero gamma */
716 "Ignoring gAMA chunk with gamma=0");
720 #ifdef PNG_READ_sRGB_SUPPORTED
721 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
722 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
725 "Ignoring incorrect gAMA value when sRGB is also present");
726 #ifdef PNG_CONSOLE_IO_SUPPORTED
727 fprintf(stderr
, "gamma = (%d/100000)", (int)igamma
);
731 #endif /* PNG_READ_sRGB_SUPPORTED */
733 #ifdef PNG_FLOATING_POINT_SUPPORTED
734 file_gamma
= (float)igamma
/ (float)100000.0;
735 # ifdef PNG_READ_GAMMA_SUPPORTED
736 png_ptr
->gamma
= file_gamma
;
738 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
740 #ifdef PNG_FIXED_POINT_SUPPORTED
741 png_set_gAMA_fixed(png_ptr
, info_ptr
, igamma
);
746 #ifdef PNG_READ_sBIT_SUPPORTED
748 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
753 png_debug(1, "in png_handle_sBIT");
755 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
757 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
758 png_error(png_ptr
, "Missing IHDR before sBIT");
759 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
761 png_warning(png_ptr
, "Invalid sBIT after IDAT");
762 png_crc_finish(png_ptr
, length
);
765 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
767 /* Should be an error, but we can cope with it */
768 png_warning(png_ptr
, "Out of place sBIT chunk");
770 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sBIT
))
772 png_warning(png_ptr
, "Duplicate sBIT chunk");
773 png_crc_finish(png_ptr
, length
);
777 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
780 truelen
= (png_size_t
)png_ptr
->channels
;
782 if (length
!= truelen
|| length
> 4)
784 png_warning(png_ptr
, "Incorrect sBIT chunk length");
785 png_crc_finish(png_ptr
, length
);
789 png_crc_read(png_ptr
, buf
, truelen
);
790 if (png_crc_finish(png_ptr
, 0))
793 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
795 png_ptr
->sig_bit
.red
= buf
[0];
796 png_ptr
->sig_bit
.green
= buf
[1];
797 png_ptr
->sig_bit
.blue
= buf
[2];
798 png_ptr
->sig_bit
.alpha
= buf
[3];
802 png_ptr
->sig_bit
.gray
= buf
[0];
803 png_ptr
->sig_bit
.red
= buf
[0];
804 png_ptr
->sig_bit
.green
= buf
[0];
805 png_ptr
->sig_bit
.blue
= buf
[0];
806 png_ptr
->sig_bit
.alpha
= buf
[1];
808 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
812 #ifdef PNG_READ_cHRM_SUPPORTED
814 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
817 #ifdef PNG_FLOATING_POINT_SUPPORTED
818 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
820 png_fixed_point int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
821 int_y_green
, int_x_blue
, int_y_blue
;
823 png_uint_32 uint_x
, uint_y
;
825 png_debug(1, "in png_handle_cHRM");
827 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
828 png_error(png_ptr
, "Missing IHDR before cHRM");
829 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
831 png_warning(png_ptr
, "Invalid cHRM after IDAT");
832 png_crc_finish(png_ptr
, length
);
835 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
836 /* Should be an error, but we can cope with it */
837 png_warning(png_ptr
, "Missing PLTE before cHRM");
839 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
)
840 #ifdef PNG_READ_sRGB_SUPPORTED
841 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
845 png_warning(png_ptr
, "Duplicate cHRM chunk");
846 png_crc_finish(png_ptr
, length
);
852 png_warning(png_ptr
, "Incorrect cHRM chunk length");
853 png_crc_finish(png_ptr
, length
);
857 png_crc_read(png_ptr
, buf
, 32);
858 if (png_crc_finish(png_ptr
, 0))
861 uint_x
= png_get_uint_32(buf
);
862 uint_y
= png_get_uint_32(buf
+ 4);
863 int_x_white
= (png_fixed_point
)uint_x
;
864 int_y_white
= (png_fixed_point
)uint_y
;
866 uint_x
= png_get_uint_32(buf
+ 8);
867 uint_y
= png_get_uint_32(buf
+ 12);
868 int_x_red
= (png_fixed_point
)uint_x
;
869 int_y_red
= (png_fixed_point
)uint_y
;
871 uint_x
= png_get_uint_32(buf
+ 16);
872 uint_y
= png_get_uint_32(buf
+ 20);
873 int_x_green
= (png_fixed_point
)uint_x
;
874 int_y_green
= (png_fixed_point
)uint_y
;
876 uint_x
= png_get_uint_32(buf
+ 24);
877 uint_y
= png_get_uint_32(buf
+ 28);
878 int_x_blue
= (png_fixed_point
)uint_x
;
879 int_y_blue
= (png_fixed_point
)uint_y
;
881 #ifdef PNG_FLOATING_POINT_SUPPORTED
882 white_x
= (float)int_x_white
/ (float)100000.0;
883 white_y
= (float)int_y_white
/ (float)100000.0;
884 red_x
= (float)int_x_red
/ (float)100000.0;
885 red_y
= (float)int_y_red
/ (float)100000.0;
886 green_x
= (float)int_x_green
/ (float)100000.0;
887 green_y
= (float)int_y_green
/ (float)100000.0;
888 blue_x
= (float)int_x_blue
/ (float)100000.0;
889 blue_y
= (float)int_y_blue
/ (float)100000.0;
892 #ifdef PNG_READ_sRGB_SUPPORTED
893 if ((info_ptr
!= NULL
) && (info_ptr
->valid
& PNG_INFO_sRGB
))
895 if (PNG_OUT_OF_RANGE(int_x_white
, 31270, 1000) ||
896 PNG_OUT_OF_RANGE(int_y_white
, 32900, 1000) ||
897 PNG_OUT_OF_RANGE(int_x_red
, 64000L, 1000) ||
898 PNG_OUT_OF_RANGE(int_y_red
, 33000, 1000) ||
899 PNG_OUT_OF_RANGE(int_x_green
, 30000, 1000) ||
900 PNG_OUT_OF_RANGE(int_y_green
, 60000L, 1000) ||
901 PNG_OUT_OF_RANGE(int_x_blue
, 15000, 1000) ||
902 PNG_OUT_OF_RANGE(int_y_blue
, 6000, 1000))
905 "Ignoring incorrect cHRM value when sRGB is also present");
906 #ifdef PNG_CONSOLE_IO_SUPPORTED
907 #ifdef PNG_FLOATING_POINT_SUPPORTED
908 fprintf(stderr
, "wx=%f, wy=%f, rx=%f, ry=%f\n",
909 white_x
, white_y
, red_x
, red_y
);
910 fprintf(stderr
, "gx=%f, gy=%f, bx=%f, by=%f\n",
911 green_x
, green_y
, blue_x
, blue_y
);
913 fprintf(stderr
, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
914 (long)int_x_white
, (long)int_y_white
,
915 (long)int_x_red
, (long)int_y_red
);
916 fprintf(stderr
, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
917 (long)int_x_green
, (long)int_y_green
,
918 (long)int_x_blue
, (long)int_y_blue
);
920 #endif /* PNG_CONSOLE_IO_SUPPORTED */
924 #endif /* PNG_READ_sRGB_SUPPORTED */
926 #ifdef PNG_FLOATING_POINT_SUPPORTED
927 png_set_cHRM(png_ptr
, info_ptr
,
928 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
930 #ifdef PNG_FIXED_POINT_SUPPORTED
931 png_set_cHRM_fixed(png_ptr
, info_ptr
,
932 int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
933 int_y_green
, int_x_blue
, int_y_blue
);
938 #ifdef PNG_READ_sRGB_SUPPORTED
940 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
945 png_debug(1, "in png_handle_sRGB");
947 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
948 png_error(png_ptr
, "Missing IHDR before sRGB");
949 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
951 png_warning(png_ptr
, "Invalid sRGB after IDAT");
952 png_crc_finish(png_ptr
, length
);
955 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
956 /* Should be an error, but we can cope with it */
957 png_warning(png_ptr
, "Out of place sRGB chunk");
959 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
961 png_warning(png_ptr
, "Duplicate sRGB chunk");
962 png_crc_finish(png_ptr
, length
);
968 png_warning(png_ptr
, "Incorrect sRGB chunk length");
969 png_crc_finish(png_ptr
, length
);
973 png_crc_read(png_ptr
, buf
, 1);
974 if (png_crc_finish(png_ptr
, 0))
978 /* Check for bad intent */
979 if (intent
>= PNG_sRGB_INTENT_LAST
)
981 png_warning(png_ptr
, "Unknown sRGB intent");
985 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
986 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
))
988 png_fixed_point igamma
;
989 #ifdef PNG_FIXED_POINT_SUPPORTED
990 igamma
=info_ptr
->int_gamma
;
992 # ifdef PNG_FLOATING_POINT_SUPPORTED
993 igamma
=(png_fixed_point
)(info_ptr
->gamma
* 100000.);
996 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
999 "Ignoring incorrect gAMA value when sRGB is also present");
1000 #ifdef PNG_CONSOLE_IO_SUPPORTED
1001 # ifdef PNG_FIXED_POINT_SUPPORTED
1002 fprintf(stderr
, "incorrect gamma=(%d/100000)\n",
1003 (int)png_ptr
->int_gamma
);
1005 # ifdef PNG_FLOATING_POINT_SUPPORTED
1006 fprintf(stderr
, "incorrect gamma=%f\n", png_ptr
->gamma
);
1012 #endif /* PNG_READ_gAMA_SUPPORTED */
1014 #ifdef PNG_READ_cHRM_SUPPORTED
1015 #ifdef PNG_FIXED_POINT_SUPPORTED
1016 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
))
1017 if (PNG_OUT_OF_RANGE(info_ptr
->int_x_white
, 31270, 1000) ||
1018 PNG_OUT_OF_RANGE(info_ptr
->int_y_white
, 32900, 1000) ||
1019 PNG_OUT_OF_RANGE(info_ptr
->int_x_red
, 64000L, 1000) ||
1020 PNG_OUT_OF_RANGE(info_ptr
->int_y_red
, 33000, 1000) ||
1021 PNG_OUT_OF_RANGE(info_ptr
->int_x_green
, 30000, 1000) ||
1022 PNG_OUT_OF_RANGE(info_ptr
->int_y_green
, 60000L, 1000) ||
1023 PNG_OUT_OF_RANGE(info_ptr
->int_x_blue
, 15000, 1000) ||
1024 PNG_OUT_OF_RANGE(info_ptr
->int_y_blue
, 6000, 1000))
1026 png_warning(png_ptr
,
1027 "Ignoring incorrect cHRM value when sRGB is also present");
1029 #endif /* PNG_FIXED_POINT_SUPPORTED */
1030 #endif /* PNG_READ_cHRM_SUPPORTED */
1032 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
1034 #endif /* PNG_READ_sRGB_SUPPORTED */
1036 #ifdef PNG_READ_iCCP_SUPPORTED
1038 png_handle_iCCP(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1039 /* Note: this does not properly handle chunks that are > 64K under DOS */
1041 png_byte compression_type
;
1044 png_uint_32 skip
= 0;
1045 png_uint_32 profile_size
, profile_length
;
1046 png_size_t slength
, prefix_length
, data_length
;
1048 png_debug(1, "in png_handle_iCCP");
1050 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1051 png_error(png_ptr
, "Missing IHDR before iCCP");
1052 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1054 png_warning(png_ptr
, "Invalid iCCP after IDAT");
1055 png_crc_finish(png_ptr
, length
);
1058 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
1059 /* Should be an error, but we can cope with it */
1060 png_warning(png_ptr
, "Out of place iCCP chunk");
1062 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_iCCP
))
1064 png_warning(png_ptr
, "Duplicate iCCP chunk");
1065 png_crc_finish(png_ptr
, length
);
1069 #ifdef PNG_MAX_MALLOC_64K
1070 if (length
> (png_uint_32
)65535L)
1072 png_warning(png_ptr
, "iCCP chunk too large to fit in memory");
1073 skip
= length
- (png_uint_32
)65535L;
1074 length
= (png_uint_32
)65535L;
1078 png_free(png_ptr
, png_ptr
->chunkdata
);
1079 png_ptr
->chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1080 slength
= (png_size_t
)length
;
1081 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1083 if (png_crc_finish(png_ptr
, skip
))
1085 png_free(png_ptr
, png_ptr
->chunkdata
);
1086 png_ptr
->chunkdata
= NULL
;
1090 png_ptr
->chunkdata
[slength
] = 0x00;
1092 for (profile
= png_ptr
->chunkdata
; *profile
; profile
++)
1093 /* Empty loop to find end of name */ ;
1097 /* There should be at least one zero (the compression type byte)
1098 * following the separator, and we should be on it
1100 if ( profile
>= png_ptr
->chunkdata
+ slength
- 1)
1102 png_free(png_ptr
, png_ptr
->chunkdata
);
1103 png_ptr
->chunkdata
= NULL
;
1104 png_warning(png_ptr
, "Malformed iCCP chunk");
1108 /* Compression_type should always be zero */
1109 compression_type
= *profile
++;
1110 if (compression_type
)
1112 png_warning(png_ptr
, "Ignoring nonzero compression type in iCCP chunk");
1113 compression_type
= 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1117 prefix_length
= profile
- png_ptr
->chunkdata
;
1118 png_decompress_chunk(png_ptr
, compression_type
,
1119 slength
, prefix_length
, &data_length
);
1121 profile_length
= data_length
- prefix_length
;
1123 if ( prefix_length
> data_length
|| profile_length
< 4)
1125 png_free(png_ptr
, png_ptr
->chunkdata
);
1126 png_ptr
->chunkdata
= NULL
;
1127 png_warning(png_ptr
, "Profile size field missing from iCCP chunk");
1131 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1132 pC
= (png_bytep
)(png_ptr
->chunkdata
+ prefix_length
);
1133 profile_size
= ((*(pC
))<<24) |
1138 if (profile_size
< profile_length
)
1139 profile_length
= profile_size
;
1141 if (profile_size
> profile_length
)
1143 png_free(png_ptr
, png_ptr
->chunkdata
);
1144 png_ptr
->chunkdata
= NULL
;
1145 png_warning(png_ptr
, "Ignoring truncated iCCP profile.");
1149 png_set_iCCP(png_ptr
, info_ptr
, png_ptr
->chunkdata
,
1150 compression_type
, png_ptr
->chunkdata
+ prefix_length
, profile_length
);
1151 png_free(png_ptr
, png_ptr
->chunkdata
);
1152 png_ptr
->chunkdata
= NULL
;
1154 #endif /* PNG_READ_iCCP_SUPPORTED */
1156 #ifdef PNG_READ_sPLT_SUPPORTED
1158 png_handle_sPLT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1159 /* Note: this does not properly handle chunks that are > 64K under DOS */
1161 png_bytep entry_start
;
1162 png_sPLT_t new_palette
;
1163 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1166 int data_length
, entry_size
, i
;
1167 png_uint_32 skip
= 0;
1170 png_debug(1, "in png_handle_sPLT");
1172 #ifdef PNG_USER_LIMITS_SUPPORTED
1174 if (png_ptr
->user_chunk_cache_max
!= 0)
1176 if (png_ptr
->user_chunk_cache_max
== 1)
1178 png_crc_finish(png_ptr
, length
);
1181 if (--png_ptr
->user_chunk_cache_max
== 1)
1183 png_warning(png_ptr
, "No space in chunk cache for sPLT");
1184 png_crc_finish(png_ptr
, length
);
1190 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1191 png_error(png_ptr
, "Missing IHDR before sPLT");
1192 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1194 png_warning(png_ptr
, "Invalid sPLT after IDAT");
1195 png_crc_finish(png_ptr
, length
);
1199 #ifdef PNG_MAX_MALLOC_64K
1200 if (length
> (png_uint_32
)65535L)
1202 png_warning(png_ptr
, "sPLT chunk too large to fit in memory");
1203 skip
= length
- (png_uint_32
)65535L;
1204 length
= (png_uint_32
)65535L;
1208 png_free(png_ptr
, png_ptr
->chunkdata
);
1209 png_ptr
->chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1210 slength
= (png_size_t
)length
;
1211 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1213 if (png_crc_finish(png_ptr
, skip
))
1215 png_free(png_ptr
, png_ptr
->chunkdata
);
1216 png_ptr
->chunkdata
= NULL
;
1220 png_ptr
->chunkdata
[slength
] = 0x00;
1222 for (entry_start
= (png_bytep
)png_ptr
->chunkdata
; *entry_start
;
1224 /* Empty loop to find end of name */ ;
1227 /* A sample depth should follow the separator, and we should be on it */
1228 if (entry_start
> (png_bytep
)png_ptr
->chunkdata
+ slength
- 2)
1230 png_free(png_ptr
, png_ptr
->chunkdata
);
1231 png_ptr
->chunkdata
= NULL
;
1232 png_warning(png_ptr
, "malformed sPLT chunk");
1236 new_palette
.depth
= *entry_start
++;
1237 entry_size
= (new_palette
.depth
== 8 ? 6 : 10);
1238 data_length
= (slength
- (entry_start
- (png_bytep
)png_ptr
->chunkdata
));
1240 /* Integrity-check the data length */
1241 if (data_length
% entry_size
)
1243 png_free(png_ptr
, png_ptr
->chunkdata
);
1244 png_ptr
->chunkdata
= NULL
;
1245 png_warning(png_ptr
, "sPLT chunk has bad length");
1249 new_palette
.nentries
= (png_int_32
) ( data_length
/ entry_size
);
1250 if ((png_uint_32
) new_palette
.nentries
>
1251 (png_uint_32
) (PNG_SIZE_MAX
/ png_sizeof(png_sPLT_entry
)))
1253 png_warning(png_ptr
, "sPLT chunk too long");
1256 new_palette
.entries
= (png_sPLT_entryp
)png_malloc_warn(
1257 png_ptr
, new_palette
.nentries
* png_sizeof(png_sPLT_entry
));
1258 if (new_palette
.entries
== NULL
)
1260 png_warning(png_ptr
, "sPLT chunk requires too much memory");
1264 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1265 for (i
= 0; i
< new_palette
.nentries
; i
++)
1267 pp
= new_palette
.entries
+ i
;
1269 if (new_palette
.depth
== 8)
1271 pp
->red
= *entry_start
++;
1272 pp
->green
= *entry_start
++;
1273 pp
->blue
= *entry_start
++;
1274 pp
->alpha
= *entry_start
++;
1278 pp
->red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1279 pp
->green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1280 pp
->blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1281 pp
->alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1283 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1286 pp
= new_palette
.entries
;
1287 for (i
= 0; i
< new_palette
.nentries
; i
++)
1290 if (new_palette
.depth
== 8)
1292 pp
[i
].red
= *entry_start
++;
1293 pp
[i
].green
= *entry_start
++;
1294 pp
[i
].blue
= *entry_start
++;
1295 pp
[i
].alpha
= *entry_start
++;
1299 pp
[i
].red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1300 pp
[i
].green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1301 pp
[i
].blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1302 pp
[i
].alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1304 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1308 /* Discard all chunk data except the name and stash that */
1309 new_palette
.name
= png_ptr
->chunkdata
;
1311 png_set_sPLT(png_ptr
, info_ptr
, &new_palette
, 1);
1313 png_free(png_ptr
, png_ptr
->chunkdata
);
1314 png_ptr
->chunkdata
= NULL
;
1315 png_free(png_ptr
, new_palette
.entries
);
1317 #endif /* PNG_READ_sPLT_SUPPORTED */
1319 #ifdef PNG_READ_tRNS_SUPPORTED
1321 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1323 png_byte readbuf
[PNG_MAX_PALETTE_LENGTH
];
1325 png_debug(1, "in png_handle_tRNS");
1327 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1328 png_error(png_ptr
, "Missing IHDR before tRNS");
1329 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1331 png_warning(png_ptr
, "Invalid tRNS after IDAT");
1332 png_crc_finish(png_ptr
, length
);
1335 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
1337 png_warning(png_ptr
, "Duplicate tRNS chunk");
1338 png_crc_finish(png_ptr
, length
);
1342 if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
1348 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1349 png_crc_finish(png_ptr
, length
);
1353 png_crc_read(png_ptr
, buf
, 2);
1354 png_ptr
->num_trans
= 1;
1355 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
);
1357 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
1363 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1364 png_crc_finish(png_ptr
, length
);
1367 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
1368 png_ptr
->num_trans
= 1;
1369 png_ptr
->trans_values
.red
= png_get_uint_16(buf
);
1370 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2);
1371 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4);
1373 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1375 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1377 /* Should be an error, but we can cope with it. */
1378 png_warning(png_ptr
, "Missing PLTE before tRNS");
1380 if (length
> (png_uint_32
)png_ptr
->num_palette
||
1381 length
> PNG_MAX_PALETTE_LENGTH
)
1383 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1384 png_crc_finish(png_ptr
, length
);
1389 png_warning(png_ptr
, "Zero length tRNS chunk");
1390 png_crc_finish(png_ptr
, length
);
1393 png_crc_read(png_ptr
, readbuf
, (png_size_t
)length
);
1394 png_ptr
->num_trans
= (png_uint_16
)length
;
1398 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
1399 png_crc_finish(png_ptr
, length
);
1403 if (png_crc_finish(png_ptr
, 0))
1405 png_ptr
->num_trans
= 0;
1409 png_set_tRNS(png_ptr
, info_ptr
, readbuf
, png_ptr
->num_trans
,
1410 &(png_ptr
->trans_values
));
1414 #ifdef PNG_READ_bKGD_SUPPORTED
1416 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1421 png_debug(1, "in png_handle_bKGD");
1423 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1424 png_error(png_ptr
, "Missing IHDR before bKGD");
1425 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1427 png_warning(png_ptr
, "Invalid bKGD after IDAT");
1428 png_crc_finish(png_ptr
, length
);
1431 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
1432 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
1434 png_warning(png_ptr
, "Missing PLTE before bKGD");
1435 png_crc_finish(png_ptr
, length
);
1438 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_bKGD
))
1440 png_warning(png_ptr
, "Duplicate bKGD chunk");
1441 png_crc_finish(png_ptr
, length
);
1445 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1447 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1452 if (length
!= truelen
)
1454 png_warning(png_ptr
, "Incorrect bKGD chunk length");
1455 png_crc_finish(png_ptr
, length
);
1459 png_crc_read(png_ptr
, buf
, truelen
);
1460 if (png_crc_finish(png_ptr
, 0))
1463 /* We convert the index value into RGB components so that we can allow
1464 * arbitrary RGB values for background when we have transparency, and
1465 * so it is easy to determine the RGB values of the background color
1466 * from the info_ptr struct. */
1467 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1469 png_ptr
->background
.index
= buf
[0];
1470 if (info_ptr
&& info_ptr
->num_palette
)
1472 if (buf
[0] >= info_ptr
->num_palette
)
1474 png_warning(png_ptr
, "Incorrect bKGD chunk index value");
1477 png_ptr
->background
.red
=
1478 (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
1479 png_ptr
->background
.green
=
1480 (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
1481 png_ptr
->background
.blue
=
1482 (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
1485 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
1487 png_ptr
->background
.red
=
1488 png_ptr
->background
.green
=
1489 png_ptr
->background
.blue
=
1490 png_ptr
->background
.gray
= png_get_uint_16(buf
);
1494 png_ptr
->background
.red
= png_get_uint_16(buf
);
1495 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
1496 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
1499 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
1503 #ifdef PNG_READ_hIST_SUPPORTED
1505 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1507 unsigned int num
, i
;
1508 png_uint_16 readbuf
[PNG_MAX_PALETTE_LENGTH
];
1510 png_debug(1, "in png_handle_hIST");
1512 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1513 png_error(png_ptr
, "Missing IHDR before hIST");
1514 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1516 png_warning(png_ptr
, "Invalid hIST after IDAT");
1517 png_crc_finish(png_ptr
, length
);
1520 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1522 png_warning(png_ptr
, "Missing PLTE before hIST");
1523 png_crc_finish(png_ptr
, length
);
1526 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_hIST
))
1528 png_warning(png_ptr
, "Duplicate hIST chunk");
1529 png_crc_finish(png_ptr
, length
);
1533 if (length
> 2*PNG_MAX_PALETTE_LENGTH
||
1534 length
!= (unsigned int) (2*png_ptr
->num_palette
))
1536 png_warning(png_ptr
, "Incorrect hIST chunk length");
1537 png_crc_finish(png_ptr
, length
);
1543 for (i
= 0; i
< num
; i
++)
1547 png_crc_read(png_ptr
, buf
, 2);
1548 readbuf
[i
] = png_get_uint_16(buf
);
1551 if (png_crc_finish(png_ptr
, 0))
1554 png_set_hIST(png_ptr
, info_ptr
, readbuf
);
1558 #ifdef PNG_READ_pHYs_SUPPORTED
1560 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1563 png_uint_32 res_x
, res_y
;
1566 png_debug(1, "in png_handle_pHYs");
1568 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1569 png_error(png_ptr
, "Missing IHDR before pHYs");
1570 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1572 png_warning(png_ptr
, "Invalid pHYs after IDAT");
1573 png_crc_finish(png_ptr
, length
);
1576 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pHYs
))
1578 png_warning(png_ptr
, "Duplicate pHYs chunk");
1579 png_crc_finish(png_ptr
, length
);
1585 png_warning(png_ptr
, "Incorrect pHYs chunk length");
1586 png_crc_finish(png_ptr
, length
);
1590 png_crc_read(png_ptr
, buf
, 9);
1591 if (png_crc_finish(png_ptr
, 0))
1594 res_x
= png_get_uint_32(buf
);
1595 res_y
= png_get_uint_32(buf
+ 4);
1597 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
1601 #ifdef PNG_READ_oFFs_SUPPORTED
1603 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1606 png_int_32 offset_x
, offset_y
;
1609 png_debug(1, "in png_handle_oFFs");
1611 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1612 png_error(png_ptr
, "Missing IHDR before oFFs");
1613 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1615 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1616 png_crc_finish(png_ptr
, length
);
1619 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_oFFs
))
1621 png_warning(png_ptr
, "Duplicate oFFs chunk");
1622 png_crc_finish(png_ptr
, length
);
1628 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1629 png_crc_finish(png_ptr
, length
);
1633 png_crc_read(png_ptr
, buf
, 9);
1634 if (png_crc_finish(png_ptr
, 0))
1637 offset_x
= png_get_int_32(buf
);
1638 offset_y
= png_get_int_32(buf
+ 4);
1640 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1644 #ifdef PNG_READ_pCAL_SUPPORTED
1645 /* Read the pCAL chunk (described in the PNG Extensions document) */
1647 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1650 png_byte type
, nparams
;
1651 png_charp buf
, units
, endptr
;
1656 png_debug(1, "in png_handle_pCAL");
1658 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1659 png_error(png_ptr
, "Missing IHDR before pCAL");
1660 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1662 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1663 png_crc_finish(png_ptr
, length
);
1666 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pCAL
))
1668 png_warning(png_ptr
, "Duplicate pCAL chunk");
1669 png_crc_finish(png_ptr
, length
);
1673 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1675 png_free(png_ptr
, png_ptr
->chunkdata
);
1676 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1677 if (png_ptr
->chunkdata
== NULL
)
1679 png_warning(png_ptr
, "No memory for pCAL purpose.");
1682 slength
= (png_size_t
)length
;
1683 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1685 if (png_crc_finish(png_ptr
, 0))
1687 png_free(png_ptr
, png_ptr
->chunkdata
);
1688 png_ptr
->chunkdata
= NULL
;
1692 png_ptr
->chunkdata
[slength
] = 0x00; /* Null terminate the last string */
1694 png_debug(3, "Finding end of pCAL purpose string");
1695 for (buf
= png_ptr
->chunkdata
; *buf
; buf
++)
1698 endptr
= png_ptr
->chunkdata
+ slength
;
1700 /* We need to have at least 12 bytes after the purpose string
1701 in order to get the parameter information. */
1702 if (endptr
<= buf
+ 12)
1704 png_warning(png_ptr
, "Invalid pCAL data");
1705 png_free(png_ptr
, png_ptr
->chunkdata
);
1706 png_ptr
->chunkdata
= NULL
;
1710 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1711 X0
= png_get_int_32((png_bytep
)buf
+1);
1712 X1
= png_get_int_32((png_bytep
)buf
+5);
1717 png_debug(3, "Checking pCAL equation type and number of parameters");
1718 /* Check that we have the right number of parameters for known
1720 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1721 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1722 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1723 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1725 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1726 png_free(png_ptr
, png_ptr
->chunkdata
);
1727 png_ptr
->chunkdata
= NULL
;
1730 else if (type
>= PNG_EQUATION_LAST
)
1732 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1735 for (buf
= units
; *buf
; buf
++)
1736 /* Empty loop to move past the units string. */ ;
1738 png_debug(3, "Allocating pCAL parameters array");
1739 params
= (png_charpp
)png_malloc_warn(png_ptr
,
1740 (png_uint_32
)(nparams
* png_sizeof(png_charp
))) ;
1743 png_free(png_ptr
, png_ptr
->chunkdata
);
1744 png_ptr
->chunkdata
= NULL
;
1745 png_warning(png_ptr
, "No memory for pCAL params.");
1749 /* Get pointers to the start of each parameter string. */
1750 for (i
= 0; i
< (int)nparams
; i
++)
1752 buf
++; /* Skip the null string terminator from previous parameter. */
1754 png_debug1(3, "Reading pCAL parameter %d", i
);
1755 for (params
[i
] = buf
; buf
<= endptr
&& *buf
!= 0x00; buf
++)
1756 /* Empty loop to move past each parameter string */ ;
1758 /* Make sure we haven't run out of data yet */
1761 png_warning(png_ptr
, "Invalid pCAL data");
1762 png_free(png_ptr
, png_ptr
->chunkdata
);
1763 png_ptr
->chunkdata
= NULL
;
1764 png_free(png_ptr
, params
);
1769 png_set_pCAL(png_ptr
, info_ptr
, png_ptr
->chunkdata
, X0
, X1
, type
, nparams
,
1772 png_free(png_ptr
, png_ptr
->chunkdata
);
1773 png_ptr
->chunkdata
= NULL
;
1774 png_free(png_ptr
, params
);
1778 #ifdef PNG_READ_sCAL_SUPPORTED
1779 /* Read the sCAL chunk */
1781 png_handle_sCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1784 #ifdef PNG_FLOATING_POINT_SUPPORTED
1785 double width
, height
;
1788 #ifdef PNG_FIXED_POINT_SUPPORTED
1789 png_charp swidth
, sheight
;
1794 png_debug(1, "in png_handle_sCAL");
1796 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1797 png_error(png_ptr
, "Missing IHDR before sCAL");
1798 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1800 png_warning(png_ptr
, "Invalid sCAL after IDAT");
1801 png_crc_finish(png_ptr
, length
);
1804 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sCAL
))
1806 png_warning(png_ptr
, "Duplicate sCAL chunk");
1807 png_crc_finish(png_ptr
, length
);
1811 /* Need unit type, width, \0, height: minimum 4 bytes */
1812 else if (length
< 4)
1814 png_warning(png_ptr
, "sCAL chunk too short");
1815 png_crc_finish(png_ptr
, length
);
1819 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1821 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1822 if (png_ptr
->chunkdata
== NULL
)
1824 png_warning(png_ptr
, "Out of memory while processing sCAL chunk");
1825 png_crc_finish(png_ptr
, length
);
1828 slength
= (png_size_t
)length
;
1829 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
1831 if (png_crc_finish(png_ptr
, 0))
1833 png_free(png_ptr
, png_ptr
->chunkdata
);
1834 png_ptr
->chunkdata
= NULL
;
1838 png_ptr
->chunkdata
[slength
] = 0x00; /* Null terminate the last string */
1840 ep
= png_ptr
->chunkdata
+ 1; /* Skip unit byte */
1842 #ifdef PNG_FLOATING_POINT_SUPPORTED
1843 width
= png_strtod(png_ptr
, ep
, &vp
);
1846 png_warning(png_ptr
, "malformed width string in sCAL chunk");
1847 png_free(png_ptr
, png_ptr
->chunkdata
);
1848 png_ptr
->chunkdata
= NULL
;
1852 #ifdef PNG_FIXED_POINT_SUPPORTED
1853 swidth
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1856 png_warning(png_ptr
, "Out of memory while processing sCAL chunk width");
1857 png_free(png_ptr
, png_ptr
->chunkdata
);
1858 png_ptr
->chunkdata
= NULL
;
1861 png_memcpy(swidth
, ep
, (png_size_t
)png_strlen(ep
) + 1);
1865 for (ep
= png_ptr
->chunkdata
+ 1; *ep
; ep
++)
1869 if (png_ptr
->chunkdata
+ slength
< ep
)
1871 png_warning(png_ptr
, "Truncated sCAL chunk");
1872 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1873 png_free(png_ptr
, swidth
);
1875 png_free(png_ptr
, png_ptr
->chunkdata
);
1876 png_ptr
->chunkdata
= NULL
;
1880 #ifdef PNG_FLOATING_POINT_SUPPORTED
1881 height
= png_strtod(png_ptr
, ep
, &vp
);
1884 png_warning(png_ptr
, "malformed height string in sCAL chunk");
1885 png_free(png_ptr
, png_ptr
->chunkdata
);
1886 png_ptr
->chunkdata
= NULL
;
1887 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1888 png_free(png_ptr
, swidth
);
1893 #ifdef PNG_FIXED_POINT_SUPPORTED
1894 sheight
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1895 if (sheight
== NULL
)
1897 png_warning(png_ptr
, "Out of memory while processing sCAL chunk height");
1898 png_free(png_ptr
, png_ptr
->chunkdata
);
1899 png_ptr
->chunkdata
= NULL
;
1900 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1901 png_free(png_ptr
, swidth
);
1905 png_memcpy(sheight
, ep
, (png_size_t
)png_strlen(ep
) + 1);
1909 if (png_ptr
->chunkdata
+ slength
< ep
1910 #ifdef PNG_FLOATING_POINT_SUPPORTED
1911 || width
<= 0. || height
<= 0.
1915 png_warning(png_ptr
, "Invalid sCAL data");
1916 png_free(png_ptr
, png_ptr
->chunkdata
);
1917 png_ptr
->chunkdata
= NULL
;
1918 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1919 png_free(png_ptr
, swidth
);
1920 png_free(png_ptr
, sheight
);
1926 #ifdef PNG_FLOATING_POINT_SUPPORTED
1927 png_set_sCAL(png_ptr
, info_ptr
, png_ptr
->chunkdata
[0], width
, height
);
1929 #ifdef PNG_FIXED_POINT_SUPPORTED
1930 png_set_sCAL_s(png_ptr
, info_ptr
, png_ptr
->chunkdata
[0], swidth
, sheight
);
1934 png_free(png_ptr
, png_ptr
->chunkdata
);
1935 png_ptr
->chunkdata
= NULL
;
1936 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1937 png_free(png_ptr
, swidth
);
1938 png_free(png_ptr
, sheight
);
1943 #ifdef PNG_READ_tIME_SUPPORTED
1945 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1950 png_debug(1, "in png_handle_tIME");
1952 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1953 png_error(png_ptr
, "Out of place tIME chunk");
1954 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tIME
))
1956 png_warning(png_ptr
, "Duplicate tIME chunk");
1957 png_crc_finish(png_ptr
, length
);
1961 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1962 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1966 png_warning(png_ptr
, "Incorrect tIME chunk length");
1967 png_crc_finish(png_ptr
, length
);
1971 png_crc_read(png_ptr
, buf
, 7);
1972 if (png_crc_finish(png_ptr
, 0))
1975 mod_time
.second
= buf
[6];
1976 mod_time
.minute
= buf
[5];
1977 mod_time
.hour
= buf
[4];
1978 mod_time
.day
= buf
[3];
1979 mod_time
.month
= buf
[2];
1980 mod_time
.year
= png_get_uint_16(buf
);
1982 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1986 #ifdef PNG_READ_tEXt_SUPPORTED
1987 /* Note: this does not properly handle chunks that are > 64K under DOS */
1989 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1994 png_uint_32 skip
= 0;
1998 png_debug(1, "in png_handle_tEXt");
2000 #ifdef PNG_USER_LIMITS_SUPPORTED
2001 if (png_ptr
->user_chunk_cache_max
!= 0)
2003 if (png_ptr
->user_chunk_cache_max
== 1)
2005 png_crc_finish(png_ptr
, length
);
2008 if (--png_ptr
->user_chunk_cache_max
== 1)
2010 png_warning(png_ptr
, "No space in chunk cache for tEXt");
2011 png_crc_finish(png_ptr
, length
);
2017 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2018 png_error(png_ptr
, "Missing IHDR before tEXt");
2020 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2021 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2023 #ifdef PNG_MAX_MALLOC_64K
2024 if (length
> (png_uint_32
)65535L)
2026 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
2027 skip
= length
- (png_uint_32
)65535L;
2028 length
= (png_uint_32
)65535L;
2032 png_free(png_ptr
, png_ptr
->chunkdata
);
2034 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2035 if (png_ptr
->chunkdata
== NULL
)
2037 png_warning(png_ptr
, "No memory to process text chunk.");
2040 slength
= (png_size_t
)length
;
2041 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
2043 if (png_crc_finish(png_ptr
, skip
))
2045 png_free(png_ptr
, png_ptr
->chunkdata
);
2046 png_ptr
->chunkdata
= NULL
;
2050 key
= png_ptr
->chunkdata
;
2052 key
[slength
] = 0x00;
2054 for (text
= key
; *text
; text
++)
2055 /* Empty loop to find end of key */ ;
2057 if (text
!= key
+ slength
)
2060 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2061 (png_uint_32
)png_sizeof(png_text
));
2062 if (text_ptr
== NULL
)
2064 png_warning(png_ptr
, "Not enough memory to process text chunk.");
2065 png_free(png_ptr
, png_ptr
->chunkdata
);
2066 png_ptr
->chunkdata
= NULL
;
2069 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
2070 text_ptr
->key
= key
;
2071 #ifdef PNG_iTXt_SUPPORTED
2072 text_ptr
->lang
= NULL
;
2073 text_ptr
->lang_key
= NULL
;
2074 text_ptr
->itxt_length
= 0;
2076 text_ptr
->text
= text
;
2077 text_ptr
->text_length
= png_strlen(text
);
2079 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2081 png_free(png_ptr
, png_ptr
->chunkdata
);
2082 png_ptr
->chunkdata
= NULL
;
2083 png_free(png_ptr
, text_ptr
);
2085 png_warning(png_ptr
, "Insufficient memory to process text chunk.");
2089 #ifdef PNG_READ_zTXt_SUPPORTED
2090 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2092 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2098 png_size_t slength
, prefix_len
, data_len
;
2100 png_debug(1, "in png_handle_zTXt");
2102 #ifdef PNG_USER_LIMITS_SUPPORTED
2103 if (png_ptr
->user_chunk_cache_max
!= 0)
2105 if (png_ptr
->user_chunk_cache_max
== 1)
2107 png_crc_finish(png_ptr
, length
);
2110 if (--png_ptr
->user_chunk_cache_max
== 1)
2112 png_warning(png_ptr
, "No space in chunk cache for zTXt");
2113 png_crc_finish(png_ptr
, length
);
2119 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2120 png_error(png_ptr
, "Missing IHDR before zTXt");
2122 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2123 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2125 #ifdef PNG_MAX_MALLOC_64K
2126 /* We will no doubt have problems with chunks even half this size, but
2127 there is no hard and fast rule to tell us where to stop. */
2128 if (length
> (png_uint_32
)65535L)
2130 png_warning(png_ptr
, "zTXt chunk too large to fit in memory");
2131 png_crc_finish(png_ptr
, length
);
2136 png_free(png_ptr
, png_ptr
->chunkdata
);
2137 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2138 if (png_ptr
->chunkdata
== NULL
)
2140 png_warning(png_ptr
, "Out of memory processing zTXt chunk.");
2143 slength
= (png_size_t
)length
;
2144 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
2145 if (png_crc_finish(png_ptr
, 0))
2147 png_free(png_ptr
, png_ptr
->chunkdata
);
2148 png_ptr
->chunkdata
= NULL
;
2152 png_ptr
->chunkdata
[slength
] = 0x00;
2154 for (text
= png_ptr
->chunkdata
; *text
; text
++)
2157 /* zTXt must have some text after the chunkdataword */
2158 if (text
>= png_ptr
->chunkdata
+ slength
- 2)
2160 png_warning(png_ptr
, "Truncated zTXt chunk");
2161 png_free(png_ptr
, png_ptr
->chunkdata
);
2162 png_ptr
->chunkdata
= NULL
;
2167 comp_type
= *(++text
);
2168 if (comp_type
!= PNG_TEXT_COMPRESSION_zTXt
)
2170 png_warning(png_ptr
, "Unknown compression type in zTXt chunk");
2171 comp_type
= PNG_TEXT_COMPRESSION_zTXt
;
2173 text
++; /* Skip the compression_method byte */
2175 prefix_len
= text
- png_ptr
->chunkdata
;
2177 png_decompress_chunk(png_ptr
, comp_type
,
2178 (png_size_t
)length
, prefix_len
, &data_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 zTXt chunk.");
2185 png_free(png_ptr
, png_ptr
->chunkdata
);
2186 png_ptr
->chunkdata
= NULL
;
2189 text_ptr
->compression
= comp_type
;
2190 text_ptr
->key
= png_ptr
->chunkdata
;
2191 #ifdef PNG_iTXt_SUPPORTED
2192 text_ptr
->lang
= NULL
;
2193 text_ptr
->lang_key
= NULL
;
2194 text_ptr
->itxt_length
= 0;
2196 text_ptr
->text
= png_ptr
->chunkdata
+ prefix_len
;
2197 text_ptr
->text_length
= data_len
;
2199 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2201 png_free(png_ptr
, text_ptr
);
2202 png_free(png_ptr
, png_ptr
->chunkdata
);
2203 png_ptr
->chunkdata
= NULL
;
2205 png_error(png_ptr
, "Insufficient memory to store zTXt chunk.");
2209 #ifdef PNG_READ_iTXt_SUPPORTED
2210 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2212 png_handle_iTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2215 png_charp key
, lang
, text
, lang_key
;
2219 png_size_t slength
, prefix_len
, data_len
;
2221 png_debug(1, "in png_handle_iTXt");
2223 #ifdef PNG_USER_LIMITS_SUPPORTED
2224 if (png_ptr
->user_chunk_cache_max
!= 0)
2226 if (png_ptr
->user_chunk_cache_max
== 1)
2228 png_crc_finish(png_ptr
, length
);
2231 if (--png_ptr
->user_chunk_cache_max
== 1)
2233 png_warning(png_ptr
, "No space in chunk cache for iTXt");
2234 png_crc_finish(png_ptr
, length
);
2240 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2241 png_error(png_ptr
, "Missing IHDR before iTXt");
2243 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2244 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2246 #ifdef PNG_MAX_MALLOC_64K
2247 /* We will no doubt have problems with chunks even half this size, but
2248 there is no hard and fast rule to tell us where to stop. */
2249 if (length
> (png_uint_32
)65535L)
2251 png_warning(png_ptr
, "iTXt chunk too large to fit in memory");
2252 png_crc_finish(png_ptr
, length
);
2257 png_free(png_ptr
, png_ptr
->chunkdata
);
2258 png_ptr
->chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2259 if (png_ptr
->chunkdata
== NULL
)
2261 png_warning(png_ptr
, "No memory to process iTXt chunk.");
2264 slength
= (png_size_t
)length
;
2265 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->chunkdata
, slength
);
2266 if (png_crc_finish(png_ptr
, 0))
2268 png_free(png_ptr
, png_ptr
->chunkdata
);
2269 png_ptr
->chunkdata
= NULL
;
2273 png_ptr
->chunkdata
[slength
] = 0x00;
2275 for (lang
= png_ptr
->chunkdata
; *lang
; lang
++)
2277 lang
++; /* Skip NUL separator */
2279 /* iTXt must have a language tag (possibly empty), two compression bytes,
2280 * translated keyword (possibly empty), and possibly some text after the
2284 if (lang
>= png_ptr
->chunkdata
+ slength
- 3)
2286 png_warning(png_ptr
, "Truncated iTXt chunk");
2287 png_free(png_ptr
, png_ptr
->chunkdata
);
2288 png_ptr
->chunkdata
= NULL
;
2293 comp_flag
= *lang
++;
2294 comp_type
= *lang
++;
2297 for (lang_key
= lang
; *lang_key
; lang_key
++)
2299 lang_key
++; /* Skip NUL separator */
2301 if (lang_key
>= png_ptr
->chunkdata
+ slength
)
2303 png_warning(png_ptr
, "Truncated iTXt chunk");
2304 png_free(png_ptr
, png_ptr
->chunkdata
);
2305 png_ptr
->chunkdata
= NULL
;
2309 for (text
= lang_key
; *text
; text
++)
2311 text
++; /* Skip NUL separator */
2312 if (text
>= png_ptr
->chunkdata
+ slength
)
2314 png_warning(png_ptr
, "Malformed iTXt chunk");
2315 png_free(png_ptr
, png_ptr
->chunkdata
);
2316 png_ptr
->chunkdata
= NULL
;
2320 prefix_len
= text
- png_ptr
->chunkdata
;
2322 key
=png_ptr
->chunkdata
;
2324 png_decompress_chunk(png_ptr
, comp_type
,
2325 (size_t)length
, prefix_len
, &data_len
);
2327 data_len
= png_strlen(png_ptr
->chunkdata
+ prefix_len
);
2328 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2329 (png_uint_32
)png_sizeof(png_text
));
2330 if (text_ptr
== NULL
)
2332 png_warning(png_ptr
, "Not enough memory to process iTXt chunk.");
2333 png_free(png_ptr
, png_ptr
->chunkdata
);
2334 png_ptr
->chunkdata
= NULL
;
2337 text_ptr
->compression
= (int)comp_flag
+ 1;
2338 text_ptr
->lang_key
= png_ptr
->chunkdata
+ (lang_key
- key
);
2339 text_ptr
->lang
= png_ptr
->chunkdata
+ (lang
- key
);
2340 text_ptr
->itxt_length
= data_len
;
2341 text_ptr
->text_length
= 0;
2342 text_ptr
->key
= png_ptr
->chunkdata
;
2343 text_ptr
->text
= png_ptr
->chunkdata
+ prefix_len
;
2345 ret
= png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2347 png_free(png_ptr
, text_ptr
);
2348 png_free(png_ptr
, png_ptr
->chunkdata
);
2349 png_ptr
->chunkdata
= NULL
;
2351 png_error(png_ptr
, "Insufficient memory to store iTXt chunk.");
2355 /* This function is called when we haven't found a handler for a
2356 chunk. If there isn't a problem with the chunk itself (ie bad
2357 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2358 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2359 case it will be saved away to be written out later. */
2361 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2363 png_uint_32 skip
= 0;
2365 png_debug(1, "in png_handle_unknown");
2367 #ifdef PNG_USER_LIMITS_SUPPORTED
2368 if (png_ptr
->user_chunk_cache_max
!= 0)
2370 if (png_ptr
->user_chunk_cache_max
== 1)
2372 png_crc_finish(png_ptr
, length
);
2375 if (--png_ptr
->user_chunk_cache_max
== 1)
2377 png_warning(png_ptr
, "No space in chunk cache for unknown chunk");
2378 png_crc_finish(png_ptr
, length
);
2384 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2386 #ifdef PNG_USE_LOCAL_ARRAYS
2389 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4)) /* Not an IDAT */
2390 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2393 if (!(png_ptr
->chunk_name
[0] & 0x20))
2395 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2396 if (png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2397 PNG_HANDLE_CHUNK_ALWAYS
2398 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2399 && png_ptr
->read_user_chunk_fn
== NULL
2403 png_chunk_error(png_ptr
, "unknown critical chunk");
2406 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2407 if ((png_ptr
->flags
& PNG_FLAG_KEEP_UNKNOWN_CHUNKS
)
2408 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2409 || (png_ptr
->read_user_chunk_fn
!= NULL
)
2413 #ifdef PNG_MAX_MALLOC_64K
2414 if (length
> (png_uint_32
)65535L)
2416 png_warning(png_ptr
, "unknown chunk too large to fit in memory");
2417 skip
= length
- (png_uint_32
)65535L;
2418 length
= (png_uint_32
)65535L;
2421 png_memcpy((png_charp
)png_ptr
->unknown_chunk
.name
,
2422 (png_charp
)png_ptr
->chunk_name
,
2423 png_sizeof(png_ptr
->unknown_chunk
.name
));
2424 png_ptr
->unknown_chunk
.name
[png_sizeof(png_ptr
->unknown_chunk
.name
)-1]
2426 png_ptr
->unknown_chunk
.size
= (png_size_t
)length
;
2428 png_ptr
->unknown_chunk
.data
= NULL
;
2431 png_ptr
->unknown_chunk
.data
= (png_bytep
)png_malloc(png_ptr
, length
);
2432 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->unknown_chunk
.data
, length
);
2434 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2435 if (png_ptr
->read_user_chunk_fn
!= NULL
)
2437 /* Callback to user unknown chunk handler */
2439 ret
= (*(png_ptr
->read_user_chunk_fn
))
2440 (png_ptr
, &png_ptr
->unknown_chunk
);
2442 png_chunk_error(png_ptr
, "error in user chunk");
2445 if (!(png_ptr
->chunk_name
[0] & 0x20))
2446 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2447 if (png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2448 PNG_HANDLE_CHUNK_ALWAYS
)
2450 png_chunk_error(png_ptr
, "unknown critical chunk");
2451 png_set_unknown_chunks(png_ptr
, info_ptr
,
2452 &png_ptr
->unknown_chunk
, 1);
2457 png_set_unknown_chunks(png_ptr
, info_ptr
, &png_ptr
->unknown_chunk
, 1);
2458 png_free(png_ptr
, png_ptr
->unknown_chunk
.data
);
2459 png_ptr
->unknown_chunk
.data
= NULL
;
2465 png_crc_finish(png_ptr
, skip
);
2467 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2468 PNG_UNUSED(info_ptr
) /* Quiet compiler warnings about unused info_ptr */
2472 /* This function is called to verify that a chunk name is valid.
2473 This function can't have the "critical chunk check" incorporated
2474 into it, since in the future we will need to be able to call user
2475 functions to handle unknown critical chunks after we check that
2476 the chunk name itself is valid. */
2478 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2481 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
2483 png_debug(1, "in png_check_chunk_name");
2484 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
2485 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
2487 png_chunk_error(png_ptr
, "invalid chunk type");
2491 /* Combines the row recently read in with the existing pixels in the
2492 row. This routine takes care of alpha and transparency if requested.
2493 This routine also handles the two methods of progressive display
2494 of interlaced images, depending on the mask value.
2495 The mask value describes which pixels are to be combined with
2496 the row. The pattern always repeats every 8 pixels, so just 8
2497 bits are needed. A one indicates the pixel is to be combined,
2498 a zero indicates the pixel is to be skipped. This is in addition
2499 to any alpha or transparency value associated with the pixel. If
2500 you want all pixels to be combined, pass 0xff (255) in mask. */
2503 png_combine_row(png_structp png_ptr
, png_bytep row
, int mask
)
2505 png_debug(1, "in png_combine_row");
2508 png_memcpy(row
, png_ptr
->row_buf
+ 1,
2509 PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
, png_ptr
->width
));
2513 switch (png_ptr
->row_info
.pixel_depth
)
2517 png_bytep sp
= png_ptr
->row_buf
+ 1;
2519 int s_inc
, s_start
, s_end
;
2523 png_uint_32 row_width
= png_ptr
->width
;
2525 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2526 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2542 for (i
= 0; i
< row_width
; i
++)
2548 value
= (*sp
>> shift
) & 0x01;
2549 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2550 *dp
|= (png_byte
)(value
<< shift
);
2571 png_bytep sp
= png_ptr
->row_buf
+ 1;
2573 int s_start
, s_end
, s_inc
;
2577 png_uint_32 row_width
= png_ptr
->width
;
2580 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2581 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2597 for (i
= 0; i
< row_width
; i
++)
2601 value
= (*sp
>> shift
) & 0x03;
2602 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2603 *dp
|= (png_byte
)(value
<< shift
);
2623 png_bytep sp
= png_ptr
->row_buf
+ 1;
2625 int s_start
, s_end
, s_inc
;
2629 png_uint_32 row_width
= png_ptr
->width
;
2632 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2633 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2648 for (i
= 0; i
< row_width
; i
++)
2652 value
= (*sp
>> shift
) & 0xf;
2653 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2654 *dp
|= (png_byte
)(value
<< shift
);
2674 png_bytep sp
= png_ptr
->row_buf
+ 1;
2676 png_size_t pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
2678 png_uint_32 row_width
= png_ptr
->width
;
2682 for (i
= 0; i
< row_width
; i
++)
2686 png_memcpy(dp
, sp
, pixel_bytes
);
2703 #ifdef PNG_READ_INTERLACING_SUPPORTED
2704 /* OLD pre-1.0.9 interface:
2705 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2706 png_uint_32 transformations)
2709 png_do_read_interlace(png_structp png_ptr
)
2711 png_row_infop row_info
= &(png_ptr
->row_info
);
2712 png_bytep row
= png_ptr
->row_buf
+ 1;
2713 int pass
= png_ptr
->pass
;
2714 png_uint_32 transformations
= png_ptr
->transformations
;
2715 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2716 /* Offset to next interlace block */
2717 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2719 png_debug(1, "in png_do_read_interlace");
2720 if (row
!= NULL
&& row_info
!= NULL
)
2722 png_uint_32 final_width
;
2724 final_width
= row_info
->width
* png_pass_inc
[pass
];
2726 switch (row_info
->pixel_depth
)
2730 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2731 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
2733 int s_start
, s_end
, s_inc
;
2734 int jstop
= png_pass_inc
[pass
];
2739 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2740 if (transformations
& PNG_PACKSWAP
)
2742 sshift
= (int)((row_info
->width
+ 7) & 0x07);
2743 dshift
= (int)((final_width
+ 7) & 0x07);
2751 sshift
= 7 - (int)((row_info
->width
+ 7) & 0x07);
2752 dshift
= 7 - (int)((final_width
+ 7) & 0x07);
2758 for (i
= 0; i
< row_info
->width
; i
++)
2760 v
= (png_byte
)((*sp
>> sshift
) & 0x01);
2761 for (j
= 0; j
< jstop
; j
++)
2763 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
2764 *dp
|= (png_byte
)(v
<< dshift
);
2765 if (dshift
== s_end
)
2773 if (sshift
== s_end
)
2785 png_bytep sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
2786 png_bytep dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
2788 int s_start
, s_end
, s_inc
;
2789 int jstop
= png_pass_inc
[pass
];
2792 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2793 if (transformations
& PNG_PACKSWAP
)
2795 sshift
= (int)(((row_info
->width
+ 3) & 0x03) << 1);
2796 dshift
= (int)(((final_width
+ 3) & 0x03) << 1);
2804 sshift
= (int)((3 - ((row_info
->width
+ 3) & 0x03)) << 1);
2805 dshift
= (int)((3 - ((final_width
+ 3) & 0x03)) << 1);
2811 for (i
= 0; i
< row_info
->width
; i
++)
2816 v
= (png_byte
)((*sp
>> sshift
) & 0x03);
2817 for (j
= 0; j
< jstop
; j
++)
2819 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
2820 *dp
|= (png_byte
)(v
<< dshift
);
2821 if (dshift
== s_end
)
2829 if (sshift
== s_end
)
2841 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2842 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
2844 int s_start
, s_end
, s_inc
;
2846 int jstop
= png_pass_inc
[pass
];
2848 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2849 if (transformations
& PNG_PACKSWAP
)
2851 sshift
= (int)(((row_info
->width
+ 1) & 0x01) << 2);
2852 dshift
= (int)(((final_width
+ 1) & 0x01) << 2);
2860 sshift
= (int)((1 - ((row_info
->width
+ 1) & 0x01)) << 2);
2861 dshift
= (int)((1 - ((final_width
+ 1) & 0x01)) << 2);
2867 for (i
= 0; i
< row_info
->width
; i
++)
2869 png_byte v
= (png_byte
)((*sp
>> sshift
) & 0xf);
2872 for (j
= 0; j
< jstop
; j
++)
2874 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
2875 *dp
|= (png_byte
)(v
<< dshift
);
2876 if (dshift
== s_end
)
2884 if (sshift
== s_end
)
2896 png_size_t pixel_bytes
= (row_info
->pixel_depth
>> 3);
2897 png_bytep sp
= row
+ (png_size_t
)(row_info
->width
- 1)
2899 png_bytep dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
2901 int jstop
= png_pass_inc
[pass
];
2904 for (i
= 0; i
< row_info
->width
; i
++)
2909 png_memcpy(v
, sp
, pixel_bytes
);
2910 for (j
= 0; j
< jstop
; j
++)
2912 png_memcpy(dp
, v
, pixel_bytes
);
2920 row_info
->width
= final_width
;
2921 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
, final_width
);
2923 #ifndef PNG_READ_PACKSWAP_SUPPORTED
2924 PNG_UNUSED(transformations
) /* Silence compiler warning */
2927 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2930 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
2931 png_bytep prev_row
, int filter
)
2933 png_debug(1, "in png_read_filter_row");
2934 png_debug2(2, "row = %lu, filter = %d", png_ptr
->row_number
, filter
);
2937 case PNG_FILTER_VALUE_NONE
:
2939 case PNG_FILTER_VALUE_SUB
:
2942 png_uint_32 istop
= row_info
->rowbytes
;
2943 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2944 png_bytep rp
= row
+ bpp
;
2947 for (i
= bpp
; i
< istop
; i
++)
2949 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
++)) & 0xff);
2954 case PNG_FILTER_VALUE_UP
:
2957 png_uint_32 istop
= row_info
->rowbytes
;
2959 png_bytep pp
= prev_row
;
2961 for (i
= 0; i
< istop
; i
++)
2963 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2968 case PNG_FILTER_VALUE_AVG
:
2972 png_bytep pp
= prev_row
;
2974 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2975 png_uint_32 istop
= row_info
->rowbytes
- bpp
;
2977 for (i
= 0; i
< bpp
; i
++)
2979 *rp
= (png_byte
)(((int)(*rp
) +
2980 ((int)(*pp
++) / 2 )) & 0xff);
2984 for (i
= 0; i
< istop
; i
++)
2986 *rp
= (png_byte
)(((int)(*rp
) +
2987 (int)(*pp
++ + *lp
++) / 2 ) & 0xff);
2992 case PNG_FILTER_VALUE_PAETH
:
2996 png_bytep pp
= prev_row
;
2998 png_bytep cp
= prev_row
;
2999 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
3000 png_uint_32 istop
=row_info
->rowbytes
- bpp
;
3002 for (i
= 0; i
< bpp
; i
++)
3004 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
3008 for (i
= 0; i
< istop
; i
++) /* Use leftover rp,pp */
3010 int a
, b
, c
, pa
, pb
, pc
, p
;
3024 pa
= p
< 0 ? -p
: p
;
3025 pb
= pc
< 0 ? -pc
: pc
;
3026 pc
= (p
+ pc
) < 0 ? -(p
+ pc
) : p
+ pc
;
3030 if (pa <= pb && pa <= pc)
3038 p
= (pa
<= pb
&& pa
<= pc
) ? a
: (pb
<= pc
) ? b
: c
;
3040 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
3046 png_warning(png_ptr
, "Ignoring bad adaptive filter type");
3052 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3054 png_read_finish_row(png_structp png_ptr
)
3056 #ifdef PNG_READ_INTERLACING_SUPPORTED
3057 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3059 /* Start of interlace block */
3060 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
3062 /* Offset to next interlace block */
3063 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
3065 /* Start of interlace block in the y direction */
3066 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
3068 /* Offset to next interlace block in the y direction */
3069 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
3070 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3072 png_debug(1, "in png_read_finish_row");
3073 png_ptr
->row_number
++;
3074 if (png_ptr
->row_number
< png_ptr
->num_rows
)
3077 #ifdef PNG_READ_INTERLACING_SUPPORTED
3078 if (png_ptr
->interlaced
)
3080 png_ptr
->row_number
= 0;
3081 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0,
3082 png_ptr
->rowbytes
+ 1);
3086 if (png_ptr
->pass
>= 7)
3088 png_ptr
->iwidth
= (png_ptr
->width
+
3089 png_pass_inc
[png_ptr
->pass
] - 1 -
3090 png_pass_start
[png_ptr
->pass
]) /
3091 png_pass_inc
[png_ptr
->pass
];
3093 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
3095 png_ptr
->num_rows
= (png_ptr
->height
+
3096 png_pass_yinc
[png_ptr
->pass
] - 1 -
3097 png_pass_ystart
[png_ptr
->pass
]) /
3098 png_pass_yinc
[png_ptr
->pass
];
3099 if (!(png_ptr
->num_rows
))
3102 else /* if (png_ptr->transformations & PNG_INTERLACE) */
3104 } while (png_ptr
->iwidth
== 0);
3106 if (png_ptr
->pass
< 7)
3109 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3111 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
3113 #ifdef PNG_USE_LOCAL_ARRAYS
3119 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
3120 png_ptr
->zstream
.avail_out
= (uInt
)1;
3123 if (!(png_ptr
->zstream
.avail_in
))
3125 while (!png_ptr
->idat_size
)
3127 png_byte chunk_length
[4];
3129 png_crc_finish(png_ptr
, 0);
3131 png_read_data(png_ptr
, chunk_length
, 4);
3132 png_ptr
->idat_size
= png_get_uint_31(png_ptr
, chunk_length
);
3133 png_reset_crc(png_ptr
);
3134 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
3135 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4))
3136 png_error(png_ptr
, "Not enough image data");
3139 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
3140 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
3141 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
3142 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
3143 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
3144 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
3146 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
3147 if (ret
== Z_STREAM_END
)
3149 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
3151 png_warning(png_ptr
, "Extra compressed data.");
3152 png_ptr
->mode
|= PNG_AFTER_IDAT
;
3153 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
3157 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
3158 "Decompression Error");
3160 if (!(png_ptr
->zstream
.avail_out
))
3162 png_warning(png_ptr
, "Extra compressed data.");
3163 png_ptr
->mode
|= PNG_AFTER_IDAT
;
3164 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
3169 png_ptr
->zstream
.avail_out
= 0;
3172 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
3173 png_warning(png_ptr
, "Extra compression data.");
3175 inflateReset(&png_ptr
->zstream
);
3177 png_ptr
->mode
|= PNG_AFTER_IDAT
;
3179 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3182 png_read_start_row(png_structp png_ptr
)
3184 #ifdef PNG_READ_INTERLACING_SUPPORTED
3185 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3187 /* Start of interlace block */
3188 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
3190 /* Offset to next interlace block */
3191 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
3193 /* Start of interlace block in the y direction */
3194 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
3196 /* Offset to next interlace block in the y direction */
3197 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
3200 int max_pixel_depth
;
3201 png_size_t row_bytes
;
3203 png_debug(1, "in png_read_start_row");
3204 png_ptr
->zstream
.avail_in
= 0;
3205 png_init_read_transformations(png_ptr
);
3206 #ifdef PNG_READ_INTERLACING_SUPPORTED
3207 if (png_ptr
->interlaced
)
3209 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
3210 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
3211 png_pass_ystart
[0]) / png_pass_yinc
[0];
3213 png_ptr
->num_rows
= png_ptr
->height
;
3215 png_ptr
->iwidth
= (png_ptr
->width
+
3216 png_pass_inc
[png_ptr
->pass
] - 1 -
3217 png_pass_start
[png_ptr
->pass
]) /
3218 png_pass_inc
[png_ptr
->pass
];
3221 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3223 png_ptr
->num_rows
= png_ptr
->height
;
3224 png_ptr
->iwidth
= png_ptr
->width
;
3226 max_pixel_depth
= png_ptr
->pixel_depth
;
3228 #ifdef PNG_READ_PACK_SUPPORTED
3229 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
3230 max_pixel_depth
= 8;
3233 #ifdef PNG_READ_EXPAND_SUPPORTED
3234 if (png_ptr
->transformations
& PNG_EXPAND
)
3236 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3238 if (png_ptr
->num_trans
)
3239 max_pixel_depth
= 32;
3241 max_pixel_depth
= 24;
3243 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3245 if (max_pixel_depth
< 8)
3246 max_pixel_depth
= 8;
3247 if (png_ptr
->num_trans
)
3248 max_pixel_depth
*= 2;
3250 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3252 if (png_ptr
->num_trans
)
3254 max_pixel_depth
*= 4;
3255 max_pixel_depth
/= 3;
3261 #ifdef PNG_READ_FILLER_SUPPORTED
3262 if (png_ptr
->transformations
& (PNG_FILLER
))
3264 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3265 max_pixel_depth
= 32;
3266 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3268 if (max_pixel_depth
<= 8)
3269 max_pixel_depth
= 16;
3271 max_pixel_depth
= 32;
3273 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3275 if (max_pixel_depth
<= 32)
3276 max_pixel_depth
= 32;
3278 max_pixel_depth
= 64;
3283 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3284 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
3287 #ifdef PNG_READ_EXPAND_SUPPORTED
3288 (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
3290 #ifdef PNG_READ_FILLER_SUPPORTED
3291 (png_ptr
->transformations
& (PNG_FILLER
)) ||
3293 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
3295 if (max_pixel_depth
<= 16)
3296 max_pixel_depth
= 32;
3298 max_pixel_depth
= 64;
3302 if (max_pixel_depth
<= 8)
3304 if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3305 max_pixel_depth
= 32;
3307 max_pixel_depth
= 24;
3309 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3310 max_pixel_depth
= 64;
3312 max_pixel_depth
= 48;
3317 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3318 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3319 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
3321 int user_pixel_depth
= png_ptr
->user_transform_depth
*
3322 png_ptr
->user_transform_channels
;
3323 if (user_pixel_depth
> max_pixel_depth
)
3324 max_pixel_depth
=user_pixel_depth
;
3328 /* Align the width on the next larger 8 pixels. Mainly used
3331 row_bytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
3332 /* Calculate the maximum bytes needed, adding a byte and a pixel
3335 row_bytes
= PNG_ROWBYTES(max_pixel_depth
, row_bytes
) +
3336 1 + ((max_pixel_depth
+ 7) >> 3);
3337 #ifdef PNG_MAX_MALLOC_64K
3338 if (row_bytes
> (png_uint_32
)65536L)
3339 png_error(png_ptr
, "This image requires a row greater than 64KB");
3342 if (row_bytes
+ 64 > png_ptr
->old_big_row_buf_size
)
3344 png_free(png_ptr
, png_ptr
->big_row_buf
);
3345 if (png_ptr
->interlaced
)
3346 png_ptr
->big_row_buf
= (png_bytep
)png_calloc(png_ptr
,
3349 png_ptr
->big_row_buf
= (png_bytep
)png_malloc(png_ptr
,
3351 png_ptr
->old_big_row_buf_size
= row_bytes
+ 64;
3353 /* Use 32 bytes of padding before and after row_buf. */
3354 png_ptr
->row_buf
= png_ptr
->big_row_buf
+ 32;
3355 png_ptr
->old_big_row_buf_size
= row_bytes
+ 64;
3358 #ifdef PNG_MAX_MALLOC_64K
3359 if ((png_uint_32
)row_bytes
+ 1 > (png_uint_32
)65536L)
3360 png_error(png_ptr
, "This image requires a row greater than 64KB");
3362 if ((png_uint_32
)row_bytes
> (png_uint_32
)(PNG_SIZE_MAX
- 1))
3363 png_error(png_ptr
, "Row has too many bytes to allocate in memory.");
3365 if (row_bytes
+ 1 > png_ptr
->old_prev_row_size
)
3367 png_free(png_ptr
, png_ptr
->prev_row
);
3368 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
3370 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, row_bytes
+ 1);
3371 png_ptr
->old_prev_row_size
= row_bytes
+ 1;
3374 png_ptr
->rowbytes
= row_bytes
;
3376 png_debug1(3, "width = %lu,", png_ptr
->width
);
3377 png_debug1(3, "height = %lu,", png_ptr
->height
);
3378 png_debug1(3, "iwidth = %lu,", png_ptr
->iwidth
);
3379 png_debug1(3, "num_rows = %lu,", png_ptr
->num_rows
);
3380 png_debug1(3, "rowbytes = %lu,", png_ptr
->rowbytes
);
3381 png_debug1(3, "irowbytes = %lu",
3382 PNG_ROWBYTES(png_ptr
->pixel_depth
, png_ptr
->iwidth
) + 1);
3384 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;
3386 #endif /* PNG_READ_SUPPORTED */