1 /* pngrutil.c - utilities to read a PNG file
3 * libpng version 1.2.8 - December 3, 2004
4 * For conditions of distribution and use, see copyright notice in png.h
5 * Copyright (c) 1998-2004 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 file contains routines that are only called from within
10 * libpng itself during the course of reading an image.
16 #if defined(_WIN32_WCE)
17 /* strtod() function is not supported on WindowsCE */
18 # ifdef PNG_FLOATING_POINT_SUPPORTED
19 __inline double strtod(const char *nptr, char **endptr)
25 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
26 str = (wchar_t *)malloc(len * sizeof(wchar_t));
29 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
30 result = wcstod(str, &end);
31 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
32 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
40 png_uint_32 /* PRIVATE */
41 png_get_uint_31(png_structp png_ptr, png_bytep buf)
43 png_uint_32 i = png_get_uint_32(buf);
44 if (i > PNG_UINT_31_MAX)
45 png_error(png_ptr, "PNG unsigned integer out of range.\n");
48 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
49 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
50 png_uint_32 /* PRIVATE */
51 png_get_uint_32(png_bytep buf)
53 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
54 ((png_uint_32)(*(buf + 1)) << 16) +
55 ((png_uint_32)(*(buf + 2)) << 8) +
56 (png_uint_32)(*(buf + 3));
61 #if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
62 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
63 * data is stored in the PNG file in two's complement format, and it is
64 * assumed that the machine format for signed integers is the same. */
65 png_int_32 /* PRIVATE */
66 png_get_int_32(png_bytep buf)
68 png_int_32 i = ((png_int_32)(*buf) << 24) +
69 ((png_int_32)(*(buf + 1)) << 16) +
70 ((png_int_32)(*(buf + 2)) << 8) +
71 (png_int_32)(*(buf + 3));
75 #endif /* PNG_READ_pCAL_SUPPORTED */
77 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
78 png_uint_16 /* PRIVATE */
79 png_get_uint_16(png_bytep buf)
81 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
82 (png_uint_16)(*(buf + 1)));
86 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
88 /* Read data, and (optionally) run it through the CRC. */
90 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
92 png_read_data(png_ptr, buf, length);
93 png_calculate_crc(png_ptr, buf, length);
96 /* Optionally skip data and then check the CRC. Depending on whether we
97 are reading a ancillary or critical chunk, and how the program has set
98 things up, we may calculate the CRC on the data and print a message.
99 Returns '1' if there was a CRC error, '0' otherwise. */
101 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
104 png_size_t istop = png_ptr->zbuf_size;
106 for (i = (png_size_t)skip; i > istop; i -= istop)
108 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
112 png_crc_read(png_ptr, png_ptr->zbuf, i);
115 if (png_crc_error(png_ptr))
117 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
118 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
119 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
120 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
122 png_chunk_warning(png_ptr, "CRC error");
126 png_chunk_error(png_ptr, "CRC error");
134 /* Compare the CRC stored in the PNG file with that calculated by libpng from
135 the data it has read thus far. */
137 png_crc_error(png_structp png_ptr)
139 png_byte crc_bytes[4];
143 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
145 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
146 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
151 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
155 png_read_data(png_ptr, crc_bytes, 4);
159 crc = png_get_uint_32(crc_bytes);
160 return ((int)(crc != png_ptr->crc));
166 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
167 defined(PNG_READ_iCCP_SUPPORTED)
169 * Decompress trailing data in a chunk. The assumption is that chunkdata
170 * points at an allocated area holding the contents of a chunk with a
171 * trailing compressed part. What we get back is an allocated area
172 * holding the original prefix part and an uncompressed version of the
173 * trailing part (the malloc area passed in is freed).
175 png_charp /* PRIVATE */
176 png_decompress_chunk(png_structp png_ptr, int comp_type,
177 png_charp chunkdata, png_size_t chunklength,
178 png_size_t prefix_size, png_size_t *newlength)
180 static char msg[] = "Error decoding compressed text";
182 png_size_t text_size;
184 if (comp_type == PNG_COMPRESSION_TYPE_BASE)
187 png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
188 png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
189 png_ptr->zstream.next_out = png_ptr->zbuf;
190 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
195 while (png_ptr->zstream.avail_in)
197 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
198 if (ret != Z_OK && ret != Z_STREAM_END)
200 if (png_ptr->zstream.msg != NULL)
201 png_warning(png_ptr, png_ptr->zstream.msg);
203 png_warning(png_ptr, msg);
204 inflateReset(&png_ptr->zstream);
205 png_ptr->zstream.avail_in = 0;
209 text_size = prefix_size + png_sizeof(msg) + 1;
210 text = (png_charp)png_malloc_warn(png_ptr, text_size);
213 png_free(png_ptr,chunkdata);
214 png_error(png_ptr,"Not enough memory to decompress chunk");
216 png_memcpy(text, chunkdata, prefix_size);
219 text[text_size - 1] = 0x00;
221 /* Copy what we can of the error message into the text chunk */
222 text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
223 text_size = png_sizeof(msg) > text_size ? text_size :
225 png_memcpy(text + prefix_size, msg, text_size + 1);
228 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
232 text_size = prefix_size +
233 png_ptr->zbuf_size - png_ptr->zstream.avail_out;
234 text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
237 png_free(png_ptr,chunkdata);
238 png_error(png_ptr,"Not enough memory to decompress chunk.");
240 png_memcpy(text + prefix_size, png_ptr->zbuf,
241 text_size - prefix_size);
242 png_memcpy(text, chunkdata, prefix_size);
243 *(text + text_size) = 0x00;
250 text = (png_charp)png_malloc_warn(png_ptr,
251 (png_uint_32)(text_size +
252 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
255 png_free(png_ptr, tmp);
256 png_free(png_ptr, chunkdata);
257 png_error(png_ptr,"Not enough memory to decompress chunk..");
259 png_memcpy(text, tmp, text_size);
260 png_free(png_ptr, tmp);
261 png_memcpy(text + text_size, png_ptr->zbuf,
262 (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
263 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
264 *(text + text_size) = 0x00;
266 if (ret == Z_STREAM_END)
270 png_ptr->zstream.next_out = png_ptr->zbuf;
271 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
275 if (ret != Z_STREAM_END)
277 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
280 if (ret == Z_BUF_ERROR)
281 sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
282 png_ptr->chunk_name);
283 else if (ret == Z_DATA_ERROR)
284 sprintf(umsg,"Data error in compressed datastream in %s chunk",
285 png_ptr->chunk_name);
287 sprintf(umsg,"Incomplete compressed datastream in %s chunk",
288 png_ptr->chunk_name);
289 png_warning(png_ptr, umsg);
292 "Incomplete compressed datastream in chunk other than IDAT");
294 text_size=prefix_size;
297 text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
300 png_free(png_ptr, chunkdata);
301 png_error(png_ptr,"Not enough memory for text.");
303 png_memcpy(text, chunkdata, prefix_size);
305 *(text + text_size) = 0x00;
308 inflateReset(&png_ptr->zstream);
309 png_ptr->zstream.avail_in = 0;
311 png_free(png_ptr, chunkdata);
313 *newlength=text_size;
315 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
317 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
320 sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
321 png_warning(png_ptr, umsg);
323 png_warning(png_ptr, "Unknown zTXt compression type");
326 *(chunkdata + prefix_size) = 0x00;
327 *newlength=prefix_size;
334 /* read and check the IDHR chunk */
336 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
339 png_uint_32 width, height;
340 int bit_depth, color_type, compression_type, filter_type;
343 png_debug(1, "in png_handle_IHDR\n");
345 if (png_ptr->mode & PNG_HAVE_IHDR)
346 png_error(png_ptr, "Out of place IHDR");
348 /* check the length */
350 png_error(png_ptr, "Invalid IHDR chunk");
352 png_ptr->mode |= PNG_HAVE_IHDR;
354 png_crc_read(png_ptr, buf, 13);
355 png_crc_finish(png_ptr, 0);
357 width = png_get_uint_31(png_ptr, buf);
358 height = png_get_uint_31(png_ptr, buf + 4);
361 compression_type = buf[10];
362 filter_type = buf[11];
363 interlace_type = buf[12];
365 /* set internal variables */
366 png_ptr->width = width;
367 png_ptr->height = height;
368 png_ptr->bit_depth = (png_byte)bit_depth;
369 png_ptr->interlaced = (png_byte)interlace_type;
370 png_ptr->color_type = (png_byte)color_type;
371 #if defined(PNG_MNG_FEATURES_SUPPORTED)
372 png_ptr->filter_type = (png_byte)filter_type;
374 png_ptr->compression_type = (png_byte)compression_type;
376 /* find number of channels */
377 switch (png_ptr->color_type)
379 case PNG_COLOR_TYPE_GRAY:
380 case PNG_COLOR_TYPE_PALETTE:
381 png_ptr->channels = 1;
383 case PNG_COLOR_TYPE_RGB:
384 png_ptr->channels = 3;
386 case PNG_COLOR_TYPE_GRAY_ALPHA:
387 png_ptr->channels = 2;
389 case PNG_COLOR_TYPE_RGB_ALPHA:
390 png_ptr->channels = 4;
394 /* set up other useful info */
395 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
397 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
398 png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
399 png_debug1(3,"channels = %d\n", png_ptr->channels);
400 png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
401 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
402 color_type, interlace_type, compression_type, filter_type);
405 /* read and check the palette */
407 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
409 png_color palette[PNG_MAX_PALETTE_LENGTH];
411 #ifndef PNG_NO_POINTER_INDEXING
415 png_debug(1, "in png_handle_PLTE\n");
417 if (!(png_ptr->mode & PNG_HAVE_IHDR))
418 png_error(png_ptr, "Missing IHDR before PLTE");
419 else if (png_ptr->mode & PNG_HAVE_IDAT)
421 png_warning(png_ptr, "Invalid PLTE after IDAT");
422 png_crc_finish(png_ptr, length);
425 else if (png_ptr->mode & PNG_HAVE_PLTE)
426 png_error(png_ptr, "Duplicate PLTE chunk");
428 png_ptr->mode |= PNG_HAVE_PLTE;
430 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
433 "Ignoring PLTE chunk in grayscale PNG");
434 png_crc_finish(png_ptr, length);
437 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
438 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
440 png_crc_finish(png_ptr, length);
445 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
447 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
449 png_warning(png_ptr, "Invalid palette chunk");
450 png_crc_finish(png_ptr, length);
455 png_error(png_ptr, "Invalid palette chunk");
459 num = (int)length / 3;
461 #ifndef PNG_NO_POINTER_INDEXING
462 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
466 png_crc_read(png_ptr, buf, 3);
467 pal_ptr->red = buf[0];
468 pal_ptr->green = buf[1];
469 pal_ptr->blue = buf[2];
472 for (i = 0; i < num; i++)
476 png_crc_read(png_ptr, buf, 3);
477 /* don't depend upon png_color being any order */
478 palette[i].red = buf[0];
479 palette[i].green = buf[1];
480 palette[i].blue = buf[2];
484 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
485 whatever the normal CRC configuration tells us. However, if we
486 have an RGB image, the PLTE can be considered ancillary, so
487 we will act as though it is. */
488 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
489 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
492 png_crc_finish(png_ptr, 0);
494 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
495 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
497 /* If we don't want to use the data from an ancillary chunk,
498 we have two options: an error abort, or a warning and we
499 ignore the data in this chunk (which should be OK, since
500 it's considered ancillary for a RGB or RGBA image). */
501 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
503 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
505 png_chunk_error(png_ptr, "CRC error");
509 png_chunk_warning(png_ptr, "CRC error");
513 /* Otherwise, we (optionally) emit a warning and use the chunk. */
514 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
516 png_chunk_warning(png_ptr, "CRC error");
521 png_set_PLTE(png_ptr, info_ptr, palette, num);
523 #if defined(PNG_READ_tRNS_SUPPORTED)
524 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
526 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
528 if (png_ptr->num_trans > (png_uint_16)num)
530 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
531 png_ptr->num_trans = (png_uint_16)num;
533 if (info_ptr->num_trans > (png_uint_16)num)
535 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
536 info_ptr->num_trans = (png_uint_16)num;
545 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
547 png_debug(1, "in png_handle_IEND\n");
549 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
551 png_error(png_ptr, "No image in file");
554 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
558 png_warning(png_ptr, "Incorrect IEND chunk length");
560 png_crc_finish(png_ptr, length);
562 if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
566 #if defined(PNG_READ_gAMA_SUPPORTED)
568 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
570 png_fixed_point igamma;
571 #ifdef PNG_FLOATING_POINT_SUPPORTED
576 png_debug(1, "in png_handle_gAMA\n");
578 if (!(png_ptr->mode & PNG_HAVE_IHDR))
579 png_error(png_ptr, "Missing IHDR before gAMA");
580 else if (png_ptr->mode & PNG_HAVE_IDAT)
582 png_warning(png_ptr, "Invalid gAMA after IDAT");
583 png_crc_finish(png_ptr, length);
586 else if (png_ptr->mode & PNG_HAVE_PLTE)
587 /* Should be an error, but we can cope with it */
588 png_warning(png_ptr, "Out of place gAMA chunk");
590 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
591 #if defined(PNG_READ_sRGB_SUPPORTED)
592 && !(info_ptr->valid & PNG_INFO_sRGB)
596 png_warning(png_ptr, "Duplicate gAMA chunk");
597 png_crc_finish(png_ptr, length);
603 png_warning(png_ptr, "Incorrect gAMA chunk length");
604 png_crc_finish(png_ptr, length);
608 png_crc_read(png_ptr, buf, 4);
609 if (png_crc_finish(png_ptr, 0))
612 igamma = (png_fixed_point)png_get_uint_32(buf);
613 /* check for zero gamma */
617 "Ignoring gAMA chunk with gamma=0");
621 #if defined(PNG_READ_sRGB_SUPPORTED)
622 if (info_ptr->valid & PNG_INFO_sRGB)
623 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
626 "Ignoring incorrect gAMA value when sRGB is also present");
627 #ifndef PNG_NO_CONSOLE_IO
628 fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
632 #endif /* PNG_READ_sRGB_SUPPORTED */
634 #ifdef PNG_FLOATING_POINT_SUPPORTED
635 file_gamma = (float)igamma / (float)100000.0;
636 # ifdef PNG_READ_GAMMA_SUPPORTED
637 png_ptr->gamma = file_gamma;
639 png_set_gAMA(png_ptr, info_ptr, file_gamma);
641 #ifdef PNG_FIXED_POINT_SUPPORTED
642 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
647 #if defined(PNG_READ_sBIT_SUPPORTED)
649 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
654 png_debug(1, "in png_handle_sBIT\n");
656 buf[0] = buf[1] = buf[2] = buf[3] = 0;
658 if (!(png_ptr->mode & PNG_HAVE_IHDR))
659 png_error(png_ptr, "Missing IHDR before sBIT");
660 else if (png_ptr->mode & PNG_HAVE_IDAT)
662 png_warning(png_ptr, "Invalid sBIT after IDAT");
663 png_crc_finish(png_ptr, length);
666 else if (png_ptr->mode & PNG_HAVE_PLTE)
668 /* Should be an error, but we can cope with it */
669 png_warning(png_ptr, "Out of place sBIT chunk");
671 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
673 png_warning(png_ptr, "Duplicate sBIT chunk");
674 png_crc_finish(png_ptr, length);
678 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
681 truelen = (png_size_t)png_ptr->channels;
683 if (length != truelen || length > 4)
685 png_warning(png_ptr, "Incorrect sBIT chunk length");
686 png_crc_finish(png_ptr, length);
690 png_crc_read(png_ptr, buf, truelen);
691 if (png_crc_finish(png_ptr, 0))
694 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
696 png_ptr->sig_bit.red = buf[0];
697 png_ptr->sig_bit.green = buf[1];
698 png_ptr->sig_bit.blue = buf[2];
699 png_ptr->sig_bit.alpha = buf[3];
703 png_ptr->sig_bit.gray = buf[0];
704 png_ptr->sig_bit.red = buf[0];
705 png_ptr->sig_bit.green = buf[0];
706 png_ptr->sig_bit.blue = buf[0];
707 png_ptr->sig_bit.alpha = buf[1];
709 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
713 #if defined(PNG_READ_cHRM_SUPPORTED)
715 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
718 #ifdef PNG_FLOATING_POINT_SUPPORTED
719 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
721 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
722 int_y_green, int_x_blue, int_y_blue;
724 png_uint_32 uint_x, uint_y;
726 png_debug(1, "in png_handle_cHRM\n");
728 if (!(png_ptr->mode & PNG_HAVE_IHDR))
729 png_error(png_ptr, "Missing IHDR before cHRM");
730 else if (png_ptr->mode & PNG_HAVE_IDAT)
732 png_warning(png_ptr, "Invalid cHRM after IDAT");
733 png_crc_finish(png_ptr, length);
736 else if (png_ptr->mode & PNG_HAVE_PLTE)
737 /* Should be an error, but we can cope with it */
738 png_warning(png_ptr, "Missing PLTE before cHRM");
740 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
741 #if defined(PNG_READ_sRGB_SUPPORTED)
742 && !(info_ptr->valid & PNG_INFO_sRGB)
746 png_warning(png_ptr, "Duplicate cHRM chunk");
747 png_crc_finish(png_ptr, length);
753 png_warning(png_ptr, "Incorrect cHRM chunk length");
754 png_crc_finish(png_ptr, length);
758 png_crc_read(png_ptr, buf, 4);
759 uint_x = png_get_uint_32(buf);
761 png_crc_read(png_ptr, buf, 4);
762 uint_y = png_get_uint_32(buf);
764 if (uint_x > 80000L || uint_y > 80000L ||
765 uint_x + uint_y > 100000L)
767 png_warning(png_ptr, "Invalid cHRM white point");
768 png_crc_finish(png_ptr, 24);
771 int_x_white = (png_fixed_point)uint_x;
772 int_y_white = (png_fixed_point)uint_y;
774 png_crc_read(png_ptr, buf, 4);
775 uint_x = png_get_uint_32(buf);
777 png_crc_read(png_ptr, buf, 4);
778 uint_y = png_get_uint_32(buf);
780 if (uint_x > 80000L || uint_y > 80000L ||
781 uint_x + uint_y > 100000L)
783 png_warning(png_ptr, "Invalid cHRM red point");
784 png_crc_finish(png_ptr, 16);
787 int_x_red = (png_fixed_point)uint_x;
788 int_y_red = (png_fixed_point)uint_y;
790 png_crc_read(png_ptr, buf, 4);
791 uint_x = png_get_uint_32(buf);
793 png_crc_read(png_ptr, buf, 4);
794 uint_y = png_get_uint_32(buf);
796 if (uint_x > 80000L || uint_y > 80000L ||
797 uint_x + uint_y > 100000L)
799 png_warning(png_ptr, "Invalid cHRM green point");
800 png_crc_finish(png_ptr, 8);
803 int_x_green = (png_fixed_point)uint_x;
804 int_y_green = (png_fixed_point)uint_y;
806 png_crc_read(png_ptr, buf, 4);
807 uint_x = png_get_uint_32(buf);
809 png_crc_read(png_ptr, buf, 4);
810 uint_y = png_get_uint_32(buf);
812 if (uint_x > 80000L || uint_y > 80000L ||
813 uint_x + uint_y > 100000L)
815 png_warning(png_ptr, "Invalid cHRM blue point");
816 png_crc_finish(png_ptr, 0);
819 int_x_blue = (png_fixed_point)uint_x;
820 int_y_blue = (png_fixed_point)uint_y;
822 #ifdef PNG_FLOATING_POINT_SUPPORTED
823 white_x = (float)int_x_white / (float)100000.0;
824 white_y = (float)int_y_white / (float)100000.0;
825 red_x = (float)int_x_red / (float)100000.0;
826 red_y = (float)int_y_red / (float)100000.0;
827 green_x = (float)int_x_green / (float)100000.0;
828 green_y = (float)int_y_green / (float)100000.0;
829 blue_x = (float)int_x_blue / (float)100000.0;
830 blue_y = (float)int_y_blue / (float)100000.0;
833 #if defined(PNG_READ_sRGB_SUPPORTED)
834 if (info_ptr->valid & PNG_INFO_sRGB)
836 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
837 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
838 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
839 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
840 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
841 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
842 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
843 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
847 "Ignoring incorrect cHRM value when sRGB is also present");
848 #ifndef PNG_NO_CONSOLE_IO
849 #ifdef PNG_FLOATING_POINT_SUPPORTED
850 fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
851 white_x, white_y, red_x, red_y);
852 fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
853 green_x, green_y, blue_x, blue_y);
855 fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
856 int_x_white, int_y_white, int_x_red, int_y_red);
857 fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
858 int_x_green, int_y_green, int_x_blue, int_y_blue);
860 #endif /* PNG_NO_CONSOLE_IO */
862 png_crc_finish(png_ptr, 0);
865 #endif /* PNG_READ_sRGB_SUPPORTED */
867 #ifdef PNG_FLOATING_POINT_SUPPORTED
868 png_set_cHRM(png_ptr, info_ptr,
869 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
871 #ifdef PNG_FIXED_POINT_SUPPORTED
872 png_set_cHRM_fixed(png_ptr, info_ptr,
873 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
874 int_y_green, int_x_blue, int_y_blue);
876 if (png_crc_finish(png_ptr, 0))
881 #if defined(PNG_READ_sRGB_SUPPORTED)
883 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
888 png_debug(1, "in png_handle_sRGB\n");
890 if (!(png_ptr->mode & PNG_HAVE_IHDR))
891 png_error(png_ptr, "Missing IHDR before sRGB");
892 else if (png_ptr->mode & PNG_HAVE_IDAT)
894 png_warning(png_ptr, "Invalid sRGB after IDAT");
895 png_crc_finish(png_ptr, length);
898 else if (png_ptr->mode & PNG_HAVE_PLTE)
899 /* Should be an error, but we can cope with it */
900 png_warning(png_ptr, "Out of place sRGB chunk");
902 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
904 png_warning(png_ptr, "Duplicate sRGB chunk");
905 png_crc_finish(png_ptr, length);
911 png_warning(png_ptr, "Incorrect sRGB chunk length");
912 png_crc_finish(png_ptr, length);
916 png_crc_read(png_ptr, buf, 1);
917 if (png_crc_finish(png_ptr, 0))
921 /* check for bad intent */
922 if (intent >= PNG_sRGB_INTENT_LAST)
924 png_warning(png_ptr, "Unknown sRGB intent");
928 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
929 if ((info_ptr->valid & PNG_INFO_gAMA))
931 png_fixed_point igamma;
932 #ifdef PNG_FIXED_POINT_SUPPORTED
933 igamma=info_ptr->int_gamma;
935 # ifdef PNG_FLOATING_POINT_SUPPORTED
936 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
939 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
942 "Ignoring incorrect gAMA value when sRGB is also present");
943 #ifndef PNG_NO_CONSOLE_IO
944 # ifdef PNG_FIXED_POINT_SUPPORTED
945 fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
947 # ifdef PNG_FLOATING_POINT_SUPPORTED
948 fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
954 #endif /* PNG_READ_gAMA_SUPPORTED */
956 #ifdef PNG_READ_cHRM_SUPPORTED
957 #ifdef PNG_FIXED_POINT_SUPPORTED
958 if (info_ptr->valid & PNG_INFO_cHRM)
959 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
960 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
961 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
962 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
963 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
964 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
965 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
966 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
969 "Ignoring incorrect cHRM value when sRGB is also present");
971 #endif /* PNG_FIXED_POINT_SUPPORTED */
972 #endif /* PNG_READ_cHRM_SUPPORTED */
974 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
976 #endif /* PNG_READ_sRGB_SUPPORTED */
978 #if defined(PNG_READ_iCCP_SUPPORTED)
980 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
981 /* Note: this does not properly handle chunks that are > 64K under DOS */
984 png_byte compression_type;
987 png_uint_32 skip = 0;
988 png_uint_32 profile_size, profile_length;
989 png_size_t slength, prefix_length, data_length;
991 png_debug(1, "in png_handle_iCCP\n");
993 if (!(png_ptr->mode & PNG_HAVE_IHDR))
994 png_error(png_ptr, "Missing IHDR before iCCP");
995 else if (png_ptr->mode & PNG_HAVE_IDAT)
997 png_warning(png_ptr, "Invalid iCCP after IDAT");
998 png_crc_finish(png_ptr, length);
1001 else if (png_ptr->mode & PNG_HAVE_PLTE)
1002 /* Should be an error, but we can cope with it */
1003 png_warning(png_ptr, "Out of place iCCP chunk");
1005 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1007 png_warning(png_ptr, "Duplicate iCCP chunk");
1008 png_crc_finish(png_ptr, length);
1012 #ifdef PNG_MAX_MALLOC_64K
1013 if (length > (png_uint_32)65535L)
1015 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1016 skip = length - (png_uint_32)65535L;
1017 length = (png_uint_32)65535L;
1021 chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1022 slength = (png_size_t)length;
1023 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1025 if (png_crc_finish(png_ptr, skip))
1027 png_free(png_ptr, chunkdata);
1031 chunkdata[slength] = 0x00;
1033 for (profile = chunkdata; *profile; profile++)
1034 /* empty loop to find end of name */ ;
1038 /* there should be at least one zero (the compression type byte)
1039 following the separator, and we should be on it */
1040 if ( profile >= chunkdata + slength)
1042 png_free(png_ptr, chunkdata);
1043 png_warning(png_ptr, "Malformed iCCP chunk");
1047 /* compression_type should always be zero */
1048 compression_type = *profile++;
1049 if (compression_type)
1051 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1052 compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1056 prefix_length = profile - chunkdata;
1057 chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
1058 slength, prefix_length, &data_length);
1060 profile_length = data_length - prefix_length;
1062 if ( prefix_length > data_length || profile_length < 4)
1064 png_free(png_ptr, chunkdata);
1065 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1069 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1070 pC = (png_bytep)(chunkdata+prefix_length);
1071 profile_size = ((*(pC ))<<24) |
1076 if(profile_size < profile_length)
1077 profile_length = profile_size;
1079 if(profile_size > profile_length)
1081 png_free(png_ptr, chunkdata);
1082 png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
1086 png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
1087 chunkdata + prefix_length, profile_length);
1088 png_free(png_ptr, chunkdata);
1090 #endif /* PNG_READ_iCCP_SUPPORTED */
1092 #if defined(PNG_READ_sPLT_SUPPORTED)
1094 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1095 /* Note: this does not properly handle chunks that are > 64K under DOS */
1097 png_bytep chunkdata;
1098 png_bytep entry_start;
1099 png_sPLT_t new_palette;
1100 #ifdef PNG_NO_POINTER_INDEXING
1103 int data_length, entry_size, i;
1104 png_uint_32 skip = 0;
1107 png_debug(1, "in png_handle_sPLT\n");
1109 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1110 png_error(png_ptr, "Missing IHDR before sPLT");
1111 else if (png_ptr->mode & PNG_HAVE_IDAT)
1113 png_warning(png_ptr, "Invalid sPLT after IDAT");
1114 png_crc_finish(png_ptr, length);
1118 #ifdef PNG_MAX_MALLOC_64K
1119 if (length > (png_uint_32)65535L)
1121 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1122 skip = length - (png_uint_32)65535L;
1123 length = (png_uint_32)65535L;
1127 chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
1128 slength = (png_size_t)length;
1129 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1131 if (png_crc_finish(png_ptr, skip))
1133 png_free(png_ptr, chunkdata);
1137 chunkdata[slength] = 0x00;
1139 for (entry_start = chunkdata; *entry_start; entry_start++)
1140 /* empty loop to find end of name */ ;
1143 /* a sample depth should follow the separator, and we should be on it */
1144 if (entry_start > chunkdata + slength)
1146 png_free(png_ptr, chunkdata);
1147 png_warning(png_ptr, "malformed sPLT chunk");
1151 new_palette.depth = *entry_start++;
1152 entry_size = (new_palette.depth == 8 ? 6 : 10);
1153 data_length = (slength - (entry_start - chunkdata));
1155 /* integrity-check the data length */
1156 if (data_length % entry_size)
1158 png_free(png_ptr, chunkdata);
1159 png_warning(png_ptr, "sPLT chunk has bad length");
1163 new_palette.nentries = (png_uint_32) (data_length / entry_size);
1164 if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
1165 png_sizeof(png_sPLT_entry)))
1167 png_warning(png_ptr, "sPLT chunk too long");
1170 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1171 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1172 if (new_palette.entries == NULL)
1174 png_warning(png_ptr, "sPLT chunk requires too much memory");
1178 #ifndef PNG_NO_POINTER_INDEXING
1179 for (i = 0; i < new_palette.nentries; i++)
1181 png_sPLT_entryp pp = new_palette.entries + i;
1183 if (new_palette.depth == 8)
1185 pp->red = *entry_start++;
1186 pp->green = *entry_start++;
1187 pp->blue = *entry_start++;
1188 pp->alpha = *entry_start++;
1192 pp->red = png_get_uint_16(entry_start); entry_start += 2;
1193 pp->green = png_get_uint_16(entry_start); entry_start += 2;
1194 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1195 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1197 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1200 pp = new_palette.entries;
1201 for (i = 0; i < new_palette.nentries; i++)
1204 if (new_palette.depth == 8)
1206 pp[i].red = *entry_start++;
1207 pp[i].green = *entry_start++;
1208 pp[i].blue = *entry_start++;
1209 pp[i].alpha = *entry_start++;
1213 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1214 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1215 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1216 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1218 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1222 /* discard all chunk data except the name and stash that */
1223 new_palette.name = (png_charp)chunkdata;
1225 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1227 png_free(png_ptr, chunkdata);
1228 png_free(png_ptr, new_palette.entries);
1230 #endif /* PNG_READ_sPLT_SUPPORTED */
1232 #if defined(PNG_READ_tRNS_SUPPORTED)
1234 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1236 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1238 png_debug(1, "in png_handle_tRNS\n");
1240 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1241 png_error(png_ptr, "Missing IHDR before tRNS");
1242 else if (png_ptr->mode & PNG_HAVE_IDAT)
1244 png_warning(png_ptr, "Invalid tRNS after IDAT");
1245 png_crc_finish(png_ptr, length);
1248 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1250 png_warning(png_ptr, "Duplicate tRNS chunk");
1251 png_crc_finish(png_ptr, length);
1255 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1261 png_warning(png_ptr, "Incorrect tRNS chunk length");
1262 png_crc_finish(png_ptr, length);
1266 png_crc_read(png_ptr, buf, 2);
1267 png_ptr->num_trans = 1;
1268 png_ptr->trans_values.gray = png_get_uint_16(buf);
1270 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1276 png_warning(png_ptr, "Incorrect tRNS chunk length");
1277 png_crc_finish(png_ptr, length);
1280 png_crc_read(png_ptr, buf, (png_size_t)length);
1281 png_ptr->num_trans = 1;
1282 png_ptr->trans_values.red = png_get_uint_16(buf);
1283 png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1284 png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1286 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1288 if (!(png_ptr->mode & PNG_HAVE_PLTE))
1290 /* Should be an error, but we can cope with it. */
1291 png_warning(png_ptr, "Missing PLTE before tRNS");
1293 if (length > (png_uint_32)png_ptr->num_palette ||
1294 length > PNG_MAX_PALETTE_LENGTH)
1296 png_warning(png_ptr, "Incorrect tRNS chunk length");
1297 png_crc_finish(png_ptr, length);
1302 png_warning(png_ptr, "Zero length tRNS chunk");
1303 png_crc_finish(png_ptr, length);
1306 png_crc_read(png_ptr, readbuf, (png_size_t)length);
1307 png_ptr->num_trans = (png_uint_16)length;
1311 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1312 png_crc_finish(png_ptr, length);
1316 if (png_crc_finish(png_ptr, 0))
1319 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1320 &(png_ptr->trans_values));
1324 #if defined(PNG_READ_bKGD_SUPPORTED)
1326 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1331 png_debug(1, "in png_handle_bKGD\n");
1333 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1334 png_error(png_ptr, "Missing IHDR before bKGD");
1335 else if (png_ptr->mode & PNG_HAVE_IDAT)
1337 png_warning(png_ptr, "Invalid bKGD after IDAT");
1338 png_crc_finish(png_ptr, length);
1341 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1342 !(png_ptr->mode & PNG_HAVE_PLTE))
1344 png_warning(png_ptr, "Missing PLTE before bKGD");
1345 png_crc_finish(png_ptr, length);
1348 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1350 png_warning(png_ptr, "Duplicate bKGD chunk");
1351 png_crc_finish(png_ptr, length);
1355 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1357 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1362 if (length != truelen)
1364 png_warning(png_ptr, "Incorrect bKGD chunk length");
1365 png_crc_finish(png_ptr, length);
1369 png_crc_read(png_ptr, buf, truelen);
1370 if (png_crc_finish(png_ptr, 0))
1373 /* We convert the index value into RGB components so that we can allow
1374 * arbitrary RGB values for background when we have transparency, and
1375 * so it is easy to determine the RGB values of the background color
1376 * from the info_ptr struct. */
1377 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1379 png_ptr->background.index = buf[0];
1380 if(info_ptr->num_palette)
1382 if(buf[0] > info_ptr->num_palette)
1384 png_warning(png_ptr, "Incorrect bKGD chunk index value");
1387 png_ptr->background.red =
1388 (png_uint_16)png_ptr->palette[buf[0]].red;
1389 png_ptr->background.green =
1390 (png_uint_16)png_ptr->palette[buf[0]].green;
1391 png_ptr->background.blue =
1392 (png_uint_16)png_ptr->palette[buf[0]].blue;
1395 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1397 png_ptr->background.red =
1398 png_ptr->background.green =
1399 png_ptr->background.blue =
1400 png_ptr->background.gray = png_get_uint_16(buf);
1404 png_ptr->background.red = png_get_uint_16(buf);
1405 png_ptr->background.green = png_get_uint_16(buf + 2);
1406 png_ptr->background.blue = png_get_uint_16(buf + 4);
1409 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1413 #if defined(PNG_READ_hIST_SUPPORTED)
1415 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1417 unsigned int num, i;
1418 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1420 png_debug(1, "in png_handle_hIST\n");
1422 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1423 png_error(png_ptr, "Missing IHDR before hIST");
1424 else if (png_ptr->mode & PNG_HAVE_IDAT)
1426 png_warning(png_ptr, "Invalid hIST after IDAT");
1427 png_crc_finish(png_ptr, length);
1430 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1432 png_warning(png_ptr, "Missing PLTE before hIST");
1433 png_crc_finish(png_ptr, length);
1436 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1438 png_warning(png_ptr, "Duplicate hIST chunk");
1439 png_crc_finish(png_ptr, length);
1444 if (num != (unsigned int) png_ptr->num_palette || num >
1445 (unsigned int) PNG_MAX_PALETTE_LENGTH)
1447 png_warning(png_ptr, "Incorrect hIST chunk length");
1448 png_crc_finish(png_ptr, length);
1452 for (i = 0; i < num; i++)
1456 png_crc_read(png_ptr, buf, 2);
1457 readbuf[i] = png_get_uint_16(buf);
1460 if (png_crc_finish(png_ptr, 0))
1463 png_set_hIST(png_ptr, info_ptr, readbuf);
1467 #if defined(PNG_READ_pHYs_SUPPORTED)
1469 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1472 png_uint_32 res_x, res_y;
1475 png_debug(1, "in png_handle_pHYs\n");
1477 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1478 png_error(png_ptr, "Missing IHDR before pHYs");
1479 else if (png_ptr->mode & PNG_HAVE_IDAT)
1481 png_warning(png_ptr, "Invalid pHYs after IDAT");
1482 png_crc_finish(png_ptr, length);
1485 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1487 png_warning(png_ptr, "Duplicate pHYs chunk");
1488 png_crc_finish(png_ptr, length);
1494 png_warning(png_ptr, "Incorrect pHYs chunk length");
1495 png_crc_finish(png_ptr, length);
1499 png_crc_read(png_ptr, buf, 9);
1500 if (png_crc_finish(png_ptr, 0))
1503 res_x = png_get_uint_32(buf);
1504 res_y = png_get_uint_32(buf + 4);
1506 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1510 #if defined(PNG_READ_oFFs_SUPPORTED)
1512 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1515 png_int_32 offset_x, offset_y;
1518 png_debug(1, "in png_handle_oFFs\n");
1520 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1521 png_error(png_ptr, "Missing IHDR before oFFs");
1522 else if (png_ptr->mode & PNG_HAVE_IDAT)
1524 png_warning(png_ptr, "Invalid oFFs after IDAT");
1525 png_crc_finish(png_ptr, length);
1528 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1530 png_warning(png_ptr, "Duplicate oFFs chunk");
1531 png_crc_finish(png_ptr, length);
1537 png_warning(png_ptr, "Incorrect oFFs chunk length");
1538 png_crc_finish(png_ptr, length);
1542 png_crc_read(png_ptr, buf, 9);
1543 if (png_crc_finish(png_ptr, 0))
1546 offset_x = png_get_int_32(buf);
1547 offset_y = png_get_int_32(buf + 4);
1549 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1553 #if defined(PNG_READ_pCAL_SUPPORTED)
1554 /* read the pCAL chunk (described in the PNG Extensions document) */
1556 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1560 png_byte type, nparams;
1561 png_charp buf, units, endptr;
1566 png_debug(1, "in png_handle_pCAL\n");
1568 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1569 png_error(png_ptr, "Missing IHDR before pCAL");
1570 else if (png_ptr->mode & PNG_HAVE_IDAT)
1572 png_warning(png_ptr, "Invalid pCAL after IDAT");
1573 png_crc_finish(png_ptr, length);
1576 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1578 png_warning(png_ptr, "Duplicate pCAL chunk");
1579 png_crc_finish(png_ptr, length);
1583 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1585 purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
1586 if (purpose == NULL)
1588 png_warning(png_ptr, "No memory for pCAL purpose.");
1591 slength = (png_size_t)length;
1592 png_crc_read(png_ptr, (png_bytep)purpose, slength);
1594 if (png_crc_finish(png_ptr, 0))
1596 png_free(png_ptr, purpose);
1600 purpose[slength] = 0x00; /* null terminate the last string */
1602 png_debug(3, "Finding end of pCAL purpose string\n");
1603 for (buf = purpose; *buf; buf++)
1606 endptr = purpose + slength;
1608 /* We need to have at least 12 bytes after the purpose string
1609 in order to get the parameter information. */
1610 if (endptr <= buf + 12)
1612 png_warning(png_ptr, "Invalid pCAL data");
1613 png_free(png_ptr, purpose);
1617 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1618 X0 = png_get_int_32((png_bytep)buf+1);
1619 X1 = png_get_int_32((png_bytep)buf+5);
1624 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1625 /* Check that we have the right number of parameters for known
1627 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1628 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1629 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1630 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1632 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1633 png_free(png_ptr, purpose);
1636 else if (type >= PNG_EQUATION_LAST)
1638 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1641 for (buf = units; *buf; buf++)
1642 /* Empty loop to move past the units string. */ ;
1644 png_debug(3, "Allocating pCAL parameters array\n");
1645 params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
1646 *png_sizeof(png_charp))) ;
1649 png_free(png_ptr, purpose);
1650 png_warning(png_ptr, "No memory for pCAL params.");
1654 /* Get pointers to the start of each parameter string. */
1655 for (i = 0; i < (int)nparams; i++)
1657 buf++; /* Skip the null string terminator from previous parameter. */
1659 png_debug1(3, "Reading pCAL parameter %d\n", i);
1660 for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
1661 /* Empty loop to move past each parameter string */ ;
1663 /* Make sure we haven't run out of data yet */
1666 png_warning(png_ptr, "Invalid pCAL data");
1667 png_free(png_ptr, purpose);
1668 png_free(png_ptr, params);
1673 png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1676 png_free(png_ptr, purpose);
1677 png_free(png_ptr, params);
1681 #if defined(PNG_READ_sCAL_SUPPORTED)
1682 /* read the sCAL chunk */
1684 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1686 png_charp buffer, ep;
1687 #ifdef PNG_FLOATING_POINT_SUPPORTED
1688 double width, height;
1691 #ifdef PNG_FIXED_POINT_SUPPORTED
1692 png_charp swidth, sheight;
1697 png_debug(1, "in png_handle_sCAL\n");
1699 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1700 png_error(png_ptr, "Missing IHDR before sCAL");
1701 else if (png_ptr->mode & PNG_HAVE_IDAT)
1703 png_warning(png_ptr, "Invalid sCAL after IDAT");
1704 png_crc_finish(png_ptr, length);
1707 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1709 png_warning(png_ptr, "Duplicate sCAL chunk");
1710 png_crc_finish(png_ptr, length);
1714 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1716 buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
1719 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1722 slength = (png_size_t)length;
1723 png_crc_read(png_ptr, (png_bytep)buffer, slength);
1725 if (png_crc_finish(png_ptr, 0))
1727 png_free(png_ptr, buffer);
1731 buffer[slength] = 0x00; /* null terminate the last string */
1733 ep = buffer + 1; /* skip unit byte */
1735 #ifdef PNG_FLOATING_POINT_SUPPORTED
1736 width = strtod(ep, &vp);
1739 png_warning(png_ptr, "malformed width string in sCAL chunk");
1743 #ifdef PNG_FIXED_POINT_SUPPORTED
1744 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1747 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1750 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1754 for (ep = buffer; *ep; ep++)
1758 #ifdef PNG_FLOATING_POINT_SUPPORTED
1759 height = strtod(ep, &vp);
1762 png_warning(png_ptr, "malformed height string in sCAL chunk");
1766 #ifdef PNG_FIXED_POINT_SUPPORTED
1767 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1770 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1773 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1777 if (buffer + slength < ep
1778 #ifdef PNG_FLOATING_POINT_SUPPORTED
1779 || width <= 0. || height <= 0.
1783 png_warning(png_ptr, "Invalid sCAL data");
1784 png_free(png_ptr, buffer);
1785 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1786 png_free(png_ptr, swidth);
1787 png_free(png_ptr, sheight);
1793 #ifdef PNG_FLOATING_POINT_SUPPORTED
1794 png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
1796 #ifdef PNG_FIXED_POINT_SUPPORTED
1797 png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
1801 png_free(png_ptr, buffer);
1802 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1803 png_free(png_ptr, swidth);
1804 png_free(png_ptr, sheight);
1809 #if defined(PNG_READ_tIME_SUPPORTED)
1811 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1816 png_debug(1, "in png_handle_tIME\n");
1818 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1819 png_error(png_ptr, "Out of place tIME chunk");
1820 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1822 png_warning(png_ptr, "Duplicate tIME chunk");
1823 png_crc_finish(png_ptr, length);
1827 if (png_ptr->mode & PNG_HAVE_IDAT)
1828 png_ptr->mode |= PNG_AFTER_IDAT;
1832 png_warning(png_ptr, "Incorrect tIME chunk length");
1833 png_crc_finish(png_ptr, length);
1837 png_crc_read(png_ptr, buf, 7);
1838 if (png_crc_finish(png_ptr, 0))
1841 mod_time.second = buf[6];
1842 mod_time.minute = buf[5];
1843 mod_time.hour = buf[4];
1844 mod_time.day = buf[3];
1845 mod_time.month = buf[2];
1846 mod_time.year = png_get_uint_16(buf);
1848 png_set_tIME(png_ptr, info_ptr, &mod_time);
1852 #if defined(PNG_READ_tEXt_SUPPORTED)
1853 /* Note: this does not properly handle chunks that are > 64K under DOS */
1855 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1860 png_uint_32 skip = 0;
1864 png_debug(1, "in png_handle_tEXt\n");
1866 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1867 png_error(png_ptr, "Missing IHDR before tEXt");
1869 if (png_ptr->mode & PNG_HAVE_IDAT)
1870 png_ptr->mode |= PNG_AFTER_IDAT;
1872 #ifdef PNG_MAX_MALLOC_64K
1873 if (length > (png_uint_32)65535L)
1875 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1876 skip = length - (png_uint_32)65535L;
1877 length = (png_uint_32)65535L;
1881 key = (png_charp)png_malloc_warn(png_ptr, length + 1);
1884 png_warning(png_ptr, "No memory to process text chunk.");
1887 slength = (png_size_t)length;
1888 png_crc_read(png_ptr, (png_bytep)key, slength);
1890 if (png_crc_finish(png_ptr, skip))
1892 png_free(png_ptr, key);
1896 key[slength] = 0x00;
1898 for (text = key; *text; text++)
1899 /* empty loop to find end of key */ ;
1901 if (text != key + slength)
1904 text_ptr = (png_textp)png_malloc_warn(png_ptr,
1905 (png_uint_32)png_sizeof(png_text));
1906 if (text_ptr == NULL)
1908 png_warning(png_ptr, "Not enough memory to process text chunk.");
1909 png_free(png_ptr, key);
1912 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1913 text_ptr->key = key;
1914 #ifdef PNG_iTXt_SUPPORTED
1915 text_ptr->lang = NULL;
1916 text_ptr->lang_key = NULL;
1917 text_ptr->itxt_length = 0;
1919 text_ptr->text = text;
1920 text_ptr->text_length = png_strlen(text);
1922 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1924 png_free(png_ptr, key);
1925 png_free(png_ptr, text_ptr);
1927 png_warning(png_ptr, "Insufficient memory to process text chunk.");
1931 #if defined(PNG_READ_zTXt_SUPPORTED)
1932 /* note: this does not correctly handle chunks that are > 64K under DOS */
1934 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1937 png_charp chunkdata;
1941 png_size_t slength, prefix_len, data_len;
1943 png_debug(1, "in png_handle_zTXt\n");
1944 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1945 png_error(png_ptr, "Missing IHDR before zTXt");
1947 if (png_ptr->mode & PNG_HAVE_IDAT)
1948 png_ptr->mode |= PNG_AFTER_IDAT;
1950 #ifdef PNG_MAX_MALLOC_64K
1951 /* We will no doubt have problems with chunks even half this size, but
1952 there is no hard and fast rule to tell us where to stop. */
1953 if (length > (png_uint_32)65535L)
1955 png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1956 png_crc_finish(png_ptr, length);
1961 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1962 if (chunkdata == NULL)
1964 png_warning(png_ptr,"Out of memory processing zTXt chunk.");
1967 slength = (png_size_t)length;
1968 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1969 if (png_crc_finish(png_ptr, 0))
1971 png_free(png_ptr, chunkdata);
1975 chunkdata[slength] = 0x00;
1977 for (text = chunkdata; *text; text++)
1980 /* zTXt must have some text after the chunkdataword */
1981 if (text == chunkdata + slength)
1983 comp_type = PNG_TEXT_COMPRESSION_NONE;
1984 png_warning(png_ptr, "Zero length zTXt chunk");
1988 comp_type = *(++text);
1989 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
1991 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
1992 comp_type = PNG_TEXT_COMPRESSION_zTXt;
1994 text++; /* skip the compression_method byte */
1996 prefix_len = text - chunkdata;
1998 chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
1999 (png_size_t)length, prefix_len, &data_len);
2001 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2002 (png_uint_32)png_sizeof(png_text));
2003 if (text_ptr == NULL)
2005 png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
2006 png_free(png_ptr, chunkdata);
2009 text_ptr->compression = comp_type;
2010 text_ptr->key = chunkdata;
2011 #ifdef PNG_iTXt_SUPPORTED
2012 text_ptr->lang = NULL;
2013 text_ptr->lang_key = NULL;
2014 text_ptr->itxt_length = 0;
2016 text_ptr->text = chunkdata + prefix_len;
2017 text_ptr->text_length = data_len;
2019 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2021 png_free(png_ptr, text_ptr);
2022 png_free(png_ptr, chunkdata);
2024 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2028 #if defined(PNG_READ_iTXt_SUPPORTED)
2029 /* note: this does not correctly handle chunks that are > 64K under DOS */
2031 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2034 png_charp chunkdata;
2035 png_charp key, lang, text, lang_key;
2039 png_size_t slength, prefix_len, data_len;
2041 png_debug(1, "in png_handle_iTXt\n");
2043 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2044 png_error(png_ptr, "Missing IHDR before iTXt");
2046 if (png_ptr->mode & PNG_HAVE_IDAT)
2047 png_ptr->mode |= PNG_AFTER_IDAT;
2049 #ifdef PNG_MAX_MALLOC_64K
2050 /* We will no doubt have problems with chunks even half this size, but
2051 there is no hard and fast rule to tell us where to stop. */
2052 if (length > (png_uint_32)65535L)
2054 png_warning(png_ptr,"iTXt chunk too large to fit in memory");
2055 png_crc_finish(png_ptr, length);
2060 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2061 if (chunkdata == NULL)
2063 png_warning(png_ptr, "No memory to process iTXt chunk.");
2066 slength = (png_size_t)length;
2067 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
2068 if (png_crc_finish(png_ptr, 0))
2070 png_free(png_ptr, chunkdata);
2074 chunkdata[slength] = 0x00;
2076 for (lang = chunkdata; *lang; lang++)
2078 lang++; /* skip NUL separator */
2080 /* iTXt must have a language tag (possibly empty), two compression bytes,
2081 translated keyword (possibly empty), and possibly some text after the
2084 if (lang >= chunkdata + slength)
2086 comp_flag = PNG_TEXT_COMPRESSION_NONE;
2087 png_warning(png_ptr, "Zero length iTXt chunk");
2091 comp_flag = *lang++;
2092 comp_type = *lang++;
2095 for (lang_key = lang; *lang_key; lang_key++)
2097 lang_key++; /* skip NUL separator */
2099 for (text = lang_key; *text; text++)
2101 text++; /* skip NUL separator */
2103 prefix_len = text - chunkdata;
2107 chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
2108 (size_t)length, prefix_len, &data_len);
2110 data_len=png_strlen(chunkdata + prefix_len);
2111 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2112 (png_uint_32)png_sizeof(png_text));
2113 if (text_ptr == NULL)
2115 png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
2116 png_free(png_ptr, chunkdata);
2119 text_ptr->compression = (int)comp_flag + 1;
2120 text_ptr->lang_key = chunkdata+(lang_key-key);
2121 text_ptr->lang = chunkdata+(lang-key);
2122 text_ptr->itxt_length = data_len;
2123 text_ptr->text_length = 0;
2124 text_ptr->key = chunkdata;
2125 text_ptr->text = chunkdata + prefix_len;
2127 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2129 png_free(png_ptr, text_ptr);
2130 png_free(png_ptr, chunkdata);
2132 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2136 /* This function is called when we haven't found a handler for a
2137 chunk. If there isn't a problem with the chunk itself (ie bad
2138 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2139 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2140 case it will be saved away to be written out later. */
2142 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2144 png_uint_32 skip = 0;
2146 png_debug(1, "in png_handle_unknown\n");
2148 if (png_ptr->mode & PNG_HAVE_IDAT)
2150 #ifdef PNG_USE_LOCAL_ARRAYS
2153 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
2154 png_ptr->mode |= PNG_AFTER_IDAT;
2157 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
2159 if (!(png_ptr->chunk_name[0] & 0x20))
2161 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2162 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2163 PNG_HANDLE_CHUNK_ALWAYS
2164 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2165 && png_ptr->read_user_chunk_fn == NULL
2169 png_chunk_error(png_ptr, "unknown critical chunk");
2172 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2173 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2175 png_unknown_chunk chunk;
2177 #ifdef PNG_MAX_MALLOC_64K
2178 if (length > (png_uint_32)65535L)
2180 png_warning(png_ptr, "unknown chunk too large to fit in memory");
2181 skip = length - (png_uint_32)65535L;
2182 length = (png_uint_32)65535L;
2185 png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
2186 chunk.data = (png_bytep)png_malloc(png_ptr, length);
2187 chunk.size = (png_size_t)length;
2188 png_crc_read(png_ptr, (png_bytep)chunk.data, length);
2189 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2190 if(png_ptr->read_user_chunk_fn != NULL)
2192 /* callback to user unknown chunk handler */
2193 if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
2195 if (!(png_ptr->chunk_name[0] & 0x20))
2196 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2197 PNG_HANDLE_CHUNK_ALWAYS)
2199 png_free(png_ptr, chunk.data);
2200 png_chunk_error(png_ptr, "unknown critical chunk");
2202 png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2207 png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2208 png_free(png_ptr, chunk.data);
2214 png_crc_finish(png_ptr, skip);
2216 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2217 if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
2222 /* This function is called to verify that a chunk name is valid.
2223 This function can't have the "critical chunk check" incorporated
2224 into it, since in the future we will need to be able to call user
2225 functions to handle unknown critical chunks after we check that
2226 the chunk name itself is valid. */
2228 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2231 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2233 png_debug(1, "in png_check_chunk_name\n");
2234 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2235 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2237 png_chunk_error(png_ptr, "invalid chunk type");
2241 /* Combines the row recently read in with the existing pixels in the
2242 row. This routine takes care of alpha and transparency if requested.
2243 This routine also handles the two methods of progressive display
2244 of interlaced images, depending on the mask value.
2245 The mask value describes which pixels are to be combined with
2246 the row. The pattern always repeats every 8 pixels, so just 8
2247 bits are needed. A one indicates the pixel is to be combined,
2248 a zero indicates the pixel is to be skipped. This is in addition
2249 to any alpha or transparency value associated with the pixel. If
2250 you want all pixels to be combined, pass 0xff (255) in mask. */
2251 #ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
2253 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2255 png_debug(1,"in png_combine_row\n");
2258 png_memcpy(row, png_ptr->row_buf + 1,
2259 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2263 switch (png_ptr->row_info.pixel_depth)
2267 png_bytep sp = png_ptr->row_buf + 1;
2269 int s_inc, s_start, s_end;
2273 png_uint_32 row_width = png_ptr->width;
2275 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2276 if (png_ptr->transformations & PNG_PACKSWAP)
2292 for (i = 0; i < row_width; i++)
2298 value = (*sp >> shift) & 0x01;
2299 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2300 *dp |= (png_byte)(value << shift);
2321 png_bytep sp = png_ptr->row_buf + 1;
2323 int s_start, s_end, s_inc;
2327 png_uint_32 row_width = png_ptr->width;
2330 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2331 if (png_ptr->transformations & PNG_PACKSWAP)
2347 for (i = 0; i < row_width; i++)
2351 value = (*sp >> shift) & 0x03;
2352 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2353 *dp |= (png_byte)(value << shift);
2373 png_bytep sp = png_ptr->row_buf + 1;
2375 int s_start, s_end, s_inc;
2379 png_uint_32 row_width = png_ptr->width;
2382 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2383 if (png_ptr->transformations & PNG_PACKSWAP)
2398 for (i = 0; i < row_width; i++)
2402 value = (*sp >> shift) & 0xf;
2403 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2404 *dp |= (png_byte)(value << shift);
2424 png_bytep sp = png_ptr->row_buf + 1;
2426 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2428 png_uint_32 row_width = png_ptr->width;
2432 for (i = 0; i < row_width; i++)
2436 png_memcpy(dp, sp, pixel_bytes);
2452 #endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
2454 #ifdef PNG_READ_INTERLACING_SUPPORTED
2455 #ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
2456 /* OLD pre-1.0.9 interface:
2457 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2458 png_uint_32 transformations)
2461 png_do_read_interlace(png_structp png_ptr)
2463 png_row_infop row_info = &(png_ptr->row_info);
2464 png_bytep row = png_ptr->row_buf + 1;
2465 int pass = png_ptr->pass;
2466 png_uint_32 transformations = png_ptr->transformations;
2467 #ifdef PNG_USE_LOCAL_ARRAYS
2468 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2469 /* offset to next interlace block */
2470 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2473 png_debug(1,"in png_do_read_interlace (stock C version)\n");
2474 if (row != NULL && row_info != NULL)
2476 png_uint_32 final_width;
2478 final_width = row_info->width * png_pass_inc[pass];
2480 switch (row_info->pixel_depth)
2484 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2485 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2487 int s_start, s_end, s_inc;
2488 int jstop = png_pass_inc[pass];
2493 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2494 if (transformations & PNG_PACKSWAP)
2496 sshift = (int)((row_info->width + 7) & 0x07);
2497 dshift = (int)((final_width + 7) & 0x07);
2505 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2506 dshift = 7 - (int)((final_width + 7) & 0x07);
2512 for (i = 0; i < row_info->width; i++)
2514 v = (png_byte)((*sp >> sshift) & 0x01);
2515 for (j = 0; j < jstop; j++)
2517 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2518 *dp |= (png_byte)(v << dshift);
2519 if (dshift == s_end)
2527 if (sshift == s_end)
2539 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2540 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2542 int s_start, s_end, s_inc;
2543 int jstop = png_pass_inc[pass];
2546 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2547 if (transformations & PNG_PACKSWAP)
2549 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2550 dshift = (int)(((final_width + 3) & 0x03) << 1);
2558 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2559 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2565 for (i = 0; i < row_info->width; i++)
2570 v = (png_byte)((*sp >> sshift) & 0x03);
2571 for (j = 0; j < jstop; j++)
2573 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2574 *dp |= (png_byte)(v << dshift);
2575 if (dshift == s_end)
2583 if (sshift == s_end)
2595 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2596 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2598 int s_start, s_end, s_inc;
2600 int jstop = png_pass_inc[pass];
2602 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2603 if (transformations & PNG_PACKSWAP)
2605 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2606 dshift = (int)(((final_width + 1) & 0x01) << 2);
2614 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2615 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2621 for (i = 0; i < row_info->width; i++)
2623 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2626 for (j = 0; j < jstop; j++)
2628 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2629 *dp |= (png_byte)(v << dshift);
2630 if (dshift == s_end)
2638 if (sshift == s_end)
2650 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2651 png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
2652 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2654 int jstop = png_pass_inc[pass];
2657 for (i = 0; i < row_info->width; i++)
2662 png_memcpy(v, sp, pixel_bytes);
2663 for (j = 0; j < jstop; j++)
2665 png_memcpy(dp, v, pixel_bytes);
2673 row_info->width = final_width;
2674 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
2676 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2677 if (&transformations == NULL) /* silence compiler warning */
2681 #endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
2682 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2684 #ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
2686 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2687 png_bytep prev_row, int filter)
2689 png_debug(1, "in png_read_filter_row\n");
2690 png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
2693 case PNG_FILTER_VALUE_NONE:
2695 case PNG_FILTER_VALUE_SUB:
2698 png_uint_32 istop = row_info->rowbytes;
2699 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2700 png_bytep rp = row + bpp;
2703 for (i = bpp; i < istop; i++)
2705 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2710 case PNG_FILTER_VALUE_UP:
2713 png_uint_32 istop = row_info->rowbytes;
2715 png_bytep pp = prev_row;
2717 for (i = 0; i < istop; i++)
2719 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2724 case PNG_FILTER_VALUE_AVG:
2728 png_bytep pp = prev_row;
2730 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2731 png_uint_32 istop = row_info->rowbytes - bpp;
2733 for (i = 0; i < bpp; i++)
2735 *rp = (png_byte)(((int)(*rp) +
2736 ((int)(*pp++) / 2 )) & 0xff);
2740 for (i = 0; i < istop; i++)
2742 *rp = (png_byte)(((int)(*rp) +
2743 (int)(*pp++ + *lp++) / 2 ) & 0xff);
2748 case PNG_FILTER_VALUE_PAETH:
2752 png_bytep pp = prev_row;
2754 png_bytep cp = prev_row;
2755 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2756 png_uint_32 istop=row_info->rowbytes - bpp;
2758 for (i = 0; i < bpp; i++)
2760 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2764 for (i = 0; i < istop; i++) /* use leftover rp,pp */
2766 int a, b, c, pa, pb, pc, p;
2780 pa = p < 0 ? -p : p;
2781 pb = pc < 0 ? -pc : pc;
2782 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2786 if (pa <= pb && pa <= pc)
2794 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2796 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2802 png_warning(png_ptr, "Ignoring bad adaptive filter type");
2807 #endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
2810 png_read_finish_row(png_structp png_ptr)
2812 #ifdef PNG_USE_LOCAL_ARRAYS
2813 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2815 /* start of interlace block */
2816 const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2818 /* offset to next interlace block */
2819 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2821 /* start of interlace block in the y direction */
2822 const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2824 /* offset to next interlace block in the y direction */
2825 const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2828 png_debug(1, "in png_read_finish_row\n");
2829 png_ptr->row_number++;
2830 if (png_ptr->row_number < png_ptr->num_rows)
2833 if (png_ptr->interlaced)
2835 png_ptr->row_number = 0;
2836 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2840 if (png_ptr->pass >= 7)
2842 png_ptr->iwidth = (png_ptr->width +
2843 png_pass_inc[png_ptr->pass] - 1 -
2844 png_pass_start[png_ptr->pass]) /
2845 png_pass_inc[png_ptr->pass];
2847 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
2848 png_ptr->iwidth) + 1;
2850 if (!(png_ptr->transformations & PNG_INTERLACE))
2852 png_ptr->num_rows = (png_ptr->height +
2853 png_pass_yinc[png_ptr->pass] - 1 -
2854 png_pass_ystart[png_ptr->pass]) /
2855 png_pass_yinc[png_ptr->pass];
2856 if (!(png_ptr->num_rows))
2859 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2861 } while (png_ptr->iwidth == 0);
2863 if (png_ptr->pass < 7)
2867 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2869 #ifdef PNG_USE_LOCAL_ARRAYS
2875 png_ptr->zstream.next_out = (Byte *)&extra;
2876 png_ptr->zstream.avail_out = (uInt)1;
2879 if (!(png_ptr->zstream.avail_in))
2881 while (!png_ptr->idat_size)
2883 png_byte chunk_length[4];
2885 png_crc_finish(png_ptr, 0);
2887 png_read_data(png_ptr, chunk_length, 4);
2888 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
2889 png_reset_crc(png_ptr);
2890 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
2891 if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
2892 png_error(png_ptr, "Not enough image data");
2895 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
2896 png_ptr->zstream.next_in = png_ptr->zbuf;
2897 if (png_ptr->zbuf_size > png_ptr->idat_size)
2898 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
2899 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
2900 png_ptr->idat_size -= png_ptr->zstream.avail_in;
2902 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2903 if (ret == Z_STREAM_END)
2905 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2907 png_warning(png_ptr, "Extra compressed data");
2908 png_ptr->mode |= PNG_AFTER_IDAT;
2909 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2913 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2914 "Decompression Error");
2916 if (!(png_ptr->zstream.avail_out))
2918 png_warning(png_ptr, "Extra compressed data.");
2919 png_ptr->mode |= PNG_AFTER_IDAT;
2920 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2925 png_ptr->zstream.avail_out = 0;
2928 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2929 png_warning(png_ptr, "Extra compression data");
2931 inflateReset(&png_ptr->zstream);
2933 png_ptr->mode |= PNG_AFTER_IDAT;
2937 png_read_start_row(png_structp png_ptr)
2939 #ifdef PNG_USE_LOCAL_ARRAYS
2940 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2942 /* start of interlace block */
2943 const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2945 /* offset to next interlace block */
2946 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2948 /* start of interlace block in the y direction */
2949 const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2951 /* offset to next interlace block in the y direction */
2952 const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2955 int max_pixel_depth;
2956 png_uint_32 row_bytes;
2958 png_debug(1, "in png_read_start_row\n");
2959 png_ptr->zstream.avail_in = 0;
2960 png_init_read_transformations(png_ptr);
2961 if (png_ptr->interlaced)
2963 if (!(png_ptr->transformations & PNG_INTERLACE))
2964 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2965 png_pass_ystart[0]) / png_pass_yinc[0];
2967 png_ptr->num_rows = png_ptr->height;
2969 png_ptr->iwidth = (png_ptr->width +
2970 png_pass_inc[png_ptr->pass] - 1 -
2971 png_pass_start[png_ptr->pass]) /
2972 png_pass_inc[png_ptr->pass];
2974 row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
2976 png_ptr->irowbytes = (png_size_t)row_bytes;
2977 if((png_uint_32)png_ptr->irowbytes != row_bytes)
2978 png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
2982 png_ptr->num_rows = png_ptr->height;
2983 png_ptr->iwidth = png_ptr->width;
2984 png_ptr->irowbytes = png_ptr->rowbytes + 1;
2986 max_pixel_depth = png_ptr->pixel_depth;
2988 #if defined(PNG_READ_PACK_SUPPORTED)
2989 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
2990 max_pixel_depth = 8;
2993 #if defined(PNG_READ_EXPAND_SUPPORTED)
2994 if (png_ptr->transformations & PNG_EXPAND)
2996 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2998 if (png_ptr->num_trans)
2999 max_pixel_depth = 32;
3001 max_pixel_depth = 24;
3003 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3005 if (max_pixel_depth < 8)
3006 max_pixel_depth = 8;
3007 if (png_ptr->num_trans)
3008 max_pixel_depth *= 2;
3010 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3012 if (png_ptr->num_trans)
3014 max_pixel_depth *= 4;
3015 max_pixel_depth /= 3;
3021 #if defined(PNG_READ_FILLER_SUPPORTED)
3022 if (png_ptr->transformations & (PNG_FILLER))
3024 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3025 max_pixel_depth = 32;
3026 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3028 if (max_pixel_depth <= 8)
3029 max_pixel_depth = 16;
3031 max_pixel_depth = 32;
3033 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3035 if (max_pixel_depth <= 32)
3036 max_pixel_depth = 32;
3038 max_pixel_depth = 64;
3043 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3044 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3047 #if defined(PNG_READ_EXPAND_SUPPORTED)
3048 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3050 #if defined(PNG_READ_FILLER_SUPPORTED)
3051 (png_ptr->transformations & (PNG_FILLER)) ||
3053 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3055 if (max_pixel_depth <= 16)
3056 max_pixel_depth = 32;
3058 max_pixel_depth = 64;
3062 if (max_pixel_depth <= 8)
3064 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3065 max_pixel_depth = 32;
3067 max_pixel_depth = 24;
3069 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3070 max_pixel_depth = 64;
3072 max_pixel_depth = 48;
3077 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3078 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3079 if(png_ptr->transformations & PNG_USER_TRANSFORM)
3081 int user_pixel_depth=png_ptr->user_transform_depth*
3082 png_ptr->user_transform_channels;
3083 if(user_pixel_depth > max_pixel_depth)
3084 max_pixel_depth=user_pixel_depth;
3088 /* align the width on the next larger 8 pixels. Mainly used
3090 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3091 /* calculate the maximum bytes needed, adding a byte and a pixel
3092 for safety's sake */
3093 row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
3094 1 + ((max_pixel_depth + 7) >> 3);
3095 #ifdef PNG_MAX_MALLOC_64K
3096 if (row_bytes > (png_uint_32)65536L)
3097 png_error(png_ptr, "This image requires a row greater than 64KB");
3099 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
3100 png_ptr->row_buf = png_ptr->big_row_buf+32;
3101 #if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
3102 png_ptr->row_buf_size = row_bytes;
3105 #ifdef PNG_MAX_MALLOC_64K
3106 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3107 png_error(png_ptr, "This image requires a row greater than 64KB");
3109 if ((png_uint_32)png_ptr->rowbytes > PNG_SIZE_MAX - 1)
3110 png_error(png_ptr, "Row has too many bytes to allocate in memory.");
3111 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3112 png_ptr->rowbytes + 1));
3114 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3116 png_debug1(3, "width = %lu,\n", png_ptr->width);
3117 png_debug1(3, "height = %lu,\n", png_ptr->height);
3118 png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
3119 png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
3120 png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
3121 png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
3123 png_ptr->flags |= PNG_FLAG_ROW_INIT;