2 /* pngrutil.c - utilities to read a PNG file
4 * libpng 1.2.5 - October 3, 2002
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2002 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(_WIN32_WCE)
18 /* strtod() function is not supported on WindowsCE */
19 # ifdef PNG_FLOATING_POINT_SUPPORTED
20 __inline double strtod(const char *nptr, char **endptr)
26 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
27 str = (wchar_t *)malloc(len * sizeof(wchar_t));
30 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
31 result = wcstod(str, &end);
32 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
33 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
41 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
42 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
43 png_uint_32 /* PRIVATE */
44 png_get_uint_32(png_bytep buf)
46 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
47 ((png_uint_32)(*(buf + 1)) << 16) +
48 ((png_uint_32)(*(buf + 2)) << 8) +
49 (png_uint_32)(*(buf + 3));
54 #if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
55 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
56 * data is stored in the PNG file in two's complement format, and it is
57 * assumed that the machine format for signed integers is the same. */
58 png_int_32 /* PRIVATE */
59 png_get_int_32(png_bytep buf)
61 png_int_32 i = ((png_int_32)(*buf) << 24) +
62 ((png_int_32)(*(buf + 1)) << 16) +
63 ((png_int_32)(*(buf + 2)) << 8) +
64 (png_int_32)(*(buf + 3));
68 #endif /* PNG_READ_pCAL_SUPPORTED */
70 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
71 png_uint_16 /* PRIVATE */
72 png_get_uint_16(png_bytep buf)
74 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
75 (png_uint_16)(*(buf + 1)));
79 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
81 /* Read data, and (optionally) run it through the CRC. */
83 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
85 png_read_data(png_ptr, buf, length);
86 png_calculate_crc(png_ptr, buf, length);
89 /* Optionally skip data and then check the CRC. Depending on whether we
90 are reading a ancillary or critical chunk, and how the program has set
91 things up, we may calculate the CRC on the data and print a message.
92 Returns '1' if there was a CRC error, '0' otherwise. */
94 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
97 png_size_t istop = png_ptr->zbuf_size;
99 for (i = (png_size_t)skip; i > istop; i -= istop)
101 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
105 png_crc_read(png_ptr, png_ptr->zbuf, i);
108 if (png_crc_error(png_ptr))
110 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
111 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
112 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
113 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
115 png_chunk_warning(png_ptr, "CRC error");
119 png_chunk_error(png_ptr, "CRC error");
127 /* Compare the CRC stored in the PNG file with that calculated by libpng from
128 the data it has read thus far. */
130 png_crc_error(png_structp png_ptr)
132 png_byte crc_bytes[4];
136 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
138 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
139 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
144 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
148 png_read_data(png_ptr, crc_bytes, 4);
152 crc = png_get_uint_32(crc_bytes);
153 return ((int)(crc != png_ptr->crc));
159 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
160 defined(PNG_READ_iCCP_SUPPORTED)
162 * Decompress trailing data in a chunk. The assumption is that chunkdata
163 * points at an allocated area holding the contents of a chunk with a
164 * trailing compressed part. What we get back is an allocated area
165 * holding the original prefix part and an uncompressed version of the
166 * trailing part (the malloc area passed in is freed).
168 png_charp /* PRIVATE */
169 png_decompress_chunk(png_structp png_ptr, int comp_type,
170 png_charp chunkdata, png_size_t chunklength,
171 png_size_t prefix_size, png_size_t *newlength)
173 static char msg[] = "Error decoding compressed text";
174 png_charp text = NULL;
175 png_size_t text_size;
177 if (comp_type == PNG_COMPRESSION_TYPE_BASE)
180 png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
181 png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
182 png_ptr->zstream.next_out = png_ptr->zbuf;
183 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
188 while (png_ptr->zstream.avail_in)
190 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
191 if (ret != Z_OK && ret != Z_STREAM_END)
193 if (png_ptr->zstream.msg != NULL)
194 png_warning(png_ptr, png_ptr->zstream.msg);
196 png_warning(png_ptr, msg);
197 inflateReset(&png_ptr->zstream);
198 png_ptr->zstream.avail_in = 0;
202 text_size = prefix_size + sizeof(msg) + 1;
203 text = (png_charp)png_malloc_warn(png_ptr, text_size);
206 png_free(png_ptr,chunkdata);
207 png_error(png_ptr,"Not enough memory to decompress chunk");
209 png_memcpy(text, chunkdata, prefix_size);
212 text[text_size - 1] = 0x00;
214 /* Copy what we can of the error message into the text chunk */
215 text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
216 text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
217 png_memcpy(text + prefix_size, msg, text_size + 1);
220 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
224 text_size = prefix_size +
225 png_ptr->zbuf_size - png_ptr->zstream.avail_out;
226 text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
229 png_free(png_ptr,chunkdata);
230 png_error(png_ptr,"Not enough memory to decompress chunk.");
232 png_memcpy(text + prefix_size, png_ptr->zbuf,
233 text_size - prefix_size);
234 png_memcpy(text, chunkdata, prefix_size);
235 *(text + text_size) = 0x00;
242 text = (png_charp)png_malloc_warn(png_ptr,
243 (png_uint_32)(text_size +
244 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
247 png_free(png_ptr, tmp);
248 png_free(png_ptr, chunkdata);
249 png_error(png_ptr,"Not enough memory to decompress chunk..");
251 png_memcpy(text, tmp, text_size);
252 png_free(png_ptr, tmp);
253 png_memcpy(text + text_size, png_ptr->zbuf,
254 (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
255 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
256 *(text + text_size) = 0x00;
258 if (ret == Z_STREAM_END)
262 png_ptr->zstream.next_out = png_ptr->zbuf;
263 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
267 if (ret != Z_STREAM_END)
269 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
272 if (ret == Z_BUF_ERROR)
273 sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
274 png_ptr->chunk_name);
275 else if (ret == Z_DATA_ERROR)
276 sprintf(umsg,"Data error in compressed datastream in %s chunk",
277 png_ptr->chunk_name);
279 sprintf(umsg,"Incomplete compressed datastream in %s chunk",
280 png_ptr->chunk_name);
281 png_warning(png_ptr, umsg);
284 "Incomplete compressed datastream in chunk other than IDAT");
286 text_size=prefix_size;
289 text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
292 png_free(png_ptr, chunkdata);
293 png_error(png_ptr,"Not enough memory for text.");
295 png_memcpy(text, chunkdata, prefix_size);
297 *(text + text_size) = 0x00;
300 inflateReset(&png_ptr->zstream);
301 png_ptr->zstream.avail_in = 0;
303 png_free(png_ptr, chunkdata);
305 *newlength=text_size;
307 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
309 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
312 sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
313 png_warning(png_ptr, umsg);
315 png_warning(png_ptr, "Unknown zTXt compression type");
318 *(chunkdata + prefix_size) = 0x00;
319 *newlength=prefix_size;
326 /* read and check the IDHR chunk */
328 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
331 png_uint_32 width, height;
332 int bit_depth, color_type, compression_type, filter_type;
335 png_debug(1, "in png_handle_IHDR\n");
337 if (png_ptr->mode & PNG_HAVE_IHDR)
338 png_error(png_ptr, "Out of place IHDR");
340 /* check the length */
342 png_error(png_ptr, "Invalid IHDR chunk");
344 png_ptr->mode |= PNG_HAVE_IHDR;
346 png_crc_read(png_ptr, buf, 13);
347 png_crc_finish(png_ptr, 0);
349 width = png_get_uint_32(buf);
350 height = png_get_uint_32(buf + 4);
353 compression_type = buf[10];
354 filter_type = buf[11];
355 interlace_type = buf[12];
358 /* set internal variables */
359 png_ptr->width = width;
360 png_ptr->height = height;
361 png_ptr->bit_depth = (png_byte)bit_depth;
362 png_ptr->interlaced = (png_byte)interlace_type;
363 png_ptr->color_type = (png_byte)color_type;
364 #if defined(PNG_MNG_FEATURES_SUPPORTED)
365 png_ptr->filter_type = (png_byte)filter_type;
368 /* find number of channels */
369 switch (png_ptr->color_type)
371 case PNG_COLOR_TYPE_GRAY:
372 case PNG_COLOR_TYPE_PALETTE:
373 png_ptr->channels = 1;
375 case PNG_COLOR_TYPE_RGB:
376 png_ptr->channels = 3;
378 case PNG_COLOR_TYPE_GRAY_ALPHA:
379 png_ptr->channels = 2;
381 case PNG_COLOR_TYPE_RGB_ALPHA:
382 png_ptr->channels = 4;
386 /* set up other useful info */
387 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
389 png_ptr->rowbytes = ((png_ptr->width *
390 (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
391 png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
392 png_debug1(3,"channels = %d\n", png_ptr->channels);
393 png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
394 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
395 color_type, interlace_type, compression_type, filter_type);
398 /* read and check the palette */
400 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
402 png_color palette[PNG_MAX_PALETTE_LENGTH];
404 #ifndef PNG_NO_POINTER_INDEXING
408 png_debug(1, "in png_handle_PLTE\n");
410 if (!(png_ptr->mode & PNG_HAVE_IHDR))
411 png_error(png_ptr, "Missing IHDR before PLTE");
412 else if (png_ptr->mode & PNG_HAVE_IDAT)
414 png_warning(png_ptr, "Invalid PLTE after IDAT");
415 png_crc_finish(png_ptr, length);
418 else if (png_ptr->mode & PNG_HAVE_PLTE)
419 png_error(png_ptr, "Duplicate PLTE chunk");
421 png_ptr->mode |= PNG_HAVE_PLTE;
423 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
426 "Ignoring PLTE chunk in grayscale PNG");
427 png_crc_finish(png_ptr, length);
430 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
431 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
433 png_crc_finish(png_ptr, length);
438 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
440 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
442 png_warning(png_ptr, "Invalid palette chunk");
443 png_crc_finish(png_ptr, length);
448 png_error(png_ptr, "Invalid palette chunk");
452 num = (int)length / 3;
454 #ifndef PNG_NO_POINTER_INDEXING
455 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
459 png_crc_read(png_ptr, buf, 3);
460 pal_ptr->red = buf[0];
461 pal_ptr->green = buf[1];
462 pal_ptr->blue = buf[2];
465 for (i = 0; i < num; i++)
469 png_crc_read(png_ptr, buf, 3);
470 /* don't depend upon png_color being any order */
471 palette[i].red = buf[0];
472 palette[i].green = buf[1];
473 palette[i].blue = buf[2];
477 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
478 whatever the normal CRC configuration tells us. However, if we
479 have an RGB image, the PLTE can be considered ancillary, so
480 we will act as though it is. */
481 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
482 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
485 png_crc_finish(png_ptr, 0);
487 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
488 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
490 /* If we don't want to use the data from an ancillary chunk,
491 we have two options: an error abort, or a warning and we
492 ignore the data in this chunk (which should be OK, since
493 it's considered ancillary for a RGB or RGBA image). */
494 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
496 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
498 png_chunk_error(png_ptr, "CRC error");
502 png_chunk_warning(png_ptr, "CRC error");
506 /* Otherwise, we (optionally) emit a warning and use the chunk. */
507 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
509 png_chunk_warning(png_ptr, "CRC error");
514 png_set_PLTE(png_ptr, info_ptr, palette, num);
516 #if defined(PNG_READ_tRNS_SUPPORTED)
517 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
519 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
521 if (png_ptr->num_trans > (png_uint_16)num)
523 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
524 png_ptr->num_trans = (png_uint_16)num;
526 if (info_ptr->num_trans > (png_uint_16)num)
528 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
529 info_ptr->num_trans = (png_uint_16)num;
538 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
540 png_debug(1, "in png_handle_IEND\n");
542 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
544 png_error(png_ptr, "No image in file");
546 info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
549 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
553 png_warning(png_ptr, "Incorrect IEND chunk length");
555 png_crc_finish(png_ptr, length);
558 #if defined(PNG_READ_gAMA_SUPPORTED)
560 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
562 png_fixed_point igamma;
563 #ifdef PNG_FLOATING_POINT_SUPPORTED
568 png_debug(1, "in png_handle_gAMA\n");
570 if (!(png_ptr->mode & PNG_HAVE_IHDR))
571 png_error(png_ptr, "Missing IHDR before gAMA");
572 else if (png_ptr->mode & PNG_HAVE_IDAT)
574 png_warning(png_ptr, "Invalid gAMA after IDAT");
575 png_crc_finish(png_ptr, length);
578 else if (png_ptr->mode & PNG_HAVE_PLTE)
579 /* Should be an error, but we can cope with it */
580 png_warning(png_ptr, "Out of place gAMA chunk");
582 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
583 #if defined(PNG_READ_sRGB_SUPPORTED)
584 && !(info_ptr->valid & PNG_INFO_sRGB)
588 png_warning(png_ptr, "Duplicate gAMA chunk");
589 png_crc_finish(png_ptr, length);
595 png_warning(png_ptr, "Incorrect gAMA chunk length");
596 png_crc_finish(png_ptr, length);
600 png_crc_read(png_ptr, buf, 4);
601 if (png_crc_finish(png_ptr, 0))
604 igamma = (png_fixed_point)png_get_uint_32(buf);
605 /* check for zero gamma */
609 "Ignoring gAMA chunk with gamma=0");
613 #if defined(PNG_READ_sRGB_SUPPORTED)
614 if (info_ptr->valid & PNG_INFO_sRGB)
615 if(igamma < 45000L || igamma > 46000L)
618 "Ignoring incorrect gAMA value when sRGB is also present");
619 #ifndef PNG_NO_CONSOLE_IO
620 fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
624 #endif /* PNG_READ_sRGB_SUPPORTED */
626 #ifdef PNG_FLOATING_POINT_SUPPORTED
627 file_gamma = (float)igamma / (float)100000.0;
628 # ifdef PNG_READ_GAMMA_SUPPORTED
629 png_ptr->gamma = file_gamma;
631 png_set_gAMA(png_ptr, info_ptr, file_gamma);
633 #ifdef PNG_FIXED_POINT_SUPPORTED
634 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
639 #if defined(PNG_READ_sBIT_SUPPORTED)
641 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
646 png_debug(1, "in png_handle_sBIT\n");
648 buf[0] = buf[1] = buf[2] = buf[3] = 0;
650 if (!(png_ptr->mode & PNG_HAVE_IHDR))
651 png_error(png_ptr, "Missing IHDR before sBIT");
652 else if (png_ptr->mode & PNG_HAVE_IDAT)
654 png_warning(png_ptr, "Invalid sBIT after IDAT");
655 png_crc_finish(png_ptr, length);
658 else if (png_ptr->mode & PNG_HAVE_PLTE)
660 /* Should be an error, but we can cope with it */
661 png_warning(png_ptr, "Out of place sBIT chunk");
663 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
665 png_warning(png_ptr, "Duplicate sBIT chunk");
666 png_crc_finish(png_ptr, length);
670 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
673 truelen = (png_size_t)png_ptr->channels;
675 if (length != truelen)
677 png_warning(png_ptr, "Incorrect sBIT chunk length");
678 png_crc_finish(png_ptr, length);
682 png_crc_read(png_ptr, buf, truelen);
683 if (png_crc_finish(png_ptr, 0))
686 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
688 png_ptr->sig_bit.red = buf[0];
689 png_ptr->sig_bit.green = buf[1];
690 png_ptr->sig_bit.blue = buf[2];
691 png_ptr->sig_bit.alpha = buf[3];
695 png_ptr->sig_bit.gray = buf[0];
696 png_ptr->sig_bit.red = buf[0];
697 png_ptr->sig_bit.green = buf[0];
698 png_ptr->sig_bit.blue = buf[0];
699 png_ptr->sig_bit.alpha = buf[1];
701 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
705 #if defined(PNG_READ_cHRM_SUPPORTED)
707 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
710 #ifdef PNG_FLOATING_POINT_SUPPORTED
711 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
713 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
714 int_y_green, int_x_blue, int_y_blue;
716 png_uint_32 uint_x, uint_y;
718 png_debug(1, "in png_handle_cHRM\n");
720 if (!(png_ptr->mode & PNG_HAVE_IHDR))
721 png_error(png_ptr, "Missing IHDR before cHRM");
722 else if (png_ptr->mode & PNG_HAVE_IDAT)
724 png_warning(png_ptr, "Invalid cHRM after IDAT");
725 png_crc_finish(png_ptr, length);
728 else if (png_ptr->mode & PNG_HAVE_PLTE)
729 /* Should be an error, but we can cope with it */
730 png_warning(png_ptr, "Missing PLTE before cHRM");
732 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
733 #if defined(PNG_READ_sRGB_SUPPORTED)
734 && !(info_ptr->valid & PNG_INFO_sRGB)
738 png_warning(png_ptr, "Duplicate cHRM chunk");
739 png_crc_finish(png_ptr, length);
745 png_warning(png_ptr, "Incorrect cHRM chunk length");
746 png_crc_finish(png_ptr, length);
750 png_crc_read(png_ptr, buf, 4);
751 uint_x = png_get_uint_32(buf);
753 png_crc_read(png_ptr, buf, 4);
754 uint_y = png_get_uint_32(buf);
756 if (uint_x > 80000L || uint_y > 80000L ||
757 uint_x + uint_y > 100000L)
759 png_warning(png_ptr, "Invalid cHRM white point");
760 png_crc_finish(png_ptr, 24);
763 int_x_white = (png_fixed_point)uint_x;
764 int_y_white = (png_fixed_point)uint_y;
766 png_crc_read(png_ptr, buf, 4);
767 uint_x = png_get_uint_32(buf);
769 png_crc_read(png_ptr, buf, 4);
770 uint_y = png_get_uint_32(buf);
772 if (uint_x > 80000L || uint_y > 80000L ||
773 uint_x + uint_y > 100000L)
775 png_warning(png_ptr, "Invalid cHRM red point");
776 png_crc_finish(png_ptr, 16);
779 int_x_red = (png_fixed_point)uint_x;
780 int_y_red = (png_fixed_point)uint_y;
782 png_crc_read(png_ptr, buf, 4);
783 uint_x = png_get_uint_32(buf);
785 png_crc_read(png_ptr, buf, 4);
786 uint_y = png_get_uint_32(buf);
788 if (uint_x > 80000L || uint_y > 80000L ||
789 uint_x + uint_y > 100000L)
791 png_warning(png_ptr, "Invalid cHRM green point");
792 png_crc_finish(png_ptr, 8);
795 int_x_green = (png_fixed_point)uint_x;
796 int_y_green = (png_fixed_point)uint_y;
798 png_crc_read(png_ptr, buf, 4);
799 uint_x = png_get_uint_32(buf);
801 png_crc_read(png_ptr, buf, 4);
802 uint_y = png_get_uint_32(buf);
804 if (uint_x > 80000L || uint_y > 80000L ||
805 uint_x + uint_y > 100000L)
807 png_warning(png_ptr, "Invalid cHRM blue point");
808 png_crc_finish(png_ptr, 0);
811 int_x_blue = (png_fixed_point)uint_x;
812 int_y_blue = (png_fixed_point)uint_y;
814 #ifdef PNG_FLOATING_POINT_SUPPORTED
815 white_x = (float)int_x_white / (float)100000.0;
816 white_y = (float)int_y_white / (float)100000.0;
817 red_x = (float)int_x_red / (float)100000.0;
818 red_y = (float)int_y_red / (float)100000.0;
819 green_x = (float)int_x_green / (float)100000.0;
820 green_y = (float)int_y_green / (float)100000.0;
821 blue_x = (float)int_x_blue / (float)100000.0;
822 blue_y = (float)int_y_blue / (float)100000.0;
825 #if defined(PNG_READ_sRGB_SUPPORTED)
826 if (info_ptr->valid & PNG_INFO_sRGB)
828 if (abs(int_x_white - 31270L) > 1000 ||
829 abs(int_y_white - 32900L) > 1000 ||
830 abs(int_x_red - 64000L) > 1000 ||
831 abs(int_y_red - 33000L) > 1000 ||
832 abs(int_x_green - 30000L) > 1000 ||
833 abs(int_y_green - 60000L) > 1000 ||
834 abs(int_x_blue - 15000L) > 1000 ||
835 abs(int_y_blue - 6000L) > 1000)
839 "Ignoring incorrect cHRM value when sRGB is also present");
840 #ifndef PNG_NO_CONSOLE_IO
841 #ifdef PNG_FLOATING_POINT_SUPPORTED
842 fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
843 white_x, white_y, red_x, red_y);
844 fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
845 green_x, green_y, blue_x, blue_y);
847 fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
848 int_x_white, int_y_white, int_x_red, int_y_red);
849 fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
850 int_x_green, int_y_green, int_x_blue, int_y_blue);
852 #endif /* PNG_NO_CONSOLE_IO */
854 png_crc_finish(png_ptr, 0);
857 #endif /* PNG_READ_sRGB_SUPPORTED */
859 #ifdef PNG_FLOATING_POINT_SUPPORTED
860 png_set_cHRM(png_ptr, info_ptr,
861 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
863 #ifdef PNG_FIXED_POINT_SUPPORTED
864 png_set_cHRM_fixed(png_ptr, info_ptr,
865 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
866 int_y_green, int_x_blue, int_y_blue);
868 if (png_crc_finish(png_ptr, 0))
873 #if defined(PNG_READ_sRGB_SUPPORTED)
875 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
880 png_debug(1, "in png_handle_sRGB\n");
882 if (!(png_ptr->mode & PNG_HAVE_IHDR))
883 png_error(png_ptr, "Missing IHDR before sRGB");
884 else if (png_ptr->mode & PNG_HAVE_IDAT)
886 png_warning(png_ptr, "Invalid sRGB after IDAT");
887 png_crc_finish(png_ptr, length);
890 else if (png_ptr->mode & PNG_HAVE_PLTE)
891 /* Should be an error, but we can cope with it */
892 png_warning(png_ptr, "Out of place sRGB chunk");
894 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
896 png_warning(png_ptr, "Duplicate sRGB chunk");
897 png_crc_finish(png_ptr, length);
903 png_warning(png_ptr, "Incorrect sRGB chunk length");
904 png_crc_finish(png_ptr, length);
908 png_crc_read(png_ptr, buf, 1);
909 if (png_crc_finish(png_ptr, 0))
913 /* check for bad intent */
914 if (intent >= PNG_sRGB_INTENT_LAST)
916 png_warning(png_ptr, "Unknown sRGB intent");
920 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
921 if ((info_ptr->valid & PNG_INFO_gAMA))
924 #ifdef PNG_FIXED_POINT_SUPPORTED
925 igamma=(int)info_ptr->int_gamma;
927 # ifdef PNG_FLOATING_POINT_SUPPORTED
928 igamma=(int)(info_ptr->gamma * 100000.);
931 if(igamma < 45000L || igamma > 46000L)
934 "Ignoring incorrect gAMA value when sRGB is also present");
935 #ifndef PNG_NO_CONSOLE_IO
936 # ifdef PNG_FIXED_POINT_SUPPORTED
937 fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
939 # ifdef PNG_FLOATING_POINT_SUPPORTED
940 fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
946 #endif /* PNG_READ_gAMA_SUPPORTED */
948 #ifdef PNG_READ_cHRM_SUPPORTED
949 #ifdef PNG_FIXED_POINT_SUPPORTED
950 if (info_ptr->valid & PNG_INFO_cHRM)
951 if (abs(info_ptr->int_x_white - 31270L) > 1000 ||
952 abs(info_ptr->int_y_white - 32900L) > 1000 ||
953 abs(info_ptr->int_x_red - 64000L) > 1000 ||
954 abs(info_ptr->int_y_red - 33000L) > 1000 ||
955 abs(info_ptr->int_x_green - 30000L) > 1000 ||
956 abs(info_ptr->int_y_green - 60000L) > 1000 ||
957 abs(info_ptr->int_x_blue - 15000L) > 1000 ||
958 abs(info_ptr->int_y_blue - 6000L) > 1000)
961 "Ignoring incorrect cHRM value when sRGB is also present");
963 #endif /* PNG_FIXED_POINT_SUPPORTED */
964 #endif /* PNG_READ_cHRM_SUPPORTED */
966 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
968 #endif /* PNG_READ_sRGB_SUPPORTED */
970 #if defined(PNG_READ_iCCP_SUPPORTED)
972 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
973 /* Note: this does not properly handle chunks that are > 64K under DOS */
976 png_byte compression_type;
979 png_uint_32 skip = 0;
980 png_uint_32 profile_size = 0;
981 png_uint_32 profile_length = 0;
982 png_size_t slength, prefix_length, data_length;
984 png_debug(1, "in png_handle_iCCP\n");
986 if (!(png_ptr->mode & PNG_HAVE_IHDR))
987 png_error(png_ptr, "Missing IHDR before iCCP");
988 else if (png_ptr->mode & PNG_HAVE_IDAT)
990 png_warning(png_ptr, "Invalid iCCP after IDAT");
991 png_crc_finish(png_ptr, length);
994 else if (png_ptr->mode & PNG_HAVE_PLTE)
995 /* Should be an error, but we can cope with it */
996 png_warning(png_ptr, "Out of place iCCP chunk");
998 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1000 png_warning(png_ptr, "Duplicate iCCP chunk");
1001 png_crc_finish(png_ptr, length);
1005 #ifdef PNG_MAX_MALLOC_64K
1006 if (length > (png_uint_32)65535L)
1008 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1009 skip = length - (png_uint_32)65535L;
1010 length = (png_uint_32)65535L;
1014 chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1015 slength = (png_size_t)length;
1016 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1018 if (png_crc_finish(png_ptr, skip))
1020 png_free(png_ptr, chunkdata);
1024 chunkdata[slength] = 0x00;
1026 for (profile = chunkdata; *profile; profile++)
1027 /* empty loop to find end of name */ ;
1031 /* there should be at least one zero (the compression type byte)
1032 following the separator, and we should be on it */
1033 if ( profile >= chunkdata + slength)
1035 png_free(png_ptr, chunkdata);
1036 png_warning(png_ptr, "Malformed iCCP chunk");
1040 /* compression_type should always be zero */
1041 compression_type = *profile++;
1042 if (compression_type)
1044 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1045 compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1049 prefix_length = profile - chunkdata;
1050 chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
1051 slength, prefix_length, &data_length);
1053 profile_length = data_length - prefix_length;
1055 if ( prefix_length > data_length || profile_length < 4)
1057 png_free(png_ptr, chunkdata);
1058 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1062 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1063 pC = (png_bytep)(chunkdata+prefix_length);
1064 profile_size = ((*(pC ))<<24) |
1069 if(profile_size < profile_length)
1070 profile_length = profile_size;
1072 if(profile_size > profile_length)
1074 png_free(png_ptr, chunkdata);
1075 png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
1079 png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
1080 chunkdata + prefix_length, profile_length);
1081 png_free(png_ptr, chunkdata);
1083 #endif /* PNG_READ_iCCP_SUPPORTED */
1085 #if defined(PNG_READ_sPLT_SUPPORTED)
1087 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1088 /* Note: this does not properly handle chunks that are > 64K under DOS */
1090 png_bytep chunkdata;
1091 png_bytep entry_start;
1092 png_sPLT_t new_palette;
1093 #ifdef PNG_NO_POINTER_INDEXING
1096 int data_length, entry_size, i;
1097 png_uint_32 skip = 0;
1100 png_debug(1, "in png_handle_sPLT\n");
1102 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1103 png_error(png_ptr, "Missing IHDR before sPLT");
1104 else if (png_ptr->mode & PNG_HAVE_IDAT)
1106 png_warning(png_ptr, "Invalid sPLT after IDAT");
1107 png_crc_finish(png_ptr, length);
1111 #ifdef PNG_MAX_MALLOC_64K
1112 if (length > (png_uint_32)65535L)
1114 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1115 skip = length - (png_uint_32)65535L;
1116 length = (png_uint_32)65535L;
1120 chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
1121 slength = (png_size_t)length;
1122 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1124 if (png_crc_finish(png_ptr, skip))
1126 png_free(png_ptr, chunkdata);
1130 chunkdata[slength] = 0x00;
1132 for (entry_start = chunkdata; *entry_start; entry_start++)
1133 /* empty loop to find end of name */ ;
1136 /* a sample depth should follow the separator, and we should be on it */
1137 if (entry_start > chunkdata + slength)
1139 png_free(png_ptr, chunkdata);
1140 png_warning(png_ptr, "malformed sPLT chunk");
1144 new_palette.depth = *entry_start++;
1145 entry_size = (new_palette.depth == 8 ? 6 : 10);
1146 data_length = (slength - (entry_start - chunkdata));
1148 /* integrity-check the data length */
1149 if (data_length % entry_size)
1151 png_free(png_ptr, chunkdata);
1152 png_warning(png_ptr, "sPLT chunk has bad length");
1156 new_palette.nentries = data_length / entry_size;
1157 new_palette.entries = (png_sPLT_entryp)png_malloc(
1158 png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
1160 #ifndef PNG_NO_POINTER_INDEXING
1161 for (i = 0; i < new_palette.nentries; i++)
1163 png_sPLT_entryp pp = new_palette.entries + i;
1165 if (new_palette.depth == 8)
1167 pp->red = *entry_start++;
1168 pp->green = *entry_start++;
1169 pp->blue = *entry_start++;
1170 pp->alpha = *entry_start++;
1174 pp->red = png_get_uint_16(entry_start); entry_start += 2;
1175 pp->green = png_get_uint_16(entry_start); entry_start += 2;
1176 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1177 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1179 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1182 pp = new_palette.entries;
1183 for (i = 0; i < new_palette.nentries; i++)
1186 if (new_palette.depth == 8)
1188 pp[i].red = *entry_start++;
1189 pp[i].green = *entry_start++;
1190 pp[i].blue = *entry_start++;
1191 pp[i].alpha = *entry_start++;
1195 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1196 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1197 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1198 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1200 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1204 /* discard all chunk data except the name and stash that */
1205 new_palette.name = (png_charp)chunkdata;
1207 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1209 png_free(png_ptr, chunkdata);
1210 png_free(png_ptr, new_palette.entries);
1212 #endif /* PNG_READ_sPLT_SUPPORTED */
1214 #if defined(PNG_READ_tRNS_SUPPORTED)
1216 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1218 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1220 png_debug(1, "in png_handle_tRNS\n");
1222 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1223 png_error(png_ptr, "Missing IHDR before tRNS");
1224 else if (png_ptr->mode & PNG_HAVE_IDAT)
1226 png_warning(png_ptr, "Invalid tRNS after IDAT");
1227 png_crc_finish(png_ptr, length);
1230 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1232 png_warning(png_ptr, "Duplicate tRNS chunk");
1233 png_crc_finish(png_ptr, length);
1237 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1239 if (!(png_ptr->mode & PNG_HAVE_PLTE))
1241 /* Should be an error, but we can cope with it */
1242 png_warning(png_ptr, "Missing PLTE before tRNS");
1244 else if (length > (png_uint_32)png_ptr->num_palette)
1246 png_warning(png_ptr, "Incorrect tRNS chunk length");
1247 png_crc_finish(png_ptr, length);
1252 png_warning(png_ptr, "Zero length tRNS chunk");
1253 png_crc_finish(png_ptr, length);
1257 png_crc_read(png_ptr, readbuf, (png_size_t)length);
1258 png_ptr->num_trans = (png_uint_16)length;
1260 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1266 png_warning(png_ptr, "Incorrect tRNS chunk length");
1267 png_crc_finish(png_ptr, length);
1271 png_crc_read(png_ptr, buf, (png_size_t)length);
1272 png_ptr->num_trans = 1;
1273 png_ptr->trans_values.red = png_get_uint_16(buf);
1274 png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1275 png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1277 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1283 png_warning(png_ptr, "Incorrect tRNS chunk length");
1284 png_crc_finish(png_ptr, length);
1288 png_crc_read(png_ptr, buf, 2);
1289 png_ptr->num_trans = 1;
1290 png_ptr->trans_values.gray = png_get_uint_16(buf);
1294 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1295 png_crc_finish(png_ptr, length);
1299 if (png_crc_finish(png_ptr, 0))
1302 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1303 &(png_ptr->trans_values));
1307 #if defined(PNG_READ_bKGD_SUPPORTED)
1309 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1314 png_debug(1, "in png_handle_bKGD\n");
1316 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1317 png_error(png_ptr, "Missing IHDR before bKGD");
1318 else if (png_ptr->mode & PNG_HAVE_IDAT)
1320 png_warning(png_ptr, "Invalid bKGD after IDAT");
1321 png_crc_finish(png_ptr, length);
1324 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1325 !(png_ptr->mode & PNG_HAVE_PLTE))
1327 png_warning(png_ptr, "Missing PLTE before bKGD");
1328 png_crc_finish(png_ptr, length);
1331 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1333 png_warning(png_ptr, "Duplicate bKGD chunk");
1334 png_crc_finish(png_ptr, length);
1338 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1340 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1345 if (length != truelen)
1347 png_warning(png_ptr, "Incorrect bKGD chunk length");
1348 png_crc_finish(png_ptr, length);
1352 png_crc_read(png_ptr, buf, truelen);
1353 if (png_crc_finish(png_ptr, 0))
1356 /* We convert the index value into RGB components so that we can allow
1357 * arbitrary RGB values for background when we have transparency, and
1358 * so it is easy to determine the RGB values of the background color
1359 * from the info_ptr struct. */
1360 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1362 png_ptr->background.index = buf[0];
1363 if(info_ptr->num_palette)
1365 if(buf[0] > info_ptr->num_palette)
1367 png_warning(png_ptr, "Incorrect bKGD chunk index value");
1370 png_ptr->background.red =
1371 (png_uint_16)png_ptr->palette[buf[0]].red;
1372 png_ptr->background.green =
1373 (png_uint_16)png_ptr->palette[buf[0]].green;
1374 png_ptr->background.blue =
1375 (png_uint_16)png_ptr->palette[buf[0]].blue;
1378 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1380 png_ptr->background.red =
1381 png_ptr->background.green =
1382 png_ptr->background.blue =
1383 png_ptr->background.gray = png_get_uint_16(buf);
1387 png_ptr->background.red = png_get_uint_16(buf);
1388 png_ptr->background.green = png_get_uint_16(buf + 2);
1389 png_ptr->background.blue = png_get_uint_16(buf + 4);
1392 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1396 #if defined(PNG_READ_hIST_SUPPORTED)
1398 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1401 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1403 png_debug(1, "in png_handle_hIST\n");
1405 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1406 png_error(png_ptr, "Missing IHDR before hIST");
1407 else if (png_ptr->mode & PNG_HAVE_IDAT)
1409 png_warning(png_ptr, "Invalid hIST after IDAT");
1410 png_crc_finish(png_ptr, length);
1413 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1415 png_warning(png_ptr, "Missing PLTE before hIST");
1416 png_crc_finish(png_ptr, length);
1419 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1421 png_warning(png_ptr, "Duplicate hIST chunk");
1422 png_crc_finish(png_ptr, length);
1426 num = (int)length / 2 ;
1427 if (num != png_ptr->num_palette)
1429 png_warning(png_ptr, "Incorrect hIST chunk length");
1430 png_crc_finish(png_ptr, length);
1434 for (i = 0; i < num; i++)
1438 png_crc_read(png_ptr, buf, 2);
1439 readbuf[i] = png_get_uint_16(buf);
1442 if (png_crc_finish(png_ptr, 0))
1445 png_set_hIST(png_ptr, info_ptr, readbuf);
1449 #if defined(PNG_READ_pHYs_SUPPORTED)
1451 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1454 png_uint_32 res_x, res_y;
1457 png_debug(1, "in png_handle_pHYs\n");
1459 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1460 png_error(png_ptr, "Missing IHDR before pHYs");
1461 else if (png_ptr->mode & PNG_HAVE_IDAT)
1463 png_warning(png_ptr, "Invalid pHYs after IDAT");
1464 png_crc_finish(png_ptr, length);
1467 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1469 png_warning(png_ptr, "Duplicate pHYs chunk");
1470 png_crc_finish(png_ptr, length);
1476 png_warning(png_ptr, "Incorrect pHYs chunk length");
1477 png_crc_finish(png_ptr, length);
1481 png_crc_read(png_ptr, buf, 9);
1482 if (png_crc_finish(png_ptr, 0))
1485 res_x = png_get_uint_32(buf);
1486 res_y = png_get_uint_32(buf + 4);
1488 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1492 #if defined(PNG_READ_oFFs_SUPPORTED)
1494 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1497 png_int_32 offset_x, offset_y;
1500 png_debug(1, "in png_handle_oFFs\n");
1502 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1503 png_error(png_ptr, "Missing IHDR before oFFs");
1504 else if (png_ptr->mode & PNG_HAVE_IDAT)
1506 png_warning(png_ptr, "Invalid oFFs after IDAT");
1507 png_crc_finish(png_ptr, length);
1510 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1512 png_warning(png_ptr, "Duplicate oFFs chunk");
1513 png_crc_finish(png_ptr, length);
1519 png_warning(png_ptr, "Incorrect oFFs chunk length");
1520 png_crc_finish(png_ptr, length);
1524 png_crc_read(png_ptr, buf, 9);
1525 if (png_crc_finish(png_ptr, 0))
1528 offset_x = png_get_int_32(buf);
1529 offset_y = png_get_int_32(buf + 4);
1531 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1535 #if defined(PNG_READ_pCAL_SUPPORTED)
1536 /* read the pCAL chunk (described in the PNG Extensions document) */
1538 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1542 png_byte type, nparams;
1543 png_charp buf, units, endptr;
1548 png_debug(1, "in png_handle_pCAL\n");
1550 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1551 png_error(png_ptr, "Missing IHDR before pCAL");
1552 else if (png_ptr->mode & PNG_HAVE_IDAT)
1554 png_warning(png_ptr, "Invalid pCAL after IDAT");
1555 png_crc_finish(png_ptr, length);
1558 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1560 png_warning(png_ptr, "Duplicate pCAL chunk");
1561 png_crc_finish(png_ptr, length);
1565 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1567 purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
1568 if (purpose == NULL)
1570 png_warning(png_ptr, "No memory for pCAL purpose.");
1573 slength = (png_size_t)length;
1574 png_crc_read(png_ptr, (png_bytep)purpose, slength);
1576 if (png_crc_finish(png_ptr, 0))
1578 png_free(png_ptr, purpose);
1582 purpose[slength] = 0x00; /* null terminate the last string */
1584 png_debug(3, "Finding end of pCAL purpose string\n");
1585 for (buf = purpose; *buf; buf++)
1588 endptr = purpose + slength;
1590 /* We need to have at least 12 bytes after the purpose string
1591 in order to get the parameter information. */
1592 if (endptr <= buf + 12)
1594 png_warning(png_ptr, "Invalid pCAL data");
1595 png_free(png_ptr, purpose);
1599 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1600 X0 = png_get_int_32((png_bytep)buf+1);
1601 X1 = png_get_int_32((png_bytep)buf+5);
1606 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1607 /* Check that we have the right number of parameters for known
1609 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1610 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1611 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1612 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1614 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1615 png_free(png_ptr, purpose);
1618 else if (type >= PNG_EQUATION_LAST)
1620 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1623 for (buf = units; *buf; buf++)
1624 /* Empty loop to move past the units string. */ ;
1626 png_debug(3, "Allocating pCAL parameters array\n");
1627 params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
1628 *sizeof(png_charp))) ;
1631 png_free(png_ptr, purpose);
1632 png_warning(png_ptr, "No memory for pCAL params.");
1636 /* Get pointers to the start of each parameter string. */
1637 for (i = 0; i < (int)nparams; i++)
1639 buf++; /* Skip the null string terminator from previous parameter. */
1641 png_debug1(3, "Reading pCAL parameter %d\n", i);
1642 for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
1643 /* Empty loop to move past each parameter string */ ;
1645 /* Make sure we haven't run out of data yet */
1648 png_warning(png_ptr, "Invalid pCAL data");
1649 png_free(png_ptr, purpose);
1650 png_free(png_ptr, params);
1655 png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1658 png_free(png_ptr, purpose);
1659 png_free(png_ptr, params);
1663 #if defined(PNG_READ_sCAL_SUPPORTED)
1664 /* read the sCAL chunk */
1666 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1668 png_charp buffer, ep;
1669 #ifdef PNG_FLOATING_POINT_SUPPORTED
1670 double width, height;
1673 #ifdef PNG_FIXED_POINT_SUPPORTED
1674 png_charp swidth, sheight;
1679 png_debug(1, "in png_handle_sCAL\n");
1681 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1682 png_error(png_ptr, "Missing IHDR before sCAL");
1683 else if (png_ptr->mode & PNG_HAVE_IDAT)
1685 png_warning(png_ptr, "Invalid sCAL after IDAT");
1686 png_crc_finish(png_ptr, length);
1689 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1691 png_warning(png_ptr, "Duplicate sCAL chunk");
1692 png_crc_finish(png_ptr, length);
1696 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1698 buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
1701 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1704 slength = (png_size_t)length;
1705 png_crc_read(png_ptr, (png_bytep)buffer, slength);
1707 if (png_crc_finish(png_ptr, 0))
1709 png_free(png_ptr, buffer);
1713 buffer[slength] = 0x00; /* null terminate the last string */
1715 ep = buffer + 1; /* skip unit byte */
1717 #ifdef PNG_FLOATING_POINT_SUPPORTED
1718 width = strtod(ep, &vp);
1721 png_warning(png_ptr, "malformed width string in sCAL chunk");
1725 #ifdef PNG_FIXED_POINT_SUPPORTED
1726 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1729 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1732 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1736 for (ep = buffer; *ep; ep++)
1740 #ifdef PNG_FLOATING_POINT_SUPPORTED
1741 height = strtod(ep, &vp);
1744 png_warning(png_ptr, "malformed height string in sCAL chunk");
1748 #ifdef PNG_FIXED_POINT_SUPPORTED
1749 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1752 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1755 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1759 if (buffer + slength < ep
1760 #ifdef PNG_FLOATING_POINT_SUPPORTED
1761 || width <= 0. || height <= 0.
1765 png_warning(png_ptr, "Invalid sCAL data");
1766 png_free(png_ptr, buffer);
1767 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1768 png_free(png_ptr, swidth);
1769 png_free(png_ptr, sheight);
1775 #ifdef PNG_FLOATING_POINT_SUPPORTED
1776 png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
1778 #ifdef PNG_FIXED_POINT_SUPPORTED
1779 png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
1783 png_free(png_ptr, buffer);
1784 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1785 png_free(png_ptr, swidth);
1786 png_free(png_ptr, sheight);
1791 #if defined(PNG_READ_tIME_SUPPORTED)
1793 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1798 png_debug(1, "in png_handle_tIME\n");
1800 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1801 png_error(png_ptr, "Out of place tIME chunk");
1802 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1804 png_warning(png_ptr, "Duplicate tIME chunk");
1805 png_crc_finish(png_ptr, length);
1809 if (png_ptr->mode & PNG_HAVE_IDAT)
1810 png_ptr->mode |= PNG_AFTER_IDAT;
1814 png_warning(png_ptr, "Incorrect tIME chunk length");
1815 png_crc_finish(png_ptr, length);
1819 png_crc_read(png_ptr, buf, 7);
1820 if (png_crc_finish(png_ptr, 0))
1823 mod_time.second = buf[6];
1824 mod_time.minute = buf[5];
1825 mod_time.hour = buf[4];
1826 mod_time.day = buf[3];
1827 mod_time.month = buf[2];
1828 mod_time.year = png_get_uint_16(buf);
1830 png_set_tIME(png_ptr, info_ptr, &mod_time);
1834 #if defined(PNG_READ_tEXt_SUPPORTED)
1835 /* Note: this does not properly handle chunks that are > 64K under DOS */
1837 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1842 png_uint_32 skip = 0;
1846 png_debug(1, "in png_handle_tEXt\n");
1848 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1849 png_error(png_ptr, "Missing IHDR before tEXt");
1851 if (png_ptr->mode & PNG_HAVE_IDAT)
1852 png_ptr->mode |= PNG_AFTER_IDAT;
1854 #ifdef PNG_MAX_MALLOC_64K
1855 if (length > (png_uint_32)65535L)
1857 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1858 skip = length - (png_uint_32)65535L;
1859 length = (png_uint_32)65535L;
1863 key = (png_charp)png_malloc_warn(png_ptr, length + 1);
1866 png_warning(png_ptr, "No memory to process text chunk.");
1869 slength = (png_size_t)length;
1870 png_crc_read(png_ptr, (png_bytep)key, slength);
1872 if (png_crc_finish(png_ptr, skip))
1874 png_free(png_ptr, key);
1878 key[slength] = 0x00;
1880 for (text = key; *text; text++)
1881 /* empty loop to find end of key */ ;
1883 if (text != key + slength)
1886 text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1887 if (text_ptr == NULL)
1889 png_warning(png_ptr, "Not enough memory to process text chunk.");
1890 png_free(png_ptr, key);
1893 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1894 text_ptr->key = key;
1895 #ifdef PNG_iTXt_SUPPORTED
1896 text_ptr->lang = NULL;
1897 text_ptr->lang_key = NULL;
1898 text_ptr->itxt_length = 0;
1900 text_ptr->text = text;
1901 text_ptr->text_length = png_strlen(text);
1903 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1905 png_free(png_ptr, key);
1906 png_free(png_ptr, text_ptr);
1908 png_warning(png_ptr, "Insufficient memory to process text chunk.");
1912 #if defined(PNG_READ_zTXt_SUPPORTED)
1913 /* note: this does not correctly handle chunks that are > 64K under DOS */
1915 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1918 png_charp chunkdata;
1922 png_size_t slength, prefix_len, data_len;
1924 png_debug(1, "in png_handle_zTXt\n");
1925 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1926 png_error(png_ptr, "Missing IHDR before zTXt");
1928 if (png_ptr->mode & PNG_HAVE_IDAT)
1929 png_ptr->mode |= PNG_AFTER_IDAT;
1931 #ifdef PNG_MAX_MALLOC_64K
1932 /* We will no doubt have problems with chunks even half this size, but
1933 there is no hard and fast rule to tell us where to stop. */
1934 if (length > (png_uint_32)65535L)
1936 png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1937 png_crc_finish(png_ptr, length);
1942 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1943 if (chunkdata == NULL)
1945 png_warning(png_ptr,"Out of memory processing zTXt chunk.");
1948 slength = (png_size_t)length;
1949 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1950 if (png_crc_finish(png_ptr, 0))
1952 png_free(png_ptr, chunkdata);
1956 chunkdata[slength] = 0x00;
1958 for (text = chunkdata; *text; text++)
1961 /* zTXt must have some text after the chunkdataword */
1962 if (text == chunkdata + slength)
1964 comp_type = PNG_TEXT_COMPRESSION_NONE;
1965 png_warning(png_ptr, "Zero length zTXt chunk");
1969 comp_type = *(++text);
1970 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
1972 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
1973 comp_type = PNG_TEXT_COMPRESSION_zTXt;
1975 text++; /* skip the compression_method byte */
1977 prefix_len = text - chunkdata;
1979 chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
1980 (png_size_t)length, prefix_len, &data_len);
1982 text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1983 if (text_ptr == NULL)
1985 png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
1986 png_free(png_ptr, chunkdata);
1989 text_ptr->compression = comp_type;
1990 text_ptr->key = chunkdata;
1991 #ifdef PNG_iTXt_SUPPORTED
1992 text_ptr->lang = NULL;
1993 text_ptr->lang_key = NULL;
1994 text_ptr->itxt_length = 0;
1996 text_ptr->text = chunkdata + prefix_len;
1997 text_ptr->text_length = data_len;
1999 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2001 png_free(png_ptr, text_ptr);
2002 png_free(png_ptr, chunkdata);
2004 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2008 #if defined(PNG_READ_iTXt_SUPPORTED)
2009 /* note: this does not correctly handle chunks that are > 64K under DOS */
2011 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2014 png_charp chunkdata;
2015 png_charp key, lang, text, lang_key;
2019 png_size_t slength, prefix_len, data_len;
2021 png_debug(1, "in png_handle_iTXt\n");
2023 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2024 png_error(png_ptr, "Missing IHDR before iTXt");
2026 if (png_ptr->mode & PNG_HAVE_IDAT)
2027 png_ptr->mode |= PNG_AFTER_IDAT;
2029 #ifdef PNG_MAX_MALLOC_64K
2030 /* We will no doubt have problems with chunks even half this size, but
2031 there is no hard and fast rule to tell us where to stop. */
2032 if (length > (png_uint_32)65535L)
2034 png_warning(png_ptr,"iTXt chunk too large to fit in memory");
2035 png_crc_finish(png_ptr, length);
2040 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2041 if (chunkdata == NULL)
2043 png_warning(png_ptr, "No memory to process iTXt chunk.");
2046 slength = (png_size_t)length;
2047 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
2048 if (png_crc_finish(png_ptr, 0))
2050 png_free(png_ptr, chunkdata);
2054 chunkdata[slength] = 0x00;
2056 for (lang = chunkdata; *lang; lang++)
2058 lang++; /* skip NUL separator */
2060 /* iTXt must have a language tag (possibly empty), two compression bytes,
2061 translated keyword (possibly empty), and possibly some text after the
2064 if (lang >= chunkdata + slength)
2066 comp_flag = PNG_TEXT_COMPRESSION_NONE;
2067 png_warning(png_ptr, "Zero length iTXt chunk");
2071 comp_flag = *lang++;
2072 comp_type = *lang++;
2075 for (lang_key = lang; *lang_key; lang_key++)
2077 lang_key++; /* skip NUL separator */
2079 for (text = lang_key; *text; text++)
2081 text++; /* skip NUL separator */
2083 prefix_len = text - chunkdata;
2087 chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
2088 (size_t)length, prefix_len, &data_len);
2090 data_len=png_strlen(chunkdata + prefix_len);
2091 text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
2092 if (text_ptr == NULL)
2094 png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
2095 png_free(png_ptr, chunkdata);
2098 text_ptr->compression = (int)comp_flag + 1;
2099 text_ptr->lang_key = chunkdata+(lang_key-key);
2100 text_ptr->lang = chunkdata+(lang-key);
2101 text_ptr->itxt_length = data_len;
2102 text_ptr->text_length = 0;
2103 text_ptr->key = chunkdata;
2104 text_ptr->text = chunkdata + prefix_len;
2106 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2108 png_free(png_ptr, text_ptr);
2109 png_free(png_ptr, chunkdata);
2111 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2115 /* This function is called when we haven't found a handler for a
2116 chunk. If there isn't a problem with the chunk itself (ie bad
2117 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2118 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2119 case it will be saved away to be written out later. */
2121 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2123 png_uint_32 skip = 0;
2125 png_debug(1, "in png_handle_unknown\n");
2127 if (png_ptr->mode & PNG_HAVE_IDAT)
2129 #ifdef PNG_USE_LOCAL_ARRAYS
2132 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
2133 png_ptr->mode |= PNG_AFTER_IDAT;
2136 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
2138 if (!(png_ptr->chunk_name[0] & 0x20))
2140 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2141 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2143 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2144 && png_ptr->read_user_chunk_fn == NULL
2148 png_chunk_error(png_ptr, "unknown critical chunk");
2151 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2152 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2154 png_unknown_chunk chunk;
2156 #ifdef PNG_MAX_MALLOC_64K
2157 if (length > (png_uint_32)65535L)
2159 png_warning(png_ptr, "unknown chunk too large to fit in memory");
2160 skip = length - (png_uint_32)65535L;
2161 length = (png_uint_32)65535L;
2164 png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
2165 chunk.data = (png_bytep)png_malloc(png_ptr, length);
2166 chunk.size = (png_size_t)length;
2167 png_crc_read(png_ptr, (png_bytep)chunk.data, length);
2168 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2169 if(png_ptr->read_user_chunk_fn != NULL)
2171 /* callback to user unknown chunk handler */
2172 if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
2174 if (!(png_ptr->chunk_name[0] & 0x20))
2175 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2176 HANDLE_CHUNK_ALWAYS)
2178 png_free(png_ptr, chunk.data);
2179 png_chunk_error(png_ptr, "unknown critical chunk");
2181 png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2186 png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2187 png_free(png_ptr, chunk.data);
2193 png_crc_finish(png_ptr, skip);
2195 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2196 info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
2200 /* This function is called to verify that a chunk name is valid.
2201 This function can't have the "critical chunk check" incorporated
2202 into it, since in the future we will need to be able to call user
2203 functions to handle unknown critical chunks after we check that
2204 the chunk name itself is valid. */
2206 #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
2209 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2211 png_debug(1, "in png_check_chunk_name\n");
2212 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2213 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2215 png_chunk_error(png_ptr, "invalid chunk type");
2219 /* Combines the row recently read in with the existing pixels in the
2220 row. This routine takes care of alpha and transparency if requested.
2221 This routine also handles the two methods of progressive display
2222 of interlaced images, depending on the mask value.
2223 The mask value describes which pixels are to be combined with
2224 the row. The pattern always repeats every 8 pixels, so just 8
2225 bits are needed. A one indicates the pixel is to be combined,
2226 a zero indicates the pixel is to be skipped. This is in addition
2227 to any alpha or transparency value associated with the pixel. If
2228 you want all pixels to be combined, pass 0xff (255) in mask. */
2229 #ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
2231 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2233 png_debug(1,"in png_combine_row\n");
2236 png_memcpy(row, png_ptr->row_buf + 1,
2237 (png_size_t)((png_ptr->width *
2238 png_ptr->row_info.pixel_depth + 7) >> 3));
2242 switch (png_ptr->row_info.pixel_depth)
2246 png_bytep sp = png_ptr->row_buf + 1;
2248 int s_inc, s_start, s_end;
2252 png_uint_32 row_width = png_ptr->width;
2254 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2255 if (png_ptr->transformations & PNG_PACKSWAP)
2271 for (i = 0; i < row_width; i++)
2277 value = (*sp >> shift) & 0x01;
2278 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2279 *dp |= (png_byte)(value << shift);
2300 png_bytep sp = png_ptr->row_buf + 1;
2302 int s_start, s_end, s_inc;
2306 png_uint_32 row_width = png_ptr->width;
2309 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2310 if (png_ptr->transformations & PNG_PACKSWAP)
2326 for (i = 0; i < row_width; i++)
2330 value = (*sp >> shift) & 0x03;
2331 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2332 *dp |= (png_byte)(value << shift);
2352 png_bytep sp = png_ptr->row_buf + 1;
2354 int s_start, s_end, s_inc;
2358 png_uint_32 row_width = png_ptr->width;
2361 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2362 if (png_ptr->transformations & PNG_PACKSWAP)
2377 for (i = 0; i < row_width; i++)
2381 value = (*sp >> shift) & 0xf;
2382 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2383 *dp |= (png_byte)(value << shift);
2403 png_bytep sp = png_ptr->row_buf + 1;
2405 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2407 png_uint_32 row_width = png_ptr->width;
2411 for (i = 0; i < row_width; i++)
2415 png_memcpy(dp, sp, pixel_bytes);
2431 #endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
2433 #ifdef PNG_READ_INTERLACING_SUPPORTED
2434 #ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
2435 /* OLD pre-1.0.9 interface:
2436 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2437 png_uint_32 transformations)
2440 png_do_read_interlace(png_structp png_ptr)
2442 png_row_infop row_info = &(png_ptr->row_info);
2443 png_bytep row = png_ptr->row_buf + 1;
2444 int pass = png_ptr->pass;
2445 png_uint_32 transformations = png_ptr->transformations;
2446 #ifdef PNG_USE_LOCAL_ARRAYS
2447 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2448 /* offset to next interlace block */
2449 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2452 png_debug(1,"in png_do_read_interlace (stock C version)\n");
2453 if (row != NULL && row_info != NULL)
2455 png_uint_32 final_width;
2457 final_width = row_info->width * png_pass_inc[pass];
2459 switch (row_info->pixel_depth)
2463 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2464 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2466 int s_start, s_end, s_inc;
2467 int jstop = png_pass_inc[pass];
2472 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2473 if (transformations & PNG_PACKSWAP)
2475 sshift = (int)((row_info->width + 7) & 0x07);
2476 dshift = (int)((final_width + 7) & 0x07);
2484 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2485 dshift = 7 - (int)((final_width + 7) & 0x07);
2491 for (i = 0; i < row_info->width; i++)
2493 v = (png_byte)((*sp >> sshift) & 0x01);
2494 for (j = 0; j < jstop; j++)
2496 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2497 *dp |= (png_byte)(v << dshift);
2498 if (dshift == s_end)
2506 if (sshift == s_end)
2518 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2519 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2521 int s_start, s_end, s_inc;
2522 int jstop = png_pass_inc[pass];
2525 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2526 if (transformations & PNG_PACKSWAP)
2528 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2529 dshift = (int)(((final_width + 3) & 0x03) << 1);
2537 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2538 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2544 for (i = 0; i < row_info->width; i++)
2549 v = (png_byte)((*sp >> sshift) & 0x03);
2550 for (j = 0; j < jstop; j++)
2552 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2553 *dp |= (png_byte)(v << dshift);
2554 if (dshift == s_end)
2562 if (sshift == s_end)
2574 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2575 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2577 int s_start, s_end, s_inc;
2579 int jstop = png_pass_inc[pass];
2581 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2582 if (transformations & PNG_PACKSWAP)
2584 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2585 dshift = (int)(((final_width + 1) & 0x01) << 2);
2593 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2594 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2600 for (i = 0; i < row_info->width; i++)
2602 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2605 for (j = 0; j < jstop; j++)
2607 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2608 *dp |= (png_byte)(v << dshift);
2609 if (dshift == s_end)
2617 if (sshift == s_end)
2629 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2630 png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
2631 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2633 int jstop = png_pass_inc[pass];
2636 for (i = 0; i < row_info->width; i++)
2641 png_memcpy(v, sp, pixel_bytes);
2642 for (j = 0; j < jstop; j++)
2644 png_memcpy(dp, v, pixel_bytes);
2652 row_info->width = final_width;
2653 row_info->rowbytes = ((final_width *
2654 (png_uint_32)row_info->pixel_depth + 7) >> 3);
2656 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2657 transformations = transformations; /* silence compiler warning */
2660 #endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
2661 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2663 #ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
2665 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2666 png_bytep prev_row, int filter)
2668 png_debug(1, "in png_read_filter_row\n");
2669 png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
2672 case PNG_FILTER_VALUE_NONE:
2674 case PNG_FILTER_VALUE_SUB:
2677 png_uint_32 istop = row_info->rowbytes;
2678 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2679 png_bytep rp = row + bpp;
2682 for (i = bpp; i < istop; i++)
2684 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2689 case PNG_FILTER_VALUE_UP:
2692 png_uint_32 istop = row_info->rowbytes;
2694 png_bytep pp = prev_row;
2696 for (i = 0; i < istop; i++)
2698 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2703 case PNG_FILTER_VALUE_AVG:
2707 png_bytep pp = prev_row;
2709 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2710 png_uint_32 istop = row_info->rowbytes - bpp;
2712 for (i = 0; i < bpp; i++)
2714 *rp = (png_byte)(((int)(*rp) +
2715 ((int)(*pp++) / 2 )) & 0xff);
2719 for (i = 0; i < istop; i++)
2721 *rp = (png_byte)(((int)(*rp) +
2722 (int)(*pp++ + *lp++) / 2 ) & 0xff);
2727 case PNG_FILTER_VALUE_PAETH:
2731 png_bytep pp = prev_row;
2733 png_bytep cp = prev_row;
2734 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2735 png_uint_32 istop=row_info->rowbytes - bpp;
2737 for (i = 0; i < bpp; i++)
2739 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2743 for (i = 0; i < istop; i++) /* use leftover rp,pp */
2745 int a, b, c, pa, pb, pc, p;
2759 pa = p < 0 ? -p : p;
2760 pb = pc < 0 ? -pc : pc;
2761 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2765 if (pa <= pb && pa <= pc)
2773 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2775 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2781 png_warning(png_ptr, "Ignoring bad adaptive filter type");
2786 #endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
2789 png_read_finish_row(png_structp png_ptr)
2791 #ifdef PNG_USE_LOCAL_ARRAYS
2792 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2794 /* start of interlace block */
2795 const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2797 /* offset to next interlace block */
2798 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2800 /* start of interlace block in the y direction */
2801 const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2803 /* offset to next interlace block in the y direction */
2804 const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2807 png_debug(1, "in png_read_finish_row\n");
2808 png_ptr->row_number++;
2809 if (png_ptr->row_number < png_ptr->num_rows)
2812 if (png_ptr->interlaced)
2814 png_ptr->row_number = 0;
2815 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2819 if (png_ptr->pass >= 7)
2821 png_ptr->iwidth = (png_ptr->width +
2822 png_pass_inc[png_ptr->pass] - 1 -
2823 png_pass_start[png_ptr->pass]) /
2824 png_pass_inc[png_ptr->pass];
2825 png_ptr->irowbytes = ((png_ptr->iwidth *
2826 (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2828 if (!(png_ptr->transformations & PNG_INTERLACE))
2830 png_ptr->num_rows = (png_ptr->height +
2831 png_pass_yinc[png_ptr->pass] - 1 -
2832 png_pass_ystart[png_ptr->pass]) /
2833 png_pass_yinc[png_ptr->pass];
2834 if (!(png_ptr->num_rows))
2837 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2839 } while (png_ptr->iwidth == 0);
2841 if (png_ptr->pass < 7)
2845 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2847 #ifdef PNG_USE_LOCAL_ARRAYS
2853 png_ptr->zstream.next_out = (Byte *)&extra;
2854 png_ptr->zstream.avail_out = (uInt)1;
2857 if (!(png_ptr->zstream.avail_in))
2859 while (!png_ptr->idat_size)
2861 png_byte chunk_length[4];
2863 png_crc_finish(png_ptr, 0);
2865 png_read_data(png_ptr, chunk_length, 4);
2866 png_ptr->idat_size = png_get_uint_32(chunk_length);
2868 png_reset_crc(png_ptr);
2869 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
2870 if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
2871 png_error(png_ptr, "Not enough image data");
2874 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
2875 png_ptr->zstream.next_in = png_ptr->zbuf;
2876 if (png_ptr->zbuf_size > png_ptr->idat_size)
2877 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
2878 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
2879 png_ptr->idat_size -= png_ptr->zstream.avail_in;
2881 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2882 if (ret == Z_STREAM_END)
2884 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2886 png_warning(png_ptr, "Extra compressed data");
2887 png_ptr->mode |= PNG_AFTER_IDAT;
2888 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2892 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2893 "Decompression Error");
2895 if (!(png_ptr->zstream.avail_out))
2897 png_warning(png_ptr, "Extra compressed data.");
2898 png_ptr->mode |= PNG_AFTER_IDAT;
2899 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2904 png_ptr->zstream.avail_out = 0;
2907 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2908 png_warning(png_ptr, "Extra compression data");
2910 inflateReset(&png_ptr->zstream);
2912 png_ptr->mode |= PNG_AFTER_IDAT;
2916 png_read_start_row(png_structp png_ptr)
2918 #ifdef PNG_USE_LOCAL_ARRAYS
2919 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2921 /* start of interlace block */
2922 const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2924 /* offset to next interlace block */
2925 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2927 /* start of interlace block in the y direction */
2928 const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2930 /* offset to next interlace block in the y direction */
2931 const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2934 int max_pixel_depth;
2935 png_uint_32 row_bytes;
2937 png_debug(1, "in png_read_start_row\n");
2938 png_ptr->zstream.avail_in = 0;
2939 png_init_read_transformations(png_ptr);
2940 if (png_ptr->interlaced)
2942 if (!(png_ptr->transformations & PNG_INTERLACE))
2943 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2944 png_pass_ystart[0]) / png_pass_yinc[0];
2946 png_ptr->num_rows = png_ptr->height;
2948 png_ptr->iwidth = (png_ptr->width +
2949 png_pass_inc[png_ptr->pass] - 1 -
2950 png_pass_start[png_ptr->pass]) /
2951 png_pass_inc[png_ptr->pass];
2953 row_bytes = ((png_ptr->iwidth *
2954 (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2955 png_ptr->irowbytes = (png_size_t)row_bytes;
2956 if((png_uint_32)png_ptr->irowbytes != row_bytes)
2957 png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
2961 png_ptr->num_rows = png_ptr->height;
2962 png_ptr->iwidth = png_ptr->width;
2963 png_ptr->irowbytes = png_ptr->rowbytes + 1;
2965 max_pixel_depth = png_ptr->pixel_depth;
2967 #if defined(PNG_READ_PACK_SUPPORTED)
2968 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
2969 max_pixel_depth = 8;
2972 #if defined(PNG_READ_EXPAND_SUPPORTED)
2973 if (png_ptr->transformations & PNG_EXPAND)
2975 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2977 if (png_ptr->num_trans)
2978 max_pixel_depth = 32;
2980 max_pixel_depth = 24;
2982 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
2984 if (max_pixel_depth < 8)
2985 max_pixel_depth = 8;
2986 if (png_ptr->num_trans)
2987 max_pixel_depth *= 2;
2989 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
2991 if (png_ptr->num_trans)
2993 max_pixel_depth *= 4;
2994 max_pixel_depth /= 3;
3000 #if defined(PNG_READ_FILLER_SUPPORTED)
3001 if (png_ptr->transformations & (PNG_FILLER))
3003 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3004 max_pixel_depth = 32;
3005 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3007 if (max_pixel_depth <= 8)
3008 max_pixel_depth = 16;
3010 max_pixel_depth = 32;
3012 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3014 if (max_pixel_depth <= 32)
3015 max_pixel_depth = 32;
3017 max_pixel_depth = 64;
3022 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3023 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3026 #if defined(PNG_READ_EXPAND_SUPPORTED)
3027 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3029 #if defined(PNG_READ_FILLER_SUPPORTED)
3030 (png_ptr->transformations & (PNG_FILLER)) ||
3032 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3034 if (max_pixel_depth <= 16)
3035 max_pixel_depth = 32;
3037 max_pixel_depth = 64;
3041 if (max_pixel_depth <= 8)
3043 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3044 max_pixel_depth = 32;
3046 max_pixel_depth = 24;
3048 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3049 max_pixel_depth = 64;
3051 max_pixel_depth = 48;
3056 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3057 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3058 if(png_ptr->transformations & PNG_USER_TRANSFORM)
3060 int user_pixel_depth=png_ptr->user_transform_depth*
3061 png_ptr->user_transform_channels;
3062 if(user_pixel_depth > max_pixel_depth)
3063 max_pixel_depth=user_pixel_depth;
3067 /* align the width on the next larger 8 pixels. Mainly used
3069 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3070 /* calculate the maximum bytes needed, adding a byte and a pixel
3071 for safety's sake */
3072 row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
3073 1 + ((max_pixel_depth + 7) >> 3);
3074 #ifdef PNG_MAX_MALLOC_64K
3075 if (row_bytes > (png_uint_32)65536L)
3076 png_error(png_ptr, "This image requires a row greater than 64KB");
3078 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
3079 png_ptr->row_buf = png_ptr->big_row_buf+32;
3080 #if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
3081 png_ptr->row_buf_size = row_bytes;
3084 #ifdef PNG_MAX_MALLOC_64K
3085 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3086 png_error(png_ptr, "This image requires a row greater than 64KB");
3088 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3089 png_ptr->rowbytes + 1));
3091 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3093 png_debug1(3, "width = %lu,\n", png_ptr->width);
3094 png_debug1(3, "height = %lu,\n", png_ptr->height);
3095 png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
3096 png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
3097 png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
3098 png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
3100 png_ptr->flags |= PNG_FLAG_ROW_INIT;