/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* pngrutil.c - utilities to read a PNG file
*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
* Last changed in libpng 1.5.4 [July 7, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* This file contains routines that are only called from within
* libpng itself during the course of reading an image.
*/
#include "pngpriv.h"
#ifdef PNG_READ_SUPPORTED
{
if (uval > PNG_UINT_31_MAX)
return (uval);
}
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
/* The following is a variation on the above for use with the fixed
* point values used for gAMA and cHRM. Instead of png_error it
* issues a warning and returns (-1) - an invalid value because both
* gAMA and cHRM use *unsigned* integers for fixed point values.
*/
static png_fixed_point /* PRIVATE */
{
if (uval <= PNG_UINT_31_MAX)
/* The caller can turn off the warning by passing NULL. */
return PNG_FIXED_ERROR;
}
#endif
/* NOTE: the read macros will obscure these definitions, so that if
* PNG_USE_READ_MACROS is set the library will not use them internally,
* but the APIs will still be available externally.
*
* The parentheses around "PNGAPI function_name" in the following three
* functions are necessary because they allow the macros to co-exist with
* these (unused but exported) functions.
*/
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
{
return uval;
}
/* Grab a signed 32-bit integer from a buffer in big-endian format. The
* data is stored in the PNG file in two's complement format and there
* is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
* the following code does a two's complement to native conversion.
*/
{
return uval;
return -(png_int_32)uval;
}
/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
{
/* ANSI-C requires an int value to accomodate at least 16 bits so this
* works and allows the compiler not to worry about possible narrowing
* on 32 bit systems. (Pre-ANSI systems did not make integers smaller
* than 16 bits either.)
*/
unsigned int val =
((unsigned int)(*buf) << 8) +
((unsigned int)(*(buf + 1)));
return (png_uint_16)val;
}
#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
/* Read and check the PNG file signature */
void /* PRIVATE */
{
/* Exit if the user application does not expect a signature. */
return;
#ifdef PNG_IO_STATE_SUPPORTED
#endif
/* The signature must be serialized in a single I/O call. */
{
if (num_checked < 4 &&
else
}
if (num_checked < 3)
}
/* Read the chunk header (length + type name).
* Put the type name into png_ptr->chunk_name, and return the length.
*/
png_uint_32 /* PRIVATE */
{
#ifdef PNG_IO_STATE_SUPPORTED
#endif
/* Read the length and the chunk name.
* This must be performed in a single I/O call.
*/
/* Put the chunk name into png_ptr->chunk_name. */
png_debug2(0, "Reading %s chunk, length = %u",
/* Reset the crc and run it over the chunk name. */
/* Check to see if chunk name is valid. */
#ifdef PNG_IO_STATE_SUPPORTED
#endif
return length;
}
/* Read data, and (optionally) run it through the CRC. */
void /* PRIVATE */
{
return;
}
/* Optionally skip data and then check the CRC. Depending on whether we
* are reading a ancillary or critical chunk, and how the program has set
* things up, we may calculate the CRC on the data and print a message.
* Returns '1' if there was a CRC error, '0' otherwise.
*/
int /* PRIVATE */
{
png_size_t i;
{
}
if (i)
{
}
if (png_crc_error(png_ptr))
{
{
}
else
{
return (0);
}
return (1);
}
return (0);
}
/* Compare the CRC stored in the PNG file with that calculated by libpng from
* the data it has read thus far.
*/
int /* PRIVATE */
{
{
need_crc = 0;
}
else /* critical */
{
need_crc = 0;
}
#ifdef PNG_IO_STATE_SUPPORTED
#endif
/* The chunk CRC must be serialized in a single I/O call. */
if (need_crc)
{
}
else
return (0);
}
static png_size_t
{
/* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
* even necessarily handle 65536 bytes) because the type uInt is "16 bits or
* more". Consequently it is necessary to chunk the input to zlib. This
* code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
* that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a
* lower value in pngpriv.h and this may sometimes have a performance
* advantage, because it forces access of the input data to be separated from
* at least some of the use by some period of time.
*/
/* avail_in is set below from 'size' */
while (1)
{
/* The setting of 'avail_in' used to be outside the loop, by setting it
* inside it is possible to chunk the input to zlib and simply rely on
* zlib to advance the 'next_in' pointer. This allows arbitrary amounts o
* data to be passed through zlib at the unavoidable cost of requiring a
* window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
* input bytes.
*/
{
if (size <= ZLIB_IO_MAX)
{
/* The value is less than ZLIB_IO_MAX so the cast is safe: */
size = 0;
}
else
{
size -= ZLIB_IO_MAX;
}
}
/* Reset the output buffer each time round - we empty it
* after every inflate call.
*/
* get an error code.
*/
{
{
}
}
continue;
/* Termination conditions - always reset the zstream, it
* must be left in inflateInit state.
*/
if (ret == Z_STREAM_END)
return count; /* NOTE: may be zero. */
/* Now handle the error codes - the API always returns 0
* and the error message is dumped into the uncompressed
* buffer if available.
*/
# ifdef PNG_WARNINGS_SUPPORTED
{
else switch (ret)
{
case Z_BUF_ERROR:
msg = "Buffer error in compressed datastream";
break;
case Z_DATA_ERROR:
msg = "Data error in compressed datastream";
break;
default:
msg = "Incomplete compressed datastream";
break;
}
}
# endif
/* 0 means an error - notice that this code simply ignores
* zero length compressed chunks as a result.
*/
return 0;
}
}
/*
* Decompress trailing data in a chunk. The assumption is that chunkdata
* points at an allocated area holding the contents of a chunk with a
* trailing compressed part. What we get back is an allocated area
* holding the original prefix part and an uncompressed version of the
* trailing part (the malloc area passed in is freed).
*/
void /* PRIVATE */
{
/* The caller should guarantee this */
if (prefix_size > chunklength)
{
/* The recovery is to delete the chunk. */
prefix_size = 0; /* To delete everything */
}
else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
{
0, /* output */
0); /* output size */
/* Now check the limits on this chunk - if the limit fails the
* compressed data will be removed, the prefix will remain.
*/
if (png_ptr->user_chunk_malloc_max &&
#else
# ifdef PNG_USER_CHUNK_MALLOC_MAX
if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
# endif
#endif
/* If the size is zero either there was an error and a message
* has already been output (warning) or the size really is zero
* and we have nothing to do - the code will exit through the
* error case below.
*/
#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
defined(PNG_USER_CHUNK_MALLOC_MAX)
else if (expanded_size > 0)
#else
if (expanded_size > 0)
#endif
{
/* Success (maybe) - really uncompress the chunk. */
{
if (new_size == expanded_size)
{
return; /* The success return! */
}
}
else
}
}
else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
{
/* The recovery is to simply drop the data. */
}
/* Generic error return - leave the prefix, delete the compressed
* data, reallocate the chunkdata to remove the potentially large
* amount of compressed data.
*/
{
{
if (prefix_size > 0)
/* This is an extra zero in the 'uncompressed' part. */
}
/* Ignore a malloc error here - it is safe. */
}
*newlength = prefix_size;
}
#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
/* Read and check the IDHR chunk */
void /* PRIVATE */
{
int interlace_type;
/* Check the length */
if (length != 13)
png_crc_finish(png_ptr, 0);
/* Set internal variables */
#ifdef PNG_MNG_FEATURES_SUPPORTED
#endif
/* Find number of channels */
switch (png_ptr->color_type)
{
default: /* invalid, png_set_IHDR calls png_error */
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_PALETTE:
break;
case PNG_COLOR_TYPE_RGB:
break;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
break;
}
/* Set up other useful info */
}
/* Read and check the palette */
void /* PRIVATE */
{
int num, i;
#endif
{
return;
}
{
"Ignoring PLTE chunk in grayscale PNG");
return;
}
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
{
return;
}
#endif
{
{
return;
}
else
{
}
}
{
}
#else
for (i = 0; i < num; i++)
{
/* Don't depend upon png_color being any order */
}
#endif
/* If we actually need the PLTE chunk (ie for a paletted image), we do
* whatever the normal CRC configuration tells us. However, if we
* have an RGB image, the PLTE can be considered ancillary, so
* we will act as though it is.
*/
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
#endif
{
png_crc_finish(png_ptr, 0);
}
#ifndef PNG_READ_OPT_PLTE_SUPPORTED
{
/* If we don't want to use the data from an ancillary chunk,
* we have two options: an error abort, or a warning and we
* ignore the data in this chunk (which should be OK, since
* it's considered ancillary for a RGB or RGBA image).
*/
{
{
}
else
{
return;
}
}
/* Otherwise, we (optionally) emit a warning and use the chunk. */
{
}
}
#endif
#ifdef PNG_READ_tRNS_SUPPORTED
{
{
{
}
{
}
}
}
#endif
}
void /* PRIVATE */
{
{
}
if (length != 0)
{
}
}
#ifdef PNG_READ_gAMA_SUPPORTED
void /* PRIVATE */
{
{
return;
}
/* Should be an error, but we can cope with it */
#ifdef PNG_READ_sRGB_SUPPORTED
#endif
)
{
return;
}
if (length != 4)
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
/* Check for zero gamma or an error. */
if (igamma <= 0)
{
"Ignoring gAMA chunk with out of range gamma");
return;
}
# ifdef PNG_READ_sRGB_SUPPORTED
{
{
"Ignoring incorrect gAMA value @1 when sRGB is also present");
return;
}
}
# endif /* PNG_READ_sRGB_SUPPORTED */
# ifdef PNG_READ_GAMMA_SUPPORTED
/* Gamma correction on read is supported. */
# endif
/* And set the 'info' structure members. */
}
#endif
#ifdef PNG_READ_sBIT_SUPPORTED
void /* PRIVATE */
{
{
return;
}
{
/* Should be an error, but we can cope with it */
}
{
return;
}
truelen = 3;
else
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
{
}
else
{
}
}
#endif
#ifdef PNG_READ_cHRM_SUPPORTED
void /* PRIVATE */
{
{
return;
}
/* Should be an error, but we can cope with it */
# ifdef PNG_READ_sRGB_SUPPORTED
# endif
)
{
return;
}
if (length != 32)
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
if (x_white == PNG_FIXED_ERROR ||
y_white == PNG_FIXED_ERROR ||
x_red == PNG_FIXED_ERROR ||
y_red == PNG_FIXED_ERROR ||
x_green == PNG_FIXED_ERROR ||
y_green == PNG_FIXED_ERROR ||
x_blue == PNG_FIXED_ERROR ||
{
return;
}
#ifdef PNG_READ_sRGB_SUPPORTED
{
{
"Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) "
"when sRGB is also present");
}
return;
}
#endif /* PNG_READ_sRGB_SUPPORTED */
/* Store the _white values as default coefficients for the rgb to gray
* operation if it is supported.
*/
{
/* png_set_background has not been called, the coefficients must be in
* range for the following to work without overflow.
*/
{
/* The y values are chromaticities: Y/X+Y+Z, the weights for the gray
* transformation are simply the normalized Y values for red, green and
* blue scaled by 32768.
*/
32768)/w);
* 32768)/w);
32768)/w);
}
}
#endif
}
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
void /* PRIVATE */
{
int intent;
{
return;
}
/* Should be an error, but we can cope with it */
{
return;
}
if (length != 1)
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
/* Check for bad intent */
if (intent >= PNG_sRGB_INTENT_LAST)
{
return;
}
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
{
{
"Ignoring incorrect gAMA value @1 when sRGB is also present");
}
}
#endif /* PNG_READ_gAMA_SUPPORTED */
#ifdef PNG_READ_cHRM_SUPPORTED
{
"Ignoring incorrect cHRM value when sRGB is also present");
}
#endif /* PNG_READ_cHRM_SUPPORTED */
}
#endif /* PNG_READ_sRGB_SUPPORTED */
#ifdef PNG_READ_iCCP_SUPPORTED
void /* PRIVATE */
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
{
return;
}
/* Should be an error, but we can cope with it */
{
return;
}
#ifdef PNG_MAX_MALLOC_64K
{
}
#endif
{
return;
}
/* Empty loop to find end of name */ ;
++profile;
/* There should be at least one zero (the compression type byte)
* following the separator, and we should be on it
*/
{
return;
}
/* Compression_type should always be zero */
compression_type = *profile++;
if (compression_type)
{
wrote nonzero) */
}
{
return;
}
/* Check the profile_size recorded in the first 32 bits of the ICC profile */
((*(pC + 3)) );
/* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
* because profile_size is a 32 bit value.
*/
if (profile_size < profile_length)
/* And the following guarantees that profile_size == profile_length. */
if (profile_size > profile_length)
{
"Ignoring iCCP chunk with declared size = @1 and actual length = @2");
return;
}
}
#endif /* PNG_READ_iCCP_SUPPORTED */
#ifdef PNG_READ_sPLT_SUPPORTED
void /* PRIVATE */
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
int entry_size, i;
#ifdef PNG_USER_LIMITS_SUPPORTED
if (png_ptr->user_chunk_cache_max != 0)
{
{
return;
}
{
return;
}
}
#endif
{
return;
}
#ifdef PNG_MAX_MALLOC_64K
{
}
#endif
/* WARNING: this may break if size_t is less than 32 bits; it is assumed
* that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
* potential breakage point if the types in pngconf.h aren't exactly right.
*/
{
return;
}
entry_start++)
/* Empty loop to find end of name */ ;
++entry_start;
/* A sample depth should follow the separator, and we should be on it */
{
return;
}
/* This must fit in a png_uint_32 because it is derived from the original
* chunk data length (and use 'length', not 'slength' here for clarity -
* they are guaranteed to be the same, see the tests above.)
*/
/* Integrity-check the data length */
if (data_length % entry_size)
{
return;
}
{
return;
}
{
return;
}
for (i = 0; i < new_palette.nentries; i++)
{
{
}
else
{
}
}
#else
for (i = 0; i < new_palette.nentries; i++)
{
{
}
else
{
}
}
#endif
/* Discard all chunk data except the name and stash that */
}
#endif /* PNG_READ_sPLT_SUPPORTED */
#ifdef PNG_READ_tRNS_SUPPORTED
void /* PRIVATE */
{
{
return;
}
{
return;
}
{
if (length != 2)
{
return;
}
}
{
if (length != 6)
{
return;
}
}
{
{
/* Should be an error, but we can cope with it. */
}
{
return;
}
if (length == 0)
{
return;
}
}
else
{
return;
}
if (png_crc_finish(png_ptr, 0))
{
return;
}
&(png_ptr->trans_color));
}
#endif
#ifdef PNG_READ_bKGD_SUPPORTED
void /* PRIVATE */
{
{
return;
}
{
return;
}
{
return;
}
truelen = 1;
truelen = 6;
else
truelen = 2;
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
/* We convert the index value into RGB components so that we can allow
* arbitrary RGB values for background when we have transparency, and
* so it is easy to determine the RGB values of the background color
* from the info_ptr struct.
*/
{
{
{
return;
}
}
else
background.gray = 0;
}
{
background.index = 0;
}
else
{
background.index = 0;
background.gray = 0;
}
}
#endif
#ifdef PNG_READ_hIST_SUPPORTED
void /* PRIVATE */
{
unsigned int num, i;
{
return;
}
{
return;
}
{
return;
}
(unsigned int)PNG_MAX_PALETTE_LENGTH)
{
return;
}
for (i = 0; i < num; i++)
{
}
if (png_crc_finish(png_ptr, 0))
return;
}
#endif
#ifdef PNG_READ_pHYs_SUPPORTED
void /* PRIVATE */
{
int unit_type;
{
return;
}
{
return;
}
if (length != 9)
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
}
#endif
#ifdef PNG_READ_oFFs_SUPPORTED
void /* PRIVATE */
{
int unit_type;
{
return;
}
{
return;
}
if (length != 9)
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
}
#endif
#ifdef PNG_READ_pCAL_SUPPORTED
/* Read the pCAL chunk (described in the PNG Extensions document) */
void /* PRIVATE */
{
int i;
{
return;
}
{
return;
}
length + 1);
{
return;
}
if (png_crc_finish(png_ptr, 0))
{
return;
}
/* Empty loop */ ;
/* We need to have at least 12 bytes after the purpose string
* in order to get the parameter information.
*/
{
return;
}
/* Check that we have the right number of parameters for known
* equation types.
*/
{
return;
}
else if (type >= PNG_EQUATION_LAST)
{
}
/* Empty loop to move past the units string. */ ;
{
return;
}
/* Get pointers to the start of each parameter string. */
for (i = 0; i < (int)nparams; i++)
{
buf++; /* Skip the null string terminator from previous parameter. */
/* Empty loop to move past each parameter string */ ;
/* Make sure we haven't run out of data yet */
{
return;
}
}
}
#endif
#ifdef PNG_READ_sCAL_SUPPORTED
/* Read the sCAL chunk */
void /* PRIVATE */
{
int state;
{
return;
}
{
return;
}
/* Need unit type, width, \0, height: minimum 4 bytes */
else if (length < 4)
{
return;
}
length + 1);
{
return;
}
if (png_crc_finish(png_ptr, 0))
{
return;
}
/* Validate the unit. */
{
return;
}
/* Validate the ASCII numbers, need two ASCII numbers separated by
* a '\0' and they need to fit exactly in the chunk data.
*/
i = 1;
state = 0;
else if (!PNG_FP_IS_POSITIVE(state))
else
{
state = 0;
i != slength)
else if (!PNG_FP_IS_POSITIVE(state))
"Invalid sCAL chunk ignored: non-positive height");
else
/* This is the (only) success case. */
}
/* Clean up - just free the temporarily allocated buffer. */
}
#endif
#ifdef PNG_READ_tIME_SUPPORTED
void /* PRIVATE */
{
{
return;
}
if (length != 7)
{
return;
}
if (png_crc_finish(png_ptr, 0))
return;
}
#endif
#ifdef PNG_READ_tEXt_SUPPORTED
/* Note: this does not properly handle chunks that are > 64K under DOS */
void /* PRIVATE */
{
int ret;
#ifdef PNG_USER_LIMITS_SUPPORTED
if (png_ptr->user_chunk_cache_max != 0)
{
{
return;
}
{
return;
}
}
#endif
#ifdef PNG_MAX_MALLOC_64K
{
}
#endif
{
return;
}
{
return;
}
/* Empty loop to find end of key */ ;
text++;
{
return;
}
text_ptr->itxt_length = 0;
if (ret)
}
#endif
#ifdef PNG_READ_zTXt_SUPPORTED
/* Note: this does not correctly handle chunks that are > 64K under DOS */
void /* PRIVATE */
{
int comp_type;
int ret;
#ifdef PNG_USER_LIMITS_SUPPORTED
if (png_ptr->user_chunk_cache_max != 0)
{
{
return;
}
{
return;
}
}
#endif
#ifdef PNG_MAX_MALLOC_64K
/* We will no doubt have problems with chunks even half this size, but
* there is no hard and fast rule to tell us where to stop.
*/
{
return;
}
#endif
{
return;
}
if (png_crc_finish(png_ptr, 0))
{
return;
}
/* Empty loop */ ;
/* zTXt must have some text after the chunkdataword */
{
return;
}
else
{
if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
{
}
text++; /* Skip the compression_method byte */
}
{
return;
}
text_ptr->itxt_length = 0;
if (ret)
}
#endif
#ifdef PNG_READ_iTXt_SUPPORTED
/* Note: this does not correctly handle chunks that are > 64K under DOS */
void /* PRIVATE */
{
int comp_flag;
int comp_type = 0;
int ret;
#ifdef PNG_USER_LIMITS_SUPPORTED
if (png_ptr->user_chunk_cache_max != 0)
{
{
return;
}
{
return;
}
}
#endif
#ifdef PNG_MAX_MALLOC_64K
/* We will no doubt have problems with chunks even half this size, but
* there is no hard and fast rule to tell us where to stop.
*/
{
return;
}
#endif
{
return;
}
if (png_crc_finish(png_ptr, 0))
{
return;
}
/* Empty loop */ ;
lang++; /* Skip NUL separator */
/* iTXt must have a language tag (possibly empty), two compression bytes,
* translated keyword (possibly empty), and possibly some text after the
* keyword
*/
{
return;
}
else
{
}
/* Empty loop */ ;
lang_key++; /* Skip NUL separator */
{
return;
}
/* Empty loop */ ;
text++; /* Skip NUL separator */
{
return;
}
if (comp_flag)
else
{
return;
}
text_ptr->text_length = 0;
if (ret)
}
#endif
/* This function is called when we haven't found a handler for a
* chunk. If there isn't a problem with the chunk itself (ie bad
* chunk name, CRC, or a critical chunk), the chunk is silently ignored
* -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
* case it will be saved away to be written out later.
*/
void /* PRIVATE */
{
#ifdef PNG_USER_LIMITS_SUPPORTED
if (png_ptr->user_chunk_cache_max != 0)
{
{
return;
}
{
return;
}
}
#endif
{
}
{
#endif
)
#endif
}
#endif
)
{
#ifdef PNG_MAX_MALLOC_64K
{
}
#endif
= '\0';
if (length == 0)
else
{
}
{
/* Callback to user unknown chunk handler */
int ret;
if (ret < 0)
if (ret == 0)
{
{
#endif
}
}
}
else
#endif
}
else
#endif
#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
#endif
}
/* This function is called to verify that a chunk name is valid.
* This function can't have the "critical chunk check" incorporated
* into it, since in the future we will need to be able to call user
* functions to handle unknown critical chunks after we check that
* the chunk name itself is valid.
*/
void /* PRIVATE */
{
{
}
}
/* Combines the row recently read in with the existing pixels in the
* row. This routine takes care of alpha and transparency if requested.
* This routine also handles the two methods of progressive display
* of interlaced images, depending on the mask value.
* The mask value describes which pixels are to be combined with
* the row. The pattern always repeats every 8 pixels, so just 8
* bits are needed. A one indicates the pixel is to be combined,
* a zero indicates the pixel is to be skipped. This is in addition
* to any alpha or transparency value associated with the pixel. If
* you want all pixels to be combined, pass 0xff (255) in mask.
*/
void /* PRIVATE */
{
/* Added in 1.5.4: the row_info should match the information returned by any
* call to png_read_update_info at this point. Do not continue if we got
* this wrong.
*/
if (mask == 0xff)
{
}
else
{
{
case 1:
{
int m = 0x80;
int shift;
png_uint_32 i;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
{
s_start = 0;
s_end = 7;
s_inc = 1;
}
else
#endif
{
s_start = 7;
s_end = 0;
s_inc = -1;
}
for (i = 0; i < row_width; i++)
{
if (m & mask)
{
int value;
}
{
sp++;
dp++;
}
else
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
case 2:
{
int m = 0x80;
int shift;
png_uint_32 i;
int value;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
{
s_start = 0;
s_end = 6;
s_inc = 2;
}
else
#endif
{
s_start = 6;
s_end = 0;
s_inc = -2;
}
for (i = 0; i < row_width; i++)
{
if (m & mask)
{
}
{
sp++;
dp++;
}
else
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
case 4:
{
int m = 0x80;
int shift;
png_uint_32 i;
int value;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
{
s_start = 0;
s_end = 4;
s_inc = 4;
}
else
#endif
{
s_start = 4;
s_end = 0;
s_inc = -4;
}
for (i = 0; i < row_width; i++)
{
if (m & mask)
{
}
{
sp++;
dp++;
}
else
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
default:
{
png_uint_32 i;
png_byte m = 0x80;
for (i = 0; i < row_width; i++)
{
if (m & mask)
{
}
sp += pixel_bytes;
dp += pixel_bytes;
if (m == 1)
m = 0x80;
else
m >>= 1;
}
break;
}
}
}
}
void /* PRIVATE */
{
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Offset to next interlace block */
{
switch (row_info->pixel_depth)
{
case 1:
{
png_byte v;
png_uint_32 i;
int j;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
if (transformations & PNG_PACKSWAP)
{
s_start = 7;
s_end = 0;
s_inc = -1;
}
else
#endif
{
s_start = 0;
s_end = 7;
s_inc = 1;
}
{
for (j = 0; j < jstop; j++)
{
{
dp--;
}
else
}
{
sp--;
}
else
}
break;
}
case 2:
{
png_uint_32 i;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
if (transformations & PNG_PACKSWAP)
{
s_start = 6;
s_end = 0;
s_inc = -2;
}
else
#endif
{
s_start = 0;
s_end = 6;
s_inc = 2;
}
{
png_byte v;
int j;
for (j = 0; j < jstop; j++)
{
{
dp--;
}
else
}
{
sp--;
}
else
}
break;
}
case 4:
{
png_uint_32 i;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
if (transformations & PNG_PACKSWAP)
{
s_start = 4;
s_end = 0;
s_inc = -4;
}
else
#endif
{
s_start = 0;
s_end = 4;
s_inc = 4;
}
{
int j;
for (j = 0; j < jstop; j++)
{
{
dp--;
}
else
}
{
sp--;
}
else
}
break;
}
default:
{
* pixel_bytes;
png_uint_32 i;
{
png_byte v[8];
int j;
for (j = 0; j < jstop; j++)
{
dp -= pixel_bytes;
}
sp -= pixel_bytes;
}
break;
}
}
}
#ifndef PNG_READ_PACKSWAP_SUPPORTED
#endif
}
#endif /* PNG_READ_INTERLACING_SUPPORTED */
void /* PRIVATE */
{
switch (filter)
{
case PNG_FILTER_VALUE_NONE:
break;
case PNG_FILTER_VALUE_SUB:
{
png_size_t i;
{
rp++;
}
break;
}
case PNG_FILTER_VALUE_UP:
{
png_size_t i;
for (i = 0; i < istop; i++)
{
rp++;
}
break;
}
case PNG_FILTER_VALUE_AVG:
{
png_size_t i;
for (i = 0; i < bpp; i++)
{
rp++;
}
for (i = 0; i < istop; i++)
{
rp++;
}
break;
}
case PNG_FILTER_VALUE_PAETH:
{
png_size_t i;
for (i = 0; i < bpp; i++)
{
rp++;
}
for (i = 0; i < istop; i++) /* Use leftover rp,pp */
{
a = *lp++;
b = *pp++;
c = *cp++;
p = b - c;
pc = a - c;
#ifdef PNG_USE_ABS
#else
pa = p < 0 ? -p : p;
#endif
/*
if (pa <= pb && pa <= pc)
p = a;
else if (pb <= pc)
p = b;
else
p = c;
*/
rp++;
}
break;
}
default:
/*NOT REACHED */
break;
}
}
void /* PRIVATE */
{
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */
/* Offset to next interlace block */
/* Start of interlace block in the y direction */
/* Offset to next interlace block in the y direction */
#endif /* PNG_READ_INTERLACING_SUPPORTED */
png_ptr->row_number++;
return;
if (png_ptr->interlaced)
{
png_ptr->row_number = 0;
do
{
break;
{
}
else /* if (png_ptr->transformations & PNG_INTERLACE) */
break; /* libpng deinterlacing sees every row */
return;
}
#endif /* PNG_READ_INTERLACING_SUPPORTED */
{
char extra;
int ret;
for (;;)
{
{
{
png_crc_finish(png_ptr, 0);
}
}
if (ret == Z_STREAM_END)
{
break;
}
"Decompression Error");
{
break;
}
}
}
}
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
void /* PRIVATE */
{
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */
/* Offset to next interlace block */
/* Start of interlace block in the y direction */
/* Offset to next interlace block in the y direction */
#endif
int max_pixel_depth;
#endif
if (png_ptr->interlaced)
{
png_pass_ystart[0]) / png_pass_yinc[0];
else
}
else
#endif /* PNG_READ_INTERLACING_SUPPORTED */
{
}
#ifdef PNG_READ_PACK_SUPPORTED
max_pixel_depth = 8;
#endif
#ifdef PNG_READ_EXPAND_SUPPORTED
{
{
max_pixel_depth = 32;
else
max_pixel_depth = 24;
}
{
if (max_pixel_depth < 8)
max_pixel_depth = 8;
max_pixel_depth *= 2;
}
{
{
max_pixel_depth *= 4;
max_pixel_depth /= 3;
}
}
}
#endif
#ifdef PNG_READ_EXPAND_16_SUPPORTED
{
# ifdef PNG_READ_EXPAND_SUPPORTED
/* In fact it is an error if it isn't supported, but checking is
* the safe way.
*/
{
max_pixel_depth *= 2;
}
else
# endif
}
#endif
#ifdef PNG_READ_FILLER_SUPPORTED
{
max_pixel_depth = 32;
{
if (max_pixel_depth <= 8)
max_pixel_depth = 16;
else
max_pixel_depth = 32;
}
{
if (max_pixel_depth <= 32)
max_pixel_depth = 32;
else
max_pixel_depth = 64;
}
}
#endif
{
if (
#ifdef PNG_READ_EXPAND_SUPPORTED
#endif
#ifdef PNG_READ_FILLER_SUPPORTED
#endif
{
if (max_pixel_depth <= 16)
max_pixel_depth = 32;
else
max_pixel_depth = 64;
}
else
{
if (max_pixel_depth <= 8)
{
max_pixel_depth = 32;
else
max_pixel_depth = 24;
}
max_pixel_depth = 64;
else
max_pixel_depth = 48;
}
}
#endif
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
{
if (user_pixel_depth > max_pixel_depth)
}
#endif
/* Align the width on the next larger 8 pixels. Mainly used
* for interlacing
*/
/* Calculate the maximum bytes needed, adding a byte and a pixel
* for safety's sake
*/
#ifdef PNG_MAX_MALLOC_64K
#endif
{
if (png_ptr->interlaced)
row_bytes + 48);
else
row_bytes + 48);
#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
/* Use 16-byte aligned memory for row_buf with at least 16 bytes
* of padding before and after row_buf.
*/
#else
/* Use 32 bytes of padding before and 16 bytes after row_buf. */
#endif
}
#ifdef PNG_MAX_MALLOC_64K
#endif
{
}
}
#endif /* PNG_READ_SUPPORTED */