Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / libpng / pngrutil.c
blob543b7e0e9997582d4a6c2f4e008ff00bc731a4e8
2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.51 [February 6, 2014]
5 * Copyright (c) 1998-2014 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
13 * This file contains routines that are only called from within
14 * libpng itself during the course of reading an image.
17 #define PNG_INTERNAL
18 #define PNG_NO_PEDANTIC_WARNINGS
19 #include "png.h"
20 #ifdef PNG_READ_SUPPORTED
22 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
23 # define WIN32_WCE_OLD
24 #endif
26 #ifdef PNG_FLOATING_POINT_SUPPORTED
27 # ifdef WIN32_WCE_OLD
28 /* The strtod() function is not supported on WindowsCE */
29 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
30 char **endptr)
32 double result = 0;
33 int len;
34 wchar_t *str, *end;
36 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
37 str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
38 if ( NULL != str )
40 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
41 result = wcstod(str, &end);
42 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
43 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
44 png_free(png_ptr, str);
46 return result;
48 # else
49 # define png_strtod(p,a,b) strtod(a,b)
50 # endif
51 #endif
53 png_uint_32 PNGAPI
54 png_get_uint_31(png_structp png_ptr, png_bytep buf)
56 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
57 png_uint_32 i = png_get_uint_32(buf);
58 #else
59 /* Avoid an extra function call by inlining the result. */
60 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
61 ((png_uint_32)(*(buf + 1)) << 16) +
62 ((png_uint_32)(*(buf + 2)) << 8) +
63 (png_uint_32)(*(buf + 3));
64 #endif
65 if (i > PNG_UINT_31_MAX)
66 png_error(png_ptr, "PNG unsigned integer out of range.");
67 return (i);
69 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
70 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
71 png_uint_32 PNGAPI
72 png_get_uint_32(png_bytep buf)
74 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
75 ((png_uint_32)(*(buf + 1)) << 16) +
76 ((png_uint_32)(*(buf + 2)) << 8) +
77 (png_uint_32)(*(buf + 3));
79 return (i);
82 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
83 * data is stored in the PNG file in two's complement format, and it is
84 * assumed that the machine format for signed integers is the same.
86 png_int_32 PNGAPI
87 png_get_int_32(png_bytep buf)
89 png_int_32 i = ((png_int_32)(*buf) << 24) +
90 ((png_int_32)(*(buf + 1)) << 16) +
91 ((png_int_32)(*(buf + 2)) << 8) +
92 (png_int_32)(*(buf + 3));
94 return (i);
97 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
98 png_uint_16 PNGAPI
99 png_get_uint_16(png_bytep buf)
101 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
102 (png_uint_16)(*(buf + 1)));
104 return (i);
106 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
108 /* Read the chunk header (length + type name).
109 * Put the type name into png_ptr->chunk_name, and return the length.
111 png_uint_32 /* PRIVATE */
112 png_read_chunk_header(png_structp png_ptr)
114 png_byte buf[8];
115 png_uint_32 length;
117 /* Read the length and the chunk name */
118 png_read_data(png_ptr, buf, 8);
119 length = png_get_uint_31(png_ptr, buf);
121 /* Put the chunk name into png_ptr->chunk_name */
122 png_memcpy(png_ptr->chunk_name, buf + 4, 4);
124 png_debug2(0, "Reading %s chunk, length = %lu",
125 png_ptr->chunk_name, length);
127 /* Reset the crc and run it over the chunk name */
128 png_reset_crc(png_ptr);
129 png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
131 /* Check to see if chunk name is valid */
132 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
134 return length;
137 /* Read data, and (optionally) run it through the CRC. */
138 void /* PRIVATE */
139 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
141 if (png_ptr == NULL)
142 return;
143 png_read_data(png_ptr, buf, length);
144 png_calculate_crc(png_ptr, buf, length);
147 /* Optionally skip data and then check the CRC. Depending on whether we
148 * are reading a ancillary or critical chunk, and how the program has set
149 * things up, we may calculate the CRC on the data and print a message.
150 * Returns '1' if there was a CRC error, '0' otherwise.
152 int /* PRIVATE */
153 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
155 png_size_t i;
156 png_size_t istop = png_ptr->zbuf_size;
158 for (i = (png_size_t)skip; i > istop; i -= istop)
160 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
162 if (i)
164 png_crc_read(png_ptr, png_ptr->zbuf, i);
167 if (png_crc_error(png_ptr))
169 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
170 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
171 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
172 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
174 png_chunk_warning(png_ptr, "CRC error");
176 else
178 png_chunk_error(png_ptr, "CRC error");
180 return (1);
183 return (0);
186 /* Compare the CRC stored in the PNG file with that calculated by libpng from
187 * the data it has read thus far.
189 int /* PRIVATE */
190 png_crc_error(png_structp png_ptr)
192 png_byte crc_bytes[4];
193 png_uint_32 crc;
194 int need_crc = 1;
196 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
198 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
199 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
200 need_crc = 0;
202 else /* critical */
204 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
205 need_crc = 0;
208 png_read_data(png_ptr, crc_bytes, 4);
210 if (need_crc)
212 crc = png_get_uint_32(crc_bytes);
213 return ((int)(crc != png_ptr->crc));
215 else
216 return (0);
219 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
220 defined(PNG_READ_iCCP_SUPPORTED)
221 static png_size_t
222 png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
223 png_bytep output, png_size_t output_size)
225 png_size_t count = 0;
227 png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
228 png_ptr->zstream.avail_in = size;
230 while (1)
232 int ret, avail;
234 /* Reset the output buffer each time round - we empty it
235 * after every inflate call.
237 png_ptr->zstream.next_out = png_ptr->zbuf;
238 png_ptr->zstream.avail_out = png_ptr->zbuf_size;
240 ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
241 avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
243 /* First copy/count any new output - but only if we didn't
244 * get an error code.
246 if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
248 if (output != 0 && output_size > count)
250 png_size_t copy = output_size - count;
251 if ((png_size_t) avail < copy) copy = (png_size_t) avail;
252 png_memcpy(output + count, png_ptr->zbuf, copy);
254 count += avail;
257 if (ret == Z_OK)
258 continue;
260 /* Termination conditions - always reset the zstream, it
261 * must be left in inflateInit state.
263 png_ptr->zstream.avail_in = 0;
264 inflateReset(&png_ptr->zstream);
266 if (ret == Z_STREAM_END)
267 return count; /* NOTE: may be zero. */
269 /* Now handle the error codes - the API always returns 0
270 * and the error message is dumped into the uncompressed
271 * buffer if available.
274 PNG_CONST char *msg;
275 if (png_ptr->zstream.msg != 0)
276 msg = png_ptr->zstream.msg;
277 else
279 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
280 char umsg[52];
282 switch (ret)
284 case Z_BUF_ERROR:
285 msg = "Buffer error in compressed datastream in %s chunk";
286 break;
287 case Z_DATA_ERROR:
288 msg = "Data error in compressed datastream in %s chunk";
289 break;
290 default:
291 msg = "Incomplete compressed datastream in %s chunk";
292 break;
295 png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
296 msg = umsg;
297 #else
298 msg = "Damaged compressed datastream in chunk other than IDAT";
299 #endif
302 png_warning(png_ptr, msg);
305 /* 0 means an error - notice that this code simple ignores
306 * zero length compressed chunks as a result.
308 return 0;
313 * Decompress trailing data in a chunk. The assumption is that chunkdata
314 * points at an allocated area holding the contents of a chunk with a
315 * trailing compressed part. What we get back is an allocated area
316 * holding the original prefix part and an uncompressed version of the
317 * trailing part (the malloc area passed in is freed).
319 void /* PRIVATE */
320 png_decompress_chunk(png_structp png_ptr, int comp_type,
321 png_size_t chunklength,
322 png_size_t prefix_size, png_size_t *newlength)
324 /* The caller should guarantee this */
325 if (prefix_size > chunklength)
327 /* The recovery is to delete the chunk. */
328 png_warning(png_ptr, "invalid chunklength");
329 prefix_size = 0; /* To delete everything */
332 else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
334 png_size_t expanded_size = png_inflate(png_ptr,
335 (png_bytep)(png_ptr->chunkdata + prefix_size),
336 chunklength - prefix_size,
337 0/*output*/, 0/*output size*/);
339 /* Now check the limits on this chunk - if the limit fails the
340 * compressed data will be removed, the prefix will remain.
342 if (prefix_size >= (~(png_size_t)0) - 1 ||
343 expanded_size >= (~(png_size_t)0) - 1 - prefix_size
344 #ifdef PNG_USER_CHUNK_MALLOC_MAX
345 || ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
346 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
347 #endif
349 png_warning(png_ptr, "Exceeded size limit while expanding chunk");
351 /* If the size is zero either there was an error and a message
352 * has already been output (warning) or the size really is zero
353 * and we have nothing to do - the code will exit through the
354 * error case below.
356 else if (expanded_size > 0)
358 /* Success (maybe) - really uncompress the chunk. */
359 png_size_t new_size = 0;
361 png_charp text = png_malloc_warn(png_ptr,
362 prefix_size + expanded_size + 1);
364 if (text != NULL)
366 png_memcpy(text, png_ptr->chunkdata, prefix_size);
367 new_size = png_inflate(png_ptr,
368 (png_bytep)(png_ptr->chunkdata + prefix_size),
369 chunklength - prefix_size,
370 (png_bytep)(text + prefix_size), expanded_size);
371 text[prefix_size + expanded_size] = 0; /* just in case */
373 if (new_size == expanded_size)
375 png_free(png_ptr, png_ptr->chunkdata);
376 png_ptr->chunkdata = text;
377 *newlength = prefix_size + expanded_size;
378 return; /* The success return! */
381 png_warning(png_ptr, "png_inflate logic error");
382 png_free(png_ptr, text);
384 else
385 png_warning(png_ptr, "Not enough memory to decompress chunk.");
389 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
391 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
392 char umsg[50];
394 png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
395 comp_type);
396 png_warning(png_ptr, umsg);
397 #else
398 png_warning(png_ptr, "Unknown zTXt compression type");
399 #endif
401 /* The recovery is to simply drop the data. */
404 /* Generic error return - leave the prefix, delete the compressed
405 * data, reallocate the chunkdata to remove the potentially large
406 * amount of compressed data.
409 png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
410 if (text != NULL)
412 if (prefix_size > 0)
413 png_memcpy(text, png_ptr->chunkdata, prefix_size);
414 png_free(png_ptr, png_ptr->chunkdata);
415 png_ptr->chunkdata = text;
417 /* This is an extra zero in the 'uncompressed' part. */
418 *(png_ptr->chunkdata + prefix_size) = 0x00;
420 /* Ignore a malloc error here - it is safe. */
423 *newlength = prefix_size;
425 #endif
427 /* Read and check the IDHR chunk */
428 void /* PRIVATE */
429 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
431 png_byte buf[13];
432 png_uint_32 width, height;
433 int bit_depth, color_type, compression_type, filter_type;
434 int interlace_type;
436 png_debug(1, "in png_handle_IHDR");
438 if (png_ptr->mode & PNG_HAVE_IHDR)
439 png_error(png_ptr, "Out of place IHDR");
441 /* Check the length */
442 if (length != 13)
443 png_error(png_ptr, "Invalid IHDR chunk");
445 png_ptr->mode |= PNG_HAVE_IHDR;
447 png_crc_read(png_ptr, buf, 13);
448 png_crc_finish(png_ptr, 0);
450 width = png_get_uint_31(png_ptr, buf);
451 height = png_get_uint_31(png_ptr, buf + 4);
452 bit_depth = buf[8];
453 color_type = buf[9];
454 compression_type = buf[10];
455 filter_type = buf[11];
456 interlace_type = buf[12];
458 /* Set internal variables */
459 png_ptr->width = width;
460 png_ptr->height = height;
461 png_ptr->bit_depth = (png_byte)bit_depth;
462 png_ptr->interlaced = (png_byte)interlace_type;
463 png_ptr->color_type = (png_byte)color_type;
464 #ifdef PNG_MNG_FEATURES_SUPPORTED
465 png_ptr->filter_type = (png_byte)filter_type;
466 #endif
467 png_ptr->compression_type = (png_byte)compression_type;
469 /* Find number of channels */
470 switch (png_ptr->color_type)
472 case PNG_COLOR_TYPE_GRAY:
473 case PNG_COLOR_TYPE_PALETTE:
474 png_ptr->channels = 1;
475 break;
477 case PNG_COLOR_TYPE_RGB:
478 png_ptr->channels = 3;
479 break;
481 case PNG_COLOR_TYPE_GRAY_ALPHA:
482 png_ptr->channels = 2;
483 break;
485 case PNG_COLOR_TYPE_RGB_ALPHA:
486 png_ptr->channels = 4;
487 break;
490 /* Set up other useful info */
491 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
492 png_ptr->channels);
493 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
494 png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
495 png_debug1(3, "channels = %d", png_ptr->channels);
496 png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
497 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
498 color_type, interlace_type, compression_type, filter_type);
501 /* Read and check the palette */
502 void /* PRIVATE */
503 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
505 png_color palette[PNG_MAX_PALETTE_LENGTH];
506 int num, i;
507 #ifdef PNG_POINTER_INDEXING_SUPPORTED
508 png_colorp pal_ptr;
509 #endif
511 png_debug(1, "in png_handle_PLTE");
513 if (!(png_ptr->mode & PNG_HAVE_IHDR))
514 png_error(png_ptr, "Missing IHDR before PLTE");
516 else if (png_ptr->mode & PNG_HAVE_IDAT)
518 png_warning(png_ptr, "Invalid PLTE after IDAT");
519 png_crc_finish(png_ptr, length);
520 return;
523 else if (png_ptr->mode & PNG_HAVE_PLTE)
524 png_error(png_ptr, "Duplicate PLTE chunk");
526 png_ptr->mode |= PNG_HAVE_PLTE;
528 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
530 png_warning(png_ptr,
531 "Ignoring PLTE chunk in grayscale PNG");
532 png_crc_finish(png_ptr, length);
533 return;
535 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
536 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
538 png_crc_finish(png_ptr, length);
539 return;
541 #endif
543 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
545 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
547 png_warning(png_ptr, "Invalid palette chunk");
548 png_crc_finish(png_ptr, length);
549 return;
552 else
554 png_error(png_ptr, "Invalid palette chunk");
558 num = (int)length / 3;
560 #ifdef PNG_POINTER_INDEXING_SUPPORTED
561 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
563 png_byte buf[3];
565 png_crc_read(png_ptr, buf, 3);
566 pal_ptr->red = buf[0];
567 pal_ptr->green = buf[1];
568 pal_ptr->blue = buf[2];
570 #else
571 for (i = 0; i < num; i++)
573 png_byte buf[3];
575 png_crc_read(png_ptr, buf, 3);
576 /* Don't depend upon png_color being any order */
577 palette[i].red = buf[0];
578 palette[i].green = buf[1];
579 palette[i].blue = buf[2];
581 #endif
583 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
584 * whatever the normal CRC configuration tells us. However, if we
585 * have an RGB image, the PLTE can be considered ancillary, so
586 * we will act as though it is.
588 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
589 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
590 #endif
592 png_crc_finish(png_ptr, 0);
594 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
595 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
597 /* If we don't want to use the data from an ancillary chunk,
598 we have two options: an error abort, or a warning and we
599 ignore the data in this chunk (which should be OK, since
600 it's considered ancillary for a RGB or RGBA image). */
601 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
603 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
605 png_chunk_error(png_ptr, "CRC error");
607 else
609 png_chunk_warning(png_ptr, "CRC error");
610 return;
613 /* Otherwise, we (optionally) emit a warning and use the chunk. */
614 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
616 png_chunk_warning(png_ptr, "CRC error");
619 #endif
621 png_set_PLTE(png_ptr, info_ptr, palette, num);
623 #ifdef PNG_READ_tRNS_SUPPORTED
624 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
626 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
628 if (png_ptr->num_trans > (png_uint_16)num)
630 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
631 png_ptr->num_trans = (png_uint_16)num;
633 if (info_ptr->num_trans > (png_uint_16)num)
635 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
636 info_ptr->num_trans = (png_uint_16)num;
640 #endif
644 void /* PRIVATE */
645 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
647 png_debug(1, "in png_handle_IEND");
649 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
651 png_error(png_ptr, "No image in file");
654 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
656 if (length != 0)
658 png_warning(png_ptr, "Incorrect IEND chunk length");
660 png_crc_finish(png_ptr, length);
662 PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
665 #ifdef PNG_READ_gAMA_SUPPORTED
666 void /* PRIVATE */
667 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
669 png_fixed_point igamma;
670 #ifdef PNG_FLOATING_POINT_SUPPORTED
671 float file_gamma;
672 #endif
673 png_byte buf[4];
675 png_debug(1, "in png_handle_gAMA");
677 if (!(png_ptr->mode & PNG_HAVE_IHDR))
678 png_error(png_ptr, "Missing IHDR before gAMA");
679 else if (png_ptr->mode & PNG_HAVE_IDAT)
681 png_warning(png_ptr, "Invalid gAMA after IDAT");
682 png_crc_finish(png_ptr, length);
683 return;
685 else if (png_ptr->mode & PNG_HAVE_PLTE)
686 /* Should be an error, but we can cope with it */
687 png_warning(png_ptr, "Out of place gAMA chunk");
689 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
690 #ifdef PNG_READ_sRGB_SUPPORTED
691 && !(info_ptr->valid & PNG_INFO_sRGB)
692 #endif
695 png_warning(png_ptr, "Duplicate gAMA chunk");
696 png_crc_finish(png_ptr, length);
697 return;
700 if (length != 4)
702 png_warning(png_ptr, "Incorrect gAMA chunk length");
703 png_crc_finish(png_ptr, length);
704 return;
707 png_crc_read(png_ptr, buf, 4);
708 if (png_crc_finish(png_ptr, 0))
709 return;
711 igamma = (png_fixed_point)png_get_uint_32(buf);
712 /* Check for zero gamma */
713 if (igamma == 0)
715 png_warning(png_ptr,
716 "Ignoring gAMA chunk with gamma=0");
717 return;
720 #ifdef PNG_READ_sRGB_SUPPORTED
721 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
722 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
724 png_warning(png_ptr,
725 "Ignoring incorrect gAMA value when sRGB is also present");
726 #ifdef PNG_CONSOLE_IO_SUPPORTED
727 fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
728 #endif
729 return;
731 #endif /* PNG_READ_sRGB_SUPPORTED */
733 #ifdef PNG_FLOATING_POINT_SUPPORTED
734 file_gamma = (float)igamma / (float)100000.0;
735 # ifdef PNG_READ_GAMMA_SUPPORTED
736 png_ptr->gamma = file_gamma;
737 # endif
738 png_set_gAMA(png_ptr, info_ptr, file_gamma);
739 #endif
740 #ifdef PNG_FIXED_POINT_SUPPORTED
741 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
742 #endif
744 #endif
746 #ifdef PNG_READ_sBIT_SUPPORTED
747 void /* PRIVATE */
748 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
750 png_size_t truelen;
751 png_byte buf[4];
753 png_debug(1, "in png_handle_sBIT");
755 buf[0] = buf[1] = buf[2] = buf[3] = 0;
757 if (!(png_ptr->mode & PNG_HAVE_IHDR))
758 png_error(png_ptr, "Missing IHDR before sBIT");
759 else if (png_ptr->mode & PNG_HAVE_IDAT)
761 png_warning(png_ptr, "Invalid sBIT after IDAT");
762 png_crc_finish(png_ptr, length);
763 return;
765 else if (png_ptr->mode & PNG_HAVE_PLTE)
767 /* Should be an error, but we can cope with it */
768 png_warning(png_ptr, "Out of place sBIT chunk");
770 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
772 png_warning(png_ptr, "Duplicate sBIT chunk");
773 png_crc_finish(png_ptr, length);
774 return;
777 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
778 truelen = 3;
779 else
780 truelen = (png_size_t)png_ptr->channels;
782 if (length != truelen || length > 4)
784 png_warning(png_ptr, "Incorrect sBIT chunk length");
785 png_crc_finish(png_ptr, length);
786 return;
789 png_crc_read(png_ptr, buf, truelen);
790 if (png_crc_finish(png_ptr, 0))
791 return;
793 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
795 png_ptr->sig_bit.red = buf[0];
796 png_ptr->sig_bit.green = buf[1];
797 png_ptr->sig_bit.blue = buf[2];
798 png_ptr->sig_bit.alpha = buf[3];
800 else
802 png_ptr->sig_bit.gray = buf[0];
803 png_ptr->sig_bit.red = buf[0];
804 png_ptr->sig_bit.green = buf[0];
805 png_ptr->sig_bit.blue = buf[0];
806 png_ptr->sig_bit.alpha = buf[1];
808 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
810 #endif
812 #ifdef PNG_READ_cHRM_SUPPORTED
813 void /* PRIVATE */
814 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
816 png_byte buf[32];
817 #ifdef PNG_FLOATING_POINT_SUPPORTED
818 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
819 #endif
820 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
821 int_y_green, int_x_blue, int_y_blue;
823 png_uint_32 uint_x, uint_y;
825 png_debug(1, "in png_handle_cHRM");
827 if (!(png_ptr->mode & PNG_HAVE_IHDR))
828 png_error(png_ptr, "Missing IHDR before cHRM");
829 else if (png_ptr->mode & PNG_HAVE_IDAT)
831 png_warning(png_ptr, "Invalid cHRM after IDAT");
832 png_crc_finish(png_ptr, length);
833 return;
835 else if (png_ptr->mode & PNG_HAVE_PLTE)
836 /* Should be an error, but we can cope with it */
837 png_warning(png_ptr, "Missing PLTE before cHRM");
839 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
840 #ifdef PNG_READ_sRGB_SUPPORTED
841 && !(info_ptr->valid & PNG_INFO_sRGB)
842 #endif
845 png_warning(png_ptr, "Duplicate cHRM chunk");
846 png_crc_finish(png_ptr, length);
847 return;
850 if (length != 32)
852 png_warning(png_ptr, "Incorrect cHRM chunk length");
853 png_crc_finish(png_ptr, length);
854 return;
857 png_crc_read(png_ptr, buf, 32);
858 if (png_crc_finish(png_ptr, 0))
859 return;
861 uint_x = png_get_uint_32(buf);
862 uint_y = png_get_uint_32(buf + 4);
863 int_x_white = (png_fixed_point)uint_x;
864 int_y_white = (png_fixed_point)uint_y;
866 uint_x = png_get_uint_32(buf + 8);
867 uint_y = png_get_uint_32(buf + 12);
868 int_x_red = (png_fixed_point)uint_x;
869 int_y_red = (png_fixed_point)uint_y;
871 uint_x = png_get_uint_32(buf + 16);
872 uint_y = png_get_uint_32(buf + 20);
873 int_x_green = (png_fixed_point)uint_x;
874 int_y_green = (png_fixed_point)uint_y;
876 uint_x = png_get_uint_32(buf + 24);
877 uint_y = png_get_uint_32(buf + 28);
878 int_x_blue = (png_fixed_point)uint_x;
879 int_y_blue = (png_fixed_point)uint_y;
881 #ifdef PNG_FLOATING_POINT_SUPPORTED
882 white_x = (float)int_x_white / (float)100000.0;
883 white_y = (float)int_y_white / (float)100000.0;
884 red_x = (float)int_x_red / (float)100000.0;
885 red_y = (float)int_y_red / (float)100000.0;
886 green_x = (float)int_x_green / (float)100000.0;
887 green_y = (float)int_y_green / (float)100000.0;
888 blue_x = (float)int_x_blue / (float)100000.0;
889 blue_y = (float)int_y_blue / (float)100000.0;
890 #endif
892 #ifdef PNG_READ_sRGB_SUPPORTED
893 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
895 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
896 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
897 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
898 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
899 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
900 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
901 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
902 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
904 png_warning(png_ptr,
905 "Ignoring incorrect cHRM value when sRGB is also present");
906 #ifdef PNG_CONSOLE_IO_SUPPORTED
907 #ifdef PNG_FLOATING_POINT_SUPPORTED
908 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
909 white_x, white_y, red_x, red_y);
910 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
911 green_x, green_y, blue_x, blue_y);
912 #else
913 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
914 (long)int_x_white, (long)int_y_white,
915 (long)int_x_red, (long)int_y_red);
916 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
917 (long)int_x_green, (long)int_y_green,
918 (long)int_x_blue, (long)int_y_blue);
919 #endif
920 #endif /* PNG_CONSOLE_IO_SUPPORTED */
922 return;
924 #endif /* PNG_READ_sRGB_SUPPORTED */
926 #ifdef PNG_FLOATING_POINT_SUPPORTED
927 png_set_cHRM(png_ptr, info_ptr,
928 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
929 #endif
930 #ifdef PNG_FIXED_POINT_SUPPORTED
931 png_set_cHRM_fixed(png_ptr, info_ptr,
932 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
933 int_y_green, int_x_blue, int_y_blue);
934 #endif
936 #endif
938 #ifdef PNG_READ_sRGB_SUPPORTED
939 void /* PRIVATE */
940 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
942 int intent;
943 png_byte buf[1];
945 png_debug(1, "in png_handle_sRGB");
947 if (!(png_ptr->mode & PNG_HAVE_IHDR))
948 png_error(png_ptr, "Missing IHDR before sRGB");
949 else if (png_ptr->mode & PNG_HAVE_IDAT)
951 png_warning(png_ptr, "Invalid sRGB after IDAT");
952 png_crc_finish(png_ptr, length);
953 return;
955 else if (png_ptr->mode & PNG_HAVE_PLTE)
956 /* Should be an error, but we can cope with it */
957 png_warning(png_ptr, "Out of place sRGB chunk");
959 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
961 png_warning(png_ptr, "Duplicate sRGB chunk");
962 png_crc_finish(png_ptr, length);
963 return;
966 if (length != 1)
968 png_warning(png_ptr, "Incorrect sRGB chunk length");
969 png_crc_finish(png_ptr, length);
970 return;
973 png_crc_read(png_ptr, buf, 1);
974 if (png_crc_finish(png_ptr, 0))
975 return;
977 intent = buf[0];
978 /* Check for bad intent */
979 if (intent >= PNG_sRGB_INTENT_LAST)
981 png_warning(png_ptr, "Unknown sRGB intent");
982 return;
985 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
986 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
988 png_fixed_point igamma;
989 #ifdef PNG_FIXED_POINT_SUPPORTED
990 igamma=info_ptr->int_gamma;
991 #else
992 # ifdef PNG_FLOATING_POINT_SUPPORTED
993 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
994 # endif
995 #endif
996 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
998 png_warning(png_ptr,
999 "Ignoring incorrect gAMA value when sRGB is also present");
1000 #ifdef PNG_CONSOLE_IO_SUPPORTED
1001 # ifdef PNG_FIXED_POINT_SUPPORTED
1002 fprintf(stderr, "incorrect gamma=(%d/100000)\n",
1003 (int)png_ptr->int_gamma);
1004 # else
1005 # ifdef PNG_FLOATING_POINT_SUPPORTED
1006 fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
1007 # endif
1008 # endif
1009 #endif
1012 #endif /* PNG_READ_gAMA_SUPPORTED */
1014 #ifdef PNG_READ_cHRM_SUPPORTED
1015 #ifdef PNG_FIXED_POINT_SUPPORTED
1016 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1017 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
1018 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
1019 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
1020 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
1021 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
1022 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
1023 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
1024 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
1026 png_warning(png_ptr,
1027 "Ignoring incorrect cHRM value when sRGB is also present");
1029 #endif /* PNG_FIXED_POINT_SUPPORTED */
1030 #endif /* PNG_READ_cHRM_SUPPORTED */
1032 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1034 #endif /* PNG_READ_sRGB_SUPPORTED */
1036 #ifdef PNG_READ_iCCP_SUPPORTED
1037 void /* PRIVATE */
1038 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1039 /* Note: this does not properly handle chunks that are > 64K under DOS */
1041 png_byte compression_type;
1042 png_bytep pC;
1043 png_charp profile;
1044 png_uint_32 skip = 0;
1045 png_uint_32 profile_size, profile_length;
1046 png_size_t slength, prefix_length, data_length;
1048 png_debug(1, "in png_handle_iCCP");
1050 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1051 png_error(png_ptr, "Missing IHDR before iCCP");
1052 else if (png_ptr->mode & PNG_HAVE_IDAT)
1054 png_warning(png_ptr, "Invalid iCCP after IDAT");
1055 png_crc_finish(png_ptr, length);
1056 return;
1058 else if (png_ptr->mode & PNG_HAVE_PLTE)
1059 /* Should be an error, but we can cope with it */
1060 png_warning(png_ptr, "Out of place iCCP chunk");
1062 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1064 png_warning(png_ptr, "Duplicate iCCP chunk");
1065 png_crc_finish(png_ptr, length);
1066 return;
1069 #ifdef PNG_MAX_MALLOC_64K
1070 if (length > (png_uint_32)65535L)
1072 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1073 skip = length - (png_uint_32)65535L;
1074 length = (png_uint_32)65535L;
1076 #endif
1078 png_free(png_ptr, png_ptr->chunkdata);
1079 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1080 slength = (png_size_t)length;
1081 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1083 if (png_crc_finish(png_ptr, skip))
1085 png_free(png_ptr, png_ptr->chunkdata);
1086 png_ptr->chunkdata = NULL;
1087 return;
1090 png_ptr->chunkdata[slength] = 0x00;
1092 for (profile = png_ptr->chunkdata; *profile; profile++)
1093 /* Empty loop to find end of name */ ;
1095 ++profile;
1097 /* There should be at least one zero (the compression type byte)
1098 * following the separator, and we should be on it
1100 if ( profile >= png_ptr->chunkdata + slength - 1)
1102 png_free(png_ptr, png_ptr->chunkdata);
1103 png_ptr->chunkdata = NULL;
1104 png_warning(png_ptr, "Malformed iCCP chunk");
1105 return;
1108 /* Compression_type should always be zero */
1109 compression_type = *profile++;
1110 if (compression_type)
1112 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1113 compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1114 wrote nonzero) */
1117 prefix_length = profile - png_ptr->chunkdata;
1118 png_decompress_chunk(png_ptr, compression_type,
1119 slength, prefix_length, &data_length);
1121 profile_length = data_length - prefix_length;
1123 if ( prefix_length > data_length || profile_length < 4)
1125 png_free(png_ptr, png_ptr->chunkdata);
1126 png_ptr->chunkdata = NULL;
1127 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1128 return;
1131 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1132 pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1133 profile_size = ((*(pC ))<<24) |
1134 ((*(pC + 1))<<16) |
1135 ((*(pC + 2))<< 8) |
1136 ((*(pC + 3)) );
1138 if (profile_size < profile_length)
1139 profile_length = profile_size;
1141 if (profile_size > profile_length)
1143 png_free(png_ptr, png_ptr->chunkdata);
1144 png_ptr->chunkdata = NULL;
1145 png_warning(png_ptr, "Ignoring truncated iCCP profile.");
1146 return;
1149 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1150 compression_type, png_ptr->chunkdata + prefix_length, profile_length);
1151 png_free(png_ptr, png_ptr->chunkdata);
1152 png_ptr->chunkdata = NULL;
1154 #endif /* PNG_READ_iCCP_SUPPORTED */
1156 #ifdef PNG_READ_sPLT_SUPPORTED
1157 void /* PRIVATE */
1158 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1159 /* Note: this does not properly handle chunks that are > 64K under DOS */
1161 png_bytep entry_start;
1162 png_sPLT_t new_palette;
1163 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1164 png_sPLT_entryp pp;
1165 #endif
1166 int data_length, entry_size, i;
1167 png_uint_32 skip = 0;
1168 png_size_t slength;
1170 png_debug(1, "in png_handle_sPLT");
1172 #ifdef PNG_USER_LIMITS_SUPPORTED
1174 if (png_ptr->user_chunk_cache_max != 0)
1176 if (png_ptr->user_chunk_cache_max == 1)
1178 png_crc_finish(png_ptr, length);
1179 return;
1181 if (--png_ptr->user_chunk_cache_max == 1)
1183 png_warning(png_ptr, "No space in chunk cache for sPLT");
1184 png_crc_finish(png_ptr, length);
1185 return;
1188 #endif
1190 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1191 png_error(png_ptr, "Missing IHDR before sPLT");
1192 else if (png_ptr->mode & PNG_HAVE_IDAT)
1194 png_warning(png_ptr, "Invalid sPLT after IDAT");
1195 png_crc_finish(png_ptr, length);
1196 return;
1199 #ifdef PNG_MAX_MALLOC_64K
1200 if (length > (png_uint_32)65535L)
1202 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1203 skip = length - (png_uint_32)65535L;
1204 length = (png_uint_32)65535L;
1206 #endif
1208 png_free(png_ptr, png_ptr->chunkdata);
1209 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1210 slength = (png_size_t)length;
1211 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1213 if (png_crc_finish(png_ptr, skip))
1215 png_free(png_ptr, png_ptr->chunkdata);
1216 png_ptr->chunkdata = NULL;
1217 return;
1220 png_ptr->chunkdata[slength] = 0x00;
1222 for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1223 entry_start++)
1224 /* Empty loop to find end of name */ ;
1225 ++entry_start;
1227 /* A sample depth should follow the separator, and we should be on it */
1228 if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1230 png_free(png_ptr, png_ptr->chunkdata);
1231 png_ptr->chunkdata = NULL;
1232 png_warning(png_ptr, "malformed sPLT chunk");
1233 return;
1236 new_palette.depth = *entry_start++;
1237 entry_size = (new_palette.depth == 8 ? 6 : 10);
1238 data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
1240 /* Integrity-check the data length */
1241 if (data_length % entry_size)
1243 png_free(png_ptr, png_ptr->chunkdata);
1244 png_ptr->chunkdata = NULL;
1245 png_warning(png_ptr, "sPLT chunk has bad length");
1246 return;
1249 new_palette.nentries = (png_int_32) ( data_length / entry_size);
1250 if ((png_uint_32) new_palette.nentries >
1251 (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
1253 png_warning(png_ptr, "sPLT chunk too long");
1254 return;
1256 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1257 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1258 if (new_palette.entries == NULL)
1260 png_warning(png_ptr, "sPLT chunk requires too much memory");
1261 return;
1264 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1265 for (i = 0; i < new_palette.nentries; i++)
1267 pp = new_palette.entries + i;
1269 if (new_palette.depth == 8)
1271 pp->red = *entry_start++;
1272 pp->green = *entry_start++;
1273 pp->blue = *entry_start++;
1274 pp->alpha = *entry_start++;
1276 else
1278 pp->red = png_get_uint_16(entry_start); entry_start += 2;
1279 pp->green = png_get_uint_16(entry_start); entry_start += 2;
1280 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1281 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1283 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1285 #else
1286 pp = new_palette.entries;
1287 for (i = 0; i < new_palette.nentries; i++)
1290 if (new_palette.depth == 8)
1292 pp[i].red = *entry_start++;
1293 pp[i].green = *entry_start++;
1294 pp[i].blue = *entry_start++;
1295 pp[i].alpha = *entry_start++;
1297 else
1299 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1300 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1301 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1302 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1304 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1306 #endif
1308 /* Discard all chunk data except the name and stash that */
1309 new_palette.name = png_ptr->chunkdata;
1311 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1313 png_free(png_ptr, png_ptr->chunkdata);
1314 png_ptr->chunkdata = NULL;
1315 png_free(png_ptr, new_palette.entries);
1317 #endif /* PNG_READ_sPLT_SUPPORTED */
1319 #ifdef PNG_READ_tRNS_SUPPORTED
1320 void /* PRIVATE */
1321 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1323 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1325 png_debug(1, "in png_handle_tRNS");
1327 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1328 png_error(png_ptr, "Missing IHDR before tRNS");
1329 else if (png_ptr->mode & PNG_HAVE_IDAT)
1331 png_warning(png_ptr, "Invalid tRNS after IDAT");
1332 png_crc_finish(png_ptr, length);
1333 return;
1335 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1337 png_warning(png_ptr, "Duplicate tRNS chunk");
1338 png_crc_finish(png_ptr, length);
1339 return;
1342 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1344 png_byte buf[2];
1346 if (length != 2)
1348 png_warning(png_ptr, "Incorrect tRNS chunk length");
1349 png_crc_finish(png_ptr, length);
1350 return;
1353 png_crc_read(png_ptr, buf, 2);
1354 png_ptr->num_trans = 1;
1355 png_ptr->trans_values.gray = png_get_uint_16(buf);
1357 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1359 png_byte buf[6];
1361 if (length != 6)
1363 png_warning(png_ptr, "Incorrect tRNS chunk length");
1364 png_crc_finish(png_ptr, length);
1365 return;
1367 png_crc_read(png_ptr, buf, (png_size_t)length);
1368 png_ptr->num_trans = 1;
1369 png_ptr->trans_values.red = png_get_uint_16(buf);
1370 png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1371 png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1373 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1375 if (!(png_ptr->mode & PNG_HAVE_PLTE))
1377 /* Should be an error, but we can cope with it. */
1378 png_warning(png_ptr, "Missing PLTE before tRNS");
1380 if (length > (png_uint_32)png_ptr->num_palette ||
1381 length > PNG_MAX_PALETTE_LENGTH)
1383 png_warning(png_ptr, "Incorrect tRNS chunk length");
1384 png_crc_finish(png_ptr, length);
1385 return;
1387 if (length == 0)
1389 png_warning(png_ptr, "Zero length tRNS chunk");
1390 png_crc_finish(png_ptr, length);
1391 return;
1393 png_crc_read(png_ptr, readbuf, (png_size_t)length);
1394 png_ptr->num_trans = (png_uint_16)length;
1396 else
1398 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1399 png_crc_finish(png_ptr, length);
1400 return;
1403 if (png_crc_finish(png_ptr, 0))
1405 png_ptr->num_trans = 0;
1406 return;
1409 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1410 &(png_ptr->trans_values));
1412 #endif
1414 #ifdef PNG_READ_bKGD_SUPPORTED
1415 void /* PRIVATE */
1416 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1418 png_size_t truelen;
1419 png_byte buf[6];
1421 png_debug(1, "in png_handle_bKGD");
1423 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1424 png_error(png_ptr, "Missing IHDR before bKGD");
1425 else if (png_ptr->mode & PNG_HAVE_IDAT)
1427 png_warning(png_ptr, "Invalid bKGD after IDAT");
1428 png_crc_finish(png_ptr, length);
1429 return;
1431 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1432 !(png_ptr->mode & PNG_HAVE_PLTE))
1434 png_warning(png_ptr, "Missing PLTE before bKGD");
1435 png_crc_finish(png_ptr, length);
1436 return;
1438 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1440 png_warning(png_ptr, "Duplicate bKGD chunk");
1441 png_crc_finish(png_ptr, length);
1442 return;
1445 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1446 truelen = 1;
1447 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1448 truelen = 6;
1449 else
1450 truelen = 2;
1452 if (length != truelen)
1454 png_warning(png_ptr, "Incorrect bKGD chunk length");
1455 png_crc_finish(png_ptr, length);
1456 return;
1459 png_crc_read(png_ptr, buf, truelen);
1460 if (png_crc_finish(png_ptr, 0))
1461 return;
1463 /* We convert the index value into RGB components so that we can allow
1464 * arbitrary RGB values for background when we have transparency, and
1465 * so it is easy to determine the RGB values of the background color
1466 * from the info_ptr struct. */
1467 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1469 png_ptr->background.index = buf[0];
1470 if (info_ptr && info_ptr->num_palette)
1472 if (buf[0] >= info_ptr->num_palette)
1474 png_warning(png_ptr, "Incorrect bKGD chunk index value");
1475 return;
1477 png_ptr->background.red =
1478 (png_uint_16)png_ptr->palette[buf[0]].red;
1479 png_ptr->background.green =
1480 (png_uint_16)png_ptr->palette[buf[0]].green;
1481 png_ptr->background.blue =
1482 (png_uint_16)png_ptr->palette[buf[0]].blue;
1485 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1487 png_ptr->background.red =
1488 png_ptr->background.green =
1489 png_ptr->background.blue =
1490 png_ptr->background.gray = png_get_uint_16(buf);
1492 else
1494 png_ptr->background.red = png_get_uint_16(buf);
1495 png_ptr->background.green = png_get_uint_16(buf + 2);
1496 png_ptr->background.blue = png_get_uint_16(buf + 4);
1499 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1501 #endif
1503 #ifdef PNG_READ_hIST_SUPPORTED
1504 void /* PRIVATE */
1505 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1507 unsigned int num, i;
1508 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1510 png_debug(1, "in png_handle_hIST");
1512 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1513 png_error(png_ptr, "Missing IHDR before hIST");
1514 else if (png_ptr->mode & PNG_HAVE_IDAT)
1516 png_warning(png_ptr, "Invalid hIST after IDAT");
1517 png_crc_finish(png_ptr, length);
1518 return;
1520 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1522 png_warning(png_ptr, "Missing PLTE before hIST");
1523 png_crc_finish(png_ptr, length);
1524 return;
1526 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1528 png_warning(png_ptr, "Duplicate hIST chunk");
1529 png_crc_finish(png_ptr, length);
1530 return;
1533 if (length > 2*PNG_MAX_PALETTE_LENGTH ||
1534 length != (unsigned int) (2*png_ptr->num_palette))
1536 png_warning(png_ptr, "Incorrect hIST chunk length");
1537 png_crc_finish(png_ptr, length);
1538 return;
1541 num = length / 2 ;
1543 for (i = 0; i < num; i++)
1545 png_byte buf[2];
1547 png_crc_read(png_ptr, buf, 2);
1548 readbuf[i] = png_get_uint_16(buf);
1551 if (png_crc_finish(png_ptr, 0))
1552 return;
1554 png_set_hIST(png_ptr, info_ptr, readbuf);
1556 #endif
1558 #ifdef PNG_READ_pHYs_SUPPORTED
1559 void /* PRIVATE */
1560 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1562 png_byte buf[9];
1563 png_uint_32 res_x, res_y;
1564 int unit_type;
1566 png_debug(1, "in png_handle_pHYs");
1568 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1569 png_error(png_ptr, "Missing IHDR before pHYs");
1570 else if (png_ptr->mode & PNG_HAVE_IDAT)
1572 png_warning(png_ptr, "Invalid pHYs after IDAT");
1573 png_crc_finish(png_ptr, length);
1574 return;
1576 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1578 png_warning(png_ptr, "Duplicate pHYs chunk");
1579 png_crc_finish(png_ptr, length);
1580 return;
1583 if (length != 9)
1585 png_warning(png_ptr, "Incorrect pHYs chunk length");
1586 png_crc_finish(png_ptr, length);
1587 return;
1590 png_crc_read(png_ptr, buf, 9);
1591 if (png_crc_finish(png_ptr, 0))
1592 return;
1594 res_x = png_get_uint_32(buf);
1595 res_y = png_get_uint_32(buf + 4);
1596 unit_type = buf[8];
1597 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1599 #endif
1601 #ifdef PNG_READ_oFFs_SUPPORTED
1602 void /* PRIVATE */
1603 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1605 png_byte buf[9];
1606 png_int_32 offset_x, offset_y;
1607 int unit_type;
1609 png_debug(1, "in png_handle_oFFs");
1611 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1612 png_error(png_ptr, "Missing IHDR before oFFs");
1613 else if (png_ptr->mode & PNG_HAVE_IDAT)
1615 png_warning(png_ptr, "Invalid oFFs after IDAT");
1616 png_crc_finish(png_ptr, length);
1617 return;
1619 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1621 png_warning(png_ptr, "Duplicate oFFs chunk");
1622 png_crc_finish(png_ptr, length);
1623 return;
1626 if (length != 9)
1628 png_warning(png_ptr, "Incorrect oFFs chunk length");
1629 png_crc_finish(png_ptr, length);
1630 return;
1633 png_crc_read(png_ptr, buf, 9);
1634 if (png_crc_finish(png_ptr, 0))
1635 return;
1637 offset_x = png_get_int_32(buf);
1638 offset_y = png_get_int_32(buf + 4);
1639 unit_type = buf[8];
1640 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1642 #endif
1644 #ifdef PNG_READ_pCAL_SUPPORTED
1645 /* Read the pCAL chunk (described in the PNG Extensions document) */
1646 void /* PRIVATE */
1647 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1649 png_int_32 X0, X1;
1650 png_byte type, nparams;
1651 png_charp buf, units, endptr;
1652 png_charpp params;
1653 png_size_t slength;
1654 int i;
1656 png_debug(1, "in png_handle_pCAL");
1658 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1659 png_error(png_ptr, "Missing IHDR before pCAL");
1660 else if (png_ptr->mode & PNG_HAVE_IDAT)
1662 png_warning(png_ptr, "Invalid pCAL after IDAT");
1663 png_crc_finish(png_ptr, length);
1664 return;
1666 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1668 png_warning(png_ptr, "Duplicate pCAL chunk");
1669 png_crc_finish(png_ptr, length);
1670 return;
1673 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1674 length + 1);
1675 png_free(png_ptr, png_ptr->chunkdata);
1676 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1677 if (png_ptr->chunkdata == NULL)
1679 png_warning(png_ptr, "No memory for pCAL purpose.");
1680 return;
1682 slength = (png_size_t)length;
1683 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1685 if (png_crc_finish(png_ptr, 0))
1687 png_free(png_ptr, png_ptr->chunkdata);
1688 png_ptr->chunkdata = NULL;
1689 return;
1692 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1694 png_debug(3, "Finding end of pCAL purpose string");
1695 for (buf = png_ptr->chunkdata; *buf; buf++)
1696 /* Empty loop */ ;
1698 endptr = png_ptr->chunkdata + slength;
1700 /* We need to have at least 12 bytes after the purpose string
1701 in order to get the parameter information. */
1702 if (endptr <= buf + 12)
1704 png_warning(png_ptr, "Invalid pCAL data");
1705 png_free(png_ptr, png_ptr->chunkdata);
1706 png_ptr->chunkdata = NULL;
1707 return;
1710 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1711 X0 = png_get_int_32((png_bytep)buf+1);
1712 X1 = png_get_int_32((png_bytep)buf+5);
1713 type = buf[9];
1714 nparams = buf[10];
1715 units = buf + 11;
1717 png_debug(3, "Checking pCAL equation type and number of parameters");
1718 /* Check that we have the right number of parameters for known
1719 equation types. */
1720 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1721 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1722 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1723 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1725 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1726 png_free(png_ptr, png_ptr->chunkdata);
1727 png_ptr->chunkdata = NULL;
1728 return;
1730 else if (type >= PNG_EQUATION_LAST)
1732 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1735 for (buf = units; *buf; buf++)
1736 /* Empty loop to move past the units string. */ ;
1738 png_debug(3, "Allocating pCAL parameters array");
1739 params = (png_charpp)png_malloc_warn(png_ptr,
1740 (png_uint_32)(nparams * png_sizeof(png_charp))) ;
1741 if (params == NULL)
1743 png_free(png_ptr, png_ptr->chunkdata);
1744 png_ptr->chunkdata = NULL;
1745 png_warning(png_ptr, "No memory for pCAL params.");
1746 return;
1749 /* Get pointers to the start of each parameter string. */
1750 for (i = 0; i < (int)nparams; i++)
1752 buf++; /* Skip the null string terminator from previous parameter. */
1754 png_debug1(3, "Reading pCAL parameter %d", i);
1755 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1756 /* Empty loop to move past each parameter string */ ;
1758 /* Make sure we haven't run out of data yet */
1759 if (buf > endptr)
1761 png_warning(png_ptr, "Invalid pCAL data");
1762 png_free(png_ptr, png_ptr->chunkdata);
1763 png_ptr->chunkdata = NULL;
1764 png_free(png_ptr, params);
1765 return;
1769 png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
1770 units, params);
1772 png_free(png_ptr, png_ptr->chunkdata);
1773 png_ptr->chunkdata = NULL;
1774 png_free(png_ptr, params);
1776 #endif
1778 #ifdef PNG_READ_sCAL_SUPPORTED
1779 /* Read the sCAL chunk */
1780 void /* PRIVATE */
1781 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1783 png_charp ep;
1784 #ifdef PNG_FLOATING_POINT_SUPPORTED
1785 double width, height;
1786 png_charp vp;
1787 #else
1788 #ifdef PNG_FIXED_POINT_SUPPORTED
1789 png_charp swidth, sheight;
1790 #endif
1791 #endif
1792 png_size_t slength;
1794 png_debug(1, "in png_handle_sCAL");
1796 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1797 png_error(png_ptr, "Missing IHDR before sCAL");
1798 else if (png_ptr->mode & PNG_HAVE_IDAT)
1800 png_warning(png_ptr, "Invalid sCAL after IDAT");
1801 png_crc_finish(png_ptr, length);
1802 return;
1804 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1806 png_warning(png_ptr, "Duplicate sCAL chunk");
1807 png_crc_finish(png_ptr, length);
1808 return;
1811 /* Need unit type, width, \0, height: minimum 4 bytes */
1812 else if (length < 4)
1814 png_warning(png_ptr, "sCAL chunk too short");
1815 png_crc_finish(png_ptr, length);
1816 return;
1819 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1820 length + 1);
1821 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1822 if (png_ptr->chunkdata == NULL)
1824 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1825 png_crc_finish(png_ptr, length);
1826 return;
1828 slength = (png_size_t)length;
1829 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1831 if (png_crc_finish(png_ptr, 0))
1833 png_free(png_ptr, png_ptr->chunkdata);
1834 png_ptr->chunkdata = NULL;
1835 return;
1838 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1840 ep = png_ptr->chunkdata + 1; /* Skip unit byte */
1842 #ifdef PNG_FLOATING_POINT_SUPPORTED
1843 width = png_strtod(png_ptr, ep, &vp);
1844 if (*vp)
1846 png_warning(png_ptr, "malformed width string in sCAL chunk");
1847 png_free(png_ptr, png_ptr->chunkdata);
1848 png_ptr->chunkdata = NULL;
1849 return;
1851 #else
1852 #ifdef PNG_FIXED_POINT_SUPPORTED
1853 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1854 if (swidth == NULL)
1856 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1857 png_free(png_ptr, png_ptr->chunkdata);
1858 png_ptr->chunkdata = NULL;
1859 return;
1861 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep) + 1);
1862 #endif
1863 #endif
1865 for (ep = png_ptr->chunkdata + 1; *ep; ep++)
1866 /* Empty loop */ ;
1867 ep++;
1869 if (png_ptr->chunkdata + slength < ep)
1871 png_warning(png_ptr, "Truncated sCAL chunk");
1872 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1873 png_free(png_ptr, swidth);
1874 #endif
1875 png_free(png_ptr, png_ptr->chunkdata);
1876 png_ptr->chunkdata = NULL;
1877 return;
1880 #ifdef PNG_FLOATING_POINT_SUPPORTED
1881 height = png_strtod(png_ptr, ep, &vp);
1882 if (*vp)
1884 png_warning(png_ptr, "malformed height string in sCAL chunk");
1885 png_free(png_ptr, png_ptr->chunkdata);
1886 png_ptr->chunkdata = NULL;
1887 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1888 png_free(png_ptr, swidth);
1889 #endif
1890 return;
1892 #else
1893 #ifdef PNG_FIXED_POINT_SUPPORTED
1894 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1895 if (sheight == NULL)
1897 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1898 png_free(png_ptr, png_ptr->chunkdata);
1899 png_ptr->chunkdata = NULL;
1900 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1901 png_free(png_ptr, swidth);
1902 #endif
1903 return;
1905 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep) + 1);
1906 #endif
1907 #endif
1909 if (png_ptr->chunkdata + slength < ep
1910 #ifdef PNG_FLOATING_POINT_SUPPORTED
1911 || width <= 0. || height <= 0.
1912 #endif
1915 png_warning(png_ptr, "Invalid sCAL data");
1916 png_free(png_ptr, png_ptr->chunkdata);
1917 png_ptr->chunkdata = NULL;
1918 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1919 png_free(png_ptr, swidth);
1920 png_free(png_ptr, sheight);
1921 #endif
1922 return;
1926 #ifdef PNG_FLOATING_POINT_SUPPORTED
1927 png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
1928 #else
1929 #ifdef PNG_FIXED_POINT_SUPPORTED
1930 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
1931 #endif
1932 #endif
1934 png_free(png_ptr, png_ptr->chunkdata);
1935 png_ptr->chunkdata = NULL;
1936 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1937 png_free(png_ptr, swidth);
1938 png_free(png_ptr, sheight);
1939 #endif
1941 #endif
1943 #ifdef PNG_READ_tIME_SUPPORTED
1944 void /* PRIVATE */
1945 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1947 png_byte buf[7];
1948 png_time mod_time;
1950 png_debug(1, "in png_handle_tIME");
1952 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1953 png_error(png_ptr, "Out of place tIME chunk");
1954 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1956 png_warning(png_ptr, "Duplicate tIME chunk");
1957 png_crc_finish(png_ptr, length);
1958 return;
1961 if (png_ptr->mode & PNG_HAVE_IDAT)
1962 png_ptr->mode |= PNG_AFTER_IDAT;
1964 if (length != 7)
1966 png_warning(png_ptr, "Incorrect tIME chunk length");
1967 png_crc_finish(png_ptr, length);
1968 return;
1971 png_crc_read(png_ptr, buf, 7);
1972 if (png_crc_finish(png_ptr, 0))
1973 return;
1975 mod_time.second = buf[6];
1976 mod_time.minute = buf[5];
1977 mod_time.hour = buf[4];
1978 mod_time.day = buf[3];
1979 mod_time.month = buf[2];
1980 mod_time.year = png_get_uint_16(buf);
1982 png_set_tIME(png_ptr, info_ptr, &mod_time);
1984 #endif
1986 #ifdef PNG_READ_tEXt_SUPPORTED
1987 /* Note: this does not properly handle chunks that are > 64K under DOS */
1988 void /* PRIVATE */
1989 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1991 png_textp text_ptr;
1992 png_charp key;
1993 png_charp text;
1994 png_uint_32 skip = 0;
1995 png_size_t slength;
1996 int ret;
1998 png_debug(1, "in png_handle_tEXt");
2000 #ifdef PNG_USER_LIMITS_SUPPORTED
2001 if (png_ptr->user_chunk_cache_max != 0)
2003 if (png_ptr->user_chunk_cache_max == 1)
2005 png_crc_finish(png_ptr, length);
2006 return;
2008 if (--png_ptr->user_chunk_cache_max == 1)
2010 png_warning(png_ptr, "No space in chunk cache for tEXt");
2011 png_crc_finish(png_ptr, length);
2012 return;
2015 #endif
2017 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2018 png_error(png_ptr, "Missing IHDR before tEXt");
2020 if (png_ptr->mode & PNG_HAVE_IDAT)
2021 png_ptr->mode |= PNG_AFTER_IDAT;
2023 #ifdef PNG_MAX_MALLOC_64K
2024 if (length > (png_uint_32)65535L)
2026 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2027 skip = length - (png_uint_32)65535L;
2028 length = (png_uint_32)65535L;
2030 #endif
2032 png_free(png_ptr, png_ptr->chunkdata);
2034 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2035 if (png_ptr->chunkdata == NULL)
2037 png_warning(png_ptr, "No memory to process text chunk.");
2038 return;
2040 slength = (png_size_t)length;
2041 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2043 if (png_crc_finish(png_ptr, skip))
2045 png_free(png_ptr, png_ptr->chunkdata);
2046 png_ptr->chunkdata = NULL;
2047 return;
2050 key = png_ptr->chunkdata;
2052 key[slength] = 0x00;
2054 for (text = key; *text; text++)
2055 /* Empty loop to find end of key */ ;
2057 if (text != key + slength)
2058 text++;
2060 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2061 (png_uint_32)png_sizeof(png_text));
2062 if (text_ptr == NULL)
2064 png_warning(png_ptr, "Not enough memory to process text chunk.");
2065 png_free(png_ptr, png_ptr->chunkdata);
2066 png_ptr->chunkdata = NULL;
2067 return;
2069 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2070 text_ptr->key = key;
2071 #ifdef PNG_iTXt_SUPPORTED
2072 text_ptr->lang = NULL;
2073 text_ptr->lang_key = NULL;
2074 text_ptr->itxt_length = 0;
2075 #endif
2076 text_ptr->text = text;
2077 text_ptr->text_length = png_strlen(text);
2079 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2081 png_free(png_ptr, png_ptr->chunkdata);
2082 png_ptr->chunkdata = NULL;
2083 png_free(png_ptr, text_ptr);
2084 if (ret)
2085 png_warning(png_ptr, "Insufficient memory to process text chunk.");
2087 #endif
2089 #ifdef PNG_READ_zTXt_SUPPORTED
2090 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2091 void /* PRIVATE */
2092 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2094 png_textp text_ptr;
2095 png_charp text;
2096 int comp_type;
2097 int ret;
2098 png_size_t slength, prefix_len, data_len;
2100 png_debug(1, "in png_handle_zTXt");
2102 #ifdef PNG_USER_LIMITS_SUPPORTED
2103 if (png_ptr->user_chunk_cache_max != 0)
2105 if (png_ptr->user_chunk_cache_max == 1)
2107 png_crc_finish(png_ptr, length);
2108 return;
2110 if (--png_ptr->user_chunk_cache_max == 1)
2112 png_warning(png_ptr, "No space in chunk cache for zTXt");
2113 png_crc_finish(png_ptr, length);
2114 return;
2117 #endif
2119 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2120 png_error(png_ptr, "Missing IHDR before zTXt");
2122 if (png_ptr->mode & PNG_HAVE_IDAT)
2123 png_ptr->mode |= PNG_AFTER_IDAT;
2125 #ifdef PNG_MAX_MALLOC_64K
2126 /* We will no doubt have problems with chunks even half this size, but
2127 there is no hard and fast rule to tell us where to stop. */
2128 if (length > (png_uint_32)65535L)
2130 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2131 png_crc_finish(png_ptr, length);
2132 return;
2134 #endif
2136 png_free(png_ptr, png_ptr->chunkdata);
2137 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2138 if (png_ptr->chunkdata == NULL)
2140 png_warning(png_ptr, "Out of memory processing zTXt chunk.");
2141 return;
2143 slength = (png_size_t)length;
2144 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2145 if (png_crc_finish(png_ptr, 0))
2147 png_free(png_ptr, png_ptr->chunkdata);
2148 png_ptr->chunkdata = NULL;
2149 return;
2152 png_ptr->chunkdata[slength] = 0x00;
2154 for (text = png_ptr->chunkdata; *text; text++)
2155 /* Empty loop */ ;
2157 /* zTXt must have some text after the chunkdataword */
2158 if (text >= png_ptr->chunkdata + slength - 2)
2160 png_warning(png_ptr, "Truncated zTXt chunk");
2161 png_free(png_ptr, png_ptr->chunkdata);
2162 png_ptr->chunkdata = NULL;
2163 return;
2165 else
2167 comp_type = *(++text);
2168 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2170 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2171 comp_type = PNG_TEXT_COMPRESSION_zTXt;
2173 text++; /* Skip the compression_method byte */
2175 prefix_len = text - png_ptr->chunkdata;
2177 png_decompress_chunk(png_ptr, comp_type,
2178 (png_size_t)length, prefix_len, &data_len);
2180 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2181 (png_uint_32)png_sizeof(png_text));
2182 if (text_ptr == NULL)
2184 png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
2185 png_free(png_ptr, png_ptr->chunkdata);
2186 png_ptr->chunkdata = NULL;
2187 return;
2189 text_ptr->compression = comp_type;
2190 text_ptr->key = png_ptr->chunkdata;
2191 #ifdef PNG_iTXt_SUPPORTED
2192 text_ptr->lang = NULL;
2193 text_ptr->lang_key = NULL;
2194 text_ptr->itxt_length = 0;
2195 #endif
2196 text_ptr->text = png_ptr->chunkdata + prefix_len;
2197 text_ptr->text_length = data_len;
2199 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2201 png_free(png_ptr, text_ptr);
2202 png_free(png_ptr, png_ptr->chunkdata);
2203 png_ptr->chunkdata = NULL;
2204 if (ret)
2205 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2207 #endif
2209 #ifdef PNG_READ_iTXt_SUPPORTED
2210 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2211 void /* PRIVATE */
2212 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2214 png_textp text_ptr;
2215 png_charp key, lang, text, lang_key;
2216 int comp_flag;
2217 int comp_type = 0;
2218 int ret;
2219 png_size_t slength, prefix_len, data_len;
2221 png_debug(1, "in png_handle_iTXt");
2223 #ifdef PNG_USER_LIMITS_SUPPORTED
2224 if (png_ptr->user_chunk_cache_max != 0)
2226 if (png_ptr->user_chunk_cache_max == 1)
2228 png_crc_finish(png_ptr, length);
2229 return;
2231 if (--png_ptr->user_chunk_cache_max == 1)
2233 png_warning(png_ptr, "No space in chunk cache for iTXt");
2234 png_crc_finish(png_ptr, length);
2235 return;
2238 #endif
2240 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2241 png_error(png_ptr, "Missing IHDR before iTXt");
2243 if (png_ptr->mode & PNG_HAVE_IDAT)
2244 png_ptr->mode |= PNG_AFTER_IDAT;
2246 #ifdef PNG_MAX_MALLOC_64K
2247 /* We will no doubt have problems with chunks even half this size, but
2248 there is no hard and fast rule to tell us where to stop. */
2249 if (length > (png_uint_32)65535L)
2251 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2252 png_crc_finish(png_ptr, length);
2253 return;
2255 #endif
2257 png_free(png_ptr, png_ptr->chunkdata);
2258 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2259 if (png_ptr->chunkdata == NULL)
2261 png_warning(png_ptr, "No memory to process iTXt chunk.");
2262 return;
2264 slength = (png_size_t)length;
2265 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2266 if (png_crc_finish(png_ptr, 0))
2268 png_free(png_ptr, png_ptr->chunkdata);
2269 png_ptr->chunkdata = NULL;
2270 return;
2273 png_ptr->chunkdata[slength] = 0x00;
2275 for (lang = png_ptr->chunkdata; *lang; lang++)
2276 /* Empty loop */ ;
2277 lang++; /* Skip NUL separator */
2279 /* iTXt must have a language tag (possibly empty), two compression bytes,
2280 * translated keyword (possibly empty), and possibly some text after the
2281 * keyword
2284 if (lang >= png_ptr->chunkdata + slength - 3)
2286 png_warning(png_ptr, "Truncated iTXt chunk");
2287 png_free(png_ptr, png_ptr->chunkdata);
2288 png_ptr->chunkdata = NULL;
2289 return;
2291 else
2293 comp_flag = *lang++;
2294 comp_type = *lang++;
2297 for (lang_key = lang; *lang_key; lang_key++)
2298 /* Empty loop */ ;
2299 lang_key++; /* Skip NUL separator */
2301 if (lang_key >= png_ptr->chunkdata + slength)
2303 png_warning(png_ptr, "Truncated iTXt chunk");
2304 png_free(png_ptr, png_ptr->chunkdata);
2305 png_ptr->chunkdata = NULL;
2306 return;
2309 for (text = lang_key; *text; text++)
2310 /* Empty loop */ ;
2311 text++; /* Skip NUL separator */
2312 if (text >= png_ptr->chunkdata + slength)
2314 png_warning(png_ptr, "Malformed iTXt chunk");
2315 png_free(png_ptr, png_ptr->chunkdata);
2316 png_ptr->chunkdata = NULL;
2317 return;
2320 prefix_len = text - png_ptr->chunkdata;
2322 key=png_ptr->chunkdata;
2323 if (comp_flag)
2324 png_decompress_chunk(png_ptr, comp_type,
2325 (size_t)length, prefix_len, &data_len);
2326 else
2327 data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2328 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2329 (png_uint_32)png_sizeof(png_text));
2330 if (text_ptr == NULL)
2332 png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
2333 png_free(png_ptr, png_ptr->chunkdata);
2334 png_ptr->chunkdata = NULL;
2335 return;
2337 text_ptr->compression = (int)comp_flag + 1;
2338 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2339 text_ptr->lang = png_ptr->chunkdata + (lang - key);
2340 text_ptr->itxt_length = data_len;
2341 text_ptr->text_length = 0;
2342 text_ptr->key = png_ptr->chunkdata;
2343 text_ptr->text = png_ptr->chunkdata + prefix_len;
2345 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2347 png_free(png_ptr, text_ptr);
2348 png_free(png_ptr, png_ptr->chunkdata);
2349 png_ptr->chunkdata = NULL;
2350 if (ret)
2351 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2353 #endif
2355 /* This function is called when we haven't found a handler for a
2356 chunk. If there isn't a problem with the chunk itself (ie bad
2357 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2358 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2359 case it will be saved away to be written out later. */
2360 void /* PRIVATE */
2361 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2363 png_uint_32 skip = 0;
2365 png_debug(1, "in png_handle_unknown");
2367 #ifdef PNG_USER_LIMITS_SUPPORTED
2368 if (png_ptr->user_chunk_cache_max != 0)
2370 if (png_ptr->user_chunk_cache_max == 1)
2372 png_crc_finish(png_ptr, length);
2373 return;
2375 if (--png_ptr->user_chunk_cache_max == 1)
2377 png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2378 png_crc_finish(png_ptr, length);
2379 return;
2382 #endif
2384 if (png_ptr->mode & PNG_HAVE_IDAT)
2386 #ifdef PNG_USE_LOCAL_ARRAYS
2387 PNG_CONST PNG_IDAT;
2388 #endif
2389 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */
2390 png_ptr->mode |= PNG_AFTER_IDAT;
2393 if (!(png_ptr->chunk_name[0] & 0x20))
2395 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2396 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2397 PNG_HANDLE_CHUNK_ALWAYS
2398 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2399 && png_ptr->read_user_chunk_fn == NULL
2400 #endif
2402 #endif
2403 png_chunk_error(png_ptr, "unknown critical chunk");
2406 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2407 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2408 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2409 || (png_ptr->read_user_chunk_fn != NULL)
2410 #endif
2413 #ifdef PNG_MAX_MALLOC_64K
2414 if (length > (png_uint_32)65535L)
2416 png_warning(png_ptr, "unknown chunk too large to fit in memory");
2417 skip = length - (png_uint_32)65535L;
2418 length = (png_uint_32)65535L;
2420 #endif
2421 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2422 (png_charp)png_ptr->chunk_name,
2423 png_sizeof(png_ptr->unknown_chunk.name));
2424 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
2425 = '\0';
2426 png_ptr->unknown_chunk.size = (png_size_t)length;
2427 if (length == 0)
2428 png_ptr->unknown_chunk.data = NULL;
2429 else
2431 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2432 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2434 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2435 if (png_ptr->read_user_chunk_fn != NULL)
2437 /* Callback to user unknown chunk handler */
2438 int ret;
2439 ret = (*(png_ptr->read_user_chunk_fn))
2440 (png_ptr, &png_ptr->unknown_chunk);
2441 if (ret < 0)
2442 png_chunk_error(png_ptr, "error in user chunk");
2443 if (ret == 0)
2445 if (!(png_ptr->chunk_name[0] & 0x20))
2446 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2447 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2448 PNG_HANDLE_CHUNK_ALWAYS)
2449 #endif
2450 png_chunk_error(png_ptr, "unknown critical chunk");
2451 png_set_unknown_chunks(png_ptr, info_ptr,
2452 &png_ptr->unknown_chunk, 1);
2455 else
2456 #endif
2457 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2458 png_free(png_ptr, png_ptr->unknown_chunk.data);
2459 png_ptr->unknown_chunk.data = NULL;
2461 else
2462 #endif
2463 skip = length;
2465 png_crc_finish(png_ptr, skip);
2467 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2468 PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
2469 #endif
2472 /* This function is called to verify that a chunk name is valid.
2473 This function can't have the "critical chunk check" incorporated
2474 into it, since in the future we will need to be able to call user
2475 functions to handle unknown critical chunks after we check that
2476 the chunk name itself is valid. */
2478 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2480 void /* PRIVATE */
2481 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2483 png_debug(1, "in png_check_chunk_name");
2484 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2485 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2487 png_chunk_error(png_ptr, "invalid chunk type");
2491 /* Combines the row recently read in with the existing pixels in the
2492 row. This routine takes care of alpha and transparency if requested.
2493 This routine also handles the two methods of progressive display
2494 of interlaced images, depending on the mask value.
2495 The mask value describes which pixels are to be combined with
2496 the row. The pattern always repeats every 8 pixels, so just 8
2497 bits are needed. A one indicates the pixel is to be combined,
2498 a zero indicates the pixel is to be skipped. This is in addition
2499 to any alpha or transparency value associated with the pixel. If
2500 you want all pixels to be combined, pass 0xff (255) in mask. */
2502 void /* PRIVATE */
2503 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2505 png_debug(1, "in png_combine_row");
2506 if (mask == 0xff)
2508 png_memcpy(row, png_ptr->row_buf + 1,
2509 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2511 else
2513 switch (png_ptr->row_info.pixel_depth)
2515 case 1:
2517 png_bytep sp = png_ptr->row_buf + 1;
2518 png_bytep dp = row;
2519 int s_inc, s_start, s_end;
2520 int m = 0x80;
2521 int shift;
2522 png_uint_32 i;
2523 png_uint_32 row_width = png_ptr->width;
2525 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2526 if (png_ptr->transformations & PNG_PACKSWAP)
2528 s_start = 0;
2529 s_end = 7;
2530 s_inc = 1;
2532 else
2533 #endif
2535 s_start = 7;
2536 s_end = 0;
2537 s_inc = -1;
2540 shift = s_start;
2542 for (i = 0; i < row_width; i++)
2544 if (m & mask)
2546 int value;
2548 value = (*sp >> shift) & 0x01;
2549 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2550 *dp |= (png_byte)(value << shift);
2553 if (shift == s_end)
2555 shift = s_start;
2556 sp++;
2557 dp++;
2559 else
2560 shift += s_inc;
2562 if (m == 1)
2563 m = 0x80;
2564 else
2565 m >>= 1;
2567 break;
2569 case 2:
2571 png_bytep sp = png_ptr->row_buf + 1;
2572 png_bytep dp = row;
2573 int s_start, s_end, s_inc;
2574 int m = 0x80;
2575 int shift;
2576 png_uint_32 i;
2577 png_uint_32 row_width = png_ptr->width;
2578 int value;
2580 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2581 if (png_ptr->transformations & PNG_PACKSWAP)
2583 s_start = 0;
2584 s_end = 6;
2585 s_inc = 2;
2587 else
2588 #endif
2590 s_start = 6;
2591 s_end = 0;
2592 s_inc = -2;
2595 shift = s_start;
2597 for (i = 0; i < row_width; i++)
2599 if (m & mask)
2601 value = (*sp >> shift) & 0x03;
2602 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2603 *dp |= (png_byte)(value << shift);
2606 if (shift == s_end)
2608 shift = s_start;
2609 sp++;
2610 dp++;
2612 else
2613 shift += s_inc;
2614 if (m == 1)
2615 m = 0x80;
2616 else
2617 m >>= 1;
2619 break;
2621 case 4:
2623 png_bytep sp = png_ptr->row_buf + 1;
2624 png_bytep dp = row;
2625 int s_start, s_end, s_inc;
2626 int m = 0x80;
2627 int shift;
2628 png_uint_32 i;
2629 png_uint_32 row_width = png_ptr->width;
2630 int value;
2632 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2633 if (png_ptr->transformations & PNG_PACKSWAP)
2635 s_start = 0;
2636 s_end = 4;
2637 s_inc = 4;
2639 else
2640 #endif
2642 s_start = 4;
2643 s_end = 0;
2644 s_inc = -4;
2646 shift = s_start;
2648 for (i = 0; i < row_width; i++)
2650 if (m & mask)
2652 value = (*sp >> shift) & 0xf;
2653 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2654 *dp |= (png_byte)(value << shift);
2657 if (shift == s_end)
2659 shift = s_start;
2660 sp++;
2661 dp++;
2663 else
2664 shift += s_inc;
2665 if (m == 1)
2666 m = 0x80;
2667 else
2668 m >>= 1;
2670 break;
2672 default:
2674 png_bytep sp = png_ptr->row_buf + 1;
2675 png_bytep dp = row;
2676 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2677 png_uint_32 i;
2678 png_uint_32 row_width = png_ptr->width;
2679 png_byte m = 0x80;
2682 for (i = 0; i < row_width; i++)
2684 if (m & mask)
2686 png_memcpy(dp, sp, pixel_bytes);
2689 sp += pixel_bytes;
2690 dp += pixel_bytes;
2692 if (m == 1)
2693 m = 0x80;
2694 else
2695 m >>= 1;
2697 break;
2703 #ifdef PNG_READ_INTERLACING_SUPPORTED
2704 /* OLD pre-1.0.9 interface:
2705 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2706 png_uint_32 transformations)
2708 void /* PRIVATE */
2709 png_do_read_interlace(png_structp png_ptr)
2711 png_row_infop row_info = &(png_ptr->row_info);
2712 png_bytep row = png_ptr->row_buf + 1;
2713 int pass = png_ptr->pass;
2714 png_uint_32 transformations = png_ptr->transformations;
2715 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2716 /* Offset to next interlace block */
2717 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2719 png_debug(1, "in png_do_read_interlace");
2720 if (row != NULL && row_info != NULL)
2722 png_uint_32 final_width;
2724 final_width = row_info->width * png_pass_inc[pass];
2726 switch (row_info->pixel_depth)
2728 case 1:
2730 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2731 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2732 int sshift, dshift;
2733 int s_start, s_end, s_inc;
2734 int jstop = png_pass_inc[pass];
2735 png_byte v;
2736 png_uint_32 i;
2737 int j;
2739 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2740 if (transformations & PNG_PACKSWAP)
2742 sshift = (int)((row_info->width + 7) & 0x07);
2743 dshift = (int)((final_width + 7) & 0x07);
2744 s_start = 7;
2745 s_end = 0;
2746 s_inc = -1;
2748 else
2749 #endif
2751 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2752 dshift = 7 - (int)((final_width + 7) & 0x07);
2753 s_start = 0;
2754 s_end = 7;
2755 s_inc = 1;
2758 for (i = 0; i < row_info->width; i++)
2760 v = (png_byte)((*sp >> sshift) & 0x01);
2761 for (j = 0; j < jstop; j++)
2763 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2764 *dp |= (png_byte)(v << dshift);
2765 if (dshift == s_end)
2767 dshift = s_start;
2768 dp--;
2770 else
2771 dshift += s_inc;
2773 if (sshift == s_end)
2775 sshift = s_start;
2776 sp--;
2778 else
2779 sshift += s_inc;
2781 break;
2783 case 2:
2785 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2786 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2787 int sshift, dshift;
2788 int s_start, s_end, s_inc;
2789 int jstop = png_pass_inc[pass];
2790 png_uint_32 i;
2792 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2793 if (transformations & PNG_PACKSWAP)
2795 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2796 dshift = (int)(((final_width + 3) & 0x03) << 1);
2797 s_start = 6;
2798 s_end = 0;
2799 s_inc = -2;
2801 else
2802 #endif
2804 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2805 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2806 s_start = 0;
2807 s_end = 6;
2808 s_inc = 2;
2811 for (i = 0; i < row_info->width; i++)
2813 png_byte v;
2814 int j;
2816 v = (png_byte)((*sp >> sshift) & 0x03);
2817 for (j = 0; j < jstop; j++)
2819 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2820 *dp |= (png_byte)(v << dshift);
2821 if (dshift == s_end)
2823 dshift = s_start;
2824 dp--;
2826 else
2827 dshift += s_inc;
2829 if (sshift == s_end)
2831 sshift = s_start;
2832 sp--;
2834 else
2835 sshift += s_inc;
2837 break;
2839 case 4:
2841 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2842 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2843 int sshift, dshift;
2844 int s_start, s_end, s_inc;
2845 png_uint_32 i;
2846 int jstop = png_pass_inc[pass];
2848 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2849 if (transformations & PNG_PACKSWAP)
2851 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2852 dshift = (int)(((final_width + 1) & 0x01) << 2);
2853 s_start = 4;
2854 s_end = 0;
2855 s_inc = -4;
2857 else
2858 #endif
2860 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2861 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2862 s_start = 0;
2863 s_end = 4;
2864 s_inc = 4;
2867 for (i = 0; i < row_info->width; i++)
2869 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2870 int j;
2872 for (j = 0; j < jstop; j++)
2874 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2875 *dp |= (png_byte)(v << dshift);
2876 if (dshift == s_end)
2878 dshift = s_start;
2879 dp--;
2881 else
2882 dshift += s_inc;
2884 if (sshift == s_end)
2886 sshift = s_start;
2887 sp--;
2889 else
2890 sshift += s_inc;
2892 break;
2894 default:
2896 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2897 png_bytep sp = row + (png_size_t)(row_info->width - 1)
2898 * pixel_bytes;
2899 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2901 int jstop = png_pass_inc[pass];
2902 png_uint_32 i;
2904 for (i = 0; i < row_info->width; i++)
2906 png_byte v[8];
2907 int j;
2909 png_memcpy(v, sp, pixel_bytes);
2910 for (j = 0; j < jstop; j++)
2912 png_memcpy(dp, v, pixel_bytes);
2913 dp -= pixel_bytes;
2915 sp -= pixel_bytes;
2917 break;
2920 row_info->width = final_width;
2921 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
2923 #ifndef PNG_READ_PACKSWAP_SUPPORTED
2924 PNG_UNUSED(transformations) /* Silence compiler warning */
2925 #endif
2927 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2929 void /* PRIVATE */
2930 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2931 png_bytep prev_row, int filter)
2933 png_debug(1, "in png_read_filter_row");
2934 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
2935 switch (filter)
2937 case PNG_FILTER_VALUE_NONE:
2938 break;
2939 case PNG_FILTER_VALUE_SUB:
2941 png_uint_32 i;
2942 png_uint_32 istop = row_info->rowbytes;
2943 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2944 png_bytep rp = row + bpp;
2945 png_bytep lp = row;
2947 for (i = bpp; i < istop; i++)
2949 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2950 rp++;
2952 break;
2954 case PNG_FILTER_VALUE_UP:
2956 png_uint_32 i;
2957 png_uint_32 istop = row_info->rowbytes;
2958 png_bytep rp = row;
2959 png_bytep pp = prev_row;
2961 for (i = 0; i < istop; i++)
2963 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2964 rp++;
2966 break;
2968 case PNG_FILTER_VALUE_AVG:
2970 png_uint_32 i;
2971 png_bytep rp = row;
2972 png_bytep pp = prev_row;
2973 png_bytep lp = row;
2974 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2975 png_uint_32 istop = row_info->rowbytes - bpp;
2977 for (i = 0; i < bpp; i++)
2979 *rp = (png_byte)(((int)(*rp) +
2980 ((int)(*pp++) / 2 )) & 0xff);
2981 rp++;
2984 for (i = 0; i < istop; i++)
2986 *rp = (png_byte)(((int)(*rp) +
2987 (int)(*pp++ + *lp++) / 2 ) & 0xff);
2988 rp++;
2990 break;
2992 case PNG_FILTER_VALUE_PAETH:
2994 png_uint_32 i;
2995 png_bytep rp = row;
2996 png_bytep pp = prev_row;
2997 png_bytep lp = row;
2998 png_bytep cp = prev_row;
2999 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
3000 png_uint_32 istop=row_info->rowbytes - bpp;
3002 for (i = 0; i < bpp; i++)
3004 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
3005 rp++;
3008 for (i = 0; i < istop; i++) /* Use leftover rp,pp */
3010 int a, b, c, pa, pb, pc, p;
3012 a = *lp++;
3013 b = *pp++;
3014 c = *cp++;
3016 p = b - c;
3017 pc = a - c;
3019 #ifdef PNG_USE_ABS
3020 pa = abs(p);
3021 pb = abs(pc);
3022 pc = abs(p + pc);
3023 #else
3024 pa = p < 0 ? -p : p;
3025 pb = pc < 0 ? -pc : pc;
3026 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3027 #endif
3030 if (pa <= pb && pa <= pc)
3031 p = a;
3032 else if (pb <= pc)
3033 p = b;
3034 else
3035 p = c;
3038 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
3040 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
3041 rp++;
3043 break;
3045 default:
3046 png_warning(png_ptr, "Ignoring bad adaptive filter type");
3047 *row = 0;
3048 break;
3052 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3053 void /* PRIVATE */
3054 png_read_finish_row(png_structp png_ptr)
3056 #ifdef PNG_READ_INTERLACING_SUPPORTED
3057 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3059 /* Start of interlace block */
3060 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3062 /* Offset to next interlace block */
3063 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3065 /* Start of interlace block in the y direction */
3066 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3068 /* Offset to next interlace block in the y direction */
3069 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3070 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3072 png_debug(1, "in png_read_finish_row");
3073 png_ptr->row_number++;
3074 if (png_ptr->row_number < png_ptr->num_rows)
3075 return;
3077 #ifdef PNG_READ_INTERLACING_SUPPORTED
3078 if (png_ptr->interlaced)
3080 png_ptr->row_number = 0;
3081 png_memset_check(png_ptr, png_ptr->prev_row, 0,
3082 png_ptr->rowbytes + 1);
3085 png_ptr->pass++;
3086 if (png_ptr->pass >= 7)
3087 break;
3088 png_ptr->iwidth = (png_ptr->width +
3089 png_pass_inc[png_ptr->pass] - 1 -
3090 png_pass_start[png_ptr->pass]) /
3091 png_pass_inc[png_ptr->pass];
3093 if (!(png_ptr->transformations & PNG_INTERLACE))
3095 png_ptr->num_rows = (png_ptr->height +
3096 png_pass_yinc[png_ptr->pass] - 1 -
3097 png_pass_ystart[png_ptr->pass]) /
3098 png_pass_yinc[png_ptr->pass];
3099 if (!(png_ptr->num_rows))
3100 continue;
3102 else /* if (png_ptr->transformations & PNG_INTERLACE) */
3103 break;
3104 } while (png_ptr->iwidth == 0);
3106 if (png_ptr->pass < 7)
3107 return;
3109 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3111 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3113 #ifdef PNG_USE_LOCAL_ARRAYS
3114 PNG_CONST PNG_IDAT;
3115 #endif
3116 char extra;
3117 int ret;
3119 png_ptr->zstream.next_out = (Byte *)&extra;
3120 png_ptr->zstream.avail_out = (uInt)1;
3121 for (;;)
3123 if (!(png_ptr->zstream.avail_in))
3125 while (!png_ptr->idat_size)
3127 png_byte chunk_length[4];
3129 png_crc_finish(png_ptr, 0);
3131 png_read_data(png_ptr, chunk_length, 4);
3132 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
3133 png_reset_crc(png_ptr);
3134 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3135 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
3136 png_error(png_ptr, "Not enough image data");
3139 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3140 png_ptr->zstream.next_in = png_ptr->zbuf;
3141 if (png_ptr->zbuf_size > png_ptr->idat_size)
3142 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3143 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3144 png_ptr->idat_size -= png_ptr->zstream.avail_in;
3146 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3147 if (ret == Z_STREAM_END)
3149 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3150 png_ptr->idat_size)
3151 png_warning(png_ptr, "Extra compressed data.");
3152 png_ptr->mode |= PNG_AFTER_IDAT;
3153 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3154 break;
3156 if (ret != Z_OK)
3157 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3158 "Decompression Error");
3160 if (!(png_ptr->zstream.avail_out))
3162 png_warning(png_ptr, "Extra compressed data.");
3163 png_ptr->mode |= PNG_AFTER_IDAT;
3164 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3165 break;
3169 png_ptr->zstream.avail_out = 0;
3172 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3173 png_warning(png_ptr, "Extra compression data.");
3175 inflateReset(&png_ptr->zstream);
3177 png_ptr->mode |= PNG_AFTER_IDAT;
3179 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3181 void /* PRIVATE */
3182 png_read_start_row(png_structp png_ptr)
3184 #ifdef PNG_READ_INTERLACING_SUPPORTED
3185 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3187 /* Start of interlace block */
3188 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3190 /* Offset to next interlace block */
3191 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3193 /* Start of interlace block in the y direction */
3194 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3196 /* Offset to next interlace block in the y direction */
3197 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3198 #endif
3200 int max_pixel_depth;
3201 png_size_t row_bytes;
3203 png_debug(1, "in png_read_start_row");
3204 png_ptr->zstream.avail_in = 0;
3205 png_init_read_transformations(png_ptr);
3206 #ifdef PNG_READ_INTERLACING_SUPPORTED
3207 if (png_ptr->interlaced)
3209 if (!(png_ptr->transformations & PNG_INTERLACE))
3210 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3211 png_pass_ystart[0]) / png_pass_yinc[0];
3212 else
3213 png_ptr->num_rows = png_ptr->height;
3215 png_ptr->iwidth = (png_ptr->width +
3216 png_pass_inc[png_ptr->pass] - 1 -
3217 png_pass_start[png_ptr->pass]) /
3218 png_pass_inc[png_ptr->pass];
3220 else
3221 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3223 png_ptr->num_rows = png_ptr->height;
3224 png_ptr->iwidth = png_ptr->width;
3226 max_pixel_depth = png_ptr->pixel_depth;
3228 #ifdef PNG_READ_PACK_SUPPORTED
3229 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3230 max_pixel_depth = 8;
3231 #endif
3233 #ifdef PNG_READ_EXPAND_SUPPORTED
3234 if (png_ptr->transformations & PNG_EXPAND)
3236 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3238 if (png_ptr->num_trans)
3239 max_pixel_depth = 32;
3240 else
3241 max_pixel_depth = 24;
3243 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3245 if (max_pixel_depth < 8)
3246 max_pixel_depth = 8;
3247 if (png_ptr->num_trans)
3248 max_pixel_depth *= 2;
3250 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3252 if (png_ptr->num_trans)
3254 max_pixel_depth *= 4;
3255 max_pixel_depth /= 3;
3259 #endif
3261 #ifdef PNG_READ_FILLER_SUPPORTED
3262 if (png_ptr->transformations & (PNG_FILLER))
3264 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3265 max_pixel_depth = 32;
3266 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3268 if (max_pixel_depth <= 8)
3269 max_pixel_depth = 16;
3270 else
3271 max_pixel_depth = 32;
3273 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3275 if (max_pixel_depth <= 32)
3276 max_pixel_depth = 32;
3277 else
3278 max_pixel_depth = 64;
3281 #endif
3283 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3284 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3286 if (
3287 #ifdef PNG_READ_EXPAND_SUPPORTED
3288 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3289 #endif
3290 #ifdef PNG_READ_FILLER_SUPPORTED
3291 (png_ptr->transformations & (PNG_FILLER)) ||
3292 #endif
3293 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3295 if (max_pixel_depth <= 16)
3296 max_pixel_depth = 32;
3297 else
3298 max_pixel_depth = 64;
3300 else
3302 if (max_pixel_depth <= 8)
3304 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3305 max_pixel_depth = 32;
3306 else
3307 max_pixel_depth = 24;
3309 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3310 max_pixel_depth = 64;
3311 else
3312 max_pixel_depth = 48;
3315 #endif
3317 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3318 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3319 if (png_ptr->transformations & PNG_USER_TRANSFORM)
3321 int user_pixel_depth = png_ptr->user_transform_depth*
3322 png_ptr->user_transform_channels;
3323 if (user_pixel_depth > max_pixel_depth)
3324 max_pixel_depth=user_pixel_depth;
3326 #endif
3328 /* Align the width on the next larger 8 pixels. Mainly used
3329 * for interlacing
3331 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3332 /* Calculate the maximum bytes needed, adding a byte and a pixel
3333 * for safety's sake
3335 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
3336 1 + ((max_pixel_depth + 7) >> 3);
3337 #ifdef PNG_MAX_MALLOC_64K
3338 if (row_bytes > (png_uint_32)65536L)
3339 png_error(png_ptr, "This image requires a row greater than 64KB");
3340 #endif
3342 if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
3344 png_free(png_ptr, png_ptr->big_row_buf);
3345 if (png_ptr->interlaced)
3346 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
3347 row_bytes + 64);
3348 else
3349 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
3350 row_bytes + 64);
3351 png_ptr->old_big_row_buf_size = row_bytes + 64;
3353 /* Use 32 bytes of padding before and after row_buf. */
3354 png_ptr->row_buf = png_ptr->big_row_buf + 32;
3355 png_ptr->old_big_row_buf_size = row_bytes + 64;
3358 #ifdef PNG_MAX_MALLOC_64K
3359 if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
3360 png_error(png_ptr, "This image requires a row greater than 64KB");
3361 #endif
3362 if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3363 png_error(png_ptr, "Row has too many bytes to allocate in memory.");
3365 if (row_bytes + 1 > png_ptr->old_prev_row_size)
3367 png_free(png_ptr, png_ptr->prev_row);
3368 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3369 row_bytes + 1));
3370 png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
3371 png_ptr->old_prev_row_size = row_bytes + 1;
3374 png_ptr->rowbytes = row_bytes;
3376 png_debug1(3, "width = %lu,", png_ptr->width);
3377 png_debug1(3, "height = %lu,", png_ptr->height);
3378 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
3379 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
3380 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
3381 png_debug1(3, "irowbytes = %lu",
3382 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
3384 png_ptr->flags |= PNG_FLAG_ROW_INIT;
3386 #endif /* PNG_READ_SUPPORTED */