f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* pngrutil.c - utilities to read a PNG file
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * libpng version 1.2.8 - December 3, 2004
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * For conditions of distribution and use, see copyright notice in png.h
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Copyright (c) 1998-2004 Glenn Randers-Pehrson
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * This file contains routines that are only called from within
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * libpng itself during the course of reading an image.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#define PNG_INTERNAL
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#include "png.h"
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(_WIN32_WCE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* strtod() function is not supported on WindowsCE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync__inline double strtod(const char *nptr, char **endptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double result = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int len;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync wchar_t *str, *end;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync str = (wchar_t *)malloc(len * sizeof(wchar_t));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ( NULL != str )
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync result = wcstod(str, &end);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync free(str);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return result;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_uint_32 /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_get_uint_31(png_structp png_ptr, png_bytep buf)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (i > PNG_UINT_31_MAX)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "PNG unsigned integer out of range.\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return (i);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_uint_32 /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_get_uint_32(png_bytep buf)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i = ((png_uint_32)(*buf) << 24) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_uint_32)(*(buf + 1)) << 16) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_uint_32)(*(buf + 2)) << 8) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(*(buf + 3));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return (i);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Grab a signed 32-bit integer from a buffer in big-endian format. The
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * data is stored in the PNG file in two's complement format, and it is
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * assumed that the machine format for signed integers is the same. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_int_32 /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_get_int_32(png_bytep buf)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_int_32 i = ((png_int_32)(*buf) << 24) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_int_32)(*(buf + 1)) << 16) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((png_int_32)(*(buf + 2)) << 8) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_int_32)(*(buf + 3));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return (i);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_pCAL_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_uint_16 /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_get_uint_16(png_bytep buf)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)(*(buf + 1)));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return (i);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Read data, and (optionally) run it through the CRC. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_read_data(png_ptr, buf, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_calculate_crc(png_ptr, buf, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Optionally skip data and then check the CRC. Depending on whether we
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync are reading a ancillary or critical chunk, and how the program has set
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync things up, we may calculate the CRC on the data and print a message.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync Returns '1' if there was a CRC error, '0' otherwise. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncint /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_crc_finish(png_structp png_ptr, png_uint_32 skip)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t istop = png_ptr->zbuf_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = (png_size_t)skip; i > istop; i -= istop)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (i)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, png_ptr->zbuf, i);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_error(png_ptr))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_warning(png_ptr, "CRC error");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_error(png_ptr, "CRC error");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return (1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return (0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Compare the CRC stored in the PNG file with that calculated by libpng from
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync the data it has read thus far. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncint /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_crc_error(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte crc_bytes[4];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 crc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int need_crc = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync need_crc = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* critical */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync need_crc = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_read_data(png_ptr, crc_bytes, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (need_crc)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync crc = png_get_uint_32(crc_bytes);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return ((int)(crc != png_ptr->crc));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return (0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync defined(PNG_READ_iCCP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/*
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * Decompress trailing data in a chunk. The assumption is that chunkdata
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * points at an allocated area holding the contents of a chunk with a
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * trailing compressed part. What we get back is an allocated area
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * holding the original prefix part and an uncompressed version of the
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * trailing part (the malloc area passed in is freed).
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_charp /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_decompress_chunk(png_structp png_ptr, int comp_type,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp chunkdata, png_size_t chunklength,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t prefix_size, png_size_t *newlength)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync static char msg[] = "Error decoding compressed text";
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp text;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t text_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (comp_type == PNG_COMPRESSION_TYPE_BASE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int ret = Z_OK;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.next_out = png_ptr->zbuf;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text = NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while (png_ptr->zstream.avail_in)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret != Z_OK && ret != Z_STREAM_END)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->zstream.msg != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, png_ptr->zstream.msg);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, msg);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync inflateReset(&png_ptr->zstream);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_in = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size = prefix_size + png_sizeof(msg) + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text = (png_charp)png_malloc_warn(png_ptr, text_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr,chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr,"Not enough memory to decompress chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(text, chunkdata, prefix_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text[text_size - 1] = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Copy what we can of the error message into the text chunk */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size = png_sizeof(msg) > text_size ? text_size :
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sizeof(msg);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(text + prefix_size, msg, text_size + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size = prefix_size +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zbuf_size - png_ptr->zstream.avail_out;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr,chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr,"Not enough memory to decompress chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(text + prefix_size, png_ptr->zbuf,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size - prefix_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(text, chunkdata, prefix_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(text + text_size) = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp tmp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync tmp = text;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text = (png_charp)png_malloc_warn(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)(text_size +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, tmp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr,"Not enough memory to decompress chunk..");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(text, tmp, text_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, tmp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(text + text_size, png_ptr->zbuf,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(text + text_size) = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret == Z_STREAM_END)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.next_out = png_ptr->zbuf;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret != Z_STREAM_END)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync char umsg[50];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret == Z_BUF_ERROR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->chunk_name);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (ret == Z_DATA_ERROR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sprintf(umsg,"Data error in compressed datastream in %s chunk",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->chunk_name);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sprintf(umsg,"Incomplete compressed datastream in %s chunk",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->chunk_name);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, umsg);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Incomplete compressed datastream in chunk other than IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_size=prefix_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr,"Not enough memory for text.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(text, chunkdata, prefix_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(text + text_size) = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync inflateReset(&png_ptr->zstream);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_in = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = text;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *newlength=text_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync char umsg[50];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, umsg);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Unknown zTXt compression type");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *(chunkdata + prefix_size) = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *newlength=prefix_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* read and check the IDHR chunk */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[13];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 width, height;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int bit_depth, color_type, compression_type, filter_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int interlace_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_IHDR\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->mode & PNG_HAVE_IHDR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Out of place IHDR");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* check the length */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 13)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Invalid IHDR chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_HAVE_IHDR;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 13);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync width = png_get_uint_31(png_ptr, buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync height = png_get_uint_31(png_ptr, buf + 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync bit_depth = buf[8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync color_type = buf[9];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync compression_type = buf[10];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync filter_type = buf[11];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync interlace_type = buf[12];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* set internal variables */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->width = width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->height = height;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->bit_depth = (png_byte)bit_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->interlaced = (png_byte)interlace_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->color_type = (png_byte)color_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_MNG_FEATURES_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->filter_type = (png_byte)filter_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->compression_type = (png_byte)compression_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* find number of channels */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (png_ptr->color_type)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_GRAY:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_PALETTE:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->channels = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_RGB:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->channels = 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_GRAY_ALPHA:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->channels = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_COLOR_TYPE_RGB_ALPHA:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->channels = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* set up other useful info */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->channels);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3,"channels = %d\n", png_ptr->channels);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync color_type, interlace_type, compression_type, filter_type);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* read and check the palette */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_color palette[PNG_MAX_PALETTE_LENGTH];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int num, i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_NO_POINTER_INDEXING
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_colorp pal_ptr;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_PLTE\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before PLTE");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid PLTE after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_PLTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Duplicate PLTE chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_HAVE_PLTE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Ignoring PLTE chunk in grayscale PNG");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid palette chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Invalid palette chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num = (int)length / 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_NO_POINTER_INDEXING
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[3];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pal_ptr->red = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pal_ptr->green = buf[1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pal_ptr->blue = buf[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[3];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* don't depend upon png_color being any order */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].red = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].green = buf[1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync palette[i].blue = buf[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync whatever the normal CRC configuration tells us. However, if we
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync have an RGB image, the PLTE can be considered ancillary, so
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync we will act as though it is. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* If we don't want to use the data from an ancillary chunk,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync we have two options: an error abort, or a warning and we
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ignore the data in this chunk (which should be OK, since
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync it's considered ancillary for a RGB or RGBA image). */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_error(png_ptr, "CRC error");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_warning(png_ptr, "CRC error");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Otherwise, we (optionally) emit a warning and use the chunk. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_warning(png_ptr, "CRC error");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_PLTE(png_ptr, info_ptr, palette, num);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_tRNS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->num_trans > (png_uint_16)num)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_trans = (png_uint_16)num;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->num_trans > (png_uint_16)num)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync info_ptr->num_trans = (png_uint_16)num;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_IEND\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "No image in file");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect IEND chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_gAMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_fixed_point igamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync float file_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[4];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_gAMA\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before gAMA");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid gAMA after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_PLTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Should be an error, but we can cope with it */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Out of place gAMA chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sRGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync && !(info_ptr->valid & PNG_INFO_sRGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync )
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate gAMA chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect gAMA chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync igamma = (png_fixed_point)png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* check for zero gamma */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (igamma == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Ignoring gAMA chunk with gamma=0");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sRGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->valid & PNG_INFO_sRGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Ignoring incorrect gAMA value when sRGB is also present");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_NO_CONSOLE_IO
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_sRGB_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync file_gamma = (float)igamma / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# ifdef PNG_READ_GAMMA_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->gamma = file_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_gAMA(png_ptr, info_ptr, file_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sBIT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t truelen;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[4];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_sBIT\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync buf[0] = buf[1] = buf[2] = buf[3] = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before sBIT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid sBIT after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_PLTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Should be an error, but we can cope with it */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Out of place sBIT chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate sBIT chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync truelen = 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync truelen = (png_size_t)png_ptr->channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != truelen || length > 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect sBIT chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, truelen);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.red = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.green = buf[1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.blue = buf[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.alpha = buf[3];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.gray = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.red = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.green = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.blue = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->sig_bit.alpha = buf[1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_cHRM_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[4];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_y_green, int_x_blue, int_y_blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 uint_x, uint_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_cHRM\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before cHRM");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid cHRM after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_PLTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Should be an error, but we can cope with it */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Missing PLTE before cHRM");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sRGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync && !(info_ptr->valid & PNG_INFO_sRGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync )
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate cHRM chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 32)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect cHRM chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_y = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (uint_x > 80000L || uint_y > 80000L ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x + uint_y > 100000L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid cHRM white point");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 24);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_x_white = (png_fixed_point)uint_x;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_y_white = (png_fixed_point)uint_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_y = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (uint_x > 80000L || uint_y > 80000L ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x + uint_y > 100000L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid cHRM red point");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 16);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_x_red = (png_fixed_point)uint_x;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_y_red = (png_fixed_point)uint_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_y = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (uint_x > 80000L || uint_y > 80000L ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x + uint_y > 100000L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid cHRM green point");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 8);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_x_green = (png_fixed_point)uint_x;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_y_green = (png_fixed_point)uint_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_y = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (uint_x > 80000L || uint_y > 80000L ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync uint_x + uint_y > 100000L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid cHRM blue point");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_x_blue = (png_fixed_point)uint_x;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_y_blue = (png_fixed_point)uint_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync white_x = (float)int_x_white / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync white_y = (float)int_y_white / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red_x = (float)int_x_red / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync red_y = (float)int_y_red / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green_x = (float)int_x_green / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green_y = (float)int_y_green / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync blue_x = (float)int_x_blue / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync blue_y = (float)int_y_blue / (float)100000.0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sRGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->valid & PNG_INFO_sRGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Ignoring incorrect cHRM value when sRGB is also present");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_NO_CONSOLE_IO
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync white_x, white_y, red_x, red_y);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync green_x, green_y, blue_x, blue_y);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_x_white, int_y_white, int_x_red, int_y_red);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_x_green, int_y_green, int_x_blue, int_y_blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_NO_CONSOLE_IO */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_sRGB_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_cHRM(png_ptr, info_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_cHRM_fixed(png_ptr, info_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int_y_green, int_x_blue, int_y_blue);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sRGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int intent;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[1];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_sRGB\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before sRGB");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid sRGB after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_PLTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Should be an error, but we can cope with it */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Out of place sRGB chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate sRGB chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 1)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect sRGB chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync intent = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* check for bad intent */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (intent >= PNG_sRGB_INTENT_LAST)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Unknown sRGB intent");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((info_ptr->valid & PNG_INFO_gAMA))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_fixed_point igamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync igamma=info_ptr->int_gamma;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Ignoring incorrect gAMA value when sRGB is also present");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_NO_CONSOLE_IO
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync# endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_gAMA_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_READ_cHRM_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr->valid & PNG_INFO_cHRM)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Ignoring incorrect cHRM value when sRGB is also present");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_FIXED_POINT_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_cHRM_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_sRGB_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_iCCP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Note: this does not properly handle chunks that are > 64K under DOS */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte compression_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep pC;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp profile;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 skip = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 profile_size, profile_length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t slength, prefix_length, data_length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_iCCP\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before iCCP");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid iCCP after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_PLTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Should be an error, but we can cope with it */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Out of place iCCP chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate iCCP chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > (png_uint_32)65535L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "iCCP chunk too large to fit in memory");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync skip = length - (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync length = (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, skip))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata[slength] = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (profile = chunkdata; *profile; profile++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop to find end of name */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ++profile;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* there should be at least one zero (the compression type byte)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync following the separator, and we should be on it */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ( profile >= chunkdata + slength)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Malformed iCCP chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* compression_type should always be zero */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync compression_type = *profile++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (compression_type)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync wrote nonzero) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync prefix_length = profile - chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength, prefix_length, &data_length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync profile_length = data_length - prefix_length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ( prefix_length > data_length || profile_length < 4)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Profile size field missing from iCCP chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Check the profile_size recorded in the first 32 bits of the ICC profile */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pC = (png_bytep)(chunkdata+prefix_length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync profile_size = ((*(pC ))<<24) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((*(pC+1))<<16) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((*(pC+2))<< 8) |
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((*(pC+3)) );
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(profile_size < profile_length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync profile_length = profile_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(profile_size > profile_length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata + prefix_length, profile_length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_iCCP_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sPLT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Note: this does not properly handle chunks that are > 64K under DOS */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep entry_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sPLT_t new_palette;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_NO_POINTER_INDEXING
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sPLT_entryp pp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int data_length, entry_size, i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 skip = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t slength;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_sPLT\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before sPLT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid sPLT after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > (png_uint_32)65535L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "sPLT chunk too large to fit in memory");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync skip = length - (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync length = (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, skip))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata[slength] = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (entry_start = chunkdata; *entry_start; entry_start++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop to find end of name */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ++entry_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* a sample depth should follow the separator, and we should be on it */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (entry_start > chunkdata + slength)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "malformed sPLT chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync new_palette.depth = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync entry_size = (new_palette.depth == 8 ? 6 : 10);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync data_length = (slength - (entry_start - chunkdata));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* integrity-check the data length */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (data_length % entry_size)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "sPLT chunk has bad length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync new_palette.nentries = (png_uint_32) (data_length / entry_size);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sizeof(png_sPLT_entry)))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "sPLT chunk too long");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (new_palette.entries == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "sPLT chunk requires too much memory");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_NO_POINTER_INDEXING
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < new_palette.nentries; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_sPLT_entryp pp = new_palette.entries + i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (new_palette.depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->red = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->green = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->blue = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->alpha = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->red = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->green = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->blue = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp = new_palette.entries;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < new_palette.nentries; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (new_palette.depth == 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].red = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].green = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].blue = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].alpha = *entry_start++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* discard all chunk data except the name and stash that */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync new_palette.name = (png_charp)chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, new_palette.entries);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_sPLT_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_tRNS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_tRNS\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before tRNS");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid tRNS after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate tRNS chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 2)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect tRNS chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_trans = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans_values.gray = png_get_uint_16(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[6];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 6)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect tRNS chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, (png_size_t)length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_trans = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans_values.red = png_get_uint_16(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans_values.green = png_get_uint_16(buf + 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_PLTE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Should be an error, but we can cope with it. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Missing PLTE before tRNS");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > (png_uint_32)png_ptr->num_palette ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync length > PNG_MAX_PALETTE_LENGTH)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect tRNS chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length == 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Zero length tRNS chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, readbuf, (png_size_t)length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_trans = (png_uint_16)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync &(png_ptr->trans_values));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_bKGD_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t truelen;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[6];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_bKGD\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before bKGD");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid bKGD after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync !(png_ptr->mode & PNG_HAVE_PLTE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Missing PLTE before bKGD");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate bKGD chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync truelen = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync truelen = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync truelen = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != truelen)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect bKGD chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, truelen);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* We convert the index value into RGB components so that we can allow
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * arbitrary RGB values for background when we have transparency, and
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * so it is easy to determine the RGB values of the background color
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync * from the info_ptr struct. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.index = buf[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(info_ptr->num_palette)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(buf[0] > info_ptr->num_palette)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect bKGD chunk index value");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)png_ptr->palette[buf[0]].red;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.green =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)png_ptr->palette[buf[0]].green;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.blue =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_16)png_ptr->palette[buf[0]].blue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.green =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.blue =
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.gray = png_get_uint_16(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.red = png_get_uint_16(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.green = png_get_uint_16(buf + 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->background.blue = png_get_uint_16(buf + 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_hIST_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync unsigned int num, i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_hIST\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before hIST");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid hIST after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (!(png_ptr->mode & PNG_HAVE_PLTE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Missing PLTE before hIST");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate hIST chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync num = length / 2 ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (num != (unsigned int) png_ptr->num_palette || num >
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (unsigned int) PNG_MAX_PALETTE_LENGTH)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect hIST chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < num; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync readbuf[i] = png_get_uint_16(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_hIST(png_ptr, info_ptr, readbuf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_pHYs_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[9];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 res_x, res_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int unit_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_pHYs\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before pHYs");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid pHYs after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate pHYs chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 9)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect pHYs chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 9);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync res_x = png_get_uint_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync res_y = png_get_uint_32(buf + 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync unit_type = buf[8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_oFFs_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[9];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_int_32 offset_x, offset_y;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int unit_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_oFFs\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before oFFs");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid oFFs after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate oFFs chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 9)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect oFFs chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 9);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync offset_x = png_get_int_32(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync offset_y = png_get_int_32(buf + 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync unit_type = buf[8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_pCAL_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* read the pCAL chunk (described in the PNG Extensions document) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp purpose;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_int_32 X0, X1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte type, nparams;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp buf, units, endptr;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charpp params;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t slength;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_pCAL\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before pCAL");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid pCAL after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate pCAL chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (purpose == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "No memory for pCAL purpose.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)purpose, slength);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, purpose);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync purpose[slength] = 0x00; /* null terminate the last string */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(3, "Finding end of pCAL purpose string\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (buf = purpose; *buf; buf++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync endptr = purpose + slength;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* We need to have at least 12 bytes after the purpose string
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync in order to get the parameter information. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (endptr <= buf + 12)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid pCAL data");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, purpose);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync X0 = png_get_int_32((png_bytep)buf+1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync X1 = png_get_int_32((png_bytep)buf+5);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync type = buf[9];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync nparams = buf[10];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync units = buf + 11;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(3, "Checking pCAL equation type and number of parameters\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Check that we have the right number of parameters for known
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync equation types. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (type == PNG_EQUATION_BASE_E && nparams != 3) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid pCAL parameters for equation type");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, purpose);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (type >= PNG_EQUATION_LAST)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (buf = units; *buf; buf++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Empty loop to move past the units string. */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(3, "Allocating pCAL parameters array\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *png_sizeof(png_charp))) ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (params == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, purpose);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "No memory for pCAL params.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Get pointers to the start of each parameter string. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < (int)nparams; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync buf++; /* Skip the null string terminator from previous parameter. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3, "Reading pCAL parameter %d\n", i);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Empty loop to move past each parameter string */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* Make sure we haven't run out of data yet */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (buf > endptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid pCAL data");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, purpose);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, params);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync units, params);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, purpose);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, params);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_sCAL_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* read the sCAL chunk */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp buffer, ep;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync double width, height;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp vp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp swidth, sheight;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t slength;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_sCAL\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before sCAL");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid sCAL after IDAT");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate sCAL chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (buffer == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Out of memory while processing sCAL chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)buffer, slength);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, buffer);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync buffer[slength] = 0x00; /* null terminate the last string */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ep = buffer + 1; /* skip unit byte */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync width = strtod(ep, &vp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*vp)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "malformed width string in sCAL chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (swidth == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (ep = buffer; *ep; ep++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ep++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync height = strtod(ep, &vp);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (*vp)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "malformed height string in sCAL chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (swidth == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (buffer + slength < ep
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync || width <= 0. || height <= 0.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync )
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Invalid sCAL data");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, buffer);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, swidth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, sheight);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FLOATING_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_FIXED_POINT_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, buffer);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, swidth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, sheight);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_tIME_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte buf[7];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_time mod_time;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_tIME\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Out of place tIME chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Duplicate tIME chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length != 7)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Incorrect tIME chunk length");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, buf, 7);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync mod_time.second = buf[6];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync mod_time.minute = buf[5];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync mod_time.hour = buf[4];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync mod_time.day = buf[3];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync mod_time.month = buf[2];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync mod_time.year = png_get_uint_16(buf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_tIME(png_ptr, info_ptr, &mod_time);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_tEXt_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Note: this does not properly handle chunks that are > 64K under DOS */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_textp text_ptr;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp key;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp text;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 skip = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t slength;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int ret;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_tEXt\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before tEXt");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > (png_uint_32)65535L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "tEXt chunk too large to fit in memory");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync skip = length - (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync length = (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync key = (png_charp)png_malloc_warn(png_ptr, length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (key == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "No memory to process text chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)key, slength);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, skip))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, key);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync key[slength] = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (text = key; *text; text++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop to find end of key */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text != key + slength)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr = (png_textp)png_malloc_warn(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)png_sizeof(png_text));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text_ptr == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Not enough memory to process text chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, key);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->key = key;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_iTXt_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->lang = NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->lang_key = NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->itxt_length = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->text = text;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->text_length = png_strlen(text);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, key);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, text_ptr);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Insufficient memory to process text chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_zTXt_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* note: this does not correctly handle chunks that are > 64K under DOS */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_textp text_ptr;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp text;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int comp_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int ret;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t slength, prefix_len, data_len;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_zTXt\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before zTXt");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* We will no doubt have problems with chunks even half this size, but
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync there is no hard and fast rule to tell us where to stop. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > (png_uint_32)65535L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,"zTXt chunk too large to fit in memory");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (chunkdata == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,"Out of memory processing zTXt chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata[slength] = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (text = chunkdata; *text; text++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* zTXt must have some text after the chunkdataword */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text == chunkdata + slength)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync comp_type = PNG_TEXT_COMPRESSION_NONE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Zero length zTXt chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync comp_type = *(++text);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Unknown compression type in zTXt chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync comp_type = PNG_TEXT_COMPRESSION_zTXt;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text++; /* skip the compression_method byte */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync prefix_len = text - chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_size_t)length, prefix_len, &data_len);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr = (png_textp)png_malloc_warn(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)png_sizeof(png_text));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text_ptr == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->compression = comp_type;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->key = chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_iTXt_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->lang = NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->lang_key = NULL;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->itxt_length = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->text = chunkdata + prefix_len;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->text_length = data_len;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, text_ptr);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_iTXt_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* note: this does not correctly handle chunks that are > 64K under DOS */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_textp text_ptr;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_charp key, lang, text, lang_key;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int comp_flag;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int comp_type = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int ret;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t slength, prefix_len, data_len;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_iTXt\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->mode & PNG_HAVE_IHDR))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Missing IHDR before iTXt");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* We will no doubt have problems with chunks even half this size, but
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync there is no hard and fast rule to tell us where to stop. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > (png_uint_32)65535L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,"iTXt chunk too large to fit in memory");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (chunkdata == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "No memory to process iTXt chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync slength = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_crc_finish(png_ptr, 0))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata[slength] = 0x00;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (lang = chunkdata; *lang; lang++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync lang++; /* skip NUL separator */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* iTXt must have a language tag (possibly empty), two compression bytes,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync translated keyword (possibly empty), and possibly some text after the
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync keyword */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (lang >= chunkdata + slength)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync comp_flag = PNG_TEXT_COMPRESSION_NONE;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Zero length iTXt chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync comp_flag = *lang++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync comp_type = *lang++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (lang_key = lang; *lang_key; lang_key++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync lang_key++; /* skip NUL separator */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (text = lang_key; *text; text++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* empty loop */ ;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text++; /* skip NUL separator */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync prefix_len = text - chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync key=chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (comp_flag)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (size_t)length, prefix_len, &data_len);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync data_len=png_strlen(chunkdata + prefix_len);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr = (png_textp)png_malloc_warn(png_ptr,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_uint_32)png_sizeof(png_text));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (text_ptr == NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->compression = (int)comp_flag + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->lang_key = chunkdata+(lang_key-key);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->lang = chunkdata+(lang-key);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->itxt_length = data_len;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->text_length = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->key = chunkdata;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync text_ptr->text = chunkdata + prefix_len;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, text_ptr);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunkdata);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* This function is called when we haven't found a handler for a
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunk. If there isn't a problem with the chunk itself (ie bad
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunk name, CRC, or a critical chunk), the chunk is silently ignored
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case it will be saved away to be written out later. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 skip = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_handle_unknown\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->mode & PNG_HAVE_IDAT)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_USE_LOCAL_ARRAYS
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_check_chunk_name(png_ptr, png_ptr->chunk_name);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->chunk_name[0] & 0x20))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_HANDLE_CHUNK_ALWAYS
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync && png_ptr->read_user_chunk_fn == NULL
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync )
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_error(png_ptr, "unknown critical chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_unknown_chunk chunk;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (length > (png_uint_32)65535L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "unknown chunk too large to fit in memory");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync skip = length - (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync length = (png_uint_32)65535L;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunk.data = (png_bytep)png_malloc(png_ptr, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync chunk.size = (png_size_t)length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, (png_bytep)chunk.data, length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->read_user_chunk_fn != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* callback to user unknown chunk handler */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->chunk_name[0] & 0x20))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_HANDLE_CHUNK_ALWAYS)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunk.data);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_error(png_ptr, "unknown critical chunk");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_free(png_ptr, chunk.data);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync skip = length;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, skip);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* This function is called to verify that a chunk name is valid.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync This function can't have the "critical chunk check" incorporated
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync into it, since in the future we will need to be able to call user
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync functions to handle unknown critical chunks after we check that
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync the chunk name itself is valid. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_check_chunk_name\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_chunk_error(png_ptr, "invalid chunk type");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* Combines the row recently read in with the existing pixels in the
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row. This routine takes care of alpha and transparency if requested.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync This routine also handles the two methods of progressive display
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync of interlaced images, depending on the mask value.
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync The mask value describes which pixels are to be combined with
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync the row. The pattern always repeats every 8 pixels, so just 8
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync bits are needed. A one indicates the pixel is to be combined,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync a zero indicates the pixel is to be skipped. This is in addition
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync to any alpha or transparency value associated with the pixel. If
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync you want all pixels to be combined, pass 0xff (255) in mask. */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_combine_row(png_structp png_ptr, png_bytep row, int mask)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1,"in png_combine_row\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (mask == 0xff)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(row, png_ptr->row_buf + 1,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (png_ptr->row_info.pixel_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = png_ptr->row_buf + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int s_inc, s_start, s_end;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int shift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = png_ptr->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_PACKSWAP)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 7;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 7;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = -1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m & mask)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int value;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (*sp >> shift) & 0x01;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp |= (png_byte)(value << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m == 1)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m >>= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = png_ptr->row_buf + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int s_start, s_end, s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int shift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = png_ptr->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int value;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_PACKSWAP)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = -2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m & mask)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (*sp >> shift) & 0x03;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp |= (png_byte)(value << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m == 1)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m >>= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = png_ptr->row_buf + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int s_start, s_end, s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int shift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = png_ptr->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int value;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_PACKSWAP)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = -4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m & mask)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync value = (*sp >> shift) & 0xf;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp |= (png_byte)(value << shift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (shift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync shift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m == 1)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m >>= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync default:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = png_ptr->row_buf + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_width = png_ptr->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m & mask)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(dp, sp, pixel_bytes);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp += pixel_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp += pixel_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (m == 1)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m = 0x80;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync m >>= 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_READ_INTERLACING_SUPPORTED
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync/* OLD pre-1.0.9 interface:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 transformations)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_do_read_interlace(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_row_infop row_info = &(png_ptr->row_info);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep row = png_ptr->row_buf + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int pass = png_ptr->pass;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 transformations = png_ptr->transformations;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_USE_LOCAL_ARRAYS
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* offset to next interlace block */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1,"in png_do_read_interlace (stock C version)\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row != NULL && row_info != NULL)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 final_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync final_width = row_info->width * png_pass_inc[pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (row_info->pixel_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 1:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int sshift, dshift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int s_start, s_end, s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int jstop = png_pass_inc[pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (transformations & PNG_PACKSWAP)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = (int)((row_info->width + 7) & 0x07);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = (int)((final_width + 7) & 0x07);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 7;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = -1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = 7 - (int)((row_info->width + 7) & 0x07);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = 7 - (int)((final_width + 7) & 0x07);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 7;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_info->width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = (png_byte)((*sp >> sshift) & 0x01);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < jstop; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp |= (png_byte)(v << dshift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (dshift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (sshift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 2:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int sshift, dshift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int s_start, s_end, s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int jstop = png_pass_inc[pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (transformations & PNG_PACKSWAP)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = (int)(((row_info->width + 3) & 0x03) << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = (int)(((final_width + 3) & 0x03) << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = -2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 6;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_info->width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync v = (png_byte)((*sp >> sshift) & 0x03);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < jstop; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp |= (png_byte)(v << dshift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (dshift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (sshift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case 4:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int sshift, dshift;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int s_start, s_end, s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int jstop = png_pass_inc[pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (transformations & PNG_PACKSWAP)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = (int)(((row_info->width + 1) & 0x01) << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = (int)(((final_width + 1) & 0x01) << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = -4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_start = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_end = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync s_inc = 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_info->width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v = (png_byte)((*sp >> sshift) & 0xf);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < jstop; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *dp |= (png_byte)(v << dshift);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (dshift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dshift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (sshift == s_end)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift = s_start;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp--;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sshift += s_inc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync default:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int jstop = png_pass_inc[pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < row_info->width; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte v[8];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int j;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(v, sp, pixel_bytes);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (j = 0; j < jstop; j++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memcpy(dp, v, pixel_bytes);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync dp -= pixel_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync sp -= pixel_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->width = final_width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (&transformations == NULL) /* silence compiler warning */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* PNG_READ_INTERLACING_SUPPORTED */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep prev_row, int filter)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_read_filter_row\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync switch (filter)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_FILTER_VALUE_NONE:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_FILTER_VALUE_SUB:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep rp = row + bpp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep lp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = bpp; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_FILTER_VALUE_UP:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = row_info->rowbytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep rp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep pp = prev_row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_FILTER_VALUE_AVG:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep rp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep pp = prev_row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep lp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop = row_info->rowbytes - bpp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < bpp; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *rp = (png_byte)(((int)(*rp) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ((int)(*pp++) / 2 )) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *rp = (png_byte)(((int)(*rp) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (int)(*pp++ + *lp++) / 2 ) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync case PNG_FILTER_VALUE_PAETH:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 i;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep rp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep pp = prev_row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep lp = row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_bytep cp = prev_row;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 istop=row_info->rowbytes - bpp;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < bpp; i++)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for (i = 0; i < istop; i++) /* use leftover rp,pp */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int a, b, c, pa, pb, pc, p;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync a = *lp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync b = *pp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync c = *cp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = b - c;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pc = a - c;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_USE_ABS
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pa = abs(p);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pb = abs(pc);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pc = abs(p + pc);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pa = p < 0 ? -p : p;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pb = pc < 0 ? -pc : pc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync pc = (p + pc) < 0 ? -(p + pc) : p + pc;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /*
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (pa <= pb && pa <= pc)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = a;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (pb <= pc)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = b;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = c;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *rp = (png_byte)(((int)(*rp) + p) & 0xff);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync rp++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync default:
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Ignoring bad adaptive filter type");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync *row=0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_read_finish_row(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_USE_LOCAL_ARRAYS
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* start of interlace block */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* offset to next interlace block */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* start of interlace block in the y direction */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* offset to next interlace block in the y direction */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_read_finish_row\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_number++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->row_number < png_ptr->num_rows)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->interlaced)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_number = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync do
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->pass++;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->pass >= 7)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->iwidth = (png_ptr->width +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_inc[png_ptr->pass] - 1 -
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_start[png_ptr->pass]) /
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_inc[png_ptr->pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->iwidth) + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->transformations & PNG_INTERLACE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_rows = (png_ptr->height +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_yinc[png_ptr->pass] - 1 -
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_ystart[png_ptr->pass]) /
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_yinc[png_ptr->pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->num_rows))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync continue;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else /* if (png_ptr->transformations & PNG_INTERLACE) */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync } while (png_ptr->iwidth == 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->pass < 7)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync return;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_USE_LOCAL_ARRAYS
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync PNG_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync char extra;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int ret;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.next_out = (Byte *)&extra;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_out = (uInt)1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for(;;)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->zstream.avail_in))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync while (!png_ptr->idat_size)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_byte chunk_length[4];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_finish(png_ptr, 0);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_read_data(png_ptr, chunk_length, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_reset_crc(png_ptr);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, png_ptr->chunk_name, 4);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Not enough image data");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.next_in = png_ptr->zbuf;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->zbuf_size > png_ptr->idat_size)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->idat_size -= png_ptr->zstream.avail_in;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret == Z_STREAM_END)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->idat_size)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Extra compressed data");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (ret != Z_OK)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync "Decompression Error");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->zstream.avail_out))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Extra compressed data.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync break;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_out = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->idat_size || png_ptr->zstream.avail_in)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_warning(png_ptr, "Extra compression data");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync inflateReset(&png_ptr->zstream);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->mode |= PNG_AFTER_IDAT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncvoid /* PRIVATE */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncpng_read_start_row(png_structp png_ptr)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync{
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_USE_LOCAL_ARRAYS
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* start of interlace block */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* offset to next interlace block */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* start of interlace block in the y direction */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* offset to next interlace block in the y direction */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int max_pixel_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_uint_32 row_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug(1, "in png_read_start_row\n");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->zstream.avail_in = 0;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_init_read_transformations(png_ptr);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->interlaced)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (!(png_ptr->transformations & PNG_INTERLACE))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_ystart[0]) / png_pass_yinc[0];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_rows = png_ptr->height;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->iwidth = (png_ptr->width +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_inc[png_ptr->pass] - 1 -
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_start[png_ptr->pass]) /
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_pass_inc[png_ptr->pass];
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->irowbytes = (png_size_t)row_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if((png_uint_32)png_ptr->irowbytes != row_bytes)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->num_rows = png_ptr->height;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->iwidth = png_ptr->width;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->irowbytes = png_ptr->rowbytes + 1;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = png_ptr->pixel_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_PACK_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_EXPAND)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 24;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (max_pixel_depth < 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 8;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth *= 2;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->num_trans)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth *= 4;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth /= 3;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_FILLER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & (PNG_FILLER))
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (max_pixel_depth <= 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 16;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (max_pixel_depth <= 32)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 64;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->transformations & PNG_GRAY_TO_RGB)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_EXPAND_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_FILLER_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync (png_ptr->transformations & (PNG_FILLER)) ||
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (max_pixel_depth <= 16)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 64;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (max_pixel_depth <= 8)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 24;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 64;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync else
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth = 48;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
f9a51917495bc8ba8b60632219652a7b122c1190vboxsyncdefined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(png_ptr->transformations & PNG_USER_TRANSFORM)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync {
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync int user_pixel_depth=png_ptr->user_transform_depth*
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->user_transform_channels;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if(user_pixel_depth > max_pixel_depth)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync max_pixel_depth=user_pixel_depth;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync }
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* align the width on the next larger 8 pixels. Mainly used
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for interlacing */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync /* calculate the maximum bytes needed, adding a byte and a pixel
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync for safety's sake */
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync 1 + ((max_pixel_depth + 7) >> 3);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if (row_bytes > (png_uint_32)65536L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "This image requires a row greater than 64KB");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_buf = png_ptr->big_row_buf+32;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->row_buf_size = row_bytes;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#ifdef PNG_MAX_MALLOC_64K
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "This image requires a row greater than 64KB");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync#endif
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync if ((png_uint_32)png_ptr->rowbytes > PNG_SIZE_MAX - 1)
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_error(png_ptr, "Row has too many bytes to allocate in memory.");
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->rowbytes + 1));
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3, "width = %lu,\n", png_ptr->width);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3, "height = %lu,\n", png_ptr->height);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync png_ptr->flags |= PNG_FLAG_ROW_INIT;
f9a51917495bc8ba8b60632219652a7b122c1190vboxsync}