2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.4.0 [January 3, 2010]
5 * Copyright (c) 1998-2010 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.
17 #define PNG_NO_PEDANTIC_WARNINGS
19 #ifdef PNG_READ_SUPPORTED
22 # define png_strtod(p,a,b) strtod(a,b)
24 png_get_uint_31(png_structp png_ptr, png_bytep buf)
26 png_uint_32 i = png_get_uint_32(buf);
27 if (i > PNG_UINT_31_MAX)
28 png_error(png_ptr, "PNG unsigned integer out of range");
31 #ifndef PNG_USE_READ_MACROS
32 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
34 png_get_uint_32(png_bytep buf)
36 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
37 ((png_uint_32)(*(buf + 1)) << 16) +
38 ((png_uint_32)(*(buf + 2)) << 8) +
39 (png_uint_32)(*(buf + 3));
44 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
45 * data is stored in the PNG file in two's complement format, and it is
46 * assumed that the machine format for signed integers is the same.
49 png_get_int_32(png_bytep buf)
51 png_int_32 i = ((png_int_32)(*buf) << 24) +
52 ((png_int_32)(*(buf + 1)) << 16) +
53 ((png_int_32)(*(buf + 2)) << 8) +
54 (png_int_32)(*(buf + 3));
59 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
61 png_get_uint_16(png_bytep buf)
63 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
64 (png_uint_16)(*(buf + 1)));
68 #endif /* PNG_USE_READ_MACROS */
70 /* Read the chunk header (length + type name).
71 * Put the type name into png_ptr->chunk_name, and return the length.
73 png_uint_32 /* PRIVATE */
74 png_read_chunk_header(png_structp png_ptr)
79 #ifdef PNG_IO_STATE_SUPPORTED
80 /* Inform the I/O callback that the chunk header is being read.
81 * PNG_IO_CHUNK_HDR requires a single I/O call.
83 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
86 /* Read the length and the chunk name */
87 png_read_data(png_ptr, buf, 8);
88 length = png_get_uint_31(png_ptr, buf);
90 /* Put the chunk name into png_ptr->chunk_name */
91 png_memcpy(png_ptr->chunk_name, buf + 4, 4);
93 png_debug2(0, "Reading %s chunk, length = %lu",
94 png_ptr->chunk_name, length);
96 /* Reset the crc and run it over the chunk name */
97 png_reset_crc(png_ptr);
98 png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
100 /* Check to see if chunk name is valid */
101 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
103 #ifdef PNG_IO_STATE_SUPPORTED
104 /* Inform the I/O callback that chunk data will (possibly) be read.
105 * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
107 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
113 /* Read data, and (optionally) run it through the CRC. */
115 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
119 png_read_data(png_ptr, buf, length);
120 png_calculate_crc(png_ptr, buf, length);
123 /* Optionally skip data and then check the CRC. Depending on whether we
124 * are reading a ancillary or critical chunk, and how the program has set
125 * things up, we may calculate the CRC on the data and print a message.
126 * Returns '1' if there was a CRC error, '0' otherwise.
129 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
132 png_size_t istop = png_ptr->zbuf_size;
134 for (i = (png_size_t)skip; i > istop; i -= istop)
136 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
140 png_crc_read(png_ptr, png_ptr->zbuf, i);
143 if (png_crc_error(png_ptr))
145 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
146 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
147 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
148 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
150 png_chunk_warning(png_ptr, "CRC error");
154 png_chunk_benign_error(png_ptr, "CRC error");
163 /* Compare the CRC stored in the PNG file with that calculated by libpng from
164 * the data it has read thus far.
167 png_crc_error(png_structp png_ptr)
169 png_byte crc_bytes[4];
173 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
175 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
176 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
181 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
185 #ifdef PNG_IO_STATE_SUPPORTED
186 /* Inform the I/O callback that the chunk CRC is being read */
187 /* PNG_IO_CHUNK_CRC requires the I/O to be done at once */
188 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
191 png_read_data(png_ptr, crc_bytes, 4);
195 crc = png_get_uint_32(crc_bytes);
196 return ((int)(crc != png_ptr->crc));
202 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
203 defined(PNG_READ_iCCP_SUPPORTED)
205 * Decompress trailing data in a chunk. The assumption is that chunkdata
206 * points at an allocated area holding the contents of a chunk with a
207 * trailing compressed part. What we get back is an allocated area
208 * holding the original prefix part and an uncompressed version of the
209 * trailing part (the malloc area passed in is freed).
212 png_decompress_chunk(png_structp png_ptr, int comp_type,
213 png_size_t chunklength,
214 png_size_t prefix_size, png_size_t *newlength)
216 static PNG_CONST char msg[] = "Error decoding compressed chunk";
218 png_size_t text_size;
220 if (comp_type == PNG_COMPRESSION_TYPE_BASE)
223 png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size);
224 png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
225 png_ptr->zstream.next_out = png_ptr->zbuf;
226 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
231 while (png_ptr->zstream.avail_in)
233 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
234 if (ret != Z_OK && ret != Z_STREAM_END)
236 if (png_ptr->zstream.msg != NULL)
237 png_warning(png_ptr, png_ptr->zstream.msg);
239 png_warning(png_ptr, msg);
240 inflateReset(&png_ptr->zstream);
241 png_ptr->zstream.avail_in = 0;
245 text_size = prefix_size + png_sizeof(msg) + 1;
246 text = (png_charp)png_malloc_warn(png_ptr, text_size);
249 png_free(png_ptr, png_ptr->chunkdata);
250 png_ptr->chunkdata = NULL;
251 png_error(png_ptr, "Not enough memory to decompress chunk");
253 png_memcpy(text, png_ptr->chunkdata, prefix_size);
256 text[text_size - 1] = 0x00;
258 /* Copy what we can of the error message into the text chunk */
259 text_size = (png_size_t)(chunklength -
260 (text - png_ptr->chunkdata) - 1);
261 if (text_size > png_sizeof(msg))
262 text_size = png_sizeof(msg);
263 png_memcpy(text + prefix_size, msg, text_size);
266 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
270 text_size = prefix_size +
271 png_ptr->zbuf_size - png_ptr->zstream.avail_out;
272 text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
275 png_free(png_ptr, png_ptr->chunkdata);
276 png_ptr->chunkdata = NULL;
278 "Not enough memory to decompress chunk");
280 png_memcpy(text + prefix_size, png_ptr->zbuf,
281 text_size - prefix_size);
282 png_memcpy(text, png_ptr->chunkdata, prefix_size);
283 *(text + text_size) = 0x00;
290 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
291 if ((png_ptr->user_chunk_cache_max != 0) &&
292 (--png_ptr->user_chunk_cache_max == 0))
294 png_warning(png_ptr, "No space in chunk cache");
301 text = (png_charp)png_malloc_warn(png_ptr,
302 (png_size_t)(text_size +
303 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
304 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
309 png_free(png_ptr, tmp);
310 png_free(png_ptr, png_ptr->chunkdata);
311 png_ptr->chunkdata = NULL;
313 "Not enough memory to decompress chunk");
315 png_memcpy(text, tmp, text_size);
316 png_free(png_ptr, tmp);
317 png_memcpy(text + text_size, png_ptr->zbuf,
318 (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
319 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
320 *(text + text_size) = 0x00;
322 if (ret == Z_STREAM_END)
326 png_ptr->zstream.next_out = png_ptr->zbuf;
327 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
331 if (ret != Z_STREAM_END)
333 #ifdef PNG_STDIO_SUPPORTED
336 if (ret == Z_BUF_ERROR)
337 png_snprintf(umsg, 52,
338 "Buffer error in compressed datastream in %s chunk",
339 png_ptr->chunk_name);
341 else if (ret == Z_DATA_ERROR)
342 png_snprintf(umsg, 52,
343 "Data error in compressed datastream in %s chunk",
344 png_ptr->chunk_name);
347 png_snprintf(umsg, 52,
348 "Incomplete compressed datastream in %s chunk",
349 png_ptr->chunk_name);
351 png_warning(png_ptr, umsg);
354 "Incomplete compressed datastream in chunk other than IDAT");
356 text_size = prefix_size;
359 text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
362 png_free(png_ptr, png_ptr->chunkdata);
363 png_ptr->chunkdata = NULL;
364 png_error(png_ptr, "Not enough memory for text");
366 png_memcpy(text, png_ptr->chunkdata, prefix_size);
368 *(text + text_size) = 0x00;
371 inflateReset(&png_ptr->zstream);
372 png_ptr->zstream.avail_in = 0;
374 png_free(png_ptr, png_ptr->chunkdata);
375 png_ptr->chunkdata = text;
376 *newlength=text_size;
378 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
380 #ifdef PNG_STDIO_SUPPORTED
383 png_snprintf(umsg, 50, "Unknown zTXt compression type %d", comp_type);
384 png_warning(png_ptr, umsg);
386 png_warning(png_ptr, "Unknown zTXt compression type");
389 *(png_ptr->chunkdata + prefix_size) = 0x00;
390 *newlength = prefix_size;
395 /* Read and check the IDHR chunk */
397 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
400 png_uint_32 width, height;
401 int bit_depth, color_type, compression_type, filter_type;
404 png_debug(1, "in png_handle_IHDR");
406 if (png_ptr->mode & PNG_HAVE_IHDR)
407 png_error(png_ptr, "Out of place IHDR");
409 /* Check the length */
411 png_error(png_ptr, "Invalid IHDR chunk");
413 png_ptr->mode |= PNG_HAVE_IHDR;
415 png_crc_read(png_ptr, buf, 13);
416 png_crc_finish(png_ptr, 0);
418 width = png_get_uint_31(png_ptr, buf);
419 height = png_get_uint_31(png_ptr, buf + 4);
422 compression_type = buf[10];
423 filter_type = buf[11];
424 interlace_type = buf[12];
426 /* Set internal variables */
427 png_ptr->width = width;
428 png_ptr->height = height;
429 png_ptr->bit_depth = (png_byte)bit_depth;
430 png_ptr->interlaced = (png_byte)interlace_type;
431 png_ptr->color_type = (png_byte)color_type;
432 #ifdef PNG_MNG_FEATURES_SUPPORTED
433 png_ptr->filter_type = (png_byte)filter_type;
435 png_ptr->compression_type = (png_byte)compression_type;
437 /* Find number of channels */
438 switch (png_ptr->color_type)
440 case PNG_COLOR_TYPE_GRAY:
441 case PNG_COLOR_TYPE_PALETTE:
442 png_ptr->channels = 1;
445 case PNG_COLOR_TYPE_RGB:
446 png_ptr->channels = 3;
449 case PNG_COLOR_TYPE_GRAY_ALPHA:
450 png_ptr->channels = 2;
453 case PNG_COLOR_TYPE_RGB_ALPHA:
454 png_ptr->channels = 4;
458 /* Set up other useful info */
459 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
461 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
462 png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
463 png_debug1(3, "channels = %d", png_ptr->channels);
464 png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
465 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
466 color_type, interlace_type, compression_type, filter_type);
469 /* Read and check the palette */
471 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
473 png_color palette[PNG_MAX_PALETTE_LENGTH];
475 #ifdef PNG_POINTER_INDEXING_SUPPORTED
479 png_debug(1, "in png_handle_PLTE");
481 if (!(png_ptr->mode & PNG_HAVE_IHDR))
482 png_error(png_ptr, "Missing IHDR before PLTE");
484 else if (png_ptr->mode & PNG_HAVE_IDAT)
486 png_warning(png_ptr, "Invalid PLTE after IDAT");
487 png_crc_finish(png_ptr, length);
491 else if (png_ptr->mode & PNG_HAVE_PLTE)
492 png_error(png_ptr, "Duplicate PLTE chunk");
494 png_ptr->mode |= PNG_HAVE_PLTE;
496 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
499 "Ignoring PLTE chunk in grayscale PNG");
500 png_crc_finish(png_ptr, length);
503 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
504 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
506 png_crc_finish(png_ptr, length);
511 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
513 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
515 png_warning(png_ptr, "Invalid palette chunk");
516 png_crc_finish(png_ptr, length);
522 png_error(png_ptr, "Invalid palette chunk");
526 num = (int)length / 3;
528 #ifdef PNG_POINTER_INDEXING_SUPPORTED
529 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
533 png_crc_read(png_ptr, buf, 3);
534 pal_ptr->red = buf[0];
535 pal_ptr->green = buf[1];
536 pal_ptr->blue = buf[2];
539 for (i = 0; i < num; i++)
543 png_crc_read(png_ptr, buf, 3);
544 /* Don't depend upon png_color being any order */
545 palette[i].red = buf[0];
546 palette[i].green = buf[1];
547 palette[i].blue = buf[2];
551 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
552 * whatever the normal CRC configuration tells us. However, if we
553 * have an RGB image, the PLTE can be considered ancillary, so
554 * we will act as though it is.
556 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
557 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
560 png_crc_finish(png_ptr, 0);
562 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
563 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
565 /* If we don't want to use the data from an ancillary chunk,
566 we have two options: an error abort, or a warning and we
567 ignore the data in this chunk (which should be OK, since
568 it's considered ancillary for a RGB or RGBA image). */
569 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
571 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
573 png_chunk_benign_error(png_ptr, "CRC error");
577 png_chunk_warning(png_ptr, "CRC error");
581 /* Otherwise, we (optionally) emit a warning and use the chunk. */
582 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
584 png_chunk_warning(png_ptr, "CRC error");
589 png_set_PLTE(png_ptr, info_ptr, palette, num);
591 #ifdef PNG_READ_tRNS_SUPPORTED
592 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
594 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
596 if (png_ptr->num_trans > (png_uint_16)num)
598 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
599 png_ptr->num_trans = (png_uint_16)num;
601 if (info_ptr->num_trans > (png_uint_16)num)
603 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
604 info_ptr->num_trans = (png_uint_16)num;
613 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
615 png_debug(1, "in png_handle_IEND");
617 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
619 png_error(png_ptr, "No image in file");
622 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
626 png_warning(png_ptr, "Incorrect IEND chunk length");
628 png_crc_finish(png_ptr, length);
630 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
633 #ifdef PNG_READ_gAMA_SUPPORTED
635 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
637 png_fixed_point igamma;
638 #ifdef PNG_FLOATING_POINT_SUPPORTED
643 png_debug(1, "in png_handle_gAMA");
645 if (!(png_ptr->mode & PNG_HAVE_IHDR))
646 png_error(png_ptr, "Missing IHDR before gAMA");
647 else if (png_ptr->mode & PNG_HAVE_IDAT)
649 png_warning(png_ptr, "Invalid gAMA after IDAT");
650 png_crc_finish(png_ptr, length);
653 else if (png_ptr->mode & PNG_HAVE_PLTE)
654 /* Should be an error, but we can cope with it */
655 png_warning(png_ptr, "Out of place gAMA chunk");
657 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
658 #ifdef PNG_READ_sRGB_SUPPORTED
659 && !(info_ptr->valid & PNG_INFO_sRGB)
663 png_warning(png_ptr, "Duplicate gAMA chunk");
664 png_crc_finish(png_ptr, length);
670 png_warning(png_ptr, "Incorrect gAMA chunk length");
671 png_crc_finish(png_ptr, length);
675 png_crc_read(png_ptr, buf, 4);
676 if (png_crc_finish(png_ptr, 0))
679 igamma = (png_fixed_point)png_get_uint_32(buf);
680 /* Check for zero gamma */
684 "Ignoring gAMA chunk with gamma=0");
688 #ifdef PNG_READ_sRGB_SUPPORTED
689 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
690 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
693 "Ignoring incorrect gAMA value when sRGB is also present");
694 #ifdef PNG_CONSOLE_IO_SUPPORTED
695 fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
699 #endif /* PNG_READ_sRGB_SUPPORTED */
701 #ifdef PNG_FLOATING_POINT_SUPPORTED
702 file_gamma = (float)igamma / (float)100000.0;
703 # ifdef PNG_READ_GAMMA_SUPPORTED
704 png_ptr->gamma = file_gamma;
706 png_set_gAMA(png_ptr, info_ptr, file_gamma);
708 #ifdef PNG_FIXED_POINT_SUPPORTED
709 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
714 #ifdef PNG_READ_sBIT_SUPPORTED
716 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
721 png_debug(1, "in png_handle_sBIT");
723 buf[0] = buf[1] = buf[2] = buf[3] = 0;
725 if (!(png_ptr->mode & PNG_HAVE_IHDR))
726 png_error(png_ptr, "Missing IHDR before sBIT");
727 else if (png_ptr->mode & PNG_HAVE_IDAT)
729 png_warning(png_ptr, "Invalid sBIT after IDAT");
730 png_crc_finish(png_ptr, length);
733 else if (png_ptr->mode & PNG_HAVE_PLTE)
735 /* Should be an error, but we can cope with it */
736 png_warning(png_ptr, "Out of place sBIT chunk");
738 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
740 png_warning(png_ptr, "Duplicate sBIT chunk");
741 png_crc_finish(png_ptr, length);
745 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
748 truelen = (png_size_t)png_ptr->channels;
750 if (length != truelen || length > 4)
752 png_warning(png_ptr, "Incorrect sBIT chunk length");
753 png_crc_finish(png_ptr, length);
757 png_crc_read(png_ptr, buf, truelen);
758 if (png_crc_finish(png_ptr, 0))
761 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
763 png_ptr->sig_bit.red = buf[0];
764 png_ptr->sig_bit.green = buf[1];
765 png_ptr->sig_bit.blue = buf[2];
766 png_ptr->sig_bit.alpha = buf[3];
770 png_ptr->sig_bit.gray = buf[0];
771 png_ptr->sig_bit.red = buf[0];
772 png_ptr->sig_bit.green = buf[0];
773 png_ptr->sig_bit.blue = buf[0];
774 png_ptr->sig_bit.alpha = buf[1];
776 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
780 #ifdef PNG_READ_cHRM_SUPPORTED
782 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
785 #ifdef PNG_FLOATING_POINT_SUPPORTED
786 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
788 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
789 int_y_green, int_x_blue, int_y_blue;
791 png_uint_32 uint_x, uint_y;
793 png_debug(1, "in png_handle_cHRM");
795 if (!(png_ptr->mode & PNG_HAVE_IHDR))
796 png_error(png_ptr, "Missing IHDR before cHRM");
797 else if (png_ptr->mode & PNG_HAVE_IDAT)
799 png_warning(png_ptr, "Invalid cHRM after IDAT");
800 png_crc_finish(png_ptr, length);
803 else if (png_ptr->mode & PNG_HAVE_PLTE)
804 /* Should be an error, but we can cope with it */
805 png_warning(png_ptr, "Missing PLTE before cHRM");
807 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
808 #ifdef PNG_READ_sRGB_SUPPORTED
809 && !(info_ptr->valid & PNG_INFO_sRGB)
813 png_warning(png_ptr, "Duplicate cHRM chunk");
814 png_crc_finish(png_ptr, length);
820 png_warning(png_ptr, "Incorrect cHRM chunk length");
821 png_crc_finish(png_ptr, length);
825 png_crc_read(png_ptr, buf, 32);
826 if (png_crc_finish(png_ptr, 0))
829 uint_x = png_get_uint_32(buf);
830 uint_y = png_get_uint_32(buf + 4);
831 int_x_white = (png_fixed_point)uint_x;
832 int_y_white = (png_fixed_point)uint_y;
834 uint_x = png_get_uint_32(buf + 8);
835 uint_y = png_get_uint_32(buf + 12);
836 int_x_red = (png_fixed_point)uint_x;
837 int_y_red = (png_fixed_point)uint_y;
839 uint_x = png_get_uint_32(buf + 16);
840 uint_y = png_get_uint_32(buf + 20);
841 int_x_green = (png_fixed_point)uint_x;
842 int_y_green = (png_fixed_point)uint_y;
844 uint_x = png_get_uint_32(buf + 24);
845 uint_y = png_get_uint_32(buf + 28);
846 int_x_blue = (png_fixed_point)uint_x;
847 int_y_blue = (png_fixed_point)uint_y;
849 #ifdef PNG_FLOATING_POINT_SUPPORTED
850 white_x = (float)int_x_white / (float)100000.0;
851 white_y = (float)int_y_white / (float)100000.0;
852 red_x = (float)int_x_red / (float)100000.0;
853 red_y = (float)int_y_red / (float)100000.0;
854 green_x = (float)int_x_green / (float)100000.0;
855 green_y = (float)int_y_green / (float)100000.0;
856 blue_x = (float)int_x_blue / (float)100000.0;
857 blue_y = (float)int_y_blue / (float)100000.0;
860 #ifdef PNG_READ_sRGB_SUPPORTED
861 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
863 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
864 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
865 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
866 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
867 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
868 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
869 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
870 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
873 "Ignoring incorrect cHRM value when sRGB is also present");
874 #ifdef PNG_CONSOLE_IO_SUPPORTED
875 #ifdef PNG_FLOATING_POINT_SUPPORTED
876 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
877 white_x, white_y, red_x, red_y);
878 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
879 green_x, green_y, blue_x, blue_y);
881 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
882 int_x_white, int_y_white, int_x_red, int_y_red);
883 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
884 int_x_green, int_y_green, int_x_blue, int_y_blue);
886 #endif /* PNG_CONSOLE_IO_SUPPORTED */
890 #endif /* PNG_READ_sRGB_SUPPORTED */
892 #ifdef PNG_FLOATING_POINT_SUPPORTED
893 png_set_cHRM(png_ptr, info_ptr,
894 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
896 #ifdef PNG_FIXED_POINT_SUPPORTED
897 png_set_cHRM_fixed(png_ptr, info_ptr,
898 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
899 int_y_green, int_x_blue, int_y_blue);
904 #ifdef PNG_READ_sRGB_SUPPORTED
906 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
911 png_debug(1, "in png_handle_sRGB");
913 if (!(png_ptr->mode & PNG_HAVE_IHDR))
914 png_error(png_ptr, "Missing IHDR before sRGB");
915 else if (png_ptr->mode & PNG_HAVE_IDAT)
917 png_warning(png_ptr, "Invalid sRGB after IDAT");
918 png_crc_finish(png_ptr, length);
921 else if (png_ptr->mode & PNG_HAVE_PLTE)
922 /* Should be an error, but we can cope with it */
923 png_warning(png_ptr, "Out of place sRGB chunk");
925 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
927 png_warning(png_ptr, "Duplicate sRGB chunk");
928 png_crc_finish(png_ptr, length);
934 png_warning(png_ptr, "Incorrect sRGB chunk length");
935 png_crc_finish(png_ptr, length);
939 png_crc_read(png_ptr, buf, 1);
940 if (png_crc_finish(png_ptr, 0))
944 /* Check for bad intent */
945 if (intent >= PNG_sRGB_INTENT_LAST)
947 png_warning(png_ptr, "Unknown sRGB intent");
951 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
952 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
954 png_fixed_point igamma;
955 #ifdef PNG_FIXED_POINT_SUPPORTED
956 igamma=info_ptr->int_gamma;
958 # ifdef PNG_FLOATING_POINT_SUPPORTED
959 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
962 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
965 "Ignoring incorrect gAMA value when sRGB is also present");
966 #ifdef PNG_CONSOLE_IO_SUPPORTED
967 # ifdef PNG_FIXED_POINT_SUPPORTED
968 fprintf(stderr, "incorrect gamma=(%d/100000)\n",
969 (int)png_ptr->int_gamma);
971 # ifdef PNG_FLOATING_POINT_SUPPORTED
972 fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
978 #endif /* PNG_READ_gAMA_SUPPORTED */
980 #ifdef PNG_READ_cHRM_SUPPORTED
981 #ifdef PNG_FIXED_POINT_SUPPORTED
982 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
983 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
984 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
985 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
986 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
987 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
988 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
989 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
990 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
993 "Ignoring incorrect cHRM value when sRGB is also present");
995 #endif /* PNG_FIXED_POINT_SUPPORTED */
996 #endif /* PNG_READ_cHRM_SUPPORTED */
998 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1000 #endif /* PNG_READ_sRGB_SUPPORTED */
1002 #ifdef PNG_READ_iCCP_SUPPORTED
1004 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1005 /* Note: this does not properly handle chunks that are > 64K under DOS */
1007 png_byte compression_type;
1010 png_uint_32 skip = 0;
1011 png_uint_32 profile_size, profile_length;
1012 png_size_t slength, prefix_length, data_length;
1014 png_debug(1, "in png_handle_iCCP");
1016 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1017 png_error(png_ptr, "Missing IHDR before iCCP");
1018 else if (png_ptr->mode & PNG_HAVE_IDAT)
1020 png_warning(png_ptr, "Invalid iCCP after IDAT");
1021 png_crc_finish(png_ptr, length);
1024 else if (png_ptr->mode & PNG_HAVE_PLTE)
1025 /* Should be an error, but we can cope with it */
1026 png_warning(png_ptr, "Out of place iCCP chunk");
1028 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1030 png_warning(png_ptr, "Duplicate iCCP chunk");
1031 png_crc_finish(png_ptr, length);
1035 #ifdef PNG_MAX_MALLOC_64K
1036 if (length > (png_uint_32)65535L)
1038 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1039 skip = length - (png_uint_32)65535L;
1040 length = (png_uint_32)65535L;
1044 png_free(png_ptr, png_ptr->chunkdata);
1045 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1046 slength = (png_size_t)length;
1047 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1049 if (png_crc_finish(png_ptr, skip))
1051 png_free(png_ptr, png_ptr->chunkdata);
1052 png_ptr->chunkdata = NULL;
1056 png_ptr->chunkdata[slength] = 0x00;
1058 for (profile = png_ptr->chunkdata; *profile; profile++)
1059 /* Empty loop to find end of name */ ;
1063 /* There should be at least one zero (the compression type byte)
1064 * following the separator, and we should be on it
1066 if ( profile >= png_ptr->chunkdata + slength - 1)
1068 png_free(png_ptr, png_ptr->chunkdata);
1069 png_ptr->chunkdata = NULL;
1070 png_warning(png_ptr, "Malformed iCCP chunk");
1074 /* Compression_type should always be zero */
1075 compression_type = *profile++;
1076 if (compression_type)
1078 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1079 compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1083 prefix_length = profile - png_ptr->chunkdata;
1084 png_decompress_chunk(png_ptr, compression_type,
1085 slength, prefix_length, &data_length);
1087 profile_length = data_length - prefix_length;
1089 if ( prefix_length > data_length || profile_length < 4)
1091 png_free(png_ptr, png_ptr->chunkdata);
1092 png_ptr->chunkdata = NULL;
1093 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1097 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1098 pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1099 profile_size = ((*(pC ))<<24) |
1104 if (profile_size < profile_length)
1105 profile_length = profile_size;
1107 if (profile_size > profile_length)
1109 png_free(png_ptr, png_ptr->chunkdata);
1110 png_ptr->chunkdata = NULL;
1111 png_warning(png_ptr, "Ignoring truncated iCCP profile");
1115 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1116 compression_type, png_ptr->chunkdata + prefix_length, profile_length);
1117 png_free(png_ptr, png_ptr->chunkdata);
1118 png_ptr->chunkdata = NULL;
1120 #endif /* PNG_READ_iCCP_SUPPORTED */
1122 #ifdef PNG_READ_sPLT_SUPPORTED
1124 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1125 /* Note: this does not properly handle chunks that are > 64K under DOS */
1127 png_bytep entry_start;
1128 png_sPLT_t new_palette;
1129 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1132 int data_length, entry_size, i;
1133 png_uint_32 skip = 0;
1136 png_debug(1, "in png_handle_sPLT");
1138 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
1140 if (png_ptr->user_chunk_cache_max != 0)
1142 if (png_ptr->user_chunk_cache_max == 1)
1144 png_crc_finish(png_ptr, length);
1147 if (--png_ptr->user_chunk_cache_max == 1)
1149 png_warning(png_ptr, "No space in chunk cache for sPLT");
1150 png_crc_finish(png_ptr, length);
1156 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1157 png_error(png_ptr, "Missing IHDR before sPLT");
1158 else if (png_ptr->mode & PNG_HAVE_IDAT)
1160 png_warning(png_ptr, "Invalid sPLT after IDAT");
1161 png_crc_finish(png_ptr, length);
1165 #ifdef PNG_MAX_MALLOC_64K
1166 if (length > (png_uint_32)65535L)
1168 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1169 skip = length - (png_uint_32)65535L;
1170 length = (png_uint_32)65535L;
1174 png_free(png_ptr, png_ptr->chunkdata);
1175 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1176 slength = (png_size_t)length;
1177 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1179 if (png_crc_finish(png_ptr, skip))
1181 png_free(png_ptr, png_ptr->chunkdata);
1182 png_ptr->chunkdata = NULL;
1186 png_ptr->chunkdata[slength] = 0x00;
1188 for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; entry_start++)
1189 /* Empty loop to find end of name */ ;
1192 /* A sample depth should follow the separator, and we should be on it */
1193 if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1195 png_free(png_ptr, png_ptr->chunkdata);
1196 png_ptr->chunkdata = NULL;
1197 png_warning(png_ptr, "malformed sPLT chunk");
1201 new_palette.depth = *entry_start++;
1202 entry_size = (new_palette.depth == 8 ? 6 : 10);
1203 data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
1205 /* Integrity-check the data length */
1206 if (data_length % entry_size)
1208 png_free(png_ptr, png_ptr->chunkdata);
1209 png_ptr->chunkdata = NULL;
1210 png_warning(png_ptr, "sPLT chunk has bad length");
1214 new_palette.nentries = (png_int_32) ( data_length / entry_size);
1215 if ((png_uint_32) new_palette.nentries >
1216 (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
1218 png_warning(png_ptr, "sPLT chunk too long");
1221 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1222 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1223 if (new_palette.entries == NULL)
1225 png_warning(png_ptr, "sPLT chunk requires too much memory");
1229 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1230 for (i = 0; i < new_palette.nentries; i++)
1232 pp = new_palette.entries + i;
1234 if (new_palette.depth == 8)
1236 pp->red = *entry_start++;
1237 pp->green = *entry_start++;
1238 pp->blue = *entry_start++;
1239 pp->alpha = *entry_start++;
1243 pp->red = png_get_uint_16(entry_start); entry_start += 2;
1244 pp->green = png_get_uint_16(entry_start); entry_start += 2;
1245 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1246 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1248 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1251 pp = new_palette.entries;
1252 for (i = 0; i < new_palette.nentries; i++)
1255 if (new_palette.depth == 8)
1257 pp[i].red = *entry_start++;
1258 pp[i].green = *entry_start++;
1259 pp[i].blue = *entry_start++;
1260 pp[i].alpha = *entry_start++;
1264 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1265 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1266 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1267 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1269 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1273 /* Discard all chunk data except the name and stash that */
1274 new_palette.name = png_ptr->chunkdata;
1276 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1278 png_free(png_ptr, png_ptr->chunkdata);
1279 png_ptr->chunkdata = NULL;
1280 png_free(png_ptr, new_palette.entries);
1282 #endif /* PNG_READ_sPLT_SUPPORTED */
1284 #ifdef PNG_READ_tRNS_SUPPORTED
1286 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1288 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1290 png_debug(1, "in png_handle_tRNS");
1292 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1293 png_error(png_ptr, "Missing IHDR before tRNS");
1294 else if (png_ptr->mode & PNG_HAVE_IDAT)
1296 png_warning(png_ptr, "Invalid tRNS after IDAT");
1297 png_crc_finish(png_ptr, length);
1300 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1302 png_warning(png_ptr, "Duplicate tRNS chunk");
1303 png_crc_finish(png_ptr, length);
1307 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1313 png_warning(png_ptr, "Incorrect tRNS chunk length");
1314 png_crc_finish(png_ptr, length);
1318 png_crc_read(png_ptr, buf, 2);
1319 png_ptr->num_trans = 1;
1320 png_ptr->trans_color.gray = png_get_uint_16(buf);
1322 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1328 png_warning(png_ptr, "Incorrect tRNS chunk length");
1329 png_crc_finish(png_ptr, length);
1332 png_crc_read(png_ptr, buf, (png_size_t)length);
1333 png_ptr->num_trans = 1;
1334 png_ptr->trans_color.red = png_get_uint_16(buf);
1335 png_ptr->trans_color.green = png_get_uint_16(buf + 2);
1336 png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
1338 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1340 if (!(png_ptr->mode & PNG_HAVE_PLTE))
1342 /* Should be an error, but we can cope with it. */
1343 png_warning(png_ptr, "Missing PLTE before tRNS");
1345 if (length > (png_uint_32)png_ptr->num_palette ||
1346 length > PNG_MAX_PALETTE_LENGTH)
1348 png_warning(png_ptr, "Incorrect tRNS chunk length");
1349 png_crc_finish(png_ptr, length);
1354 png_warning(png_ptr, "Zero length tRNS chunk");
1355 png_crc_finish(png_ptr, length);
1358 png_crc_read(png_ptr, readbuf, (png_size_t)length);
1359 png_ptr->num_trans = (png_uint_16)length;
1363 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1364 png_crc_finish(png_ptr, length);
1368 if (png_crc_finish(png_ptr, 0))
1370 png_ptr->num_trans = 0;
1374 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1375 &(png_ptr->trans_color));
1379 #ifdef PNG_READ_bKGD_SUPPORTED
1381 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1386 png_debug(1, "in png_handle_bKGD");
1388 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1389 png_error(png_ptr, "Missing IHDR before bKGD");
1390 else if (png_ptr->mode & PNG_HAVE_IDAT)
1392 png_warning(png_ptr, "Invalid bKGD after IDAT");
1393 png_crc_finish(png_ptr, length);
1396 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1397 !(png_ptr->mode & PNG_HAVE_PLTE))
1399 png_warning(png_ptr, "Missing PLTE before bKGD");
1400 png_crc_finish(png_ptr, length);
1403 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1405 png_warning(png_ptr, "Duplicate bKGD chunk");
1406 png_crc_finish(png_ptr, length);
1410 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1412 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1417 if (length != truelen)
1419 png_warning(png_ptr, "Incorrect bKGD chunk length");
1420 png_crc_finish(png_ptr, length);
1424 png_crc_read(png_ptr, buf, truelen);
1425 if (png_crc_finish(png_ptr, 0))
1428 /* We convert the index value into RGB components so that we can allow
1429 * arbitrary RGB values for background when we have transparency, and
1430 * so it is easy to determine the RGB values of the background color
1431 * from the info_ptr struct. */
1432 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1434 png_ptr->background.index = buf[0];
1435 if (info_ptr && info_ptr->num_palette)
1437 if (buf[0] >= info_ptr->num_palette)
1439 png_warning(png_ptr, "Incorrect bKGD chunk index value");
1442 png_ptr->background.red =
1443 (png_uint_16)png_ptr->palette[buf[0]].red;
1444 png_ptr->background.green =
1445 (png_uint_16)png_ptr->palette[buf[0]].green;
1446 png_ptr->background.blue =
1447 (png_uint_16)png_ptr->palette[buf[0]].blue;
1450 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1452 png_ptr->background.red =
1453 png_ptr->background.green =
1454 png_ptr->background.blue =
1455 png_ptr->background.gray = png_get_uint_16(buf);
1459 png_ptr->background.red = png_get_uint_16(buf);
1460 png_ptr->background.green = png_get_uint_16(buf + 2);
1461 png_ptr->background.blue = png_get_uint_16(buf + 4);
1464 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1468 #ifdef PNG_READ_hIST_SUPPORTED
1470 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1472 unsigned int num, i;
1473 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1475 png_debug(1, "in png_handle_hIST");
1477 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1478 png_error(png_ptr, "Missing IHDR before hIST");
1479 else if (png_ptr->mode & PNG_HAVE_IDAT)
1481 png_warning(png_ptr, "Invalid hIST after IDAT");
1482 png_crc_finish(png_ptr, length);
1485 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1487 png_warning(png_ptr, "Missing PLTE before hIST");
1488 png_crc_finish(png_ptr, length);
1491 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1493 png_warning(png_ptr, "Duplicate hIST chunk");
1494 png_crc_finish(png_ptr, length);
1499 if (num != (unsigned int) png_ptr->num_palette || num >
1500 (unsigned int) PNG_MAX_PALETTE_LENGTH)
1502 png_warning(png_ptr, "Incorrect hIST chunk length");
1503 png_crc_finish(png_ptr, length);
1507 for (i = 0; i < num; i++)
1511 png_crc_read(png_ptr, buf, 2);
1512 readbuf[i] = png_get_uint_16(buf);
1515 if (png_crc_finish(png_ptr, 0))
1518 png_set_hIST(png_ptr, info_ptr, readbuf);
1522 #ifdef PNG_READ_pHYs_SUPPORTED
1524 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1527 png_uint_32 res_x, res_y;
1530 png_debug(1, "in png_handle_pHYs");
1532 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1533 png_error(png_ptr, "Missing IHDR before pHYs");
1534 else if (png_ptr->mode & PNG_HAVE_IDAT)
1536 png_warning(png_ptr, "Invalid pHYs after IDAT");
1537 png_crc_finish(png_ptr, length);
1540 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1542 png_warning(png_ptr, "Duplicate pHYs chunk");
1543 png_crc_finish(png_ptr, length);
1549 png_warning(png_ptr, "Incorrect pHYs chunk length");
1550 png_crc_finish(png_ptr, length);
1554 png_crc_read(png_ptr, buf, 9);
1555 if (png_crc_finish(png_ptr, 0))
1558 res_x = png_get_uint_32(buf);
1559 res_y = png_get_uint_32(buf + 4);
1561 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1565 #ifdef PNG_READ_oFFs_SUPPORTED
1567 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1570 png_int_32 offset_x, offset_y;
1573 png_debug(1, "in png_handle_oFFs");
1575 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1576 png_error(png_ptr, "Missing IHDR before oFFs");
1577 else if (png_ptr->mode & PNG_HAVE_IDAT)
1579 png_warning(png_ptr, "Invalid oFFs after IDAT");
1580 png_crc_finish(png_ptr, length);
1583 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1585 png_warning(png_ptr, "Duplicate oFFs chunk");
1586 png_crc_finish(png_ptr, length);
1592 png_warning(png_ptr, "Incorrect oFFs chunk length");
1593 png_crc_finish(png_ptr, length);
1597 png_crc_read(png_ptr, buf, 9);
1598 if (png_crc_finish(png_ptr, 0))
1601 offset_x = png_get_int_32(buf);
1602 offset_y = png_get_int_32(buf + 4);
1604 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1608 #ifdef PNG_READ_pCAL_SUPPORTED
1609 /* Read the pCAL chunk (described in the PNG Extensions document) */
1611 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1614 png_byte type, nparams;
1615 png_charp buf, units, endptr;
1620 png_debug(1, "in png_handle_pCAL");
1622 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1623 png_error(png_ptr, "Missing IHDR before pCAL");
1624 else if (png_ptr->mode & PNG_HAVE_IDAT)
1626 png_warning(png_ptr, "Invalid pCAL after IDAT");
1627 png_crc_finish(png_ptr, length);
1630 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1632 png_warning(png_ptr, "Duplicate pCAL chunk");
1633 png_crc_finish(png_ptr, length);
1637 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1639 png_free(png_ptr, png_ptr->chunkdata);
1640 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1641 if (png_ptr->chunkdata == NULL)
1643 png_warning(png_ptr, "No memory for pCAL purpose");
1646 slength = (png_size_t)length;
1647 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1649 if (png_crc_finish(png_ptr, 0))
1651 png_free(png_ptr, png_ptr->chunkdata);
1652 png_ptr->chunkdata = NULL;
1656 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1658 png_debug(3, "Finding end of pCAL purpose string");
1659 for (buf = png_ptr->chunkdata; *buf; buf++)
1662 endptr = png_ptr->chunkdata + slength;
1664 /* We need to have at least 12 bytes after the purpose string
1665 in order to get the parameter information. */
1666 if (endptr <= buf + 12)
1668 png_warning(png_ptr, "Invalid pCAL data");
1669 png_free(png_ptr, png_ptr->chunkdata);
1670 png_ptr->chunkdata = NULL;
1674 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1675 X0 = png_get_int_32((png_bytep)buf+1);
1676 X1 = png_get_int_32((png_bytep)buf+5);
1681 png_debug(3, "Checking pCAL equation type and number of parameters");
1682 /* Check that we have the right number of parameters for known
1684 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1685 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1686 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1687 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1689 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1690 png_free(png_ptr, png_ptr->chunkdata);
1691 png_ptr->chunkdata = NULL;
1694 else if (type >= PNG_EQUATION_LAST)
1696 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1699 for (buf = units; *buf; buf++)
1700 /* Empty loop to move past the units string. */ ;
1702 png_debug(3, "Allocating pCAL parameters array");
1703 params = (png_charpp)png_malloc_warn(png_ptr,
1704 (png_size_t)(nparams * png_sizeof(png_charp)));
1707 png_free(png_ptr, png_ptr->chunkdata);
1708 png_ptr->chunkdata = NULL;
1709 png_warning(png_ptr, "No memory for pCAL params");
1713 /* Get pointers to the start of each parameter string. */
1714 for (i = 0; i < (int)nparams; i++)
1716 buf++; /* Skip the null string terminator from previous parameter. */
1718 png_debug1(3, "Reading pCAL parameter %d", i);
1719 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1720 /* Empty loop to move past each parameter string */ ;
1722 /* Make sure we haven't run out of data yet */
1725 png_warning(png_ptr, "Invalid pCAL data");
1726 png_free(png_ptr, png_ptr->chunkdata);
1727 png_ptr->chunkdata = NULL;
1728 png_free(png_ptr, params);
1733 png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
1736 png_free(png_ptr, png_ptr->chunkdata);
1737 png_ptr->chunkdata = NULL;
1738 png_free(png_ptr, params);
1742 #ifdef PNG_READ_sCAL_SUPPORTED
1743 /* Read the sCAL chunk */
1745 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1748 #ifdef PNG_FLOATING_POINT_SUPPORTED
1749 double width, height;
1752 #ifdef PNG_FIXED_POINT_SUPPORTED
1753 png_charp swidth, sheight;
1758 png_debug(1, "in png_handle_sCAL");
1760 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1761 png_error(png_ptr, "Missing IHDR before sCAL");
1762 else if (png_ptr->mode & PNG_HAVE_IDAT)
1764 png_warning(png_ptr, "Invalid sCAL after IDAT");
1765 png_crc_finish(png_ptr, length);
1768 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1770 png_warning(png_ptr, "Duplicate sCAL chunk");
1771 png_crc_finish(png_ptr, length);
1775 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1777 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1778 if (png_ptr->chunkdata == NULL)
1780 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1783 slength = (png_size_t)length;
1784 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1786 if (png_crc_finish(png_ptr, 0))
1788 png_free(png_ptr, png_ptr->chunkdata);
1789 png_ptr->chunkdata = NULL;
1793 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1795 ep = png_ptr->chunkdata + 1; /* Skip unit byte */
1797 #ifdef PNG_FLOATING_POINT_SUPPORTED
1798 width = png_strtod(png_ptr, ep, &vp);
1801 png_warning(png_ptr, "malformed width string in sCAL chunk");
1805 #ifdef PNG_FIXED_POINT_SUPPORTED
1806 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1809 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1812 png_memcpy(swidth, ep, png_strlen(ep));
1816 for (ep = png_ptr->chunkdata; *ep; ep++)
1820 if (png_ptr->chunkdata + slength < ep)
1822 png_warning(png_ptr, "Truncated sCAL chunk");
1823 #if defined(PNG_FIXED_POINT_SUPPORTED) && \
1824 !defined(PNG_FLOATING_POINT_SUPPORTED)
1825 png_free(png_ptr, swidth);
1827 png_free(png_ptr, png_ptr->chunkdata);
1828 png_ptr->chunkdata = NULL;
1832 #ifdef PNG_FLOATING_POINT_SUPPORTED
1833 height = png_strtod(png_ptr, ep, &vp);
1836 png_warning(png_ptr, "malformed height string in sCAL chunk");
1840 #ifdef PNG_FIXED_POINT_SUPPORTED
1841 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1842 if (sheight == NULL)
1844 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1847 png_memcpy(sheight, ep, png_strlen(ep));
1851 if (png_ptr->chunkdata + slength < ep
1852 #ifdef PNG_FLOATING_POINT_SUPPORTED
1853 || width <= 0. || height <= 0.
1857 png_warning(png_ptr, "Invalid sCAL data");
1858 png_free(png_ptr, png_ptr->chunkdata);
1859 png_ptr->chunkdata = NULL;
1860 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1861 png_free(png_ptr, swidth);
1862 png_free(png_ptr, sheight);
1868 #ifdef PNG_FLOATING_POINT_SUPPORTED
1869 png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
1871 #ifdef PNG_FIXED_POINT_SUPPORTED
1872 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
1876 png_free(png_ptr, png_ptr->chunkdata);
1877 png_ptr->chunkdata = NULL;
1878 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1879 png_free(png_ptr, swidth);
1880 png_free(png_ptr, sheight);
1885 #ifdef PNG_READ_tIME_SUPPORTED
1887 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1892 png_debug(1, "in png_handle_tIME");
1894 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1895 png_error(png_ptr, "Out of place tIME chunk");
1896 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1898 png_warning(png_ptr, "Duplicate tIME chunk");
1899 png_crc_finish(png_ptr, length);
1903 if (png_ptr->mode & PNG_HAVE_IDAT)
1904 png_ptr->mode |= PNG_AFTER_IDAT;
1908 png_warning(png_ptr, "Incorrect tIME chunk length");
1909 png_crc_finish(png_ptr, length);
1913 png_crc_read(png_ptr, buf, 7);
1914 if (png_crc_finish(png_ptr, 0))
1917 mod_time.second = buf[6];
1918 mod_time.minute = buf[5];
1919 mod_time.hour = buf[4];
1920 mod_time.day = buf[3];
1921 mod_time.month = buf[2];
1922 mod_time.year = png_get_uint_16(buf);
1924 png_set_tIME(png_ptr, info_ptr, &mod_time);
1928 #ifdef PNG_READ_tEXt_SUPPORTED
1929 /* Note: this does not properly handle chunks that are > 64K under DOS */
1931 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1936 png_uint_32 skip = 0;
1940 png_debug(1, "in png_handle_tEXt");
1942 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
1943 if (png_ptr->user_chunk_cache_max != 0)
1945 if (png_ptr->user_chunk_cache_max == 1)
1947 png_crc_finish(png_ptr, length);
1950 if (--png_ptr->user_chunk_cache_max == 1)
1952 png_warning(png_ptr, "No space in chunk cache for tEXt");
1953 png_crc_finish(png_ptr, length);
1959 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1960 png_error(png_ptr, "Missing IHDR before tEXt");
1962 if (png_ptr->mode & PNG_HAVE_IDAT)
1963 png_ptr->mode |= PNG_AFTER_IDAT;
1965 #ifdef PNG_MAX_MALLOC_64K
1966 if (length > (png_uint_32)65535L)
1968 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1969 skip = length - (png_uint_32)65535L;
1970 length = (png_uint_32)65535L;
1974 png_free(png_ptr, png_ptr->chunkdata);
1976 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1977 if (png_ptr->chunkdata == NULL)
1979 png_warning(png_ptr, "No memory to process text chunk");
1982 slength = (png_size_t)length;
1983 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1985 if (png_crc_finish(png_ptr, skip))
1987 png_free(png_ptr, png_ptr->chunkdata);
1988 png_ptr->chunkdata = NULL;
1992 key = png_ptr->chunkdata;
1994 key[slength] = 0x00;
1996 for (text = key; *text; text++)
1997 /* Empty loop to find end of key */ ;
1999 if (text != key + slength)
2002 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2003 png_sizeof(png_text));
2004 if (text_ptr == NULL)
2006 png_warning(png_ptr, "Not enough memory to process text chunk");
2007 png_free(png_ptr, png_ptr->chunkdata);
2008 png_ptr->chunkdata = NULL;
2011 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2012 text_ptr->key = key;
2013 #ifdef PNG_iTXt_SUPPORTED
2014 text_ptr->lang = NULL;
2015 text_ptr->lang_key = NULL;
2016 text_ptr->itxt_length = 0;
2018 text_ptr->text = text;
2019 text_ptr->text_length = png_strlen(text);
2021 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2023 png_free(png_ptr, png_ptr->chunkdata);
2024 png_ptr->chunkdata = NULL;
2025 png_free(png_ptr, text_ptr);
2027 png_warning(png_ptr, "Insufficient memory to process text chunk");
2031 #ifdef PNG_READ_zTXt_SUPPORTED
2032 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2034 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2040 png_size_t slength, prefix_len, data_len;
2042 png_debug(1, "in png_handle_zTXt");
2044 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
2045 if (png_ptr->user_chunk_cache_max != 0)
2047 if (png_ptr->user_chunk_cache_max == 1)
2049 png_crc_finish(png_ptr, length);
2052 if (--png_ptr->user_chunk_cache_max == 1)
2054 png_warning(png_ptr, "No space in chunk cache for zTXt");
2055 png_crc_finish(png_ptr, length);
2061 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2062 png_error(png_ptr, "Missing IHDR before zTXt");
2064 if (png_ptr->mode & PNG_HAVE_IDAT)
2065 png_ptr->mode |= PNG_AFTER_IDAT;
2067 #ifdef PNG_MAX_MALLOC_64K
2068 /* We will no doubt have problems with chunks even half this size, but
2069 there is no hard and fast rule to tell us where to stop. */
2070 if (length > (png_uint_32)65535L)
2072 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2073 png_crc_finish(png_ptr, length);
2078 png_free(png_ptr, png_ptr->chunkdata);
2079 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2080 if (png_ptr->chunkdata == NULL)
2082 png_warning(png_ptr, "Out of memory processing zTXt chunk");
2085 slength = (png_size_t)length;
2086 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2087 if (png_crc_finish(png_ptr, 0))
2089 png_free(png_ptr, png_ptr->chunkdata);
2090 png_ptr->chunkdata = NULL;
2094 png_ptr->chunkdata[slength] = 0x00;
2096 for (text = png_ptr->chunkdata; *text; text++)
2099 /* zTXt must have some text after the chunkdataword */
2100 if (text >= png_ptr->chunkdata + slength - 2)
2102 png_warning(png_ptr, "Truncated zTXt chunk");
2103 png_free(png_ptr, png_ptr->chunkdata);
2104 png_ptr->chunkdata = NULL;
2109 comp_type = *(++text);
2110 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2112 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2113 comp_type = PNG_TEXT_COMPRESSION_zTXt;
2115 text++; /* Skip the compression_method byte */
2117 prefix_len = text - png_ptr->chunkdata;
2119 png_decompress_chunk(png_ptr, comp_type,
2120 (png_size_t)length, prefix_len, &data_len);
2122 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2123 png_sizeof(png_text));
2124 if (text_ptr == NULL)
2126 png_warning(png_ptr, "Not enough memory to process zTXt chunk");
2127 png_free(png_ptr, png_ptr->chunkdata);
2128 png_ptr->chunkdata = NULL;
2131 text_ptr->compression = comp_type;
2132 text_ptr->key = png_ptr->chunkdata;
2133 #ifdef PNG_iTXt_SUPPORTED
2134 text_ptr->lang = NULL;
2135 text_ptr->lang_key = NULL;
2136 text_ptr->itxt_length = 0;
2138 text_ptr->text = png_ptr->chunkdata + prefix_len;
2139 text_ptr->text_length = data_len;
2141 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2143 png_free(png_ptr, text_ptr);
2144 png_free(png_ptr, png_ptr->chunkdata);
2145 png_ptr->chunkdata = NULL;
2147 png_error(png_ptr, "Insufficient memory to store zTXt chunk");
2151 #ifdef PNG_READ_iTXt_SUPPORTED
2152 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2154 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2157 png_charp key, lang, text, lang_key;
2161 png_size_t slength, prefix_len, data_len;
2163 png_debug(1, "in png_handle_iTXt");
2165 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
2166 if (png_ptr->user_chunk_cache_max != 0)
2168 if (png_ptr->user_chunk_cache_max == 1)
2170 png_crc_finish(png_ptr, length);
2173 if (--png_ptr->user_chunk_cache_max == 1)
2175 png_warning(png_ptr, "No space in chunk cache for iTXt");
2176 png_crc_finish(png_ptr, length);
2182 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2183 png_error(png_ptr, "Missing IHDR before iTXt");
2185 if (png_ptr->mode & PNG_HAVE_IDAT)
2186 png_ptr->mode |= PNG_AFTER_IDAT;
2188 #ifdef PNG_MAX_MALLOC_64K
2189 /* We will no doubt have problems with chunks even half this size, but
2190 there is no hard and fast rule to tell us where to stop. */
2191 if (length > (png_uint_32)65535L)
2193 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2194 png_crc_finish(png_ptr, length);
2199 png_free(png_ptr, png_ptr->chunkdata);
2200 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2201 if (png_ptr->chunkdata == NULL)
2203 png_warning(png_ptr, "No memory to process iTXt chunk");
2206 slength = (png_size_t)length;
2207 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2208 if (png_crc_finish(png_ptr, 0))
2210 png_free(png_ptr, png_ptr->chunkdata);
2211 png_ptr->chunkdata = NULL;
2215 png_ptr->chunkdata[slength] = 0x00;
2217 for (lang = png_ptr->chunkdata; *lang; lang++)
2219 lang++; /* Skip NUL separator */
2221 /* iTXt must have a language tag (possibly empty), two compression bytes,
2222 * translated keyword (possibly empty), and possibly some text after the
2226 if (lang >= png_ptr->chunkdata + slength - 3)
2228 png_warning(png_ptr, "Truncated iTXt chunk");
2229 png_free(png_ptr, png_ptr->chunkdata);
2230 png_ptr->chunkdata = NULL;
2235 comp_flag = *lang++;
2236 comp_type = *lang++;
2239 for (lang_key = lang; *lang_key; lang_key++)
2241 lang_key++; /* Skip NUL separator */
2243 if (lang_key >= png_ptr->chunkdata + slength)
2245 png_warning(png_ptr, "Truncated iTXt chunk");
2246 png_free(png_ptr, png_ptr->chunkdata);
2247 png_ptr->chunkdata = NULL;
2251 for (text = lang_key; *text; text++)
2253 text++; /* Skip NUL separator */
2254 if (text >= png_ptr->chunkdata + slength)
2256 png_warning(png_ptr, "Malformed iTXt chunk");
2257 png_free(png_ptr, png_ptr->chunkdata);
2258 png_ptr->chunkdata = NULL;
2262 prefix_len = text - png_ptr->chunkdata;
2264 key=png_ptr->chunkdata;
2266 png_decompress_chunk(png_ptr, comp_type,
2267 (size_t)length, prefix_len, &data_len);
2269 data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2270 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2271 png_sizeof(png_text));
2272 if (text_ptr == NULL)
2274 png_warning(png_ptr, "Not enough memory to process iTXt chunk");
2275 png_free(png_ptr, png_ptr->chunkdata);
2276 png_ptr->chunkdata = NULL;
2279 text_ptr->compression = (int)comp_flag + 1;
2280 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2281 text_ptr->lang = png_ptr->chunkdata + (lang - key);
2282 text_ptr->itxt_length = data_len;
2283 text_ptr->text_length = 0;
2284 text_ptr->key = png_ptr->chunkdata;
2285 text_ptr->text = png_ptr->chunkdata + prefix_len;
2287 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2289 png_free(png_ptr, text_ptr);
2290 png_free(png_ptr, png_ptr->chunkdata);
2291 png_ptr->chunkdata = NULL;
2293 png_error(png_ptr, "Insufficient memory to store iTXt chunk");
2297 /* This function is called when we haven't found a handler for a
2298 chunk. If there isn't a problem with the chunk itself (ie bad
2299 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2300 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2301 case it will be saved away to be written out later. */
2303 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2305 png_uint_32 skip = 0;
2307 png_debug(1, "in png_handle_unknown");
2309 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
2310 if (png_ptr->user_chunk_cache_max != 0)
2312 if (png_ptr->user_chunk_cache_max == 1)
2314 png_crc_finish(png_ptr, length);
2317 if (--png_ptr->user_chunk_cache_max == 1)
2319 png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2320 png_crc_finish(png_ptr, length);
2326 if (png_ptr->mode & PNG_HAVE_IDAT)
2329 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */
2330 png_ptr->mode |= PNG_AFTER_IDAT;
2333 if (!(png_ptr->chunk_name[0] & 0x20))
2335 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2336 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2337 PNG_HANDLE_CHUNK_ALWAYS
2338 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2339 && png_ptr->read_user_chunk_fn == NULL
2343 png_chunk_error(png_ptr, "unknown critical chunk");
2346 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2347 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2348 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2349 || (png_ptr->read_user_chunk_fn != NULL)
2353 #ifdef PNG_MAX_MALLOC_64K
2354 if (length > (png_uint_32)65535L)
2356 png_warning(png_ptr, "unknown chunk too large to fit in memory");
2357 skip = length - (png_uint_32)65535L;
2358 length = (png_uint_32)65535L;
2361 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2362 (png_charp)png_ptr->chunk_name,
2363 png_sizeof(png_ptr->unknown_chunk.name));
2364 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] = '\0';
2365 png_ptr->unknown_chunk.size = (png_size_t)length;
2367 png_ptr->unknown_chunk.data = NULL;
2370 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2371 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2373 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2374 if (png_ptr->read_user_chunk_fn != NULL)
2376 /* Callback to user unknown chunk handler */
2378 ret = (*(png_ptr->read_user_chunk_fn))
2379 (png_ptr, &png_ptr->unknown_chunk);
2381 png_chunk_error(png_ptr, "error in user chunk");
2384 if (!(png_ptr->chunk_name[0] & 0x20))
2385 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2386 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2387 PNG_HANDLE_CHUNK_ALWAYS)
2389 png_chunk_error(png_ptr, "unknown critical chunk");
2390 png_set_unknown_chunks(png_ptr, info_ptr,
2391 &png_ptr->unknown_chunk, 1);
2396 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2397 png_free(png_ptr, png_ptr->unknown_chunk.data);
2398 png_ptr->unknown_chunk.data = NULL;
2404 png_crc_finish(png_ptr, skip);
2406 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2407 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
2411 /* This function is called to verify that a chunk name is valid.
2412 This function can't have the "critical chunk check" incorporated
2413 into it, since in the future we will need to be able to call user
2414 functions to handle unknown critical chunks after we check that
2415 the chunk name itself is valid. */
2417 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2420 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2422 png_debug(1, "in png_check_chunk_name");
2423 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2424 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2426 png_chunk_error(png_ptr, "invalid chunk type");
2430 /* Combines the row recently read in with the existing pixels in the
2431 row. This routine takes care of alpha and transparency if requested.
2432 This routine also handles the two methods of progressive display
2433 of interlaced images, depending on the mask value.
2434 The mask value describes which pixels are to be combined with
2435 the row. The pattern always repeats every 8 pixels, so just 8
2436 bits are needed. A one indicates the pixel is to be combined,
2437 a zero indicates the pixel is to be skipped. This is in addition
2438 to any alpha or transparency value associated with the pixel. If
2439 you want all pixels to be combined, pass 0xff (255) in mask. */
2442 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2444 png_debug(1, "in png_combine_row");
2447 png_memcpy(row, png_ptr->row_buf + 1,
2448 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2452 switch (png_ptr->row_info.pixel_depth)
2456 png_bytep sp = png_ptr->row_buf + 1;
2458 int s_inc, s_start, s_end;
2462 png_uint_32 row_width = png_ptr->width;
2464 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2465 if (png_ptr->transformations & PNG_PACKSWAP)
2481 for (i = 0; i < row_width; i++)
2487 value = (*sp >> shift) & 0x01;
2488 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2489 *dp |= (png_byte)(value << shift);
2510 png_bytep sp = png_ptr->row_buf + 1;
2512 int s_start, s_end, s_inc;
2516 png_uint_32 row_width = png_ptr->width;
2519 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2520 if (png_ptr->transformations & PNG_PACKSWAP)
2536 for (i = 0; i < row_width; i++)
2540 value = (*sp >> shift) & 0x03;
2541 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2542 *dp |= (png_byte)(value << shift);
2562 png_bytep sp = png_ptr->row_buf + 1;
2564 int s_start, s_end, s_inc;
2568 png_uint_32 row_width = png_ptr->width;
2571 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2572 if (png_ptr->transformations & PNG_PACKSWAP)
2587 for (i = 0; i < row_width; i++)
2591 value = (*sp >> shift) & 0xf;
2592 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2593 *dp |= (png_byte)(value << shift);
2613 png_bytep sp = png_ptr->row_buf + 1;
2615 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2617 png_uint_32 row_width = png_ptr->width;
2621 for (i = 0; i < row_width; i++)
2625 png_memcpy(dp, sp, pixel_bytes);
2642 #ifdef PNG_READ_INTERLACING_SUPPORTED
2643 /* OLD pre-1.0.9 interface:
2644 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2645 png_uint_32 transformations)
2648 png_do_read_interlace(png_structp png_ptr)
2650 png_row_infop row_info = &(png_ptr->row_info);
2651 png_bytep row = png_ptr->row_buf + 1;
2652 int pass = png_ptr->pass;
2653 png_uint_32 transformations = png_ptr->transformations;
2654 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2655 /* Offset to next interlace block */
2656 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2658 png_debug(1, "in png_do_read_interlace");
2659 if (row != NULL && row_info != NULL)
2661 png_uint_32 final_width;
2663 final_width = row_info->width * png_pass_inc[pass];
2665 switch (row_info->pixel_depth)
2669 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2670 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2672 int s_start, s_end, s_inc;
2673 int jstop = png_pass_inc[pass];
2678 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2679 if (transformations & PNG_PACKSWAP)
2681 sshift = (int)((row_info->width + 7) & 0x07);
2682 dshift = (int)((final_width + 7) & 0x07);
2690 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2691 dshift = 7 - (int)((final_width + 7) & 0x07);
2697 for (i = 0; i < row_info->width; i++)
2699 v = (png_byte)((*sp >> sshift) & 0x01);
2700 for (j = 0; j < jstop; j++)
2702 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2703 *dp |= (png_byte)(v << dshift);
2704 if (dshift == s_end)
2712 if (sshift == s_end)
2724 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2725 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2727 int s_start, s_end, s_inc;
2728 int jstop = png_pass_inc[pass];
2731 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2732 if (transformations & PNG_PACKSWAP)
2734 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2735 dshift = (int)(((final_width + 3) & 0x03) << 1);
2743 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2744 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2750 for (i = 0; i < row_info->width; i++)
2755 v = (png_byte)((*sp >> sshift) & 0x03);
2756 for (j = 0; j < jstop; j++)
2758 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2759 *dp |= (png_byte)(v << dshift);
2760 if (dshift == s_end)
2768 if (sshift == s_end)
2780 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2781 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2783 int s_start, s_end, s_inc;
2785 int jstop = png_pass_inc[pass];
2787 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2788 if (transformations & PNG_PACKSWAP)
2790 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2791 dshift = (int)(((final_width + 1) & 0x01) << 2);
2799 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2800 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2806 for (i = 0; i < row_info->width; i++)
2808 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2811 for (j = 0; j < jstop; j++)
2813 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2814 *dp |= (png_byte)(v << dshift);
2815 if (dshift == s_end)
2823 if (sshift == s_end)
2835 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2836 png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
2837 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2839 int jstop = png_pass_inc[pass];
2842 for (i = 0; i < row_info->width; i++)
2847 png_memcpy(v, sp, pixel_bytes);
2848 for (j = 0; j < jstop; j++)
2850 png_memcpy(dp, v, pixel_bytes);
2858 row_info->width = final_width;
2859 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
2861 #ifndef PNG_READ_PACKSWAP_SUPPORTED
2862 transformations = transformations; /* Silence compiler warning */
2865 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2868 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2869 png_bytep prev_row, int filter)
2871 png_debug(1, "in png_read_filter_row");
2872 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
2875 case PNG_FILTER_VALUE_NONE:
2877 case PNG_FILTER_VALUE_SUB:
2880 png_uint_32 istop = row_info->rowbytes;
2881 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2882 png_bytep rp = row + bpp;
2885 for (i = bpp; i < istop; i++)
2887 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2892 case PNG_FILTER_VALUE_UP:
2895 png_uint_32 istop = row_info->rowbytes;
2897 png_bytep pp = prev_row;
2899 for (i = 0; i < istop; i++)
2901 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2906 case PNG_FILTER_VALUE_AVG:
2910 png_bytep pp = prev_row;
2912 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2913 png_uint_32 istop = row_info->rowbytes - bpp;
2915 for (i = 0; i < bpp; i++)
2917 *rp = (png_byte)(((int)(*rp) +
2918 ((int)(*pp++) / 2 )) & 0xff);
2922 for (i = 0; i < istop; i++)
2924 *rp = (png_byte)(((int)(*rp) +
2925 (int)(*pp++ + *lp++) / 2 ) & 0xff);
2930 case PNG_FILTER_VALUE_PAETH:
2934 png_bytep pp = prev_row;
2936 png_bytep cp = prev_row;
2937 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2938 png_uint_32 istop=row_info->rowbytes - bpp;
2940 for (i = 0; i < bpp; i++)
2942 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2946 for (i = 0; i < istop; i++) /* Use leftover rp,pp */
2948 int a, b, c, pa, pb, pc, p;
2962 pa = p < 0 ? -p : p;
2963 pb = pc < 0 ? -pc : pc;
2964 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2968 if (pa <= pb && pa <= pc)
2976 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
2978 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2984 png_warning(png_ptr, "Ignoring bad adaptive filter type");
2990 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
2992 png_read_finish_row(png_structp png_ptr)
2994 #ifdef PNG_READ_INTERLACING_SUPPORTED
2995 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2997 /* Start of interlace block */
2998 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3000 /* Offset to next interlace block */
3001 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3003 /* Start of interlace block in the y direction */
3004 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3006 /* Offset to next interlace block in the y direction */
3007 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3008 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3010 png_debug(1, "in png_read_finish_row");
3011 png_ptr->row_number++;
3012 if (png_ptr->row_number < png_ptr->num_rows)
3015 #ifdef PNG_READ_INTERLACING_SUPPORTED
3016 if (png_ptr->interlaced)
3018 png_ptr->row_number = 0;
3019 png_memset(png_ptr->prev_row, 0,
3020 png_ptr->rowbytes + 1);
3024 if (png_ptr->pass >= 7)
3026 png_ptr->iwidth = (png_ptr->width +
3027 png_pass_inc[png_ptr->pass] - 1 -
3028 png_pass_start[png_ptr->pass]) /
3029 png_pass_inc[png_ptr->pass];
3031 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
3032 png_ptr->iwidth) + 1;
3034 if (!(png_ptr->transformations & PNG_INTERLACE))
3036 png_ptr->num_rows = (png_ptr->height +
3037 png_pass_yinc[png_ptr->pass] - 1 -
3038 png_pass_ystart[png_ptr->pass]) /
3039 png_pass_yinc[png_ptr->pass];
3040 if (!(png_ptr->num_rows))
3043 else /* if (png_ptr->transformations & PNG_INTERLACE) */
3045 } while (png_ptr->iwidth == 0);
3047 if (png_ptr->pass < 7)
3050 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3052 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3058 png_ptr->zstream.next_out = (Byte *)&extra;
3059 png_ptr->zstream.avail_out = (uInt)1;
3062 if (!(png_ptr->zstream.avail_in))
3064 while (!png_ptr->idat_size)
3066 png_byte chunk_length[4];
3068 png_crc_finish(png_ptr, 0);
3070 png_read_data(png_ptr, chunk_length, 4);
3071 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
3072 png_reset_crc(png_ptr);
3073 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3074 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
3075 png_error(png_ptr, "Not enough image data");
3078 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3079 png_ptr->zstream.next_in = png_ptr->zbuf;
3080 if (png_ptr->zbuf_size > png_ptr->idat_size)
3081 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3082 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3083 png_ptr->idat_size -= png_ptr->zstream.avail_in;
3085 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3086 if (ret == Z_STREAM_END)
3088 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3090 png_warning(png_ptr, "Extra compressed data");
3091 png_ptr->mode |= PNG_AFTER_IDAT;
3092 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3096 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3097 "Decompression Error");
3099 if (!(png_ptr->zstream.avail_out))
3101 png_warning(png_ptr, "Extra compressed data");
3102 png_ptr->mode |= PNG_AFTER_IDAT;
3103 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3108 png_ptr->zstream.avail_out = 0;
3111 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3112 png_warning(png_ptr, "Extra compression data");
3114 inflateReset(&png_ptr->zstream);
3116 png_ptr->mode |= PNG_AFTER_IDAT;
3118 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3121 png_read_start_row(png_structp png_ptr)
3123 #ifdef PNG_READ_INTERLACING_SUPPORTED
3124 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3126 /* Start of interlace block */
3127 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3129 /* Offset to next interlace block */
3130 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3132 /* Start of interlace block in the y direction */
3133 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3135 /* Offset to next interlace block in the y direction */
3136 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3139 int max_pixel_depth;
3140 png_size_t row_bytes;
3142 png_debug(1, "in png_read_start_row");
3143 png_ptr->zstream.avail_in = 0;
3144 png_init_read_transformations(png_ptr);
3145 #ifdef PNG_READ_INTERLACING_SUPPORTED
3146 if (png_ptr->interlaced)
3148 if (!(png_ptr->transformations & PNG_INTERLACE))
3149 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3150 png_pass_ystart[0]) / png_pass_yinc[0];
3152 png_ptr->num_rows = png_ptr->height;
3154 png_ptr->iwidth = (png_ptr->width +
3155 png_pass_inc[png_ptr->pass] - 1 -
3156 png_pass_start[png_ptr->pass]) /
3157 png_pass_inc[png_ptr->pass];
3159 png_ptr->irowbytes =
3160 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1;
3163 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3165 png_ptr->num_rows = png_ptr->height;
3166 png_ptr->iwidth = png_ptr->width;
3167 png_ptr->irowbytes = png_ptr->rowbytes + 1;
3169 max_pixel_depth = png_ptr->pixel_depth;
3171 #ifdef PNG_READ_PACK_SUPPORTED
3172 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3173 max_pixel_depth = 8;
3176 #ifdef PNG_READ_EXPAND_SUPPORTED
3177 if (png_ptr->transformations & PNG_EXPAND)
3179 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3181 if (png_ptr->num_trans)
3182 max_pixel_depth = 32;
3184 max_pixel_depth = 24;
3186 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3188 if (max_pixel_depth < 8)
3189 max_pixel_depth = 8;
3190 if (png_ptr->num_trans)
3191 max_pixel_depth *= 2;
3193 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3195 if (png_ptr->num_trans)
3197 max_pixel_depth *= 4;
3198 max_pixel_depth /= 3;
3204 #ifdef PNG_READ_FILLER_SUPPORTED
3205 if (png_ptr->transformations & (PNG_FILLER))
3207 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3208 max_pixel_depth = 32;
3209 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3211 if (max_pixel_depth <= 8)
3212 max_pixel_depth = 16;
3214 max_pixel_depth = 32;
3216 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3218 if (max_pixel_depth <= 32)
3219 max_pixel_depth = 32;
3221 max_pixel_depth = 64;
3226 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3227 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3230 #ifdef PNG_READ_EXPAND_SUPPORTED
3231 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3233 #ifdef PNG_READ_FILLER_SUPPORTED
3234 (png_ptr->transformations & (PNG_FILLER)) ||
3236 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3238 if (max_pixel_depth <= 16)
3239 max_pixel_depth = 32;
3241 max_pixel_depth = 64;
3245 if (max_pixel_depth <= 8)
3247 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3248 max_pixel_depth = 32;
3250 max_pixel_depth = 24;
3252 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3253 max_pixel_depth = 64;
3255 max_pixel_depth = 48;
3260 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3261 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3262 if (png_ptr->transformations & PNG_USER_TRANSFORM)
3264 int user_pixel_depth = png_ptr->user_transform_depth*
3265 png_ptr->user_transform_channels;
3266 if (user_pixel_depth > max_pixel_depth)
3267 max_pixel_depth=user_pixel_depth;
3271 /* Align the width on the next larger 8 pixels. Mainly used
3274 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3275 /* Calculate the maximum bytes needed, adding a byte and a pixel
3278 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
3279 1 + ((max_pixel_depth + 7) >> 3);
3280 #ifdef PNG_MAX_MALLOC_64K
3281 if (row_bytes > (png_uint_32)65536L)
3282 png_error(png_ptr, "This image requires a row greater than 64KB");
3285 if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
3287 png_free(png_ptr, png_ptr->big_row_buf);
3288 if (png_ptr->interlaced)
3289 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
3292 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
3294 png_ptr->old_big_row_buf_size = row_bytes + 48;
3296 #ifdef PNG_ALIGNED_MEMORY_SUPPORTED
3297 /* Use 16-byte aligned memory for row_buf with at least 16 bytes
3298 * of padding before and after row_buf.
3300 png_ptr->row_buf = png_ptr->big_row_buf + 32
3301 - (((png_alloc_size_t)&(png_ptr->big_row_buf[0]) + 15) % 16);
3302 png_ptr->old_big_row_buf_size = row_bytes + 48;
3304 /* Use 32 bytes of padding before and 16 bytes after row_buf. */
3305 png_ptr->row_buf = png_ptr->big_row_buf + 32;
3307 png_ptr->old_big_row_buf_size = row_bytes + 48;
3310 #ifdef PNG_MAX_MALLOC_64K
3311 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3312 png_error(png_ptr, "This image requires a row greater than 64KB");
3314 if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3315 png_error(png_ptr, "Row has too many bytes to allocate in memory");
3317 if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size)
3319 png_free(png_ptr, png_ptr->prev_row);
3320 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3321 png_ptr->rowbytes + 1));
3322 png_ptr->old_prev_row_size = png_ptr->rowbytes + 1;
3325 png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3327 png_debug1(3, "width = %lu,", png_ptr->width);
3328 png_debug1(3, "height = %lu,", png_ptr->height);
3329 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
3330 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
3331 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
3332 png_debug1(3, "irowbytes = %lu", png_ptr->irowbytes);
3334 png_ptr->flags |= PNG_FLAG_ROW_INIT;
3336 #endif /* PNG_READ_SUPPORTED */