2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.27 [April 29, 2008]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2008 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This file contains routines that are only called from within
11 * libpng itself during the course of reading an image.
17 #if defined(PNG_READ_SUPPORTED)
19 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
20 # define WIN32_WCE_OLD
23 #ifdef PNG_FLOATING_POINT_SUPPORTED
24 # if defined(WIN32_WCE_OLD)
25 /* strtod() function is not supported on WindowsCE */
26 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
32 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
33 str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t));
36 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
37 result = wcstod(str, &end);
38 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
39 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
40 png_free(png_ptr, str);
45 # define png_strtod(p,a,b) strtod(a,b)
50 png_get_uint_31(png_structp png_ptr, png_bytep buf)
52 png_uint_32 i = png_get_uint_32(buf);
53 if (i > PNG_UINT_31_MAX)
54 png_error(png_ptr, "PNG unsigned integer out of range.");
57 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
58 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
60 png_get_uint_32(png_bytep buf)
62 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
63 ((png_uint_32)(*(buf + 1)) << 16) +
64 ((png_uint_32)(*(buf + 2)) << 8) +
65 (png_uint_32)(*(buf + 3));
70 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
71 * data is stored in the PNG file in two's complement format, and it is
72 * assumed that the machine format for signed integers is the same. */
74 png_get_int_32(png_bytep buf)
76 png_int_32 i = ((png_int_32)(*buf) << 24) +
77 ((png_int_32)(*(buf + 1)) << 16) +
78 ((png_int_32)(*(buf + 2)) << 8) +
79 (png_int_32)(*(buf + 3));
84 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
86 png_get_uint_16(png_bytep buf)
88 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
89 (png_uint_16)(*(buf + 1)));
93 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
95 /* Read data, and (optionally) run it through the CRC. */
97 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
99 if(png_ptr == NULL) return;
100 png_read_data(png_ptr, buf, length);
101 png_calculate_crc(png_ptr, buf, length);
104 /* Optionally skip data and then check the CRC. Depending on whether we
105 are reading a ancillary or critical chunk, and how the program has set
106 things up, we may calculate the CRC on the data and print a message.
107 Returns '1' if there was a CRC error, '0' otherwise. */
109 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
112 png_size_t istop = png_ptr->zbuf_size;
114 for (i = (png_size_t)skip; i > istop; i -= istop)
116 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
120 png_crc_read(png_ptr, png_ptr->zbuf, i);
123 if (png_crc_error(png_ptr))
125 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
126 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
127 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
128 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
130 png_chunk_warning(png_ptr, "CRC error");
134 png_chunk_error(png_ptr, "CRC error");
142 /* Compare the CRC stored in the PNG file with that calculated by libpng from
143 the data it has read thus far. */
145 png_crc_error(png_structp png_ptr)
147 png_byte crc_bytes[4];
151 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
153 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
154 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
159 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
163 png_read_data(png_ptr, crc_bytes, 4);
167 crc = png_get_uint_32(crc_bytes);
168 return ((int)(crc != png_ptr->crc));
174 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
175 defined(PNG_READ_iCCP_SUPPORTED)
177 * Decompress trailing data in a chunk. The assumption is that chunkdata
178 * points at an allocated area holding the contents of a chunk with a
179 * trailing compressed part. What we get back is an allocated area
180 * holding the original prefix part and an uncompressed version of the
181 * trailing part (the malloc area passed in is freed).
183 png_charp /* PRIVATE */
184 png_decompress_chunk(png_structp png_ptr, int comp_type,
185 png_charp chunkdata, png_size_t chunklength,
186 png_size_t prefix_size, png_size_t *newlength)
188 static PNG_CONST char msg[] = "Error decoding compressed text";
190 png_size_t text_size;
192 if (comp_type == PNG_COMPRESSION_TYPE_BASE)
195 png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
196 png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
197 png_ptr->zstream.next_out = png_ptr->zbuf;
198 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
203 while (png_ptr->zstream.avail_in)
205 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
206 if (ret != Z_OK && ret != Z_STREAM_END)
208 if (png_ptr->zstream.msg != NULL)
209 png_warning(png_ptr, png_ptr->zstream.msg);
211 png_warning(png_ptr, msg);
212 inflateReset(&png_ptr->zstream);
213 png_ptr->zstream.avail_in = 0;
217 text_size = prefix_size + png_sizeof(msg) + 1;
218 text = (png_charp)png_malloc_warn(png_ptr, text_size);
221 png_free(png_ptr,chunkdata);
222 png_error(png_ptr,"Not enough memory to decompress chunk");
224 png_memcpy(text, chunkdata, prefix_size);
227 text[text_size - 1] = 0x00;
229 /* Copy what we can of the error message into the text chunk */
230 text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
231 text_size = png_sizeof(msg) > text_size ? text_size :
233 png_memcpy(text + prefix_size, msg, text_size);
236 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
240 text_size = prefix_size +
241 png_ptr->zbuf_size - png_ptr->zstream.avail_out;
242 text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
245 png_free(png_ptr,chunkdata);
246 png_error(png_ptr,"Not enough memory to decompress chunk.");
248 png_memcpy(text + prefix_size, png_ptr->zbuf,
249 text_size - prefix_size);
250 png_memcpy(text, chunkdata, prefix_size);
251 *(text + text_size) = 0x00;
258 text = (png_charp)png_malloc_warn(png_ptr,
259 (png_uint_32)(text_size +
260 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
263 png_free(png_ptr, tmp);
264 png_free(png_ptr, chunkdata);
265 png_error(png_ptr,"Not enough memory to decompress chunk..");
267 png_memcpy(text, tmp, text_size);
268 png_free(png_ptr, tmp);
269 png_memcpy(text + text_size, png_ptr->zbuf,
270 (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
271 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
272 *(text + text_size) = 0x00;
274 if (ret == Z_STREAM_END)
278 png_ptr->zstream.next_out = png_ptr->zbuf;
279 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
283 if (ret != Z_STREAM_END)
285 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
288 if (ret == Z_BUF_ERROR)
289 png_snprintf(umsg, 52,
290 "Buffer error in compressed datastream in %s chunk",
291 png_ptr->chunk_name);
292 else if (ret == Z_DATA_ERROR)
293 png_snprintf(umsg, 52,
294 "Data error in compressed datastream in %s chunk",
295 png_ptr->chunk_name);
297 png_snprintf(umsg, 52,
298 "Incomplete compressed datastream in %s chunk",
299 png_ptr->chunk_name);
300 png_warning(png_ptr, umsg);
303 "Incomplete compressed datastream in chunk other than IDAT");
305 text_size=prefix_size;
308 text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
311 png_free(png_ptr, chunkdata);
312 png_error(png_ptr,"Not enough memory for text.");
314 png_memcpy(text, chunkdata, prefix_size);
316 *(text + text_size) = 0x00;
319 inflateReset(&png_ptr->zstream);
320 png_ptr->zstream.avail_in = 0;
322 png_free(png_ptr, chunkdata);
324 *newlength=text_size;
326 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
328 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
331 png_snprintf(umsg, 50,
332 "Unknown zTXt compression type %d", comp_type);
333 png_warning(png_ptr, umsg);
335 png_warning(png_ptr, "Unknown zTXt compression type");
338 *(chunkdata + prefix_size) = 0x00;
339 *newlength=prefix_size;
346 /* read and check the IDHR chunk */
348 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
351 png_uint_32 width, height;
352 int bit_depth, color_type, compression_type, filter_type;
355 png_debug(1, "in png_handle_IHDR\n");
357 if (png_ptr->mode & PNG_HAVE_IHDR)
358 png_error(png_ptr, "Out of place IHDR");
360 /* check the length */
362 png_error(png_ptr, "Invalid IHDR chunk");
364 png_ptr->mode |= PNG_HAVE_IHDR;
366 png_crc_read(png_ptr, buf, 13);
367 png_crc_finish(png_ptr, 0);
369 width = png_get_uint_31(png_ptr, buf);
370 height = png_get_uint_31(png_ptr, buf + 4);
373 compression_type = buf[10];
374 filter_type = buf[11];
375 interlace_type = buf[12];
377 /* set internal variables */
378 png_ptr->width = width;
379 png_ptr->height = height;
380 png_ptr->bit_depth = (png_byte)bit_depth;
381 png_ptr->interlaced = (png_byte)interlace_type;
382 png_ptr->color_type = (png_byte)color_type;
383 #if defined(PNG_MNG_FEATURES_SUPPORTED)
384 png_ptr->filter_type = (png_byte)filter_type;
386 png_ptr->compression_type = (png_byte)compression_type;
388 /* find number of channels */
389 switch (png_ptr->color_type)
391 case PNG_COLOR_TYPE_GRAY:
392 case PNG_COLOR_TYPE_PALETTE:
393 png_ptr->channels = 1;
395 case PNG_COLOR_TYPE_RGB:
396 png_ptr->channels = 3;
398 case PNG_COLOR_TYPE_GRAY_ALPHA:
399 png_ptr->channels = 2;
401 case PNG_COLOR_TYPE_RGB_ALPHA:
402 png_ptr->channels = 4;
406 /* set up other useful info */
407 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
409 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
410 png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
411 png_debug1(3,"channels = %d\n", png_ptr->channels);
412 png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
413 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
414 color_type, interlace_type, compression_type, filter_type);
417 /* read and check the palette */
419 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
421 png_color palette[PNG_MAX_PALETTE_LENGTH];
423 #ifndef PNG_NO_POINTER_INDEXING
427 png_debug(1, "in png_handle_PLTE\n");
429 if (!(png_ptr->mode & PNG_HAVE_IHDR))
430 png_error(png_ptr, "Missing IHDR before PLTE");
431 else if (png_ptr->mode & PNG_HAVE_IDAT)
433 png_warning(png_ptr, "Invalid PLTE after IDAT");
434 png_crc_finish(png_ptr, length);
437 else if (png_ptr->mode & PNG_HAVE_PLTE)
438 png_error(png_ptr, "Duplicate PLTE chunk");
440 png_ptr->mode |= PNG_HAVE_PLTE;
442 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
445 "Ignoring PLTE chunk in grayscale PNG");
446 png_crc_finish(png_ptr, length);
449 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
450 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
452 png_crc_finish(png_ptr, length);
457 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
459 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
461 png_warning(png_ptr, "Invalid palette chunk");
462 png_crc_finish(png_ptr, length);
467 png_error(png_ptr, "Invalid palette chunk");
471 num = (int)length / 3;
473 #ifndef PNG_NO_POINTER_INDEXING
474 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
478 png_crc_read(png_ptr, buf, 3);
479 pal_ptr->red = buf[0];
480 pal_ptr->green = buf[1];
481 pal_ptr->blue = buf[2];
484 for (i = 0; i < num; i++)
488 png_crc_read(png_ptr, buf, 3);
489 /* don't depend upon png_color being any order */
490 palette[i].red = buf[0];
491 palette[i].green = buf[1];
492 palette[i].blue = buf[2];
496 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
497 whatever the normal CRC configuration tells us. However, if we
498 have an RGB image, the PLTE can be considered ancillary, so
499 we will act as though it is. */
500 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
501 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
504 png_crc_finish(png_ptr, 0);
506 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
507 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
509 /* If we don't want to use the data from an ancillary chunk,
510 we have two options: an error abort, or a warning and we
511 ignore the data in this chunk (which should be OK, since
512 it's considered ancillary for a RGB or RGBA image). */
513 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
515 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
517 png_chunk_error(png_ptr, "CRC error");
521 png_chunk_warning(png_ptr, "CRC error");
525 /* Otherwise, we (optionally) emit a warning and use the chunk. */
526 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
528 png_chunk_warning(png_ptr, "CRC error");
533 png_set_PLTE(png_ptr, info_ptr, palette, num);
535 #if defined(PNG_READ_tRNS_SUPPORTED)
536 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
538 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
540 if (png_ptr->num_trans > (png_uint_16)num)
542 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
543 png_ptr->num_trans = (png_uint_16)num;
545 if (info_ptr->num_trans > (png_uint_16)num)
547 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
548 info_ptr->num_trans = (png_uint_16)num;
557 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
559 png_debug(1, "in png_handle_IEND\n");
561 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
563 png_error(png_ptr, "No image in file");
566 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
570 png_warning(png_ptr, "Incorrect IEND chunk length");
572 png_crc_finish(png_ptr, length);
574 info_ptr =info_ptr; /* quiet compiler warnings about unused info_ptr */
577 #if defined(PNG_READ_gAMA_SUPPORTED)
579 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
581 png_fixed_point igamma;
582 #ifdef PNG_FLOATING_POINT_SUPPORTED
587 png_debug(1, "in png_handle_gAMA\n");
589 if (!(png_ptr->mode & PNG_HAVE_IHDR))
590 png_error(png_ptr, "Missing IHDR before gAMA");
591 else if (png_ptr->mode & PNG_HAVE_IDAT)
593 png_warning(png_ptr, "Invalid gAMA after IDAT");
594 png_crc_finish(png_ptr, length);
597 else if (png_ptr->mode & PNG_HAVE_PLTE)
598 /* Should be an error, but we can cope with it */
599 png_warning(png_ptr, "Out of place gAMA chunk");
601 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
602 #if defined(PNG_READ_sRGB_SUPPORTED)
603 && !(info_ptr->valid & PNG_INFO_sRGB)
607 png_warning(png_ptr, "Duplicate gAMA chunk");
608 png_crc_finish(png_ptr, length);
614 png_warning(png_ptr, "Incorrect gAMA chunk length");
615 png_crc_finish(png_ptr, length);
619 png_crc_read(png_ptr, buf, 4);
620 if (png_crc_finish(png_ptr, 0))
623 igamma = (png_fixed_point)png_get_uint_32(buf);
624 /* check for zero gamma */
628 "Ignoring gAMA chunk with gamma=0");
632 #if defined(PNG_READ_sRGB_SUPPORTED)
633 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
634 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
637 "Ignoring incorrect gAMA value when sRGB is also present");
638 #ifndef PNG_NO_CONSOLE_IO
639 fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
643 #endif /* PNG_READ_sRGB_SUPPORTED */
645 #ifdef PNG_FLOATING_POINT_SUPPORTED
646 file_gamma = (float)igamma / (float)100000.0;
647 # ifdef PNG_READ_GAMMA_SUPPORTED
648 png_ptr->gamma = file_gamma;
650 png_set_gAMA(png_ptr, info_ptr, file_gamma);
652 #ifdef PNG_FIXED_POINT_SUPPORTED
653 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
658 #if defined(PNG_READ_sBIT_SUPPORTED)
660 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
665 png_debug(1, "in png_handle_sBIT\n");
667 buf[0] = buf[1] = buf[2] = buf[3] = 0;
669 if (!(png_ptr->mode & PNG_HAVE_IHDR))
670 png_error(png_ptr, "Missing IHDR before sBIT");
671 else if (png_ptr->mode & PNG_HAVE_IDAT)
673 png_warning(png_ptr, "Invalid sBIT after IDAT");
674 png_crc_finish(png_ptr, length);
677 else if (png_ptr->mode & PNG_HAVE_PLTE)
679 /* Should be an error, but we can cope with it */
680 png_warning(png_ptr, "Out of place sBIT chunk");
682 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
684 png_warning(png_ptr, "Duplicate sBIT chunk");
685 png_crc_finish(png_ptr, length);
689 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
692 truelen = (png_size_t)png_ptr->channels;
694 if (length != truelen || length > 4)
696 png_warning(png_ptr, "Incorrect sBIT chunk length");
697 png_crc_finish(png_ptr, length);
701 png_crc_read(png_ptr, buf, truelen);
702 if (png_crc_finish(png_ptr, 0))
705 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
707 png_ptr->sig_bit.red = buf[0];
708 png_ptr->sig_bit.green = buf[1];
709 png_ptr->sig_bit.blue = buf[2];
710 png_ptr->sig_bit.alpha = buf[3];
714 png_ptr->sig_bit.gray = buf[0];
715 png_ptr->sig_bit.red = buf[0];
716 png_ptr->sig_bit.green = buf[0];
717 png_ptr->sig_bit.blue = buf[0];
718 png_ptr->sig_bit.alpha = buf[1];
720 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
724 #if defined(PNG_READ_cHRM_SUPPORTED)
726 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
729 #ifdef PNG_FLOATING_POINT_SUPPORTED
730 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
732 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
733 int_y_green, int_x_blue, int_y_blue;
735 png_uint_32 uint_x, uint_y;
737 png_debug(1, "in png_handle_cHRM\n");
739 if (!(png_ptr->mode & PNG_HAVE_IHDR))
740 png_error(png_ptr, "Missing IHDR before cHRM");
741 else if (png_ptr->mode & PNG_HAVE_IDAT)
743 png_warning(png_ptr, "Invalid cHRM after IDAT");
744 png_crc_finish(png_ptr, length);
747 else if (png_ptr->mode & PNG_HAVE_PLTE)
748 /* Should be an error, but we can cope with it */
749 png_warning(png_ptr, "Missing PLTE before cHRM");
751 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
752 #if defined(PNG_READ_sRGB_SUPPORTED)
753 && !(info_ptr->valid & PNG_INFO_sRGB)
757 png_warning(png_ptr, "Duplicate cHRM chunk");
758 png_crc_finish(png_ptr, length);
764 png_warning(png_ptr, "Incorrect cHRM chunk length");
765 png_crc_finish(png_ptr, length);
769 png_crc_read(png_ptr, buf, 4);
770 uint_x = png_get_uint_32(buf);
772 png_crc_read(png_ptr, buf, 4);
773 uint_y = png_get_uint_32(buf);
775 if (uint_x > 80000L || uint_y > 80000L ||
776 uint_x + uint_y > 100000L)
778 png_warning(png_ptr, "Invalid cHRM white point");
779 png_crc_finish(png_ptr, 24);
782 int_x_white = (png_fixed_point)uint_x;
783 int_y_white = (png_fixed_point)uint_y;
785 png_crc_read(png_ptr, buf, 4);
786 uint_x = png_get_uint_32(buf);
788 png_crc_read(png_ptr, buf, 4);
789 uint_y = png_get_uint_32(buf);
791 if (uint_x + uint_y > 100000L)
793 png_warning(png_ptr, "Invalid cHRM red point");
794 png_crc_finish(png_ptr, 16);
797 int_x_red = (png_fixed_point)uint_x;
798 int_y_red = (png_fixed_point)uint_y;
800 png_crc_read(png_ptr, buf, 4);
801 uint_x = png_get_uint_32(buf);
803 png_crc_read(png_ptr, buf, 4);
804 uint_y = png_get_uint_32(buf);
806 if (uint_x + uint_y > 100000L)
808 png_warning(png_ptr, "Invalid cHRM green point");
809 png_crc_finish(png_ptr, 8);
812 int_x_green = (png_fixed_point)uint_x;
813 int_y_green = (png_fixed_point)uint_y;
815 png_crc_read(png_ptr, buf, 4);
816 uint_x = png_get_uint_32(buf);
818 png_crc_read(png_ptr, buf, 4);
819 uint_y = png_get_uint_32(buf);
821 if (uint_x + uint_y > 100000L)
823 png_warning(png_ptr, "Invalid cHRM blue point");
824 png_crc_finish(png_ptr, 0);
827 int_x_blue = (png_fixed_point)uint_x;
828 int_y_blue = (png_fixed_point)uint_y;
830 #ifdef PNG_FLOATING_POINT_SUPPORTED
831 white_x = (float)int_x_white / (float)100000.0;
832 white_y = (float)int_y_white / (float)100000.0;
833 red_x = (float)int_x_red / (float)100000.0;
834 red_y = (float)int_y_red / (float)100000.0;
835 green_x = (float)int_x_green / (float)100000.0;
836 green_y = (float)int_y_green / (float)100000.0;
837 blue_x = (float)int_x_blue / (float)100000.0;
838 blue_y = (float)int_y_blue / (float)100000.0;
841 #if defined(PNG_READ_sRGB_SUPPORTED)
842 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
844 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
845 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
846 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
847 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
848 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
849 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
850 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
851 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
854 "Ignoring incorrect cHRM value when sRGB is also present");
855 #ifndef PNG_NO_CONSOLE_IO
856 #ifdef PNG_FLOATING_POINT_SUPPORTED
857 fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
858 white_x, white_y, red_x, red_y);
859 fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
860 green_x, green_y, blue_x, blue_y);
862 fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
863 int_x_white, int_y_white, int_x_red, int_y_red);
864 fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
865 int_x_green, int_y_green, int_x_blue, int_y_blue);
867 #endif /* PNG_NO_CONSOLE_IO */
869 png_crc_finish(png_ptr, 0);
872 #endif /* PNG_READ_sRGB_SUPPORTED */
874 #ifdef PNG_FLOATING_POINT_SUPPORTED
875 png_set_cHRM(png_ptr, info_ptr,
876 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
878 #ifdef PNG_FIXED_POINT_SUPPORTED
879 png_set_cHRM_fixed(png_ptr, info_ptr,
880 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
881 int_y_green, int_x_blue, int_y_blue);
883 if (png_crc_finish(png_ptr, 0))
888 #if defined(PNG_READ_sRGB_SUPPORTED)
890 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
895 png_debug(1, "in png_handle_sRGB\n");
897 if (!(png_ptr->mode & PNG_HAVE_IHDR))
898 png_error(png_ptr, "Missing IHDR before sRGB");
899 else if (png_ptr->mode & PNG_HAVE_IDAT)
901 png_warning(png_ptr, "Invalid sRGB after IDAT");
902 png_crc_finish(png_ptr, length);
905 else if (png_ptr->mode & PNG_HAVE_PLTE)
906 /* Should be an error, but we can cope with it */
907 png_warning(png_ptr, "Out of place sRGB chunk");
909 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
911 png_warning(png_ptr, "Duplicate sRGB chunk");
912 png_crc_finish(png_ptr, length);
918 png_warning(png_ptr, "Incorrect sRGB chunk length");
919 png_crc_finish(png_ptr, length);
923 png_crc_read(png_ptr, buf, 1);
924 if (png_crc_finish(png_ptr, 0))
928 /* check for bad intent */
929 if (intent >= PNG_sRGB_INTENT_LAST)
931 png_warning(png_ptr, "Unknown sRGB intent");
935 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
936 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
938 png_fixed_point igamma;
939 #ifdef PNG_FIXED_POINT_SUPPORTED
940 igamma=info_ptr->int_gamma;
942 # ifdef PNG_FLOATING_POINT_SUPPORTED
943 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
946 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
949 "Ignoring incorrect gAMA value when sRGB is also present");
950 #ifndef PNG_NO_CONSOLE_IO
951 # ifdef PNG_FIXED_POINT_SUPPORTED
952 fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
954 # ifdef PNG_FLOATING_POINT_SUPPORTED
955 fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
961 #endif /* PNG_READ_gAMA_SUPPORTED */
963 #ifdef PNG_READ_cHRM_SUPPORTED
964 #ifdef PNG_FIXED_POINT_SUPPORTED
965 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
966 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
967 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
968 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
969 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
970 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
971 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
972 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
973 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
976 "Ignoring incorrect cHRM value when sRGB is also present");
978 #endif /* PNG_FIXED_POINT_SUPPORTED */
979 #endif /* PNG_READ_cHRM_SUPPORTED */
981 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
983 #endif /* PNG_READ_sRGB_SUPPORTED */
985 #if defined(PNG_READ_iCCP_SUPPORTED)
987 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
988 /* Note: this does not properly handle chunks that are > 64K under DOS */
991 png_byte compression_type;
994 png_uint_32 skip = 0;
995 png_uint_32 profile_size, profile_length;
996 png_size_t slength, prefix_length, data_length;
998 png_debug(1, "in png_handle_iCCP\n");
1000 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1001 png_error(png_ptr, "Missing IHDR before iCCP");
1002 else if (png_ptr->mode & PNG_HAVE_IDAT)
1004 png_warning(png_ptr, "Invalid iCCP after IDAT");
1005 png_crc_finish(png_ptr, length);
1008 else if (png_ptr->mode & PNG_HAVE_PLTE)
1009 /* Should be an error, but we can cope with it */
1010 png_warning(png_ptr, "Out of place iCCP chunk");
1012 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1014 png_warning(png_ptr, "Duplicate iCCP chunk");
1015 png_crc_finish(png_ptr, length);
1019 #ifdef PNG_MAX_MALLOC_64K
1020 if (length > (png_uint_32)65535L)
1022 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1023 skip = length - (png_uint_32)65535L;
1024 length = (png_uint_32)65535L;
1028 chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1029 slength = (png_size_t)length;
1030 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1032 if (png_crc_finish(png_ptr, skip))
1034 png_free(png_ptr, chunkdata);
1038 chunkdata[slength] = 0x00;
1040 for (profile = chunkdata; *profile; profile++)
1041 /* empty loop to find end of name */ ;
1045 /* there should be at least one zero (the compression type byte)
1046 following the separator, and we should be on it */
1047 if ( profile >= chunkdata + slength - 1)
1049 png_free(png_ptr, chunkdata);
1050 png_warning(png_ptr, "Malformed iCCP chunk");
1054 /* compression_type should always be zero */
1055 compression_type = *profile++;
1056 if (compression_type)
1058 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1059 compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1063 prefix_length = profile - chunkdata;
1064 chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
1065 slength, prefix_length, &data_length);
1067 profile_length = data_length - prefix_length;
1069 if ( prefix_length > data_length || profile_length < 4)
1071 png_free(png_ptr, chunkdata);
1072 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1076 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1077 pC = (png_bytep)(chunkdata+prefix_length);
1078 profile_size = ((*(pC ))<<24) |
1083 if(profile_size < profile_length)
1084 profile_length = profile_size;
1086 if(profile_size > profile_length)
1088 png_free(png_ptr, chunkdata);
1089 png_warning(png_ptr, "Ignoring truncated iCCP profile.");
1093 png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
1094 chunkdata + prefix_length, profile_length);
1095 png_free(png_ptr, chunkdata);
1097 #endif /* PNG_READ_iCCP_SUPPORTED */
1099 #if defined(PNG_READ_sPLT_SUPPORTED)
1101 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1102 /* Note: this does not properly handle chunks that are > 64K under DOS */
1104 png_bytep chunkdata;
1105 png_bytep entry_start;
1106 png_sPLT_t new_palette;
1107 #ifdef PNG_NO_POINTER_INDEXING
1110 int data_length, entry_size, i;
1111 png_uint_32 skip = 0;
1114 png_debug(1, "in png_handle_sPLT\n");
1116 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1117 png_error(png_ptr, "Missing IHDR before sPLT");
1118 else if (png_ptr->mode & PNG_HAVE_IDAT)
1120 png_warning(png_ptr, "Invalid sPLT after IDAT");
1121 png_crc_finish(png_ptr, length);
1125 #ifdef PNG_MAX_MALLOC_64K
1126 if (length > (png_uint_32)65535L)
1128 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1129 skip = length - (png_uint_32)65535L;
1130 length = (png_uint_32)65535L;
1134 chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
1135 slength = (png_size_t)length;
1136 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1138 if (png_crc_finish(png_ptr, skip))
1140 png_free(png_ptr, chunkdata);
1144 chunkdata[slength] = 0x00;
1146 for (entry_start = chunkdata; *entry_start; entry_start++)
1147 /* empty loop to find end of name */ ;
1150 /* a sample depth should follow the separator, and we should be on it */
1151 if (entry_start > chunkdata + slength - 2)
1153 png_free(png_ptr, chunkdata);
1154 png_warning(png_ptr, "malformed sPLT chunk");
1158 new_palette.depth = *entry_start++;
1159 entry_size = (new_palette.depth == 8 ? 6 : 10);
1160 data_length = (slength - (entry_start - chunkdata));
1162 /* integrity-check the data length */
1163 if (data_length % entry_size)
1165 png_free(png_ptr, chunkdata);
1166 png_warning(png_ptr, "sPLT chunk has bad length");
1170 new_palette.nentries = (png_int_32) ( data_length / entry_size);
1171 if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
1172 png_sizeof(png_sPLT_entry)))
1174 png_warning(png_ptr, "sPLT chunk too long");
1177 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1178 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1179 if (new_palette.entries == NULL)
1181 png_warning(png_ptr, "sPLT chunk requires too much memory");
1185 #ifndef PNG_NO_POINTER_INDEXING
1186 for (i = 0; i < new_palette.nentries; i++)
1188 png_sPLT_entryp pp = new_palette.entries + i;
1190 if (new_palette.depth == 8)
1192 pp->red = *entry_start++;
1193 pp->green = *entry_start++;
1194 pp->blue = *entry_start++;
1195 pp->alpha = *entry_start++;
1199 pp->red = png_get_uint_16(entry_start); entry_start += 2;
1200 pp->green = png_get_uint_16(entry_start); entry_start += 2;
1201 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1202 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1204 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1207 pp = new_palette.entries;
1208 for (i = 0; i < new_palette.nentries; i++)
1211 if (new_palette.depth == 8)
1213 pp[i].red = *entry_start++;
1214 pp[i].green = *entry_start++;
1215 pp[i].blue = *entry_start++;
1216 pp[i].alpha = *entry_start++;
1220 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1221 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1222 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1223 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1225 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1229 /* discard all chunk data except the name and stash that */
1230 new_palette.name = (png_charp)chunkdata;
1232 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1234 png_free(png_ptr, chunkdata);
1235 png_free(png_ptr, new_palette.entries);
1237 #endif /* PNG_READ_sPLT_SUPPORTED */
1239 #if defined(PNG_READ_tRNS_SUPPORTED)
1241 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1243 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1245 png_debug(1, "in png_handle_tRNS\n");
1247 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1248 png_error(png_ptr, "Missing IHDR before tRNS");
1249 else if (png_ptr->mode & PNG_HAVE_IDAT)
1251 png_warning(png_ptr, "Invalid tRNS after IDAT");
1252 png_crc_finish(png_ptr, length);
1255 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1257 png_warning(png_ptr, "Duplicate tRNS chunk");
1258 png_crc_finish(png_ptr, length);
1262 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1268 png_warning(png_ptr, "Incorrect tRNS chunk length");
1269 png_crc_finish(png_ptr, length);
1273 png_crc_read(png_ptr, buf, 2);
1274 png_ptr->num_trans = 1;
1275 png_ptr->trans_values.gray = png_get_uint_16(buf);
1277 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1283 png_warning(png_ptr, "Incorrect tRNS chunk length");
1284 png_crc_finish(png_ptr, length);
1287 png_crc_read(png_ptr, buf, (png_size_t)length);
1288 png_ptr->num_trans = 1;
1289 png_ptr->trans_values.red = png_get_uint_16(buf);
1290 png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1291 png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1293 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1295 if (!(png_ptr->mode & PNG_HAVE_PLTE))
1297 /* Should be an error, but we can cope with it. */
1298 png_warning(png_ptr, "Missing PLTE before tRNS");
1300 if (length > (png_uint_32)png_ptr->num_palette ||
1301 length > PNG_MAX_PALETTE_LENGTH)
1303 png_warning(png_ptr, "Incorrect tRNS chunk length");
1304 png_crc_finish(png_ptr, length);
1309 png_warning(png_ptr, "Zero length tRNS chunk");
1310 png_crc_finish(png_ptr, length);
1313 png_crc_read(png_ptr, readbuf, (png_size_t)length);
1314 png_ptr->num_trans = (png_uint_16)length;
1318 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1319 png_crc_finish(png_ptr, length);
1323 if (png_crc_finish(png_ptr, 0))
1325 png_ptr->num_trans = 0;
1329 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1330 &(png_ptr->trans_values));
1334 #if defined(PNG_READ_bKGD_SUPPORTED)
1336 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1341 png_debug(1, "in png_handle_bKGD\n");
1343 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1344 png_error(png_ptr, "Missing IHDR before bKGD");
1345 else if (png_ptr->mode & PNG_HAVE_IDAT)
1347 png_warning(png_ptr, "Invalid bKGD after IDAT");
1348 png_crc_finish(png_ptr, length);
1351 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1352 !(png_ptr->mode & PNG_HAVE_PLTE))
1354 png_warning(png_ptr, "Missing PLTE before bKGD");
1355 png_crc_finish(png_ptr, length);
1358 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1360 png_warning(png_ptr, "Duplicate bKGD chunk");
1361 png_crc_finish(png_ptr, length);
1365 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1367 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1372 if (length != truelen)
1374 png_warning(png_ptr, "Incorrect bKGD chunk length");
1375 png_crc_finish(png_ptr, length);
1379 png_crc_read(png_ptr, buf, truelen);
1380 if (png_crc_finish(png_ptr, 0))
1383 /* We convert the index value into RGB components so that we can allow
1384 * arbitrary RGB values for background when we have transparency, and
1385 * so it is easy to determine the RGB values of the background color
1386 * from the info_ptr struct. */
1387 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1389 png_ptr->background.index = buf[0];
1390 if (info_ptr && info_ptr->num_palette)
1392 if(buf[0] > info_ptr->num_palette)
1394 png_warning(png_ptr, "Incorrect bKGD chunk index value");
1397 png_ptr->background.red =
1398 (png_uint_16)png_ptr->palette[buf[0]].red;
1399 png_ptr->background.green =
1400 (png_uint_16)png_ptr->palette[buf[0]].green;
1401 png_ptr->background.blue =
1402 (png_uint_16)png_ptr->palette[buf[0]].blue;
1405 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1407 png_ptr->background.red =
1408 png_ptr->background.green =
1409 png_ptr->background.blue =
1410 png_ptr->background.gray = png_get_uint_16(buf);
1414 png_ptr->background.red = png_get_uint_16(buf);
1415 png_ptr->background.green = png_get_uint_16(buf + 2);
1416 png_ptr->background.blue = png_get_uint_16(buf + 4);
1419 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1423 #if defined(PNG_READ_hIST_SUPPORTED)
1425 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1427 unsigned int num, i;
1428 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1430 png_debug(1, "in png_handle_hIST\n");
1432 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1433 png_error(png_ptr, "Missing IHDR before hIST");
1434 else if (png_ptr->mode & PNG_HAVE_IDAT)
1436 png_warning(png_ptr, "Invalid hIST after IDAT");
1437 png_crc_finish(png_ptr, length);
1440 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1442 png_warning(png_ptr, "Missing PLTE before hIST");
1443 png_crc_finish(png_ptr, length);
1446 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1448 png_warning(png_ptr, "Duplicate hIST chunk");
1449 png_crc_finish(png_ptr, length);
1454 if (num != (unsigned int) png_ptr->num_palette || num >
1455 (unsigned int) PNG_MAX_PALETTE_LENGTH)
1457 png_warning(png_ptr, "Incorrect hIST chunk length");
1458 png_crc_finish(png_ptr, length);
1462 for (i = 0; i < num; i++)
1466 png_crc_read(png_ptr, buf, 2);
1467 readbuf[i] = png_get_uint_16(buf);
1470 if (png_crc_finish(png_ptr, 0))
1473 png_set_hIST(png_ptr, info_ptr, readbuf);
1477 #if defined(PNG_READ_pHYs_SUPPORTED)
1479 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1482 png_uint_32 res_x, res_y;
1485 png_debug(1, "in png_handle_pHYs\n");
1487 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1488 png_error(png_ptr, "Missing IHDR before pHYs");
1489 else if (png_ptr->mode & PNG_HAVE_IDAT)
1491 png_warning(png_ptr, "Invalid pHYs after IDAT");
1492 png_crc_finish(png_ptr, length);
1495 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1497 png_warning(png_ptr, "Duplicate pHYs chunk");
1498 png_crc_finish(png_ptr, length);
1504 png_warning(png_ptr, "Incorrect pHYs chunk length");
1505 png_crc_finish(png_ptr, length);
1509 png_crc_read(png_ptr, buf, 9);
1510 if (png_crc_finish(png_ptr, 0))
1513 res_x = png_get_uint_32(buf);
1514 res_y = png_get_uint_32(buf + 4);
1516 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1520 #if defined(PNG_READ_oFFs_SUPPORTED)
1522 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1525 png_int_32 offset_x, offset_y;
1528 png_debug(1, "in png_handle_oFFs\n");
1530 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1531 png_error(png_ptr, "Missing IHDR before oFFs");
1532 else if (png_ptr->mode & PNG_HAVE_IDAT)
1534 png_warning(png_ptr, "Invalid oFFs after IDAT");
1535 png_crc_finish(png_ptr, length);
1538 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1540 png_warning(png_ptr, "Duplicate oFFs chunk");
1541 png_crc_finish(png_ptr, length);
1547 png_warning(png_ptr, "Incorrect oFFs chunk length");
1548 png_crc_finish(png_ptr, length);
1552 png_crc_read(png_ptr, buf, 9);
1553 if (png_crc_finish(png_ptr, 0))
1556 offset_x = png_get_int_32(buf);
1557 offset_y = png_get_int_32(buf + 4);
1559 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1563 #if defined(PNG_READ_pCAL_SUPPORTED)
1564 /* read the pCAL chunk (described in the PNG Extensions document) */
1566 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1570 png_byte type, nparams;
1571 png_charp buf, units, endptr;
1576 png_debug(1, "in png_handle_pCAL\n");
1578 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1579 png_error(png_ptr, "Missing IHDR before pCAL");
1580 else if (png_ptr->mode & PNG_HAVE_IDAT)
1582 png_warning(png_ptr, "Invalid pCAL after IDAT");
1583 png_crc_finish(png_ptr, length);
1586 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1588 png_warning(png_ptr, "Duplicate pCAL chunk");
1589 png_crc_finish(png_ptr, length);
1593 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1595 purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
1596 if (purpose == NULL)
1598 png_warning(png_ptr, "No memory for pCAL purpose.");
1601 slength = (png_size_t)length;
1602 png_crc_read(png_ptr, (png_bytep)purpose, slength);
1604 if (png_crc_finish(png_ptr, 0))
1606 png_free(png_ptr, purpose);
1610 purpose[slength] = 0x00; /* null terminate the last string */
1612 png_debug(3, "Finding end of pCAL purpose string\n");
1613 for (buf = purpose; *buf; buf++)
1616 endptr = purpose + slength;
1618 /* We need to have at least 12 bytes after the purpose string
1619 in order to get the parameter information. */
1620 if (endptr <= buf + 12)
1622 png_warning(png_ptr, "Invalid pCAL data");
1623 png_free(png_ptr, purpose);
1627 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1628 X0 = png_get_int_32((png_bytep)buf+1);
1629 X1 = png_get_int_32((png_bytep)buf+5);
1634 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1635 /* Check that we have the right number of parameters for known
1637 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1638 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1639 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1640 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1642 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1643 png_free(png_ptr, purpose);
1646 else if (type >= PNG_EQUATION_LAST)
1648 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1651 for (buf = units; *buf; buf++)
1652 /* Empty loop to move past the units string. */ ;
1654 png_debug(3, "Allocating pCAL parameters array\n");
1655 params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
1656 *png_sizeof(png_charp))) ;
1659 png_free(png_ptr, purpose);
1660 png_warning(png_ptr, "No memory for pCAL params.");
1664 /* Get pointers to the start of each parameter string. */
1665 for (i = 0; i < (int)nparams; i++)
1667 buf++; /* Skip the null string terminator from previous parameter. */
1669 png_debug1(3, "Reading pCAL parameter %d\n", i);
1670 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1671 /* Empty loop to move past each parameter string */ ;
1673 /* Make sure we haven't run out of data yet */
1676 png_warning(png_ptr, "Invalid pCAL data");
1677 png_free(png_ptr, purpose);
1678 png_free(png_ptr, params);
1683 png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1686 png_free(png_ptr, purpose);
1687 png_free(png_ptr, params);
1691 #if defined(PNG_READ_sCAL_SUPPORTED)
1692 /* read the sCAL chunk */
1694 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1696 png_charp buffer, ep;
1697 #ifdef PNG_FLOATING_POINT_SUPPORTED
1698 double width, height;
1701 #ifdef PNG_FIXED_POINT_SUPPORTED
1702 png_charp swidth, sheight;
1707 png_debug(1, "in png_handle_sCAL\n");
1709 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1710 png_error(png_ptr, "Missing IHDR before sCAL");
1711 else if (png_ptr->mode & PNG_HAVE_IDAT)
1713 png_warning(png_ptr, "Invalid sCAL after IDAT");
1714 png_crc_finish(png_ptr, length);
1717 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1719 png_warning(png_ptr, "Duplicate sCAL chunk");
1720 png_crc_finish(png_ptr, length);
1724 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1726 buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
1729 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1732 slength = (png_size_t)length;
1733 png_crc_read(png_ptr, (png_bytep)buffer, slength);
1735 if (png_crc_finish(png_ptr, 0))
1737 png_free(png_ptr, buffer);
1741 buffer[slength] = 0x00; /* null terminate the last string */
1743 ep = buffer + 1; /* skip unit byte */
1745 #ifdef PNG_FLOATING_POINT_SUPPORTED
1746 width = png_strtod(png_ptr, ep, &vp);
1749 png_warning(png_ptr, "malformed width string in sCAL chunk");
1753 #ifdef PNG_FIXED_POINT_SUPPORTED
1754 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1757 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1760 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1764 for (ep = buffer; *ep; ep++)
1768 if (buffer + slength < ep)
1770 png_warning(png_ptr, "Truncated sCAL chunk");
1771 #if defined(PNG_FIXED_POINT_SUPPORTED) && \
1772 !defined(PNG_FLOATING_POINT_SUPPORTED)
1773 png_free(png_ptr, swidth);
1775 png_free(png_ptr, buffer);
1779 #ifdef PNG_FLOATING_POINT_SUPPORTED
1780 height = png_strtod(png_ptr, ep, &vp);
1783 png_warning(png_ptr, "malformed height string in sCAL chunk");
1787 #ifdef PNG_FIXED_POINT_SUPPORTED
1788 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1789 if (sheight == NULL)
1791 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1794 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1798 if (buffer + slength < ep
1799 #ifdef PNG_FLOATING_POINT_SUPPORTED
1800 || width <= 0. || height <= 0.
1804 png_warning(png_ptr, "Invalid sCAL data");
1805 png_free(png_ptr, buffer);
1806 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1807 png_free(png_ptr, swidth);
1808 png_free(png_ptr, sheight);
1814 #ifdef PNG_FLOATING_POINT_SUPPORTED
1815 png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
1817 #ifdef PNG_FIXED_POINT_SUPPORTED
1818 png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
1822 png_free(png_ptr, buffer);
1823 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1824 png_free(png_ptr, swidth);
1825 png_free(png_ptr, sheight);
1830 #if defined(PNG_READ_tIME_SUPPORTED)
1832 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1837 png_debug(1, "in png_handle_tIME\n");
1839 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1840 png_error(png_ptr, "Out of place tIME chunk");
1841 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1843 png_warning(png_ptr, "Duplicate tIME chunk");
1844 png_crc_finish(png_ptr, length);
1848 if (png_ptr->mode & PNG_HAVE_IDAT)
1849 png_ptr->mode |= PNG_AFTER_IDAT;
1853 png_warning(png_ptr, "Incorrect tIME chunk length");
1854 png_crc_finish(png_ptr, length);
1858 png_crc_read(png_ptr, buf, 7);
1859 if (png_crc_finish(png_ptr, 0))
1862 mod_time.second = buf[6];
1863 mod_time.minute = buf[5];
1864 mod_time.hour = buf[4];
1865 mod_time.day = buf[3];
1866 mod_time.month = buf[2];
1867 mod_time.year = png_get_uint_16(buf);
1869 png_set_tIME(png_ptr, info_ptr, &mod_time);
1873 #if defined(PNG_READ_tEXt_SUPPORTED)
1874 /* Note: this does not properly handle chunks that are > 64K under DOS */
1876 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1881 png_uint_32 skip = 0;
1885 png_debug(1, "in png_handle_tEXt\n");
1887 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1888 png_error(png_ptr, "Missing IHDR before tEXt");
1890 if (png_ptr->mode & PNG_HAVE_IDAT)
1891 png_ptr->mode |= PNG_AFTER_IDAT;
1893 #ifdef PNG_MAX_MALLOC_64K
1894 if (length > (png_uint_32)65535L)
1896 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1897 skip = length - (png_uint_32)65535L;
1898 length = (png_uint_32)65535L;
1902 key = (png_charp)png_malloc_warn(png_ptr, length + 1);
1905 png_warning(png_ptr, "No memory to process text chunk.");
1908 slength = (png_size_t)length;
1909 png_crc_read(png_ptr, (png_bytep)key, slength);
1911 if (png_crc_finish(png_ptr, skip))
1913 png_free(png_ptr, key);
1917 key[slength] = 0x00;
1919 for (text = key; *text; text++)
1920 /* empty loop to find end of key */ ;
1922 if (text != key + slength)
1925 text_ptr = (png_textp)png_malloc_warn(png_ptr,
1926 (png_uint_32)png_sizeof(png_text));
1927 if (text_ptr == NULL)
1929 png_warning(png_ptr, "Not enough memory to process text chunk.");
1930 png_free(png_ptr, key);
1933 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1934 text_ptr->key = key;
1935 #ifdef PNG_iTXt_SUPPORTED
1936 text_ptr->lang = NULL;
1937 text_ptr->lang_key = NULL;
1938 text_ptr->itxt_length = 0;
1940 text_ptr->text = text;
1941 text_ptr->text_length = png_strlen(text);
1943 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1945 png_free(png_ptr, key);
1946 png_free(png_ptr, text_ptr);
1948 png_warning(png_ptr, "Insufficient memory to process text chunk.");
1952 #if defined(PNG_READ_zTXt_SUPPORTED)
1953 /* note: this does not correctly handle chunks that are > 64K under DOS */
1955 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1958 png_charp chunkdata;
1962 png_size_t slength, prefix_len, data_len;
1964 png_debug(1, "in png_handle_zTXt\n");
1965 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1966 png_error(png_ptr, "Missing IHDR before zTXt");
1968 if (png_ptr->mode & PNG_HAVE_IDAT)
1969 png_ptr->mode |= PNG_AFTER_IDAT;
1971 #ifdef PNG_MAX_MALLOC_64K
1972 /* We will no doubt have problems with chunks even half this size, but
1973 there is no hard and fast rule to tell us where to stop. */
1974 if (length > (png_uint_32)65535L)
1976 png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1977 png_crc_finish(png_ptr, length);
1982 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1983 if (chunkdata == NULL)
1985 png_warning(png_ptr,"Out of memory processing zTXt chunk.");
1988 slength = (png_size_t)length;
1989 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1990 if (png_crc_finish(png_ptr, 0))
1992 png_free(png_ptr, chunkdata);
1996 chunkdata[slength] = 0x00;
1998 for (text = chunkdata; *text; text++)
2001 /* zTXt must have some text after the chunkdataword */
2002 if (text >= chunkdata + slength - 2)
2004 png_warning(png_ptr, "Truncated zTXt chunk");
2005 png_free(png_ptr, chunkdata);
2010 comp_type = *(++text);
2011 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2013 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2014 comp_type = PNG_TEXT_COMPRESSION_zTXt;
2016 text++; /* skip the compression_method byte */
2018 prefix_len = text - chunkdata;
2020 chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
2021 (png_size_t)length, prefix_len, &data_len);
2023 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2024 (png_uint_32)png_sizeof(png_text));
2025 if (text_ptr == NULL)
2027 png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
2028 png_free(png_ptr, chunkdata);
2031 text_ptr->compression = comp_type;
2032 text_ptr->key = chunkdata;
2033 #ifdef PNG_iTXt_SUPPORTED
2034 text_ptr->lang = NULL;
2035 text_ptr->lang_key = NULL;
2036 text_ptr->itxt_length = 0;
2038 text_ptr->text = chunkdata + prefix_len;
2039 text_ptr->text_length = data_len;
2041 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2043 png_free(png_ptr, text_ptr);
2044 png_free(png_ptr, chunkdata);
2046 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2050 #if defined(PNG_READ_iTXt_SUPPORTED)
2051 /* note: this does not correctly handle chunks that are > 64K under DOS */
2053 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2056 png_charp chunkdata;
2057 png_charp key, lang, text, lang_key;
2061 png_size_t slength, prefix_len, data_len;
2063 png_debug(1, "in png_handle_iTXt\n");
2065 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2066 png_error(png_ptr, "Missing IHDR before iTXt");
2068 if (png_ptr->mode & PNG_HAVE_IDAT)
2069 png_ptr->mode |= PNG_AFTER_IDAT;
2071 #ifdef PNG_MAX_MALLOC_64K
2072 /* We will no doubt have problems with chunks even half this size, but
2073 there is no hard and fast rule to tell us where to stop. */
2074 if (length > (png_uint_32)65535L)
2076 png_warning(png_ptr,"iTXt chunk too large to fit in memory");
2077 png_crc_finish(png_ptr, length);
2082 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2083 if (chunkdata == NULL)
2085 png_warning(png_ptr, "No memory to process iTXt chunk.");
2088 slength = (png_size_t)length;
2089 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
2090 if (png_crc_finish(png_ptr, 0))
2092 png_free(png_ptr, chunkdata);
2096 chunkdata[slength] = 0x00;
2098 for (lang = chunkdata; *lang; lang++)
2100 lang++; /* skip NUL separator */
2102 /* iTXt must have a language tag (possibly empty), two compression bytes,
2103 translated keyword (possibly empty), and possibly some text after the
2106 if (lang >= chunkdata + slength - 3)
2108 png_warning(png_ptr, "Truncated iTXt chunk");
2109 png_free(png_ptr, chunkdata);
2114 comp_flag = *lang++;
2115 comp_type = *lang++;
2118 for (lang_key = lang; *lang_key; lang_key++)
2120 lang_key++; /* skip NUL separator */
2122 if (lang_key >= chunkdata + slength)
2124 png_warning(png_ptr, "Truncated iTXt chunk");
2125 png_free(png_ptr, chunkdata);
2129 for (text = lang_key; *text; text++)
2131 text++; /* skip NUL separator */
2132 if (text >= chunkdata + slength)
2134 png_warning(png_ptr, "Malformed iTXt chunk");
2135 png_free(png_ptr, chunkdata);
2139 prefix_len = text - chunkdata;
2143 chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
2144 (size_t)length, prefix_len, &data_len);
2146 data_len=png_strlen(chunkdata + prefix_len);
2147 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2148 (png_uint_32)png_sizeof(png_text));
2149 if (text_ptr == NULL)
2151 png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
2152 png_free(png_ptr, chunkdata);
2155 text_ptr->compression = (int)comp_flag + 1;
2156 text_ptr->lang_key = chunkdata+(lang_key-key);
2157 text_ptr->lang = chunkdata+(lang-key);
2158 text_ptr->itxt_length = data_len;
2159 text_ptr->text_length = 0;
2160 text_ptr->key = chunkdata;
2161 text_ptr->text = chunkdata + prefix_len;
2163 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2165 png_free(png_ptr, text_ptr);
2166 png_free(png_ptr, chunkdata);
2168 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2172 /* This function is called when we haven't found a handler for a
2173 chunk. If there isn't a problem with the chunk itself (ie bad
2174 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2175 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2176 case it will be saved away to be written out later. */
2178 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2180 png_uint_32 skip = 0;
2182 png_debug(1, "in png_handle_unknown\n");
2184 if (png_ptr->mode & PNG_HAVE_IDAT)
2186 #ifdef PNG_USE_LOCAL_ARRAYS
2189 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
2190 png_ptr->mode |= PNG_AFTER_IDAT;
2193 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
2195 if (!(png_ptr->chunk_name[0] & 0x20))
2197 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2198 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2199 PNG_HANDLE_CHUNK_ALWAYS
2200 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2201 && png_ptr->read_user_chunk_fn == NULL
2205 png_chunk_error(png_ptr, "unknown critical chunk");
2208 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2209 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
2210 (png_ptr->read_user_chunk_fn != NULL))
2212 #ifdef PNG_MAX_MALLOC_64K
2213 if (length > (png_uint_32)65535L)
2215 png_warning(png_ptr, "unknown chunk too large to fit in memory");
2216 skip = length - (png_uint_32)65535L;
2217 length = (png_uint_32)65535L;
2220 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2221 (png_charp)png_ptr->chunk_name,
2222 png_sizeof(png_ptr->unknown_chunk.name));
2223 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] = '\0';
2224 png_ptr->unknown_chunk.size = (png_size_t)length;
2226 png_ptr->unknown_chunk.data = NULL;
2229 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2230 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2232 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2233 if(png_ptr->read_user_chunk_fn != NULL)
2235 /* callback to user unknown chunk handler */
2237 ret = (*(png_ptr->read_user_chunk_fn))
2238 (png_ptr, &png_ptr->unknown_chunk);
2240 png_chunk_error(png_ptr, "error in user chunk");
2243 if (!(png_ptr->chunk_name[0] & 0x20))
2244 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2245 PNG_HANDLE_CHUNK_ALWAYS)
2246 png_chunk_error(png_ptr, "unknown critical chunk");
2247 png_set_unknown_chunks(png_ptr, info_ptr,
2248 &png_ptr->unknown_chunk, 1);
2253 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2254 png_free(png_ptr, png_ptr->unknown_chunk.data);
2255 png_ptr->unknown_chunk.data = NULL;
2261 png_crc_finish(png_ptr, skip);
2263 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2264 info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
2268 /* This function is called to verify that a chunk name is valid.
2269 This function can't have the "critical chunk check" incorporated
2270 into it, since in the future we will need to be able to call user
2271 functions to handle unknown critical chunks after we check that
2272 the chunk name itself is valid. */
2274 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2277 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2279 png_debug(1, "in png_check_chunk_name\n");
2280 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2281 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2283 png_chunk_error(png_ptr, "invalid chunk type");
2287 /* Combines the row recently read in with the existing pixels in the
2288 row. This routine takes care of alpha and transparency if requested.
2289 This routine also handles the two methods of progressive display
2290 of interlaced images, depending on the mask value.
2291 The mask value describes which pixels are to be combined with
2292 the row. The pattern always repeats every 8 pixels, so just 8
2293 bits are needed. A one indicates the pixel is to be combined,
2294 a zero indicates the pixel is to be skipped. This is in addition
2295 to any alpha or transparency value associated with the pixel. If
2296 you want all pixels to be combined, pass 0xff (255) in mask. */
2299 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2301 png_debug(1,"in png_combine_row\n");
2304 png_memcpy(row, png_ptr->row_buf + 1,
2305 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2309 switch (png_ptr->row_info.pixel_depth)
2313 png_bytep sp = png_ptr->row_buf + 1;
2315 int s_inc, s_start, s_end;
2319 png_uint_32 row_width = png_ptr->width;
2321 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2322 if (png_ptr->transformations & PNG_PACKSWAP)
2338 for (i = 0; i < row_width; i++)
2344 value = (*sp >> shift) & 0x01;
2345 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2346 *dp |= (png_byte)(value << shift);
2367 png_bytep sp = png_ptr->row_buf + 1;
2369 int s_start, s_end, s_inc;
2373 png_uint_32 row_width = png_ptr->width;
2376 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2377 if (png_ptr->transformations & PNG_PACKSWAP)
2393 for (i = 0; i < row_width; i++)
2397 value = (*sp >> shift) & 0x03;
2398 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2399 *dp |= (png_byte)(value << shift);
2419 png_bytep sp = png_ptr->row_buf + 1;
2421 int s_start, s_end, s_inc;
2425 png_uint_32 row_width = png_ptr->width;
2428 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2429 if (png_ptr->transformations & PNG_PACKSWAP)
2444 for (i = 0; i < row_width; i++)
2448 value = (*sp >> shift) & 0xf;
2449 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2450 *dp |= (png_byte)(value << shift);
2470 png_bytep sp = png_ptr->row_buf + 1;
2472 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2474 png_uint_32 row_width = png_ptr->width;
2478 for (i = 0; i < row_width; i++)
2482 png_memcpy(dp, sp, pixel_bytes);
2499 #ifdef PNG_READ_INTERLACING_SUPPORTED
2500 /* OLD pre-1.0.9 interface:
2501 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2502 png_uint_32 transformations)
2505 png_do_read_interlace(png_structp png_ptr)
2507 png_row_infop row_info = &(png_ptr->row_info);
2508 png_bytep row = png_ptr->row_buf + 1;
2509 int pass = png_ptr->pass;
2510 png_uint_32 transformations = png_ptr->transformations;
2511 #ifdef PNG_USE_LOCAL_ARRAYS
2512 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2513 /* offset to next interlace block */
2514 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2517 png_debug(1,"in png_do_read_interlace\n");
2518 if (row != NULL && row_info != NULL)
2520 png_uint_32 final_width;
2522 final_width = row_info->width * png_pass_inc[pass];
2524 switch (row_info->pixel_depth)
2528 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2529 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2531 int s_start, s_end, s_inc;
2532 int jstop = png_pass_inc[pass];
2537 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2538 if (transformations & PNG_PACKSWAP)
2540 sshift = (int)((row_info->width + 7) & 0x07);
2541 dshift = (int)((final_width + 7) & 0x07);
2549 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2550 dshift = 7 - (int)((final_width + 7) & 0x07);
2556 for (i = 0; i < row_info->width; i++)
2558 v = (png_byte)((*sp >> sshift) & 0x01);
2559 for (j = 0; j < jstop; j++)
2561 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2562 *dp |= (png_byte)(v << dshift);
2563 if (dshift == s_end)
2571 if (sshift == s_end)
2583 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2584 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2586 int s_start, s_end, s_inc;
2587 int jstop = png_pass_inc[pass];
2590 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2591 if (transformations & PNG_PACKSWAP)
2593 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2594 dshift = (int)(((final_width + 3) & 0x03) << 1);
2602 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2603 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2609 for (i = 0; i < row_info->width; i++)
2614 v = (png_byte)((*sp >> sshift) & 0x03);
2615 for (j = 0; j < jstop; j++)
2617 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2618 *dp |= (png_byte)(v << dshift);
2619 if (dshift == s_end)
2627 if (sshift == s_end)
2639 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2640 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2642 int s_start, s_end, s_inc;
2644 int jstop = png_pass_inc[pass];
2646 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2647 if (transformations & PNG_PACKSWAP)
2649 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2650 dshift = (int)(((final_width + 1) & 0x01) << 2);
2658 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2659 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2665 for (i = 0; i < row_info->width; i++)
2667 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2670 for (j = 0; j < jstop; j++)
2672 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2673 *dp |= (png_byte)(v << dshift);
2674 if (dshift == s_end)
2682 if (sshift == s_end)
2694 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2695 png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
2696 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2698 int jstop = png_pass_inc[pass];
2701 for (i = 0; i < row_info->width; i++)
2706 png_memcpy(v, sp, pixel_bytes);
2707 for (j = 0; j < jstop; j++)
2709 png_memcpy(dp, v, pixel_bytes);
2717 row_info->width = final_width;
2718 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
2720 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2721 transformations = transformations; /* silence compiler warning */
2724 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2727 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2728 png_bytep prev_row, int filter)
2730 png_debug(1, "in png_read_filter_row\n");
2731 png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
2734 case PNG_FILTER_VALUE_NONE:
2736 case PNG_FILTER_VALUE_SUB:
2739 png_uint_32 istop = row_info->rowbytes;
2740 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2741 png_bytep rp = row + bpp;
2744 for (i = bpp; i < istop; i++)
2746 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2751 case PNG_FILTER_VALUE_UP:
2754 png_uint_32 istop = row_info->rowbytes;
2756 png_bytep pp = prev_row;
2758 for (i = 0; i < istop; i++)
2760 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2765 case PNG_FILTER_VALUE_AVG:
2769 png_bytep pp = prev_row;
2771 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2772 png_uint_32 istop = row_info->rowbytes - bpp;
2774 for (i = 0; i < bpp; i++)
2776 *rp = (png_byte)(((int)(*rp) +
2777 ((int)(*pp++) / 2 )) & 0xff);
2781 for (i = 0; i < istop; i++)
2783 *rp = (png_byte)(((int)(*rp) +
2784 (int)(*pp++ + *lp++) / 2 ) & 0xff);
2789 case PNG_FILTER_VALUE_PAETH:
2793 png_bytep pp = prev_row;
2795 png_bytep cp = prev_row;
2796 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2797 png_uint_32 istop=row_info->rowbytes - bpp;
2799 for (i = 0; i < bpp; i++)
2801 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2805 for (i = 0; i < istop; i++) /* use leftover rp,pp */
2807 int a, b, c, pa, pb, pc, p;
2821 pa = p < 0 ? -p : p;
2822 pb = pc < 0 ? -pc : pc;
2823 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2827 if (pa <= pb && pa <= pc)
2835 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2837 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2843 png_warning(png_ptr, "Ignoring bad adaptive filter type");
2850 png_read_finish_row(png_structp png_ptr)
2852 #ifdef PNG_USE_LOCAL_ARRAYS
2853 #ifdef PNG_READ_INTERLACING_SUPPORTED
2854 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2856 /* start of interlace block */
2857 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2859 /* offset to next interlace block */
2860 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2862 /* start of interlace block in the y direction */
2863 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2865 /* offset to next interlace block in the y direction */
2866 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2867 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2870 png_debug(1, "in png_read_finish_row\n");
2871 png_ptr->row_number++;
2872 if (png_ptr->row_number < png_ptr->num_rows)
2875 #ifdef PNG_READ_INTERLACING_SUPPORTED
2876 if (png_ptr->interlaced)
2878 png_ptr->row_number = 0;
2879 png_memset_check(png_ptr, png_ptr->prev_row, 0,
2880 png_ptr->rowbytes + 1);
2884 if (png_ptr->pass >= 7)
2886 png_ptr->iwidth = (png_ptr->width +
2887 png_pass_inc[png_ptr->pass] - 1 -
2888 png_pass_start[png_ptr->pass]) /
2889 png_pass_inc[png_ptr->pass];
2891 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
2892 png_ptr->iwidth) + 1;
2894 if (!(png_ptr->transformations & PNG_INTERLACE))
2896 png_ptr->num_rows = (png_ptr->height +
2897 png_pass_yinc[png_ptr->pass] - 1 -
2898 png_pass_ystart[png_ptr->pass]) /
2899 png_pass_yinc[png_ptr->pass];
2900 if (!(png_ptr->num_rows))
2903 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2905 } while (png_ptr->iwidth == 0);
2907 if (png_ptr->pass < 7)
2910 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2912 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2914 #ifdef PNG_USE_LOCAL_ARRAYS
2920 png_ptr->zstream.next_out = (Byte *)&extra;
2921 png_ptr->zstream.avail_out = (uInt)1;
2924 if (!(png_ptr->zstream.avail_in))
2926 while (!png_ptr->idat_size)
2928 png_byte chunk_length[4];
2930 png_crc_finish(png_ptr, 0);
2932 png_read_data(png_ptr, chunk_length, 4);
2933 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
2934 png_reset_crc(png_ptr);
2935 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
2936 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
2937 png_error(png_ptr, "Not enough image data");
2940 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
2941 png_ptr->zstream.next_in = png_ptr->zbuf;
2942 if (png_ptr->zbuf_size > png_ptr->idat_size)
2943 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
2944 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
2945 png_ptr->idat_size -= png_ptr->zstream.avail_in;
2947 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2948 if (ret == Z_STREAM_END)
2950 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2952 png_warning(png_ptr, "Extra compressed data");
2953 png_ptr->mode |= PNG_AFTER_IDAT;
2954 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2958 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2959 "Decompression Error");
2961 if (!(png_ptr->zstream.avail_out))
2963 png_warning(png_ptr, "Extra compressed data.");
2964 png_ptr->mode |= PNG_AFTER_IDAT;
2965 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2970 png_ptr->zstream.avail_out = 0;
2973 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2974 png_warning(png_ptr, "Extra compression data");
2976 inflateReset(&png_ptr->zstream);
2978 png_ptr->mode |= PNG_AFTER_IDAT;
2982 png_read_start_row(png_structp png_ptr)
2984 #ifdef PNG_USE_LOCAL_ARRAYS
2985 #ifdef PNG_READ_INTERLACING_SUPPORTED
2986 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2988 /* start of interlace block */
2989 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2991 /* offset to next interlace block */
2992 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2994 /* start of interlace block in the y direction */
2995 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2997 /* offset to next interlace block in the y direction */
2998 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3002 int max_pixel_depth;
3003 png_uint_32 row_bytes;
3005 png_debug(1, "in png_read_start_row\n");
3006 png_ptr->zstream.avail_in = 0;
3007 png_init_read_transformations(png_ptr);
3008 #ifdef PNG_READ_INTERLACING_SUPPORTED
3009 if (png_ptr->interlaced)
3011 if (!(png_ptr->transformations & PNG_INTERLACE))
3012 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3013 png_pass_ystart[0]) / png_pass_yinc[0];
3015 png_ptr->num_rows = png_ptr->height;
3017 png_ptr->iwidth = (png_ptr->width +
3018 png_pass_inc[png_ptr->pass] - 1 -
3019 png_pass_start[png_ptr->pass]) /
3020 png_pass_inc[png_ptr->pass];
3022 row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
3024 png_ptr->irowbytes = (png_size_t)row_bytes;
3025 if((png_uint_32)png_ptr->irowbytes != row_bytes)
3026 png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
3029 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3031 png_ptr->num_rows = png_ptr->height;
3032 png_ptr->iwidth = png_ptr->width;
3033 png_ptr->irowbytes = png_ptr->rowbytes + 1;
3035 max_pixel_depth = png_ptr->pixel_depth;
3037 #if defined(PNG_READ_PACK_SUPPORTED)
3038 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3039 max_pixel_depth = 8;
3042 #if defined(PNG_READ_EXPAND_SUPPORTED)
3043 if (png_ptr->transformations & PNG_EXPAND)
3045 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3047 if (png_ptr->num_trans)
3048 max_pixel_depth = 32;
3050 max_pixel_depth = 24;
3052 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3054 if (max_pixel_depth < 8)
3055 max_pixel_depth = 8;
3056 if (png_ptr->num_trans)
3057 max_pixel_depth *= 2;
3059 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3061 if (png_ptr->num_trans)
3063 max_pixel_depth *= 4;
3064 max_pixel_depth /= 3;
3070 #if defined(PNG_READ_FILLER_SUPPORTED)
3071 if (png_ptr->transformations & (PNG_FILLER))
3073 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3074 max_pixel_depth = 32;
3075 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3077 if (max_pixel_depth <= 8)
3078 max_pixel_depth = 16;
3080 max_pixel_depth = 32;
3082 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3084 if (max_pixel_depth <= 32)
3085 max_pixel_depth = 32;
3087 max_pixel_depth = 64;
3092 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3093 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3096 #if defined(PNG_READ_EXPAND_SUPPORTED)
3097 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3099 #if defined(PNG_READ_FILLER_SUPPORTED)
3100 (png_ptr->transformations & (PNG_FILLER)) ||
3102 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3104 if (max_pixel_depth <= 16)
3105 max_pixel_depth = 32;
3107 max_pixel_depth = 64;
3111 if (max_pixel_depth <= 8)
3113 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3114 max_pixel_depth = 32;
3116 max_pixel_depth = 24;
3118 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3119 max_pixel_depth = 64;
3121 max_pixel_depth = 48;
3126 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3127 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3128 if(png_ptr->transformations & PNG_USER_TRANSFORM)
3130 int user_pixel_depth=png_ptr->user_transform_depth*
3131 png_ptr->user_transform_channels;
3132 if(user_pixel_depth > max_pixel_depth)
3133 max_pixel_depth=user_pixel_depth;
3137 /* align the width on the next larger 8 pixels. Mainly used
3139 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3140 /* calculate the maximum bytes needed, adding a byte and a pixel
3141 for safety's sake */
3142 row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
3143 1 + ((max_pixel_depth + 7) >> 3);
3144 #ifdef PNG_MAX_MALLOC_64K
3145 if (row_bytes > (png_uint_32)65536L)
3146 png_error(png_ptr, "This image requires a row greater than 64KB");
3149 if(row_bytes + 64 > png_ptr->old_big_row_buf_size)
3151 png_free(png_ptr,png_ptr->big_row_buf);
3152 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
3153 png_ptr->row_buf = png_ptr->big_row_buf+32;
3154 png_ptr->old_big_row_buf_size = row_bytes+64;
3157 #ifdef PNG_MAX_MALLOC_64K
3158 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3159 png_error(png_ptr, "This image requires a row greater than 64KB");
3161 if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3162 png_error(png_ptr, "Row has too many bytes to allocate in memory.");
3164 if(png_ptr->rowbytes+1 > png_ptr->old_prev_row_size)
3166 png_free(png_ptr,png_ptr->prev_row);
3167 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3168 png_ptr->rowbytes + 1));
3169 png_ptr->old_prev_row_size = png_ptr->rowbytes+1;
3172 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3174 png_debug1(3, "width = %lu,\n", png_ptr->width);
3175 png_debug1(3, "height = %lu,\n", png_ptr->height);
3176 png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
3177 png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
3178 png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
3179 png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
3181 png_ptr->flags |= PNG_FLAG_ROW_INIT;
3183 #endif /* PNG_READ_SUPPORTED */