2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.45 [July 7, 2011]
5 * Copyright (c) 1998-2011 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 int copy = output_size - count;
251 if (avail < copy) copy = 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 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
343 if (png_ptr->user_chunk_malloc_max &&
344 (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
346 # ifdef PNG_USER_CHUNK_MALLOC_MAX
347 if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
348 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
351 png_warning(png_ptr, "Exceeded size limit while expanding chunk");
353 /* If the size is zero either there was an error and a message
354 * has already been output (warning) or the size really is zero
355 * and we have nothing to do - the code will exit through the
358 #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
359 defined(PNG_USER_CHUNK_MALLOC_MAX)
362 if (expanded_size > 0)
364 /* Success (maybe) - really uncompress the chunk. */
365 png_size_t new_size = 0;
366 png_charp text = png_malloc_warn(png_ptr,
367 prefix_size + expanded_size + 1);
371 png_memcpy(text, png_ptr->chunkdata, prefix_size);
372 new_size = png_inflate(png_ptr,
373 (png_bytep)(png_ptr->chunkdata + prefix_size),
374 chunklength - prefix_size,
375 (png_bytep)(text + prefix_size), expanded_size);
376 text[prefix_size + expanded_size] = 0; /* just in case */
378 if (new_size == expanded_size)
380 png_free(png_ptr, png_ptr->chunkdata);
381 png_ptr->chunkdata = text;
382 *newlength = prefix_size + expanded_size;
383 return; /* The success return! */
386 png_warning(png_ptr, "png_inflate logic error");
387 png_free(png_ptr, text);
390 png_warning(png_ptr, "Not enough memory to decompress chunk.");
394 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
396 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
399 png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
401 png_warning(png_ptr, umsg);
403 png_warning(png_ptr, "Unknown zTXt compression type");
406 /* The recovery is to simply drop the data. */
409 /* Generic error return - leave the prefix, delete the compressed
410 * data, reallocate the chunkdata to remove the potentially large
411 * amount of compressed data.
414 png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
418 png_memcpy(text, png_ptr->chunkdata, prefix_size);
419 png_free(png_ptr, png_ptr->chunkdata);
420 png_ptr->chunkdata = text;
422 /* This is an extra zero in the 'uncompressed' part. */
423 *(png_ptr->chunkdata + prefix_size) = 0x00;
425 /* Ignore a malloc error here - it is safe. */
428 *newlength = prefix_size;
432 /* Read and check the IDHR chunk */
434 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
437 png_uint_32 width, height;
438 int bit_depth, color_type, compression_type, filter_type;
441 png_debug(1, "in png_handle_IHDR");
443 if (png_ptr->mode & PNG_HAVE_IHDR)
444 png_error(png_ptr, "Out of place IHDR");
446 /* Check the length */
448 png_error(png_ptr, "Invalid IHDR chunk");
450 png_ptr->mode |= PNG_HAVE_IHDR;
452 png_crc_read(png_ptr, buf, 13);
453 png_crc_finish(png_ptr, 0);
455 width = png_get_uint_31(png_ptr, buf);
456 height = png_get_uint_31(png_ptr, buf + 4);
459 compression_type = buf[10];
460 filter_type = buf[11];
461 interlace_type = buf[12];
463 /* Set internal variables */
464 png_ptr->width = width;
465 png_ptr->height = height;
466 png_ptr->bit_depth = (png_byte)bit_depth;
467 png_ptr->interlaced = (png_byte)interlace_type;
468 png_ptr->color_type = (png_byte)color_type;
469 #ifdef PNG_MNG_FEATURES_SUPPORTED
470 png_ptr->filter_type = (png_byte)filter_type;
472 png_ptr->compression_type = (png_byte)compression_type;
474 /* Find number of channels */
475 switch (png_ptr->color_type)
477 case PNG_COLOR_TYPE_GRAY:
478 case PNG_COLOR_TYPE_PALETTE:
479 png_ptr->channels = 1;
482 case PNG_COLOR_TYPE_RGB:
483 png_ptr->channels = 3;
486 case PNG_COLOR_TYPE_GRAY_ALPHA:
487 png_ptr->channels = 2;
490 case PNG_COLOR_TYPE_RGB_ALPHA:
491 png_ptr->channels = 4;
495 /* Set up other useful info */
496 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
498 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
499 png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
500 png_debug1(3, "channels = %d", png_ptr->channels);
501 png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
502 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
503 color_type, interlace_type, compression_type, filter_type);
506 /* Read and check the palette */
508 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
510 png_color palette[PNG_MAX_PALETTE_LENGTH];
512 #ifdef PNG_POINTER_INDEXING_SUPPORTED
516 png_debug(1, "in png_handle_PLTE");
518 if (!(png_ptr->mode & PNG_HAVE_IHDR))
519 png_error(png_ptr, "Missing IHDR before PLTE");
521 else if (png_ptr->mode & PNG_HAVE_IDAT)
523 png_warning(png_ptr, "Invalid PLTE after IDAT");
524 png_crc_finish(png_ptr, length);
528 else if (png_ptr->mode & PNG_HAVE_PLTE)
529 png_error(png_ptr, "Duplicate PLTE chunk");
531 png_ptr->mode |= PNG_HAVE_PLTE;
533 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
536 "Ignoring PLTE chunk in grayscale PNG");
537 png_crc_finish(png_ptr, length);
540 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
541 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
543 png_crc_finish(png_ptr, length);
548 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
550 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
552 png_warning(png_ptr, "Invalid palette chunk");
553 png_crc_finish(png_ptr, length);
559 png_error(png_ptr, "Invalid palette chunk");
563 num = (int)length / 3;
565 #ifdef PNG_POINTER_INDEXING_SUPPORTED
566 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
570 png_crc_read(png_ptr, buf, 3);
571 pal_ptr->red = buf[0];
572 pal_ptr->green = buf[1];
573 pal_ptr->blue = buf[2];
576 for (i = 0; i < num; i++)
580 png_crc_read(png_ptr, buf, 3);
581 /* Don't depend upon png_color being any order */
582 palette[i].red = buf[0];
583 palette[i].green = buf[1];
584 palette[i].blue = buf[2];
588 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
589 * whatever the normal CRC configuration tells us. However, if we
590 * have an RGB image, the PLTE can be considered ancillary, so
591 * we will act as though it is.
593 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
594 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
597 png_crc_finish(png_ptr, 0);
599 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
600 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
602 /* If we don't want to use the data from an ancillary chunk,
603 we have two options: an error abort, or a warning and we
604 ignore the data in this chunk (which should be OK, since
605 it's considered ancillary for a RGB or RGBA image). */
606 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
608 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
610 png_chunk_error(png_ptr, "CRC error");
614 png_chunk_warning(png_ptr, "CRC error");
618 /* Otherwise, we (optionally) emit a warning and use the chunk. */
619 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
621 png_chunk_warning(png_ptr, "CRC error");
626 png_set_PLTE(png_ptr, info_ptr, palette, num);
628 #ifdef PNG_READ_tRNS_SUPPORTED
629 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
631 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
633 if (png_ptr->num_trans > (png_uint_16)num)
635 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
636 png_ptr->num_trans = (png_uint_16)num;
638 if (info_ptr->num_trans > (png_uint_16)num)
640 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
641 info_ptr->num_trans = (png_uint_16)num;
650 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
652 png_debug(1, "in png_handle_IEND");
654 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
656 png_error(png_ptr, "No image in file");
659 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
663 png_warning(png_ptr, "Incorrect IEND chunk length");
665 png_crc_finish(png_ptr, length);
667 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
670 #ifdef PNG_READ_gAMA_SUPPORTED
672 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
674 png_fixed_point igamma;
675 #ifdef PNG_FLOATING_POINT_SUPPORTED
680 png_debug(1, "in png_handle_gAMA");
682 if (!(png_ptr->mode & PNG_HAVE_IHDR))
683 png_error(png_ptr, "Missing IHDR before gAMA");
684 else if (png_ptr->mode & PNG_HAVE_IDAT)
686 png_warning(png_ptr, "Invalid gAMA after IDAT");
687 png_crc_finish(png_ptr, length);
690 else if (png_ptr->mode & PNG_HAVE_PLTE)
691 /* Should be an error, but we can cope with it */
692 png_warning(png_ptr, "Out of place gAMA chunk");
694 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
695 #ifdef PNG_READ_sRGB_SUPPORTED
696 && !(info_ptr->valid & PNG_INFO_sRGB)
700 png_warning(png_ptr, "Duplicate gAMA chunk");
701 png_crc_finish(png_ptr, length);
707 png_warning(png_ptr, "Incorrect gAMA chunk length");
708 png_crc_finish(png_ptr, length);
712 png_crc_read(png_ptr, buf, 4);
713 if (png_crc_finish(png_ptr, 0))
716 igamma = (png_fixed_point)png_get_uint_32(buf);
717 /* Check for zero gamma */
721 "Ignoring gAMA chunk with gamma=0");
725 #ifdef PNG_READ_sRGB_SUPPORTED
726 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
727 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
730 "Ignoring incorrect gAMA value when sRGB is also present");
731 #ifdef PNG_CONSOLE_IO_SUPPORTED
732 fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
736 #endif /* PNG_READ_sRGB_SUPPORTED */
738 #ifdef PNG_FLOATING_POINT_SUPPORTED
739 file_gamma = (float)igamma / (float)100000.0;
740 # ifdef PNG_READ_GAMMA_SUPPORTED
741 png_ptr->gamma = file_gamma;
743 png_set_gAMA(png_ptr, info_ptr, file_gamma);
745 #ifdef PNG_FIXED_POINT_SUPPORTED
746 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
751 #ifdef PNG_READ_sBIT_SUPPORTED
753 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
758 png_debug(1, "in png_handle_sBIT");
760 buf[0] = buf[1] = buf[2] = buf[3] = 0;
762 if (!(png_ptr->mode & PNG_HAVE_IHDR))
763 png_error(png_ptr, "Missing IHDR before sBIT");
764 else if (png_ptr->mode & PNG_HAVE_IDAT)
766 png_warning(png_ptr, "Invalid sBIT after IDAT");
767 png_crc_finish(png_ptr, length);
770 else if (png_ptr->mode & PNG_HAVE_PLTE)
772 /* Should be an error, but we can cope with it */
773 png_warning(png_ptr, "Out of place sBIT chunk");
775 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
777 png_warning(png_ptr, "Duplicate sBIT chunk");
778 png_crc_finish(png_ptr, length);
782 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
785 truelen = (png_size_t)png_ptr->channels;
787 if (length != truelen || length > 4)
789 png_warning(png_ptr, "Incorrect sBIT chunk length");
790 png_crc_finish(png_ptr, length);
794 png_crc_read(png_ptr, buf, truelen);
795 if (png_crc_finish(png_ptr, 0))
798 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
800 png_ptr->sig_bit.red = buf[0];
801 png_ptr->sig_bit.green = buf[1];
802 png_ptr->sig_bit.blue = buf[2];
803 png_ptr->sig_bit.alpha = buf[3];
807 png_ptr->sig_bit.gray = buf[0];
808 png_ptr->sig_bit.red = buf[0];
809 png_ptr->sig_bit.green = buf[0];
810 png_ptr->sig_bit.blue = buf[0];
811 png_ptr->sig_bit.alpha = buf[1];
813 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
817 #ifdef PNG_READ_cHRM_SUPPORTED
819 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
822 #ifdef PNG_FLOATING_POINT_SUPPORTED
823 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
825 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
826 int_y_green, int_x_blue, int_y_blue;
828 png_uint_32 uint_x, uint_y;
830 png_debug(1, "in png_handle_cHRM");
832 if (!(png_ptr->mode & PNG_HAVE_IHDR))
833 png_error(png_ptr, "Missing IHDR before cHRM");
834 else if (png_ptr->mode & PNG_HAVE_IDAT)
836 png_warning(png_ptr, "Invalid cHRM after IDAT");
837 png_crc_finish(png_ptr, length);
840 else if (png_ptr->mode & PNG_HAVE_PLTE)
841 /* Should be an error, but we can cope with it */
842 png_warning(png_ptr, "Missing PLTE before cHRM");
844 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
845 #ifdef PNG_READ_sRGB_SUPPORTED
846 && !(info_ptr->valid & PNG_INFO_sRGB)
850 png_warning(png_ptr, "Duplicate cHRM chunk");
851 png_crc_finish(png_ptr, length);
857 png_warning(png_ptr, "Incorrect cHRM chunk length");
858 png_crc_finish(png_ptr, length);
862 png_crc_read(png_ptr, buf, 32);
863 if (png_crc_finish(png_ptr, 0))
866 uint_x = png_get_uint_32(buf);
867 uint_y = png_get_uint_32(buf + 4);
868 int_x_white = (png_fixed_point)uint_x;
869 int_y_white = (png_fixed_point)uint_y;
871 uint_x = png_get_uint_32(buf + 8);
872 uint_y = png_get_uint_32(buf + 12);
873 int_x_red = (png_fixed_point)uint_x;
874 int_y_red = (png_fixed_point)uint_y;
876 uint_x = png_get_uint_32(buf + 16);
877 uint_y = png_get_uint_32(buf + 20);
878 int_x_green = (png_fixed_point)uint_x;
879 int_y_green = (png_fixed_point)uint_y;
881 uint_x = png_get_uint_32(buf + 24);
882 uint_y = png_get_uint_32(buf + 28);
883 int_x_blue = (png_fixed_point)uint_x;
884 int_y_blue = (png_fixed_point)uint_y;
886 #ifdef PNG_FLOATING_POINT_SUPPORTED
887 white_x = (float)int_x_white / (float)100000.0;
888 white_y = (float)int_y_white / (float)100000.0;
889 red_x = (float)int_x_red / (float)100000.0;
890 red_y = (float)int_y_red / (float)100000.0;
891 green_x = (float)int_x_green / (float)100000.0;
892 green_y = (float)int_y_green / (float)100000.0;
893 blue_x = (float)int_x_blue / (float)100000.0;
894 blue_y = (float)int_y_blue / (float)100000.0;
897 #ifdef PNG_READ_sRGB_SUPPORTED
898 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
900 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
901 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
902 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
903 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
904 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
905 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
906 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
907 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
910 "Ignoring incorrect cHRM value when sRGB is also present");
911 #ifdef PNG_CONSOLE_IO_SUPPORTED
912 #ifdef PNG_FLOATING_POINT_SUPPORTED
913 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
914 white_x, white_y, red_x, red_y);
915 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
916 green_x, green_y, blue_x, blue_y);
918 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
919 (long)int_x_white, (long)int_y_white,
920 (long)int_x_red, (long)int_y_red);
921 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
922 (long)int_x_green, (long)int_y_green,
923 (long)int_x_blue, (long)int_y_blue);
925 #endif /* PNG_CONSOLE_IO_SUPPORTED */
929 #endif /* PNG_READ_sRGB_SUPPORTED */
931 #ifdef PNG_FLOATING_POINT_SUPPORTED
932 png_set_cHRM(png_ptr, info_ptr,
933 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
935 #ifdef PNG_FIXED_POINT_SUPPORTED
936 png_set_cHRM_fixed(png_ptr, info_ptr,
937 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
938 int_y_green, int_x_blue, int_y_blue);
943 #ifdef PNG_READ_sRGB_SUPPORTED
945 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
950 png_debug(1, "in png_handle_sRGB");
952 if (!(png_ptr->mode & PNG_HAVE_IHDR))
953 png_error(png_ptr, "Missing IHDR before sRGB");
954 else if (png_ptr->mode & PNG_HAVE_IDAT)
956 png_warning(png_ptr, "Invalid sRGB after IDAT");
957 png_crc_finish(png_ptr, length);
960 else if (png_ptr->mode & PNG_HAVE_PLTE)
961 /* Should be an error, but we can cope with it */
962 png_warning(png_ptr, "Out of place sRGB chunk");
964 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
966 png_warning(png_ptr, "Duplicate sRGB chunk");
967 png_crc_finish(png_ptr, length);
973 png_warning(png_ptr, "Incorrect sRGB chunk length");
974 png_crc_finish(png_ptr, length);
978 png_crc_read(png_ptr, buf, 1);
979 if (png_crc_finish(png_ptr, 0))
983 /* Check for bad intent */
984 if (intent >= PNG_sRGB_INTENT_LAST)
986 png_warning(png_ptr, "Unknown sRGB intent");
990 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
991 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
993 png_fixed_point igamma;
994 #ifdef PNG_FIXED_POINT_SUPPORTED
995 igamma=info_ptr->int_gamma;
997 # ifdef PNG_FLOATING_POINT_SUPPORTED
998 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
1001 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
1003 png_warning(png_ptr,
1004 "Ignoring incorrect gAMA value when sRGB is also present");
1005 #ifdef PNG_CONSOLE_IO_SUPPORTED
1006 # ifdef PNG_FIXED_POINT_SUPPORTED
1007 fprintf(stderr, "incorrect gamma=(%d/100000)\n",
1008 (int)png_ptr->int_gamma);
1010 # ifdef PNG_FLOATING_POINT_SUPPORTED
1011 fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
1017 #endif /* PNG_READ_gAMA_SUPPORTED */
1019 #ifdef PNG_READ_cHRM_SUPPORTED
1020 #ifdef PNG_FIXED_POINT_SUPPORTED
1021 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1022 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
1023 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
1024 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
1025 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
1026 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
1027 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
1028 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
1029 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
1031 png_warning(png_ptr,
1032 "Ignoring incorrect cHRM value when sRGB is also present");
1034 #endif /* PNG_FIXED_POINT_SUPPORTED */
1035 #endif /* PNG_READ_cHRM_SUPPORTED */
1037 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1039 #endif /* PNG_READ_sRGB_SUPPORTED */
1041 #ifdef PNG_READ_iCCP_SUPPORTED
1043 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1044 /* Note: this does not properly handle chunks that are > 64K under DOS */
1046 png_byte compression_type;
1049 png_uint_32 skip = 0;
1050 png_uint_32 profile_size, profile_length;
1051 png_size_t slength, prefix_length, data_length;
1053 png_debug(1, "in png_handle_iCCP");
1055 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1056 png_error(png_ptr, "Missing IHDR before iCCP");
1057 else if (png_ptr->mode & PNG_HAVE_IDAT)
1059 png_warning(png_ptr, "Invalid iCCP after IDAT");
1060 png_crc_finish(png_ptr, length);
1063 else if (png_ptr->mode & PNG_HAVE_PLTE)
1064 /* Should be an error, but we can cope with it */
1065 png_warning(png_ptr, "Out of place iCCP chunk");
1067 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1069 png_warning(png_ptr, "Duplicate iCCP chunk");
1070 png_crc_finish(png_ptr, length);
1074 #ifdef PNG_MAX_MALLOC_64K
1075 if (length > (png_uint_32)65535L)
1077 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1078 skip = length - (png_uint_32)65535L;
1079 length = (png_uint_32)65535L;
1083 png_free(png_ptr, png_ptr->chunkdata);
1084 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1085 slength = (png_size_t)length;
1086 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1088 if (png_crc_finish(png_ptr, skip))
1090 png_free(png_ptr, png_ptr->chunkdata);
1091 png_ptr->chunkdata = NULL;
1095 png_ptr->chunkdata[slength] = 0x00;
1097 for (profile = png_ptr->chunkdata; *profile; profile++)
1098 /* Empty loop to find end of name */ ;
1102 /* There should be at least one zero (the compression type byte)
1103 * following the separator, and we should be on it
1105 if ( profile >= png_ptr->chunkdata + slength - 1)
1107 png_free(png_ptr, png_ptr->chunkdata);
1108 png_ptr->chunkdata = NULL;
1109 png_warning(png_ptr, "Malformed iCCP chunk");
1113 /* Compression_type should always be zero */
1114 compression_type = *profile++;
1115 if (compression_type)
1117 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1118 compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1122 prefix_length = profile - png_ptr->chunkdata;
1123 png_decompress_chunk(png_ptr, compression_type,
1124 slength, prefix_length, &data_length);
1126 profile_length = data_length - prefix_length;
1128 if ( prefix_length > data_length || profile_length < 4)
1130 png_free(png_ptr, png_ptr->chunkdata);
1131 png_ptr->chunkdata = NULL;
1132 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1136 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1137 pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1138 profile_size = ((*(pC ))<<24) |
1143 if (profile_size < profile_length)
1144 profile_length = profile_size;
1146 if (profile_size > profile_length)
1148 png_free(png_ptr, png_ptr->chunkdata);
1149 png_ptr->chunkdata = NULL;
1150 png_warning(png_ptr, "Ignoring truncated iCCP profile.");
1154 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1155 compression_type, png_ptr->chunkdata + prefix_length, profile_length);
1156 png_free(png_ptr, png_ptr->chunkdata);
1157 png_ptr->chunkdata = NULL;
1159 #endif /* PNG_READ_iCCP_SUPPORTED */
1161 #ifdef PNG_READ_sPLT_SUPPORTED
1163 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1164 /* Note: this does not properly handle chunks that are > 64K under DOS */
1166 png_bytep entry_start;
1167 png_sPLT_t new_palette;
1168 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1171 int data_length, entry_size, i;
1172 png_uint_32 skip = 0;
1175 png_debug(1, "in png_handle_sPLT");
1177 #ifdef PNG_USER_LIMITS_SUPPORTED
1179 if (png_ptr->user_chunk_cache_max != 0)
1181 if (png_ptr->user_chunk_cache_max == 1)
1183 png_crc_finish(png_ptr, length);
1186 if (--png_ptr->user_chunk_cache_max == 1)
1188 png_warning(png_ptr, "No space in chunk cache for sPLT");
1189 png_crc_finish(png_ptr, length);
1195 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1196 png_error(png_ptr, "Missing IHDR before sPLT");
1197 else if (png_ptr->mode & PNG_HAVE_IDAT)
1199 png_warning(png_ptr, "Invalid sPLT after IDAT");
1200 png_crc_finish(png_ptr, length);
1204 #ifdef PNG_MAX_MALLOC_64K
1205 if (length > (png_uint_32)65535L)
1207 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1208 skip = length - (png_uint_32)65535L;
1209 length = (png_uint_32)65535L;
1213 png_free(png_ptr, png_ptr->chunkdata);
1214 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1215 slength = (png_size_t)length;
1216 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1218 if (png_crc_finish(png_ptr, skip))
1220 png_free(png_ptr, png_ptr->chunkdata);
1221 png_ptr->chunkdata = NULL;
1225 png_ptr->chunkdata[slength] = 0x00;
1227 for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1229 /* Empty loop to find end of name */ ;
1232 /* A sample depth should follow the separator, and we should be on it */
1233 if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1235 png_free(png_ptr, png_ptr->chunkdata);
1236 png_ptr->chunkdata = NULL;
1237 png_warning(png_ptr, "malformed sPLT chunk");
1241 new_palette.depth = *entry_start++;
1242 entry_size = (new_palette.depth == 8 ? 6 : 10);
1243 data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
1245 /* Integrity-check the data length */
1246 if (data_length % entry_size)
1248 png_free(png_ptr, png_ptr->chunkdata);
1249 png_ptr->chunkdata = NULL;
1250 png_warning(png_ptr, "sPLT chunk has bad length");
1254 new_palette.nentries = (png_int_32) ( data_length / entry_size);
1255 if ((png_uint_32) new_palette.nentries >
1256 (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
1258 png_warning(png_ptr, "sPLT chunk too long");
1261 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1262 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1263 if (new_palette.entries == NULL)
1265 png_warning(png_ptr, "sPLT chunk requires too much memory");
1269 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1270 for (i = 0; i < new_palette.nentries; i++)
1272 pp = new_palette.entries + i;
1274 if (new_palette.depth == 8)
1276 pp->red = *entry_start++;
1277 pp->green = *entry_start++;
1278 pp->blue = *entry_start++;
1279 pp->alpha = *entry_start++;
1283 pp->red = png_get_uint_16(entry_start); entry_start += 2;
1284 pp->green = png_get_uint_16(entry_start); entry_start += 2;
1285 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1286 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1288 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1291 pp = new_palette.entries;
1292 for (i = 0; i < new_palette.nentries; i++)
1295 if (new_palette.depth == 8)
1297 pp[i].red = *entry_start++;
1298 pp[i].green = *entry_start++;
1299 pp[i].blue = *entry_start++;
1300 pp[i].alpha = *entry_start++;
1304 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1305 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1306 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1307 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1309 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1313 /* Discard all chunk data except the name and stash that */
1314 new_palette.name = png_ptr->chunkdata;
1316 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1318 png_free(png_ptr, png_ptr->chunkdata);
1319 png_ptr->chunkdata = NULL;
1320 png_free(png_ptr, new_palette.entries);
1322 #endif /* PNG_READ_sPLT_SUPPORTED */
1324 #ifdef PNG_READ_tRNS_SUPPORTED
1326 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1328 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1330 png_debug(1, "in png_handle_tRNS");
1332 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1333 png_error(png_ptr, "Missing IHDR before tRNS");
1334 else if (png_ptr->mode & PNG_HAVE_IDAT)
1336 png_warning(png_ptr, "Invalid tRNS after IDAT");
1337 png_crc_finish(png_ptr, length);
1340 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1342 png_warning(png_ptr, "Duplicate tRNS chunk");
1343 png_crc_finish(png_ptr, length);
1347 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1353 png_warning(png_ptr, "Incorrect tRNS chunk length");
1354 png_crc_finish(png_ptr, length);
1358 png_crc_read(png_ptr, buf, 2);
1359 png_ptr->num_trans = 1;
1360 png_ptr->trans_values.gray = png_get_uint_16(buf);
1362 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1368 png_warning(png_ptr, "Incorrect tRNS chunk length");
1369 png_crc_finish(png_ptr, length);
1372 png_crc_read(png_ptr, buf, (png_size_t)length);
1373 png_ptr->num_trans = 1;
1374 png_ptr->trans_values.red = png_get_uint_16(buf);
1375 png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1376 png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1378 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1380 if (!(png_ptr->mode & PNG_HAVE_PLTE))
1382 /* Should be an error, but we can cope with it. */
1383 png_warning(png_ptr, "Missing PLTE before tRNS");
1385 if (length > (png_uint_32)png_ptr->num_palette ||
1386 length > PNG_MAX_PALETTE_LENGTH)
1388 png_warning(png_ptr, "Incorrect tRNS chunk length");
1389 png_crc_finish(png_ptr, length);
1394 png_warning(png_ptr, "Zero length tRNS chunk");
1395 png_crc_finish(png_ptr, length);
1398 png_crc_read(png_ptr, readbuf, (png_size_t)length);
1399 png_ptr->num_trans = (png_uint_16)length;
1403 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1404 png_crc_finish(png_ptr, length);
1408 if (png_crc_finish(png_ptr, 0))
1410 png_ptr->num_trans = 0;
1414 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1415 &(png_ptr->trans_values));
1419 #ifdef PNG_READ_bKGD_SUPPORTED
1421 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1426 png_debug(1, "in png_handle_bKGD");
1428 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1429 png_error(png_ptr, "Missing IHDR before bKGD");
1430 else if (png_ptr->mode & PNG_HAVE_IDAT)
1432 png_warning(png_ptr, "Invalid bKGD after IDAT");
1433 png_crc_finish(png_ptr, length);
1436 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1437 !(png_ptr->mode & PNG_HAVE_PLTE))
1439 png_warning(png_ptr, "Missing PLTE before bKGD");
1440 png_crc_finish(png_ptr, length);
1443 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1445 png_warning(png_ptr, "Duplicate bKGD chunk");
1446 png_crc_finish(png_ptr, length);
1450 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1452 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1457 if (length != truelen)
1459 png_warning(png_ptr, "Incorrect bKGD chunk length");
1460 png_crc_finish(png_ptr, length);
1464 png_crc_read(png_ptr, buf, truelen);
1465 if (png_crc_finish(png_ptr, 0))
1468 /* We convert the index value into RGB components so that we can allow
1469 * arbitrary RGB values for background when we have transparency, and
1470 * so it is easy to determine the RGB values of the background color
1471 * from the info_ptr struct. */
1472 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1474 png_ptr->background.index = buf[0];
1475 if (info_ptr && info_ptr->num_palette)
1477 if (buf[0] >= info_ptr->num_palette)
1479 png_warning(png_ptr, "Incorrect bKGD chunk index value");
1482 png_ptr->background.red =
1483 (png_uint_16)png_ptr->palette[buf[0]].red;
1484 png_ptr->background.green =
1485 (png_uint_16)png_ptr->palette[buf[0]].green;
1486 png_ptr->background.blue =
1487 (png_uint_16)png_ptr->palette[buf[0]].blue;
1490 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1492 png_ptr->background.red =
1493 png_ptr->background.green =
1494 png_ptr->background.blue =
1495 png_ptr->background.gray = png_get_uint_16(buf);
1499 png_ptr->background.red = png_get_uint_16(buf);
1500 png_ptr->background.green = png_get_uint_16(buf + 2);
1501 png_ptr->background.blue = png_get_uint_16(buf + 4);
1504 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1508 #ifdef PNG_READ_hIST_SUPPORTED
1510 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1512 unsigned int num, i;
1513 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1515 png_debug(1, "in png_handle_hIST");
1517 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1518 png_error(png_ptr, "Missing IHDR before hIST");
1519 else if (png_ptr->mode & PNG_HAVE_IDAT)
1521 png_warning(png_ptr, "Invalid hIST after IDAT");
1522 png_crc_finish(png_ptr, length);
1525 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1527 png_warning(png_ptr, "Missing PLTE before hIST");
1528 png_crc_finish(png_ptr, length);
1531 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1533 png_warning(png_ptr, "Duplicate hIST chunk");
1534 png_crc_finish(png_ptr, length);
1539 if (num != (unsigned int) png_ptr->num_palette || num >
1540 (unsigned int) PNG_MAX_PALETTE_LENGTH)
1542 png_warning(png_ptr, "Incorrect hIST chunk length");
1543 png_crc_finish(png_ptr, length);
1547 for (i = 0; i < num; i++)
1551 png_crc_read(png_ptr, buf, 2);
1552 readbuf[i] = png_get_uint_16(buf);
1555 if (png_crc_finish(png_ptr, 0))
1558 png_set_hIST(png_ptr, info_ptr, readbuf);
1562 #ifdef PNG_READ_pHYs_SUPPORTED
1564 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1567 png_uint_32 res_x, res_y;
1570 png_debug(1, "in png_handle_pHYs");
1572 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1573 png_error(png_ptr, "Missing IHDR before pHYs");
1574 else if (png_ptr->mode & PNG_HAVE_IDAT)
1576 png_warning(png_ptr, "Invalid pHYs after IDAT");
1577 png_crc_finish(png_ptr, length);
1580 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1582 png_warning(png_ptr, "Duplicate pHYs chunk");
1583 png_crc_finish(png_ptr, length);
1589 png_warning(png_ptr, "Incorrect pHYs chunk length");
1590 png_crc_finish(png_ptr, length);
1594 png_crc_read(png_ptr, buf, 9);
1595 if (png_crc_finish(png_ptr, 0))
1598 res_x = png_get_uint_32(buf);
1599 res_y = png_get_uint_32(buf + 4);
1601 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1605 #ifdef PNG_READ_oFFs_SUPPORTED
1607 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1610 png_int_32 offset_x, offset_y;
1613 png_debug(1, "in png_handle_oFFs");
1615 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1616 png_error(png_ptr, "Missing IHDR before oFFs");
1617 else if (png_ptr->mode & PNG_HAVE_IDAT)
1619 png_warning(png_ptr, "Invalid oFFs after IDAT");
1620 png_crc_finish(png_ptr, length);
1623 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1625 png_warning(png_ptr, "Duplicate oFFs chunk");
1626 png_crc_finish(png_ptr, length);
1632 png_warning(png_ptr, "Incorrect oFFs chunk length");
1633 png_crc_finish(png_ptr, length);
1637 png_crc_read(png_ptr, buf, 9);
1638 if (png_crc_finish(png_ptr, 0))
1641 offset_x = png_get_int_32(buf);
1642 offset_y = png_get_int_32(buf + 4);
1644 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1648 #ifdef PNG_READ_pCAL_SUPPORTED
1649 /* Read the pCAL chunk (described in the PNG Extensions document) */
1651 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1654 png_byte type, nparams;
1655 png_charp buf, units, endptr;
1660 png_debug(1, "in png_handle_pCAL");
1662 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1663 png_error(png_ptr, "Missing IHDR before pCAL");
1664 else if (png_ptr->mode & PNG_HAVE_IDAT)
1666 png_warning(png_ptr, "Invalid pCAL after IDAT");
1667 png_crc_finish(png_ptr, length);
1670 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1672 png_warning(png_ptr, "Duplicate pCAL chunk");
1673 png_crc_finish(png_ptr, length);
1677 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1679 png_free(png_ptr, png_ptr->chunkdata);
1680 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1681 if (png_ptr->chunkdata == NULL)
1683 png_warning(png_ptr, "No memory for pCAL purpose.");
1686 slength = (png_size_t)length;
1687 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1689 if (png_crc_finish(png_ptr, 0))
1691 png_free(png_ptr, png_ptr->chunkdata);
1692 png_ptr->chunkdata = NULL;
1696 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1698 png_debug(3, "Finding end of pCAL purpose string");
1699 for (buf = png_ptr->chunkdata; *buf; buf++)
1702 endptr = png_ptr->chunkdata + slength;
1704 /* We need to have at least 12 bytes after the purpose string
1705 in order to get the parameter information. */
1706 if (endptr <= buf + 12)
1708 png_warning(png_ptr, "Invalid pCAL data");
1709 png_free(png_ptr, png_ptr->chunkdata);
1710 png_ptr->chunkdata = NULL;
1714 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1715 X0 = png_get_int_32((png_bytep)buf+1);
1716 X1 = png_get_int_32((png_bytep)buf+5);
1721 png_debug(3, "Checking pCAL equation type and number of parameters");
1722 /* Check that we have the right number of parameters for known
1724 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1725 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1726 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1727 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1729 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1730 png_free(png_ptr, png_ptr->chunkdata);
1731 png_ptr->chunkdata = NULL;
1734 else if (type >= PNG_EQUATION_LAST)
1736 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1739 for (buf = units; *buf; buf++)
1740 /* Empty loop to move past the units string. */ ;
1742 png_debug(3, "Allocating pCAL parameters array");
1743 params = (png_charpp)png_malloc_warn(png_ptr,
1744 (png_uint_32)(nparams * png_sizeof(png_charp))) ;
1747 png_free(png_ptr, png_ptr->chunkdata);
1748 png_ptr->chunkdata = NULL;
1749 png_warning(png_ptr, "No memory for pCAL params.");
1753 /* Get pointers to the start of each parameter string. */
1754 for (i = 0; i < (int)nparams; i++)
1756 buf++; /* Skip the null string terminator from previous parameter. */
1758 png_debug1(3, "Reading pCAL parameter %d", i);
1759 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1760 /* Empty loop to move past each parameter string */ ;
1762 /* Make sure we haven't run out of data yet */
1765 png_warning(png_ptr, "Invalid pCAL data");
1766 png_free(png_ptr, png_ptr->chunkdata);
1767 png_ptr->chunkdata = NULL;
1768 png_free(png_ptr, params);
1773 png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
1776 png_free(png_ptr, png_ptr->chunkdata);
1777 png_ptr->chunkdata = NULL;
1778 png_free(png_ptr, params);
1782 #ifdef PNG_READ_sCAL_SUPPORTED
1783 /* Read the sCAL chunk */
1785 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1788 #ifdef PNG_FLOATING_POINT_SUPPORTED
1789 double width, height;
1792 #ifdef PNG_FIXED_POINT_SUPPORTED
1793 png_charp swidth, sheight;
1798 png_debug(1, "in png_handle_sCAL");
1800 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1801 png_error(png_ptr, "Missing IHDR before sCAL");
1802 else if (png_ptr->mode & PNG_HAVE_IDAT)
1804 png_warning(png_ptr, "Invalid sCAL after IDAT");
1805 png_crc_finish(png_ptr, length);
1808 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1810 png_warning(png_ptr, "Duplicate sCAL chunk");
1811 png_crc_finish(png_ptr, length);
1815 /* Need unit type, width, \0, height: minimum 4 bytes */
1816 else if (length < 4)
1818 png_warning(png_ptr, "sCAL chunk too short");
1819 png_crc_finish(png_ptr, length);
1823 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1825 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1826 if (png_ptr->chunkdata == NULL)
1828 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1829 png_crc_finish(png_ptr, length);
1832 slength = (png_size_t)length;
1833 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1835 if (png_crc_finish(png_ptr, 0))
1837 png_free(png_ptr, png_ptr->chunkdata);
1838 png_ptr->chunkdata = NULL;
1842 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1844 ep = png_ptr->chunkdata + 1; /* Skip unit byte */
1846 #ifdef PNG_FLOATING_POINT_SUPPORTED
1847 width = png_strtod(png_ptr, ep, &vp);
1850 png_warning(png_ptr, "malformed width string in sCAL chunk");
1851 png_free(png_ptr, png_ptr->chunkdata);
1852 png_ptr->chunkdata = NULL;
1856 #ifdef PNG_FIXED_POINT_SUPPORTED
1857 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1860 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1861 png_free(png_ptr, png_ptr->chunkdata);
1862 png_ptr->chunkdata = NULL;
1865 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1869 for (ep = png_ptr->chunkdata; *ep; ep++)
1873 if (png_ptr->chunkdata + slength < ep)
1875 png_warning(png_ptr, "Truncated sCAL chunk");
1876 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1877 png_free(png_ptr, swidth);
1879 png_free(png_ptr, png_ptr->chunkdata);
1880 png_ptr->chunkdata = NULL;
1884 #ifdef PNG_FLOATING_POINT_SUPPORTED
1885 height = png_strtod(png_ptr, ep, &vp);
1888 png_warning(png_ptr, "malformed height string in sCAL chunk");
1889 png_free(png_ptr, png_ptr->chunkdata);
1890 png_ptr->chunkdata = NULL;
1891 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1892 png_free(png_ptr, swidth);
1897 #ifdef PNG_FIXED_POINT_SUPPORTED
1898 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1899 if (sheight == NULL)
1901 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1902 png_free(png_ptr, png_ptr->chunkdata);
1903 png_ptr->chunkdata = NULL;
1904 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1905 png_free(png_ptr, swidth);
1909 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1913 if (png_ptr->chunkdata + slength < ep
1914 #ifdef PNG_FLOATING_POINT_SUPPORTED
1915 || width <= 0. || height <= 0.
1919 png_warning(png_ptr, "Invalid sCAL data");
1920 png_free(png_ptr, png_ptr->chunkdata);
1921 png_ptr->chunkdata = NULL;
1922 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1923 png_free(png_ptr, swidth);
1924 png_free(png_ptr, sheight);
1930 #ifdef PNG_FLOATING_POINT_SUPPORTED
1931 png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
1933 #ifdef PNG_FIXED_POINT_SUPPORTED
1934 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
1938 png_free(png_ptr, png_ptr->chunkdata);
1939 png_ptr->chunkdata = NULL;
1940 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1941 png_free(png_ptr, swidth);
1942 png_free(png_ptr, sheight);
1947 #ifdef PNG_READ_tIME_SUPPORTED
1949 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1954 png_debug(1, "in png_handle_tIME");
1956 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1957 png_error(png_ptr, "Out of place tIME chunk");
1958 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1960 png_warning(png_ptr, "Duplicate tIME chunk");
1961 png_crc_finish(png_ptr, length);
1965 if (png_ptr->mode & PNG_HAVE_IDAT)
1966 png_ptr->mode |= PNG_AFTER_IDAT;
1970 png_warning(png_ptr, "Incorrect tIME chunk length");
1971 png_crc_finish(png_ptr, length);
1975 png_crc_read(png_ptr, buf, 7);
1976 if (png_crc_finish(png_ptr, 0))
1979 mod_time.second = buf[6];
1980 mod_time.minute = buf[5];
1981 mod_time.hour = buf[4];
1982 mod_time.day = buf[3];
1983 mod_time.month = buf[2];
1984 mod_time.year = png_get_uint_16(buf);
1986 png_set_tIME(png_ptr, info_ptr, &mod_time);
1990 #ifdef PNG_READ_tEXt_SUPPORTED
1991 /* Note: this does not properly handle chunks that are > 64K under DOS */
1993 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1998 png_uint_32 skip = 0;
2002 png_debug(1, "in png_handle_tEXt");
2004 #ifdef PNG_USER_LIMITS_SUPPORTED
2005 if (png_ptr->user_chunk_cache_max != 0)
2007 if (png_ptr->user_chunk_cache_max == 1)
2009 png_crc_finish(png_ptr, length);
2012 if (--png_ptr->user_chunk_cache_max == 1)
2014 png_warning(png_ptr, "No space in chunk cache for tEXt");
2015 png_crc_finish(png_ptr, length);
2021 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2022 png_error(png_ptr, "Missing IHDR before tEXt");
2024 if (png_ptr->mode & PNG_HAVE_IDAT)
2025 png_ptr->mode |= PNG_AFTER_IDAT;
2027 #ifdef PNG_MAX_MALLOC_64K
2028 if (length > (png_uint_32)65535L)
2030 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2031 skip = length - (png_uint_32)65535L;
2032 length = (png_uint_32)65535L;
2036 png_free(png_ptr, png_ptr->chunkdata);
2038 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2039 if (png_ptr->chunkdata == NULL)
2041 png_warning(png_ptr, "No memory to process text chunk.");
2044 slength = (png_size_t)length;
2045 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2047 if (png_crc_finish(png_ptr, skip))
2049 png_free(png_ptr, png_ptr->chunkdata);
2050 png_ptr->chunkdata = NULL;
2054 key = png_ptr->chunkdata;
2056 key[slength] = 0x00;
2058 for (text = key; *text; text++)
2059 /* Empty loop to find end of key */ ;
2061 if (text != key + slength)
2064 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2065 (png_uint_32)png_sizeof(png_text));
2066 if (text_ptr == NULL)
2068 png_warning(png_ptr, "Not enough memory to process text chunk.");
2069 png_free(png_ptr, png_ptr->chunkdata);
2070 png_ptr->chunkdata = NULL;
2073 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2074 text_ptr->key = key;
2075 #ifdef PNG_iTXt_SUPPORTED
2076 text_ptr->lang = NULL;
2077 text_ptr->lang_key = NULL;
2078 text_ptr->itxt_length = 0;
2080 text_ptr->text = text;
2081 text_ptr->text_length = png_strlen(text);
2083 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2085 png_free(png_ptr, png_ptr->chunkdata);
2086 png_ptr->chunkdata = NULL;
2087 png_free(png_ptr, text_ptr);
2089 png_warning(png_ptr, "Insufficient memory to process text chunk.");
2093 #ifdef PNG_READ_zTXt_SUPPORTED
2094 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2096 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2102 png_size_t slength, prefix_len, data_len;
2104 png_debug(1, "in png_handle_zTXt");
2106 #ifdef PNG_USER_LIMITS_SUPPORTED
2107 if (png_ptr->user_chunk_cache_max != 0)
2109 if (png_ptr->user_chunk_cache_max == 1)
2111 png_crc_finish(png_ptr, length);
2114 if (--png_ptr->user_chunk_cache_max == 1)
2116 png_warning(png_ptr, "No space in chunk cache for zTXt");
2117 png_crc_finish(png_ptr, length);
2123 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2124 png_error(png_ptr, "Missing IHDR before zTXt");
2126 if (png_ptr->mode & PNG_HAVE_IDAT)
2127 png_ptr->mode |= PNG_AFTER_IDAT;
2129 #ifdef PNG_MAX_MALLOC_64K
2130 /* We will no doubt have problems with chunks even half this size, but
2131 there is no hard and fast rule to tell us where to stop. */
2132 if (length > (png_uint_32)65535L)
2134 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2135 png_crc_finish(png_ptr, length);
2140 png_free(png_ptr, png_ptr->chunkdata);
2141 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2142 if (png_ptr->chunkdata == NULL)
2144 png_warning(png_ptr, "Out of memory processing zTXt chunk.");
2147 slength = (png_size_t)length;
2148 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2149 if (png_crc_finish(png_ptr, 0))
2151 png_free(png_ptr, png_ptr->chunkdata);
2152 png_ptr->chunkdata = NULL;
2156 png_ptr->chunkdata[slength] = 0x00;
2158 for (text = png_ptr->chunkdata; *text; text++)
2161 /* zTXt must have some text after the chunkdataword */
2162 if (text >= png_ptr->chunkdata + slength - 2)
2164 png_warning(png_ptr, "Truncated zTXt chunk");
2165 png_free(png_ptr, png_ptr->chunkdata);
2166 png_ptr->chunkdata = NULL;
2171 comp_type = *(++text);
2172 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2174 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2175 comp_type = PNG_TEXT_COMPRESSION_zTXt;
2177 text++; /* Skip the compression_method byte */
2179 prefix_len = text - png_ptr->chunkdata;
2181 png_decompress_chunk(png_ptr, comp_type,
2182 (png_size_t)length, prefix_len, &data_len);
2184 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2185 (png_uint_32)png_sizeof(png_text));
2186 if (text_ptr == NULL)
2188 png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
2189 png_free(png_ptr, png_ptr->chunkdata);
2190 png_ptr->chunkdata = NULL;
2193 text_ptr->compression = comp_type;
2194 text_ptr->key = png_ptr->chunkdata;
2195 #ifdef PNG_iTXt_SUPPORTED
2196 text_ptr->lang = NULL;
2197 text_ptr->lang_key = NULL;
2198 text_ptr->itxt_length = 0;
2200 text_ptr->text = png_ptr->chunkdata + prefix_len;
2201 text_ptr->text_length = data_len;
2203 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2205 png_free(png_ptr, text_ptr);
2206 png_free(png_ptr, png_ptr->chunkdata);
2207 png_ptr->chunkdata = NULL;
2209 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2213 #ifdef PNG_READ_iTXt_SUPPORTED
2214 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2216 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2219 png_charp key, lang, text, lang_key;
2223 png_size_t slength, prefix_len, data_len;
2225 png_debug(1, "in png_handle_iTXt");
2227 #ifdef PNG_USER_LIMITS_SUPPORTED
2228 if (png_ptr->user_chunk_cache_max != 0)
2230 if (png_ptr->user_chunk_cache_max == 1)
2232 png_crc_finish(png_ptr, length);
2235 if (--png_ptr->user_chunk_cache_max == 1)
2237 png_warning(png_ptr, "No space in chunk cache for iTXt");
2238 png_crc_finish(png_ptr, length);
2244 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2245 png_error(png_ptr, "Missing IHDR before iTXt");
2247 if (png_ptr->mode & PNG_HAVE_IDAT)
2248 png_ptr->mode |= PNG_AFTER_IDAT;
2250 #ifdef PNG_MAX_MALLOC_64K
2251 /* We will no doubt have problems with chunks even half this size, but
2252 there is no hard and fast rule to tell us where to stop. */
2253 if (length > (png_uint_32)65535L)
2255 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2256 png_crc_finish(png_ptr, length);
2261 png_free(png_ptr, png_ptr->chunkdata);
2262 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2263 if (png_ptr->chunkdata == NULL)
2265 png_warning(png_ptr, "No memory to process iTXt chunk.");
2268 slength = (png_size_t)length;
2269 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2270 if (png_crc_finish(png_ptr, 0))
2272 png_free(png_ptr, png_ptr->chunkdata);
2273 png_ptr->chunkdata = NULL;
2277 png_ptr->chunkdata[slength] = 0x00;
2279 for (lang = png_ptr->chunkdata; *lang; lang++)
2281 lang++; /* Skip NUL separator */
2283 /* iTXt must have a language tag (possibly empty), two compression bytes,
2284 * translated keyword (possibly empty), and possibly some text after the
2288 if (lang >= png_ptr->chunkdata + slength - 3)
2290 png_warning(png_ptr, "Truncated iTXt chunk");
2291 png_free(png_ptr, png_ptr->chunkdata);
2292 png_ptr->chunkdata = NULL;
2297 comp_flag = *lang++;
2298 comp_type = *lang++;
2301 for (lang_key = lang; *lang_key; lang_key++)
2303 lang_key++; /* Skip NUL separator */
2305 if (lang_key >= png_ptr->chunkdata + slength)
2307 png_warning(png_ptr, "Truncated iTXt chunk");
2308 png_free(png_ptr, png_ptr->chunkdata);
2309 png_ptr->chunkdata = NULL;
2313 for (text = lang_key; *text; text++)
2315 text++; /* Skip NUL separator */
2316 if (text >= png_ptr->chunkdata + slength)
2318 png_warning(png_ptr, "Malformed iTXt chunk");
2319 png_free(png_ptr, png_ptr->chunkdata);
2320 png_ptr->chunkdata = NULL;
2324 prefix_len = text - png_ptr->chunkdata;
2326 key=png_ptr->chunkdata;
2328 png_decompress_chunk(png_ptr, comp_type,
2329 (size_t)length, prefix_len, &data_len);
2331 data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2332 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2333 (png_uint_32)png_sizeof(png_text));
2334 if (text_ptr == NULL)
2336 png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
2337 png_free(png_ptr, png_ptr->chunkdata);
2338 png_ptr->chunkdata = NULL;
2341 text_ptr->compression = (int)comp_flag + 1;
2342 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2343 text_ptr->lang = png_ptr->chunkdata + (lang - key);
2344 text_ptr->itxt_length = data_len;
2345 text_ptr->text_length = 0;
2346 text_ptr->key = png_ptr->chunkdata;
2347 text_ptr->text = png_ptr->chunkdata + prefix_len;
2349 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2351 png_free(png_ptr, text_ptr);
2352 png_free(png_ptr, png_ptr->chunkdata);
2353 png_ptr->chunkdata = NULL;
2355 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2359 /* This function is called when we haven't found a handler for a
2360 chunk. If there isn't a problem with the chunk itself (ie bad
2361 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2362 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2363 case it will be saved away to be written out later. */
2365 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2367 png_uint_32 skip = 0;
2369 png_debug(1, "in png_handle_unknown");
2371 #ifdef PNG_USER_LIMITS_SUPPORTED
2372 if (png_ptr->user_chunk_cache_max != 0)
2374 if (png_ptr->user_chunk_cache_max == 1)
2376 png_crc_finish(png_ptr, length);
2379 if (--png_ptr->user_chunk_cache_max == 1)
2381 png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2382 png_crc_finish(png_ptr, length);
2388 if (png_ptr->mode & PNG_HAVE_IDAT)
2390 #ifdef PNG_USE_LOCAL_ARRAYS
2393 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */
2394 png_ptr->mode |= PNG_AFTER_IDAT;
2397 if (!(png_ptr->chunk_name[0] & 0x20))
2399 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2400 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2401 PNG_HANDLE_CHUNK_ALWAYS
2402 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2403 && png_ptr->read_user_chunk_fn == NULL
2407 png_chunk_error(png_ptr, "unknown critical chunk");
2410 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2411 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2412 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2413 || (png_ptr->read_user_chunk_fn != NULL)
2417 #ifdef PNG_MAX_MALLOC_64K
2418 if (length > (png_uint_32)65535L)
2420 png_warning(png_ptr, "unknown chunk too large to fit in memory");
2421 skip = length - (png_uint_32)65535L;
2422 length = (png_uint_32)65535L;
2425 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2426 (png_charp)png_ptr->chunk_name,
2427 png_sizeof(png_ptr->unknown_chunk.name));
2428 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
2430 png_ptr->unknown_chunk.size = (png_size_t)length;
2432 png_ptr->unknown_chunk.data = NULL;
2435 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2436 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2438 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2439 if (png_ptr->read_user_chunk_fn != NULL)
2441 /* Callback to user unknown chunk handler */
2443 ret = (*(png_ptr->read_user_chunk_fn))
2444 (png_ptr, &png_ptr->unknown_chunk);
2446 png_chunk_error(png_ptr, "error in user chunk");
2449 if (!(png_ptr->chunk_name[0] & 0x20))
2450 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2451 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2452 PNG_HANDLE_CHUNK_ALWAYS)
2454 png_chunk_error(png_ptr, "unknown critical chunk");
2455 png_set_unknown_chunks(png_ptr, info_ptr,
2456 &png_ptr->unknown_chunk, 1);
2461 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2462 png_free(png_ptr, png_ptr->unknown_chunk.data);
2463 png_ptr->unknown_chunk.data = NULL;
2469 png_crc_finish(png_ptr, skip);
2471 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2472 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
2476 /* This function is called to verify that a chunk name is valid.
2477 This function can't have the "critical chunk check" incorporated
2478 into it, since in the future we will need to be able to call user
2479 functions to handle unknown critical chunks after we check that
2480 the chunk name itself is valid. */
2482 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2485 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2487 png_debug(1, "in png_check_chunk_name");
2488 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2489 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2491 png_chunk_error(png_ptr, "invalid chunk type");
2495 /* Combines the row recently read in with the existing pixels in the
2496 row. This routine takes care of alpha and transparency if requested.
2497 This routine also handles the two methods of progressive display
2498 of interlaced images, depending on the mask value.
2499 The mask value describes which pixels are to be combined with
2500 the row. The pattern always repeats every 8 pixels, so just 8
2501 bits are needed. A one indicates the pixel is to be combined,
2502 a zero indicates the pixel is to be skipped. This is in addition
2503 to any alpha or transparency value associated with the pixel. If
2504 you want all pixels to be combined, pass 0xff (255) in mask. */
2507 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2509 png_debug(1, "in png_combine_row");
2512 png_memcpy(row, png_ptr->row_buf + 1,
2513 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2517 switch (png_ptr->row_info.pixel_depth)
2521 png_bytep sp = png_ptr->row_buf + 1;
2523 int s_inc, s_start, s_end;
2527 png_uint_32 row_width = png_ptr->width;
2529 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2530 if (png_ptr->transformations & PNG_PACKSWAP)
2546 for (i = 0; i < row_width; i++)
2552 value = (*sp >> shift) & 0x01;
2553 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2554 *dp |= (png_byte)(value << shift);
2575 png_bytep sp = png_ptr->row_buf + 1;
2577 int s_start, s_end, s_inc;
2581 png_uint_32 row_width = png_ptr->width;
2584 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2585 if (png_ptr->transformations & PNG_PACKSWAP)
2601 for (i = 0; i < row_width; i++)
2605 value = (*sp >> shift) & 0x03;
2606 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2607 *dp |= (png_byte)(value << shift);
2627 png_bytep sp = png_ptr->row_buf + 1;
2629 int s_start, s_end, s_inc;
2633 png_uint_32 row_width = png_ptr->width;
2636 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2637 if (png_ptr->transformations & PNG_PACKSWAP)
2652 for (i = 0; i < row_width; i++)
2656 value = (*sp >> shift) & 0xf;
2657 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2658 *dp |= (png_byte)(value << shift);
2678 png_bytep sp = png_ptr->row_buf + 1;
2680 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2682 png_uint_32 row_width = png_ptr->width;
2686 for (i = 0; i < row_width; i++)
2690 png_memcpy(dp, sp, pixel_bytes);
2707 #ifdef PNG_READ_INTERLACING_SUPPORTED
2708 /* OLD pre-1.0.9 interface:
2709 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2710 png_uint_32 transformations)
2713 png_do_read_interlace(png_structp png_ptr)
2715 png_row_infop row_info = &(png_ptr->row_info);
2716 png_bytep row = png_ptr->row_buf + 1;
2717 int pass = png_ptr->pass;
2718 png_uint_32 transformations = png_ptr->transformations;
2719 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2720 /* Offset to next interlace block */
2721 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2723 png_debug(1, "in png_do_read_interlace");
2724 if (row != NULL && row_info != NULL)
2726 png_uint_32 final_width;
2728 final_width = row_info->width * png_pass_inc[pass];
2730 switch (row_info->pixel_depth)
2734 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2735 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2737 int s_start, s_end, s_inc;
2738 int jstop = png_pass_inc[pass];
2743 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2744 if (transformations & PNG_PACKSWAP)
2746 sshift = (int)((row_info->width + 7) & 0x07);
2747 dshift = (int)((final_width + 7) & 0x07);
2755 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2756 dshift = 7 - (int)((final_width + 7) & 0x07);
2762 for (i = 0; i < row_info->width; i++)
2764 v = (png_byte)((*sp >> sshift) & 0x01);
2765 for (j = 0; j < jstop; j++)
2767 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2768 *dp |= (png_byte)(v << dshift);
2769 if (dshift == s_end)
2777 if (sshift == s_end)
2789 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2790 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2792 int s_start, s_end, s_inc;
2793 int jstop = png_pass_inc[pass];
2796 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2797 if (transformations & PNG_PACKSWAP)
2799 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2800 dshift = (int)(((final_width + 3) & 0x03) << 1);
2808 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2809 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2815 for (i = 0; i < row_info->width; i++)
2820 v = (png_byte)((*sp >> sshift) & 0x03);
2821 for (j = 0; j < jstop; j++)
2823 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2824 *dp |= (png_byte)(v << dshift);
2825 if (dshift == s_end)
2833 if (sshift == s_end)
2845 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2846 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2848 int s_start, s_end, s_inc;
2850 int jstop = png_pass_inc[pass];
2852 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2853 if (transformations & PNG_PACKSWAP)
2855 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2856 dshift = (int)(((final_width + 1) & 0x01) << 2);
2864 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2865 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2871 for (i = 0; i < row_info->width; i++)
2873 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2876 for (j = 0; j < jstop; j++)
2878 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2879 *dp |= (png_byte)(v << dshift);
2880 if (dshift == s_end)
2888 if (sshift == s_end)
2900 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2901 png_bytep sp = row + (png_size_t)(row_info->width - 1)
2903 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2905 int jstop = png_pass_inc[pass];
2908 for (i = 0; i < row_info->width; i++)
2913 png_memcpy(v, sp, pixel_bytes);
2914 for (j = 0; j < jstop; j++)
2916 png_memcpy(dp, v, pixel_bytes);
2924 row_info->width = final_width;
2925 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
2927 #ifndef PNG_READ_PACKSWAP_SUPPORTED
2928 transformations = transformations; /* Silence compiler warning */
2931 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2934 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2935 png_bytep prev_row, int filter)
2937 png_debug(1, "in png_read_filter_row");
2938 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
2941 case PNG_FILTER_VALUE_NONE:
2943 case PNG_FILTER_VALUE_SUB:
2946 png_uint_32 istop = row_info->rowbytes;
2947 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2948 png_bytep rp = row + bpp;
2951 for (i = bpp; i < istop; i++)
2953 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2958 case PNG_FILTER_VALUE_UP:
2961 png_uint_32 istop = row_info->rowbytes;
2963 png_bytep pp = prev_row;
2965 for (i = 0; i < istop; i++)
2967 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2972 case PNG_FILTER_VALUE_AVG:
2976 png_bytep pp = prev_row;
2978 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2979 png_uint_32 istop = row_info->rowbytes - bpp;
2981 for (i = 0; i < bpp; i++)
2983 *rp = (png_byte)(((int)(*rp) +
2984 ((int)(*pp++) / 2 )) & 0xff);
2988 for (i = 0; i < istop; i++)
2990 *rp = (png_byte)(((int)(*rp) +
2991 (int)(*pp++ + *lp++) / 2 ) & 0xff);
2996 case PNG_FILTER_VALUE_PAETH:
3000 png_bytep pp = prev_row;
3002 png_bytep cp = prev_row;
3003 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
3004 png_uint_32 istop=row_info->rowbytes - bpp;
3006 for (i = 0; i < bpp; i++)
3008 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
3012 for (i = 0; i < istop; i++) /* Use leftover rp,pp */
3014 int a, b, c, pa, pb, pc, p;
3028 pa = p < 0 ? -p : p;
3029 pb = pc < 0 ? -pc : pc;
3030 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3034 if (pa <= pb && pa <= pc)
3042 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
3044 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
3050 png_warning(png_ptr, "Ignoring bad adaptive filter type");
3056 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3058 png_read_finish_row(png_structp png_ptr)
3060 #ifdef PNG_READ_INTERLACING_SUPPORTED
3061 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3063 /* Start of interlace block */
3064 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3066 /* Offset to next interlace block */
3067 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3069 /* Start of interlace block in the y direction */
3070 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3072 /* Offset to next interlace block in the y direction */
3073 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3074 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3076 png_debug(1, "in png_read_finish_row");
3077 png_ptr->row_number++;
3078 if (png_ptr->row_number < png_ptr->num_rows)
3081 #ifdef PNG_READ_INTERLACING_SUPPORTED
3082 if (png_ptr->interlaced)
3084 png_ptr->row_number = 0;
3085 png_memset_check(png_ptr, png_ptr->prev_row, 0,
3086 png_ptr->rowbytes + 1);
3090 if (png_ptr->pass >= 7)
3092 png_ptr->iwidth = (png_ptr->width +
3093 png_pass_inc[png_ptr->pass] - 1 -
3094 png_pass_start[png_ptr->pass]) /
3095 png_pass_inc[png_ptr->pass];
3097 if (!(png_ptr->transformations & PNG_INTERLACE))
3099 png_ptr->num_rows = (png_ptr->height +
3100 png_pass_yinc[png_ptr->pass] - 1 -
3101 png_pass_ystart[png_ptr->pass]) /
3102 png_pass_yinc[png_ptr->pass];
3103 if (!(png_ptr->num_rows))
3106 else /* if (png_ptr->transformations & PNG_INTERLACE) */
3108 } while (png_ptr->iwidth == 0);
3110 if (png_ptr->pass < 7)
3113 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3115 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3117 #ifdef PNG_USE_LOCAL_ARRAYS
3123 png_ptr->zstream.next_out = (Byte *)&extra;
3124 png_ptr->zstream.avail_out = (uInt)1;
3127 if (!(png_ptr->zstream.avail_in))
3129 while (!png_ptr->idat_size)
3131 png_byte chunk_length[4];
3133 png_crc_finish(png_ptr, 0);
3135 png_read_data(png_ptr, chunk_length, 4);
3136 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
3137 png_reset_crc(png_ptr);
3138 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3139 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
3140 png_error(png_ptr, "Not enough image data");
3143 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3144 png_ptr->zstream.next_in = png_ptr->zbuf;
3145 if (png_ptr->zbuf_size > png_ptr->idat_size)
3146 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3147 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3148 png_ptr->idat_size -= png_ptr->zstream.avail_in;
3150 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3151 if (ret == Z_STREAM_END)
3153 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3155 png_warning(png_ptr, "Extra compressed data.");
3156 png_ptr->mode |= PNG_AFTER_IDAT;
3157 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3161 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3162 "Decompression Error");
3164 if (!(png_ptr->zstream.avail_out))
3166 png_warning(png_ptr, "Extra compressed data.");
3167 png_ptr->mode |= PNG_AFTER_IDAT;
3168 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3173 png_ptr->zstream.avail_out = 0;
3176 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3177 png_warning(png_ptr, "Extra compression data.");
3179 inflateReset(&png_ptr->zstream);
3181 png_ptr->mode |= PNG_AFTER_IDAT;
3183 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3186 png_read_start_row(png_structp png_ptr)
3188 #ifdef PNG_READ_INTERLACING_SUPPORTED
3189 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3191 /* Start of interlace block */
3192 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3194 /* Offset to next interlace block */
3195 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3197 /* Start of interlace block in the y direction */
3198 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3200 /* Offset to next interlace block in the y direction */
3201 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3204 int max_pixel_depth;
3205 png_size_t row_bytes;
3207 png_debug(1, "in png_read_start_row");
3208 png_ptr->zstream.avail_in = 0;
3209 png_init_read_transformations(png_ptr);
3210 #ifdef PNG_READ_INTERLACING_SUPPORTED
3211 if (png_ptr->interlaced)
3213 if (!(png_ptr->transformations & PNG_INTERLACE))
3214 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3215 png_pass_ystart[0]) / png_pass_yinc[0];
3217 png_ptr->num_rows = png_ptr->height;
3219 png_ptr->iwidth = (png_ptr->width +
3220 png_pass_inc[png_ptr->pass] - 1 -
3221 png_pass_start[png_ptr->pass]) /
3222 png_pass_inc[png_ptr->pass];
3225 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3227 png_ptr->num_rows = png_ptr->height;
3228 png_ptr->iwidth = png_ptr->width;
3230 max_pixel_depth = png_ptr->pixel_depth;
3232 #ifdef PNG_READ_PACK_SUPPORTED
3233 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3234 max_pixel_depth = 8;
3237 #ifdef PNG_READ_EXPAND_SUPPORTED
3238 if (png_ptr->transformations & PNG_EXPAND)
3240 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3242 if (png_ptr->num_trans)
3243 max_pixel_depth = 32;
3245 max_pixel_depth = 24;
3247 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3249 if (max_pixel_depth < 8)
3250 max_pixel_depth = 8;
3251 if (png_ptr->num_trans)
3252 max_pixel_depth *= 2;
3254 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3256 if (png_ptr->num_trans)
3258 max_pixel_depth *= 4;
3259 max_pixel_depth /= 3;
3265 #ifdef PNG_READ_FILLER_SUPPORTED
3266 if (png_ptr->transformations & (PNG_FILLER))
3268 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3269 max_pixel_depth = 32;
3270 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3272 if (max_pixel_depth <= 8)
3273 max_pixel_depth = 16;
3275 max_pixel_depth = 32;
3277 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3279 if (max_pixel_depth <= 32)
3280 max_pixel_depth = 32;
3282 max_pixel_depth = 64;
3287 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3288 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3291 #ifdef PNG_READ_EXPAND_SUPPORTED
3292 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3294 #ifdef PNG_READ_FILLER_SUPPORTED
3295 (png_ptr->transformations & (PNG_FILLER)) ||
3297 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3299 if (max_pixel_depth <= 16)
3300 max_pixel_depth = 32;
3302 max_pixel_depth = 64;
3306 if (max_pixel_depth <= 8)
3308 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3309 max_pixel_depth = 32;
3311 max_pixel_depth = 24;
3313 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3314 max_pixel_depth = 64;
3316 max_pixel_depth = 48;
3321 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3322 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3323 if (png_ptr->transformations & PNG_USER_TRANSFORM)
3325 int user_pixel_depth = png_ptr->user_transform_depth*
3326 png_ptr->user_transform_channels;
3327 if (user_pixel_depth > max_pixel_depth)
3328 max_pixel_depth=user_pixel_depth;
3332 /* Align the width on the next larger 8 pixels. Mainly used
3335 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3336 /* Calculate the maximum bytes needed, adding a byte and a pixel
3339 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
3340 1 + ((max_pixel_depth + 7) >> 3);
3341 #ifdef PNG_MAX_MALLOC_64K
3342 if (row_bytes > (png_uint_32)65536L)
3343 png_error(png_ptr, "This image requires a row greater than 64KB");
3346 if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
3348 png_free(png_ptr, png_ptr->big_row_buf);
3349 if (png_ptr->interlaced)
3350 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
3353 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
3355 png_ptr->old_big_row_buf_size = row_bytes + 64;
3357 /* Use 32 bytes of padding before and after row_buf. */
3358 png_ptr->row_buf = png_ptr->big_row_buf + 32;
3359 png_ptr->old_big_row_buf_size = row_bytes + 64;
3362 #ifdef PNG_MAX_MALLOC_64K
3363 if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
3364 png_error(png_ptr, "This image requires a row greater than 64KB");
3366 if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3367 png_error(png_ptr, "Row has too many bytes to allocate in memory.");
3369 if (row_bytes + 1 > png_ptr->old_prev_row_size)
3371 png_free(png_ptr, png_ptr->prev_row);
3372 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3374 png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
3375 png_ptr->old_prev_row_size = row_bytes + 1;
3378 png_ptr->rowbytes = row_bytes;
3380 png_debug1(3, "width = %lu,", png_ptr->width);
3381 png_debug1(3, "height = %lu,", png_ptr->height);
3382 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
3383 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
3384 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
3385 png_debug1(3, "irowbytes = %lu",
3386 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
3388 png_ptr->flags |= PNG_FLAG_ROW_INIT;
3390 #endif /* PNG_READ_SUPPORTED */