This code is released under the libpng license.
-libpng versions 1.0.7, July 1, 2000, through 1.6.21, January 15, 2016, are
+libpng versions 1.0.7, July 1, 2000 through 1.6.24, August 4, 2016 are
Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
derived from libpng-1.0.6, and are distributed according to the same
disclaimer and license as libpng-1.0.6 with the following individuals
risk of satisfactory quality, performance, accuracy, and effort is with
the user.
+Some files in the "contrib" directory and some configure-generated
+files that are distributed with libpng have other copyright owners and
+are released under other open source licenses.
+
libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
libpng-0.96, and are distributed according to the same disclaimer and
Greg Roelofs
Tom Tanner
+Some files in the "scripts" directory have other copyright owners
+but are released under this license.
+
libpng versions 0.5, May 1995, through 0.88, January 1996, are
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
-A "png_get_copyright" function is available, for convenient use in "about"
-boxes and the like:
+TRADEMARK:
- printf("%s", png_get_copyright(NULL));
+The name "libpng" has not been registered by the Copyright owner
+as a trademark in any jurisdiction. However, because libpng has
+been distributed and maintained world-wide, continually since 1995,
+the Copyright owner claims "common-law trademark protection" in any
+jurisdiction where common-law trademark is recognized.
-Also, the PNG logo (in PNG format, of course) is supplied in the
-files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+OSI CERTIFICATION:
Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
a certification mark of the Open Source Initiative. OSI has not addressed
the additional disclaimers inserted at version 1.0.7.
+EXPORT CONTROL:
+
+The Copyright owner believes that the Export Control Classification
+Number (ECCN) for libpng is EAR99, which means not subject to export
+controls or International Traffic in Arms Regulations (ITAR) because
+it is open source, publicly available software, that does not contain
+any encryption software. See the EAR, paragraphs 734.3(b)(3) and
+734.7(b).
+
Glenn Randers-Pehrson
glennrp at users.sourceforge.net
-January 15, 2016
+August 4, 2016
/* png.c - location for general purpose libpng functions
*
- * Last changed in libpng 1.6.19 [November 12, 2015]
+ * Last changed in libpng 1.6.24 [August 4, 2016]
* Copyright (c) 1998-2002,2004,2006-2015 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.)
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_21 Your_png_h_is_not_version_1_6_21;
+typedef png_libpng_version_1_6_24 Your_png_h_is_not_version_1_6_24;
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
if (items >= (~(png_alloc_size_t)0)/size)
{
png_warning (png_voidcast(png_structrp, png_ptr),
- "Potential overflow in png_zalloc()");
+ "Potential overflow in png_zalloc()");
return NULL;
}
int
png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
{
- /* Libpng versions 1.0.0 and later are binary compatible if the version
- * string matches through the second '.'; we must recompile any
- * applications that use any older library version.
- */
+ /* Libpng versions 1.0.0 and later are binary compatible if the version
+ * string matches through the second '.'; we must recompile any
+ * applications that use any older library version.
+ */
if (user_png_ver != NULL)
{
if (png_user_version_check(&create_struct, user_png_ver) != 0)
{
png_structrp png_ptr = png_voidcast(png_structrp,
- png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+ png_malloc_warn(&create_struct, (sizeof *png_ptr)));
if (png_ptr != NULL)
{
* has always been done in 'example.c'.
*/
info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
- (sizeof *info_ptr)));
+ (sizeof *info_ptr)));
if (info_ptr != NULL)
memset(info_ptr, 0, (sizeof *info_ptr));
*/
PNG_FUNCTION(void,PNGAPI
png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
- PNG_DEPRECATED)
+ PNG_DEPRECATED)
{
png_inforp info_ptr = *ptr_ptr;
/* The following line is why this API should not be used: */
free(info_ptr);
info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
- (sizeof *info_ptr)));
+ (sizeof *info_ptr)));
if (info_ptr == NULL)
return;
*ptr_ptr = info_ptr;
/* The following API is not called internally */
void PNGAPI
png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
- int freer, png_uint_32 mask)
+ int freer, png_uint_32 mask)
{
png_debug(1, "in png_data_freer");
void PNGAPI
png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
- int num)
+ int num)
{
png_debug(1, "in png_free_data");
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
- "libpng version 1.6.21 - January 15, 2016" PNG_STRING_NEWLINE \
+ "libpng version 1.6.24 - August 4, 2016" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson" \
PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# else
- return "libpng version 1.6.21 - January 15, 2016\
+ return "libpng version 1.6.24 - August 4, 2016\
Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
static int
png_colorspace_check_gamma(png_const_structrp png_ptr,
- png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+ png_colorspacerp colorspace, png_fixed_point gAMA, int from)
/* This is called to check a new gamma value against an existing one. The
* routine returns false if the new gamma value should not be written.
*
png_fixed_point gtest;
if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
- (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 ||
+ (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 ||
png_gamma_significant(gtest) != 0))
{
/* Either this is an sRGB image, in which case the calculated gamma
if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
{
png_chunk_report(png_ptr, "gamma value does not match sRGB",
- PNG_CHUNK_ERROR);
+ PNG_CHUNK_ERROR);
/* Do not overwrite an sRGB value */
return from == 2;
}
else /* sRGB tag not involved */
{
png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
- PNG_CHUNK_WARNING);
+ PNG_CHUNK_WARNING);
return from == 1;
}
}
void /* PRIVATE */
png_colorspace_set_gamma(png_const_structrp png_ptr,
- png_colorspacerp colorspace, png_fixed_point gAMA)
+ png_colorspacerp colorspace, png_fixed_point gAMA)
{
/* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
* occur. Since the fixed point representation is asymetrical it is
static int
png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
- png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
- int preferred)
+ png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+ int preferred)
{
if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
return 0;
int /* PRIVATE */
png_colorspace_set_chromaticities(png_const_structrp png_ptr,
- png_colorspacerp colorspace, const png_xy *xy, int preferred)
+ png_colorspacerp colorspace, const png_xy *xy, int preferred)
{
/* We must check the end points to ensure they are reasonable - in the past
* color management systems have crashed as a result of getting bogus
{
case 0: /* success */
return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
- preferred);
+ preferred);
case 1:
/* We can't invert the chromaticities so we can't produce value XYZ
int /* PRIVATE */
png_colorspace_set_endpoints(png_const_structrp png_ptr,
- png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+ png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
{
png_XYZ XYZ = *XYZ_in;
png_xy xy;
{
case 0:
return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
- preferred);
+ preferred);
case 1:
/* End points are invalid. */
static int
png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
- png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+ png_const_charp name, png_alloc_size_t value, png_const_charp reason)
{
size_t pos;
char message[196]; /* see below for calculation */
char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
pos = png_safecat(message, (sizeof message), pos,
- png_format_number(number, number+(sizeof number),
- PNG_NUMBER_FORMAT_x, value));
+ png_format_number(number, number+(sizeof number),
+ PNG_NUMBER_FORMAT_x, value));
pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
}
# endif
* application errors the PNG won't be written.)
*/
png_chunk_report(png_ptr, message,
- (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+ (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
return 0;
}
#ifdef PNG_sRGB_SUPPORTED
int /* PRIVATE */
png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
- int intent)
+ int intent)
{
/* sRGB sets known gamma, end points and (from the chunk) intent. */
/* IMPORTANT: these are not necessarily the values found in an ICC profile
*/
if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
return png_icc_profile_error(png_ptr, colorspace, "sRGB",
- (unsigned)intent, "invalid sRGB rendering intent");
+ (unsigned)intent, "invalid sRGB rendering intent");
if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
- colorspace->rendering_intent != intent)
+ colorspace->rendering_intent != intent)
return png_icc_profile_error(png_ptr, colorspace, "sRGB",
(unsigned)intent, "inconsistent rendering intents");
* warn but overwrite the value with the correct one.
*/
if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
- !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
- 100))
+ !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+ 100))
png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
PNG_CHUNK_ERROR);
* returns true when the 'from' argument corresponds to sRGB (2).
*/
(void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
- 2/*from sRGB*/);
+ 2/*from sRGB*/);
/* intent: bugs in GCC force 'int' to be used as the parameter type. */
colorspace->rendering_intent = (png_uint_16)intent;
int /* PRIVATE */
png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
- png_const_charp name, png_uint_32 profile_length)
+ png_const_charp name, png_uint_32 profile_length)
{
if (profile_length < 132)
return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
- "too short");
+ "too short");
return 1;
}
int /* PRIVATE */
png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
- png_const_charp name, png_uint_32 profile_length,
- png_const_bytep profile/* first 132 bytes only */, int color_type)
+ png_const_charp name, png_uint_32 profile_length,
+ png_const_bytep profile/* first 132 bytes only */, int color_type)
{
png_uint_32 temp;
temp = png_get_uint_32(profile);
if (temp != profile_length)
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "length does not match profile");
+ "length does not match profile");
temp = (png_uint_32) (*(profile+8));
if (temp > 3 && (profile_length & 3))
return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
- "invalid length");
+ "invalid length");
temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
profile_length < 132+12*temp) /* truncated tag table */
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "tag count too large");
+ "tag count too large");
/* The 'intent' must be valid or we can't store it, ICC limits the intent to
* 16 bits.
temp = png_get_uint_32(profile+64);
if (temp >= 0xffff) /* The ICC limit */
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "invalid rendering intent");
+ "invalid rendering intent");
/* This is just a warning because the profile may be valid in future
* versions.
*/
if (temp >= PNG_sRGB_INTENT_LAST)
(void)png_icc_profile_error(png_ptr, NULL, name, temp,
- "intent outside defined range");
+ "intent outside defined range");
/* At this point the tag table can't be checked because it hasn't necessarily
* been loaded; however, various header fields can be checked. These checks
temp = png_get_uint_32(profile+36); /* signature 'ascp' */
if (temp != 0x61637370)
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "invalid signature");
+ "invalid signature");
/* Currently the PCS illuminant/adopted white point (the computational
* white point) are required to be D50,
*/
if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
(void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
- "PCS illuminant is not D50");
+ "PCS illuminant is not D50");
/* The PNG spec requires this:
* "If the iCCP chunk is present, the image samples conform to the colour
case 0x52474220: /* 'RGB ' */
if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "RGB color space not permitted on grayscale PNG");
+ "RGB color space not permitted on grayscale PNG");
break;
case 0x47524159: /* 'GRAY' */
if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "Gray color space not permitted on RGB PNG");
+ "Gray color space not permitted on RGB PNG");
break;
default:
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "invalid ICC profile color space");
+ "invalid ICC profile color space");
}
/* It is up to the application to check that the profile class matches the
case 0x61627374: /* 'abst' */
/* May not be embedded in an image */
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "invalid embedded Abstract ICC profile");
+ "invalid embedded Abstract ICC profile");
case 0x6c696e6b: /* 'link' */
/* DeviceLink profiles cannot be interpreted in a non-device specific
* PNG.
*/
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "unexpected DeviceLink ICC profile class");
+ "unexpected DeviceLink ICC profile class");
case 0x6e6d636c: /* 'nmcl' */
/* A NamedColor profile is also device specific, however it doesn't
* certainly it will fail the tests below.
*/
(void)png_icc_profile_error(png_ptr, NULL, name, temp,
- "unexpected NamedColor ICC profile class");
+ "unexpected NamedColor ICC profile class");
break;
default:
* understood profiles.
*/
(void)png_icc_profile_error(png_ptr, NULL, name, temp,
- "unrecognized ICC profile class");
+ "unrecognized ICC profile class");
break;
}
default:
return png_icc_profile_error(png_ptr, colorspace, name, temp,
- "unexpected ICC PCS encoding");
+ "unexpected ICC PCS encoding");
}
return 1;
int /* PRIVATE */
png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
- png_const_charp name, png_uint_32 profile_length,
- png_const_bytep profile /* header plus whole tag table */)
+ png_const_charp name, png_uint_32 profile_length,
+ png_const_bytep profile /* header plus whole tag table */)
{
png_uint_32 tag_count = png_get_uint_32(profile+128);
png_uint_32 itag;
* alignment.
*/
(void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "ICC profile tag start not a multiple of 4");
+ "ICC profile tag start not a multiple of 4");
}
/* This is a hard error; potentially it can cause read outside the
*/
if (tag_start > profile_length || tag_length > profile_length - tag_start)
return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
- "ICC profile tag outside profile");
+ "ICC profile tag outside profile");
}
return 1; /* success, maybe with warnings */
*/
/* adler32, crc32, MD5[4], intent, date, length, file-name */
PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
- PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
- "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+ PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+ "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
/* ICC sRGB v2 perceptual no black-compensation: */
PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
- PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
- "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+ PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+ "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
- PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
- "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+ PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+ "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
/* ICC sRGB v4 perceptual */
PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
- PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
- "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+ PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+ "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
/* The following profiles have no known MD5 checksum. If there is a match
* on the (empty) MD5 the other fields are used to attempt a match and
* which suggests that they were also made by Hewlett Packard.
*/
PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
- PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
- "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+ "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
/* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
* match the D50 PCS illuminant in the header (it is in fact the D65 values,
* chromaticAdaptationTag.
*/
PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
- PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
- "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
- PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
- "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
};
static int
png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
- png_const_bytep profile, uLong adler)
+ png_const_bytep profile, uLong adler)
{
/* The quick check is to verify just the MD5 signature and trust the
* rest of the data. Because the profile has already been verified for
* which is made irrelevant by this error.
*/
png_chunk_report(png_ptr, "known incorrect sRGB profile",
- PNG_CHUNK_ERROR);
+ PNG_CHUNK_ERROR);
}
/* Warn that this being done; this isn't even an error since
else if (png_sRGB_checks[i].have_md5 == 0)
{
png_chunk_report(png_ptr,
- "out-of-date sRGB profile with no signature",
- PNG_CHUNK_WARNING);
+ "out-of-date sRGB profile with no signature",
+ PNG_CHUNK_WARNING);
}
return 1+png_sRGB_checks[i].is_broken;
return 0; /* no match */
}
-#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
void /* PRIVATE */
png_icc_set_sRGB(png_const_structrp png_ptr,
- png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+ png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
{
/* Is this profile one of the known ICC sRGB profiles? If it is, just set
* the sRGB information.
*/
-#if PNG_sRGB_PROFILE_CHECKS >= 0
if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
-#endif
(void)png_colorspace_set_sRGB(png_ptr, colorspace,
(int)/*already checked*/png_get_uint_32(profile+64));
}
+#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
#endif /* sRGB */
int /* PRIVATE */
png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
- png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
- int color_type)
+ png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+ int color_type)
{
if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
return 0;
if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
- color_type) != 0 &&
+ color_type) != 0 &&
png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
- profile) != 0)
+ profile) != 0)
{
-# ifdef PNG_sRGB_SUPPORTED
+# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
/* If no sRGB support, don't try storing sRGB information */
png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
# endif
/* Check for an internal error. */
if (r+g+b != 32768)
png_error(png_ptr,
- "internal error handling cHRM coefficients");
+ "internal error handling cHRM coefficients");
else
{
static int /* PRIVATE */
png_gt(size_t a, size_t b)
{
- return a > b;
+ return a > b;
}
#else
# define png_gt(a,b) ((a) > (b))
void /* PRIVATE */
png_check_IHDR(png_const_structrp png_ptr,
- png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_type, int compression_type,
- int filter_type)
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
{
int error = 0;
int /* PRIVATE */
png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
- png_size_tp whereami)
+ png_size_tp whereami)
{
int state = *statep;
png_size_t i = *whereami;
{
if (value > 0 && value < 65535)
{
-# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
- /* The same (unsigned int)->(double) constraints apply here as above,
- * however in this case the (unsigned int) to (int) conversion can
- * overflow on an ANSI-C90 compliant system so the cast needs to ensure
- * that this is not possible.
- */
- double r = floor(65535*pow((png_int_32)value/65535.,
- gamma_val*.00001)+.5);
- return (png_uint_16)r;
-# else
- png_int_32 lg2 = png_log16bit(value);
- png_fixed_point res;
-
- if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
- return png_exp16bit(res);
-
- /* Overflow. */
- value = 0;
-# endif
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ /* The same (unsigned int)->(double) constraints apply here as above,
+ * however in this case the (unsigned int) to (int) conversion can
+ * overflow on an ANSI-C90 compliant system so the cast needs to ensure
+ * that this is not possible.
+ */
+ double r = floor(65535*pow((png_int_32)value/65535.,
+ gamma_val*.00001)+.5);
+ return (png_uint_16)r;
+# else
+ png_int_32 lg2 = png_log16bit(value);
+ png_fixed_point res;
+
+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+ return png_exp16bit(res);
+
+ /* Overflow. */
+ value = 0;
+# endif
}
return (png_uint_16)value;
*/
static void
png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
- PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
{
/* Various values derived from 'shift': */
PNG_CONST unsigned int num = 1U << (8U - shift);
*/
static void
png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
- PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
{
PNG_CONST unsigned int num = 1U << (8U - shift);
PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
*/
static void
png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
- PNG_CONST png_fixed_point gamma_val)
+ PNG_CONST png_fixed_point gamma_val)
{
unsigned int i;
png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
void /* PRIVATE */
png_build_gamma_table(png_structrp png_ptr, int bit_depth)
{
- png_debug(1, "in png_build_gamma_table");
-
- /* Remove any existing table; this copes with multiple calls to
- * png_read_update_info. The warning is because building the gamma tables
- * multiple times is a performance hit - it's harmless but the ability to call
- * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
- * to warn if the app introduces such a hit.
- */
- if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
- {
- png_warning(png_ptr, "gamma table being rebuilt");
- png_destroy_gamma_table(png_ptr);
- }
-
- if (bit_depth <= 8)
- {
- png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
- png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
- png_ptr->screen_gamma) : PNG_FP_1);
+ png_debug(1, "in png_build_gamma_table");
+
+ /* Remove any existing table; this copes with multiple calls to
+ * png_read_update_info. The warning is because building the gamma tables
+ * multiple times is a performance hit - it's harmless but the ability to
+ * call png_read_update_info() multiple times is new in 1.5.6 so it seems
+ * sensible to warn if the app introduces such a hit.
+ */
+ if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+ {
+ png_warning(png_ptr, "gamma table being rebuilt");
+ png_destroy_gamma_table(png_ptr);
+ }
+
+ if (bit_depth <= 8)
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+ png_ptr->screen_gamma > 0 ?
+ png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
- {
- png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
- png_reciprocal(png_ptr->colorspace.gamma));
-
- png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
- png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
- png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
- }
+ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+ png_reciprocal(png_ptr->colorspace.gamma));
+
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+ png_ptr->screen_gamma > 0 ?
+ png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
- }
+ }
#ifdef PNG_16BIT_SUPPORTED
- else
- {
- png_byte shift, sig_bit;
-
- if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
- {
- sig_bit = png_ptr->sig_bit.red;
-
- if (png_ptr->sig_bit.green > sig_bit)
- sig_bit = png_ptr->sig_bit.green;
-
- if (png_ptr->sig_bit.blue > sig_bit)
- sig_bit = png_ptr->sig_bit.blue;
- }
- else
- sig_bit = png_ptr->sig_bit.gray;
-
- /* 16-bit gamma code uses this equation:
- *
- * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
- *
- * Where 'iv' is the input color value and 'ov' is the output value -
- * pow(iv, gamma).
- *
- * Thus the gamma table consists of up to 256 256-entry tables. The table
- * is selected by the (8-gamma_shift) most significant of the low 8 bits of
- * the color value then indexed by the upper 8 bits:
- *
- * table[low bits][high 8 bits]
- *
- * So the table 'n' corresponds to all those 'iv' of:
- *
- * <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
- *
- */
- if (sig_bit > 0 && sig_bit < 16U)
- /* shift == insignificant bits */
- shift = (png_byte)((16U - sig_bit) & 0xff);
-
- else
- shift = 0; /* keep all 16 bits */
-
- if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
- {
- /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
- * the significant bits in the *input* when the output will
- * eventually be 8 bits. By default it is 11.
- */
- if (shift < (16U - PNG_MAX_GAMMA_8))
- shift = (16U - PNG_MAX_GAMMA_8);
- }
-
- if (shift > 8U)
- shift = 8U; /* Guarantees at least one table! */
-
- png_ptr->gamma_shift = shift;
-
- /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
- * PNG_COMPOSE). This effectively smashed the background calculation for
- * 16-bit output because the 8-bit table assumes the result will be reduced
- * to 8 bits.
- */
- if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
- png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
- png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
- png_ptr->screen_gamma) : PNG_FP_1);
-
- else
- png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
- png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
- png_ptr->screen_gamma) : PNG_FP_1);
+ else
+ {
+ png_byte shift, sig_bit;
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ sig_bit = png_ptr->sig_bit.red;
+
+ if (png_ptr->sig_bit.green > sig_bit)
+ sig_bit = png_ptr->sig_bit.green;
+
+ if (png_ptr->sig_bit.blue > sig_bit)
+ sig_bit = png_ptr->sig_bit.blue;
+ }
+ else
+ sig_bit = png_ptr->sig_bit.gray;
+
+ /* 16-bit gamma code uses this equation:
+ *
+ * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+ *
+ * Where 'iv' is the input color value and 'ov' is the output value -
+ * pow(iv, gamma).
+ *
+ * Thus the gamma table consists of up to 256 256-entry tables. The table
+ * is selected by the (8-gamma_shift) most significant of the low 8 bits
+ * of the color value then indexed by the upper 8 bits:
+ *
+ * table[low bits][high 8 bits]
+ *
+ * So the table 'n' corresponds to all those 'iv' of:
+ *
+ * <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
+ *
+ */
+ if (sig_bit > 0 && sig_bit < 16U)
+ /* shift == insignificant bits */
+ shift = (png_byte)((16U - sig_bit) & 0xff);
+
+ else
+ shift = 0; /* keep all 16 bits */
+
+ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+ {
+ /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+ * the significant bits in the *input* when the output will
+ * eventually be 8 bits. By default it is 11.
+ */
+ if (shift < (16U - PNG_MAX_GAMMA_8))
+ shift = (16U - PNG_MAX_GAMMA_8);
+ }
+
+ if (shift > 8U)
+ shift = 8U; /* Guarantees at least one table! */
+
+ png_ptr->gamma_shift = shift;
+
+ /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+ * PNG_COMPOSE). This effectively smashed the background calculation for
+ * 16-bit output because the 8-bit table assumes the result will be
+ * reduced to 8 bits.
+ */
+ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+ png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+ png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+
+ else
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
- if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
- {
- png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
- png_reciprocal(png_ptr->colorspace.gamma));
-
- /* Notice that the '16 from 1' table should be full precision, however
- * the lookup on this table still uses gamma_shift, so it can't be.
- * TODO: fix this.
- */
- png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
- png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
- png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
- }
+ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+ {
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+ png_reciprocal(png_ptr->colorspace.gamma));
+
+ /* Notice that the '16 from 1' table should be full precision, however
+ * the lookup on this table still uses gamma_shift, so it can't be.
+ * TODO: fix this.
+ */
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+ png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
- }
+ }
#endif /* 16BIT */
}
#endif /* READ_GAMMA */
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.21, January 15, 2016
+ * libpng version 1.6.24, August 4, 2016
*
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
- * libpng versions 0.97, January 1998, through 1.6.21, January 15, 2016:
+ * libpng versions 0.97, January 1998, through 1.6.24, August 4, 2016:
* Glenn Randers-Pehrson.
* See also "Contributing Authors", below.
*/
*
* This code is released under the libpng license.
*
- * libpng versions 1.0.7, July 1, 2000, through 1.6.21, January 15, 2016, are
+ * Some files in the "contrib" directory and some configure-generated
+ * files that are distributed with libpng have other copyright owners and
+ * are released under other open source licenses.
+ *
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.24, August 4, 2016 are
* Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
* derived from libpng-1.0.6, and are distributed according to the same
* disclaimer and license as libpng-1.0.6 with the following individuals
* risk of satisfactory quality, performance, accuracy, and effort is with
* the user.
*
+ * Some files in the "contrib" directory have other copyright owners and
+ * are released under other open source licenses.
+ *
+ *
* libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
* Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
* libpng-0.96, and are distributed according to the same disclaimer and
* Glenn Randers-Pehrson
* Willem van Schaik
*
+ * Some files in the "scripts" directory have different copyright owners
+ * but are also released under this license.
+ *
* libpng versions 0.89, June 1996, through 0.96, May 1997, are
* Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
* and are distributed according to the same disclaimer and license as
* Greg Roelofs
* Tom Tanner
*
+ * Some files in the "scripts" directory have other copyright owners
+ * but are released under this license.
+ *
* libpng versions 0.5, May 1995, through 0.88, January 1996, are
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
*
* appreciated.
*
* END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
+ *
+ * TRADEMARK:
+ *
+ * The name "libpng" has not been registered by the Copyright owner
+ * as a trademark in any jurisdiction. However, because libpng has
+ * been distributed and maintained world-wide, continually since 1995,
+ * the Copyright owner claims "common-law trademark protection" in any
+ * jurisdiction where common-law trademark is recognized.
+ *
+ * OSI CERTIFICATION:
+ *
+ * Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
+ * a certification mark of the Open Source Initiative. OSI has not addressed
+ * the additional disclaimers inserted at version 1.0.7.
+ *
+ * EXPORT CONTROL:
+ *
+ * The Copyright owner believes that the Export Control Classification
+ * Number (ECCN) for libpng is EAR99, which means not subject to export
+ * controls or International Traffic in Arms Regulations (ITAR) because
+ * it is open source, publicly available software, that does not contain
+ * any encryption software. See the EAR, paragraphs 734.3(b)(3) and
+ * 734.7(b).
*/
/*
* files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
*/
-/*
- * Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
- * a certification mark of the Open Source Initiative. OSI has not addressed
- * the additional disclaimers inserted at version 1.0.7.
- */
-
/*
* The contributing authors would like to thank all those who helped
* with testing, bug fixes, and patience. This wouldn't have been
* ...
* 1.0.19 10 10019 10.so.0.19[.0]
* ...
- * 1.2.53 13 10253 12.so.0.53[.0]
+ * 1.2.56 13 10256 12.so.0.56[.0]
* ...
- * 1.5.23 15 10523 15.so.15.23[.0]
+ * 1.5.27 15 10527 15.so.15.27[.0]
* ...
- * 1.6.21 16 10621 16.so.16.21[.0]
+ * 1.6.24 16 10624 16.so.16.24[.0]
*
* Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be
* Y2K compliance in libpng:
* =========================
*
- * January 15, 2016
+ * August 4, 2016
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
*
* This is your unofficial assurance that libpng from version 0.71 and
- * upward through 1.6.21 are Y2K compliant. It is my belief that
+ * upward through 1.6.24 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant.
*
* Libpng only has two year fields. One is a 2-byte unsigned integer
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.21"
-#define PNG_HEADER_VERSION_STRING \
- " libpng version 1.6.21 - January 15, 2016\n"
+#define PNG_LIBPNG_VER_STRING "1.6.24"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.24 - August 4, 2016\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 21
+#define PNG_LIBPNG_VER_RELEASE 24
/* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero:
* version 1.0.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/
-#define PNG_LIBPNG_VER 10621 /* 1.6.21 */
+#define PNG_LIBPNG_VER 10624 /* 1.6.24 */
/* Library configuration: these options cannot be changed after
* the library has been built.
*/
#ifndef PNGLCONF_H
- /* If pnglibconf.h is missing, you can
- * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
- */
+/* If pnglibconf.h is missing, you can
+ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+ */
# include "pnglibconf.h"
#endif
#ifndef PNG_VERSION_INFO_ONLY
- /* Machine specific configuration. */
+/* Machine specific configuration. */
# include "pngconf.h"
#endif
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char* png_libpng_version_1_6_21;
+typedef char* png_libpng_version_1_6_24;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
*/
typedef struct png_unknown_chunk_t
{
- png_byte name[5]; /* Textual chunk name with '\0' terminator */
- png_byte *data; /* Data, should not be modified on read! */
- png_size_t size;
-
- /* On write 'location' must be set using the flag values listed below.
- * Notice that on read it is set by libpng however the values stored have
- * more bits set than are listed below. Always treat the value as a
- * bitmask. On write set only one bit - setting multiple bits may cause the
- * chunk to be written in multiple places.
- */
- png_byte location; /* mode of operation at read time */
+ png_byte name[5]; /* Textual chunk name with '\0' terminator */
+ png_byte *data; /* Data, should not be modified on read! */
+ png_size_t size;
+
+ /* On write 'location' must be set using the flag values listed below.
+ * Notice that on read it is set by libpng however the values stored have
+ * more bits set than are listed below. Always treat the value as a
+ * bitmask. On write set only one bit - setting multiple bits may cause the
+ * chunk to be written in multiple places.
+ */
+ png_byte location; /* mode of operation at read time */
}
png_unknown_chunk;
* data in the info_struct to be written into the output file. The values
* of the PNG_INFO_<chunk> defines should NOT be changed.
*/
-#define PNG_INFO_gAMA 0x0001
-#define PNG_INFO_sBIT 0x0002
-#define PNG_INFO_cHRM 0x0004
-#define PNG_INFO_PLTE 0x0008
-#define PNG_INFO_tRNS 0x0010
-#define PNG_INFO_bKGD 0x0020
-#define PNG_INFO_hIST 0x0040
-#define PNG_INFO_pHYs 0x0080
-#define PNG_INFO_oFFs 0x0100
-#define PNG_INFO_tIME 0x0200
-#define PNG_INFO_pCAL 0x0400
-#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
-#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
-#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
-#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
-#if INT_MAX >= 0x8000 /* else this might break */
-#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */
-#endif
+#define PNG_INFO_gAMA 0x0001U
+#define PNG_INFO_sBIT 0x0002U
+#define PNG_INFO_cHRM 0x0004U
+#define PNG_INFO_PLTE 0x0008U
+#define PNG_INFO_tRNS 0x0010U
+#define PNG_INFO_bKGD 0x0020U
+#define PNG_INFO_hIST 0x0040U
+#define PNG_INFO_pHYs 0x0080U
+#define PNG_INFO_oFFs 0x0100U
+#define PNG_INFO_tIME 0x0200U
+#define PNG_INFO_pCAL 0x0400U
+#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */
/* This is used for the transformation routines, as some of them
* change these values for the row. It also should enable using
#endif
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */
+#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */
/* Strip the second byte of information from a 16-bit depth file. */
PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
#endif
#define PNG_FILTER_UP 0x20
#define PNG_FILTER_AVG 0x40
#define PNG_FILTER_PAETH 0x80
-#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
- PNG_FILTER_AVG | PNG_FILTER_PAETH)
+#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP)
+#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH)
/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
* These defines should NOT be changed.
#define PNG_SET_WILL_FREE_DATA 1
#define PNG_USER_WILL_FREE_DATA 2
/* Flags for png_ptr->free_me and info_ptr->free_me */
-#define PNG_FREE_HIST 0x0008
-#define PNG_FREE_ICCP 0x0010
-#define PNG_FREE_SPLT 0x0020
-#define PNG_FREE_ROWS 0x0040
-#define PNG_FREE_PCAL 0x0080
-#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_HIST 0x0008U
+#define PNG_FREE_ICCP 0x0010U
+#define PNG_FREE_SPLT 0x0020U
+#define PNG_FREE_ROWS 0x0040U
+#define PNG_FREE_PCAL 0x0080U
+#define PNG_FREE_SCAL 0x0100U
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-# define PNG_FREE_UNKN 0x0200
+# define PNG_FREE_UNKN 0x0200U
#endif
-/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */
-#define PNG_FREE_PLTE 0x1000
-#define PNG_FREE_TRNS 0x2000
-#define PNG_FREE_TEXT 0x4000
-#define PNG_FREE_ALL 0x7fff
-#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */
+#define PNG_FREE_PLTE 0x1000U
+#define PNG_FREE_TRNS 0x2000U
+#define PNG_FREE_TEXT 0x4000U
+#define PNG_FREE_ALL 0x7fffU
+#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
#ifdef PNG_USER_MEM_SUPPORTED
PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
* except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
* be processed by libpng.
*/
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
int keep, png_const_bytep chunk_list, int num_chunks));
+#endif /* HANDLE_AS_UNKNOWN */
/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
* the result is therefore true (non-zero) if special handling is required,
*/
PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
png_const_bytep chunk_name));
-#endif
+#endif /* SET_UNKNOWN_CHUNKS */
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
/* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
-# define png_composite(composite, fg, alpha, bg) \
- { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
- * (png_uint_16)(alpha) \
- + (png_uint_16)(bg)*(png_uint_16)(255 \
- - (png_uint_16)(alpha)) + 128); \
- (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); }
-
-# define png_composite_16(composite, fg, alpha, bg) \
- { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
- * (png_uint_32)(alpha) \
- + (png_uint_32)(bg)*(65535 \
- - (png_uint_32)(alpha)) + 32768); \
- (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); }
+# define png_composite(composite, fg, alpha, bg) \
+ { \
+ png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+ * (png_uint_16)(alpha) \
+ + (png_uint_16)(bg)*(png_uint_16)(255 \
+ - (png_uint_16)(alpha)) + 128); \
+ (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
+ }
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ { \
+ png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
+ * (png_uint_32)(alpha) \
+ + (png_uint_32)(bg)*(65535 \
+ - (png_uint_32)(alpha)) + 32768); \
+ (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
+ }
#else /* Standard method using integer division */
-# define png_composite(composite, fg, alpha, bg) \
- (composite) = \
- (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \
- (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
- 127) / 255))
-
-# define png_composite_16(composite, fg, alpha, bg) \
- (composite) = \
- (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
- (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
- 32767) / 65535))
+# define png_composite(composite, fg, alpha, bg) \
+ (composite) = \
+ (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+ 127) / 255))
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ (composite) = \
+ (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+ (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
+ 32767) / 65535))
#endif /* READ_COMPOSITE_NODIV */
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
* format for negative values, which is almost certainly true.
*/
# define PNG_get_uint_32(buf) \
- (((png_uint_32)(*(buf)) << 24) + \
- ((png_uint_32)(*((buf) + 1)) << 16) + \
- ((png_uint_32)(*((buf) + 2)) << 8) + \
- ((png_uint_32)(*((buf) + 3))))
+ (((png_uint_32)(*(buf)) << 24) + \
+ ((png_uint_32)(*((buf) + 1)) << 16) + \
+ ((png_uint_32)(*((buf) + 2)) << 8) + \
+ ((png_uint_32)(*((buf) + 3))))
/* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
* function) incorrectly returned a value of type png_uint_32.
*/
# define PNG_get_uint_16(buf) \
- ((png_uint_16) \
- (((unsigned int)(*(buf)) << 8) + \
- ((unsigned int)(*((buf) + 1)))))
+ ((png_uint_16) \
+ (((unsigned int)(*(buf)) << 8) + \
+ ((unsigned int)(*((buf) + 1)))))
# define PNG_get_int_32(buf) \
- ((png_int_32)((*(buf) & 0x80) \
- ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
- : (png_int_32)png_get_uint_32(buf)))
+ ((png_int_32)((*(buf) & 0x80) \
+ ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
+ : (png_int_32)png_get_uint_32(buf)))
- /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
- * but defining a macro name prefixed with PNG_PREFIX.
- */
+/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+ * but defining a macro name prefixed with PNG_PREFIX.
+ */
# ifndef PNG_PREFIX
-# define png_get_uint_32(buf) PNG_get_uint_32(buf)
-# define png_get_uint_16(buf) PNG_get_uint_16(buf)
-# define png_get_int_32(buf) PNG_get_int_32(buf)
+# define png_get_uint_32(buf) PNG_get_uint_32(buf)
+# define png_get_uint_16(buf) PNG_get_uint_16(buf)
+# define png_get_int_32(buf) PNG_get_int_32(buf)
# endif
#else
# ifdef PNG_PREFIX
- /* No macros; revert to the (redefined) function */
-# define PNG_get_uint_32 (png_get_uint_32)
-# define PNG_get_uint_16 (png_get_uint_16)
-# define PNG_get_int_32 (png_get_int_32)
+ /* No macros; revert to the (redefined) function */
+# define PNG_get_uint_32 (png_get_uint_32)
+# define PNG_get_uint_16 (png_get_uint_16)
+# define PNG_get_int_32 (png_get_int_32)
# endif
#endif
* is the minimum 'row stride', the minimum count of components between each
* row. For a color-mapped image this is the minimum number of bytes in a
* row.
+ *
+ * WARNING: this macro overflows for some images with more than one component
+ * and very large image widths. libpng will refuse to process an image where
+ * this macro would overflow.
*/
#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
(PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
/* Return the size, in bytes, of an image buffer given a png_image and a row
* stride - the number of components to leave space for in each row.
+ *
+ * WARNING: this macro overflows a 32-bit integer for some large PNG images,
+ * libpng will refuse to process an image where such an overflow would occur.
*/
#define PNG_IMAGE_SIZE(image)\
#endif /* SIMPLIFIED_READ */
#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
-#ifdef PNG_STDIO_SUPPORTED
/* WRITE APIS
* ----------
* For write you must initialize a png_image structure to describe the image to
* values do not correspond to the colors in sRGB.
* colormap_entries: set to the number of entries in the color-map (0 to 256)
*/
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
const char *file, int convert_to_8bit, const void *buffer,
png_int_32 row_stride, const void *colormap));
int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
const void *colormap));
/* Write the image to the given (FILE*). */
+#endif /* SIMPLIFIED_WRITE_STDIO */
-/* With both write APIs if image is in one of the linear formats with 16-bit
+/* With all write APIs if image is in one of the linear formats with 16-bit
* data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
* gamma encoded according to the sRGB specification, otherwise a 16-bit linear
* encoded PNG file is written.
*
* With all APIs row_stride is handled as in the read APIs - it is the spacing
* from one row to the next in component sized units (1 or 2 bytes) and if
- * negative indicates a bottom-up row layout in the buffer. If row_stride is zero,
- * libpng will calculate it for you from the image width and number of channels.
+ * negative indicates a bottom-up row layout in the buffer. If row_stride is
+ * zero, libpng will calculate it for you from the image width and number of
+ * channels.
*
- * Note that the write API does not support interlacing, sub-8-bit pixels, indexed
- * PNG (color_type 3) or most ancillary chunks.
+ * Note that the write API does not support interlacing, sub-8-bit pixels or
+ * most ancillary chunks. If you need to write text chunks (e.g. for copyright
+ * notices) you need to use one of the other APIs.
*/
-#endif /* STDIO */
+
+PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
+ png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,
+ const void *buffer, png_int_32 row_stride, const void *colormap));
+ /* Write the image to the given memory buffer. The function both writes the
+ * whole PNG data stream to *memory and updates *memory_bytes with the count
+ * of bytes written.
+ *
+ * 'memory' may be NULL. In this case *memory_bytes is not read however on
+ * success the number of bytes which would have been written will still be
+ * stored in *memory_bytes. On failure *memory_bytes will contain 0.
+ *
+ * If 'memory' is not NULL it must point to memory[*memory_bytes] of
+ * writeable memory.
+ *
+ * If the function returns success memory[*memory_bytes] (if 'memory' is not
+ * NULL) contains the written PNG data. *memory_bytes will always be less
+ * than or equal to the original value.
+ *
+ * If the function returns false and *memory_bytes was not changed an error
+ * occured during write. If *memory_bytes was changed, or is not 0 if
+ * 'memory' was NULL, the write would have succeeded but for the memory
+ * buffer being too small. *memory_bytes contains the required number of
+ * bytes and will be bigger that the original value.
+ */
+
+#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\
+ row_stride, colormap)\
+ png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\
+ row_stride, colormap)
+ /* Return the amount of memory in 'size' required to compress this image.
+ * The png_image structure 'image' must be filled in as in the above
+ * function and must not be changed before the actual write call, the buffer
+ * and all other parameters must also be identical to that in the final
+ * write call. The 'size' variable need not be initialized.
+ *
+ * NOTE: the macro returns true/false, if false is returned 'size' will be
+ * set to zero and the write failed and probably will fail if tried again.
+ */
+
+/* You can pre-allocate the buffer by making sure it is of sufficient size
+ * regardless of the amount of compression achieved. The buffer size will
+ * always be bigger than the original image and it will never be filled. The
+ * following macros are provided to assist in allocating the buffer.
+ */
+#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)
+ /* The number of uncompressed bytes in the PNG byte encoding of the image;
+ * uncompressing the PNG IDAT data will give this number of bytes.
+ *
+ * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this
+ * macro can because of the extra bytes used in the PNG byte encoding. You
+ * need to avoid this macro if your image size approaches 2^30 in width or
+ * height. The same goes for the remainder of these macros; they all produce
+ * bigger numbers than the actual in-memory image size.
+ */
+#ifndef PNG_ZLIB_MAX_SIZE
+# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)
+ /* An upper bound on the number of compressed bytes given 'b' uncompressed
+ * bytes. This is based on deflateBounds() in zlib; different
+ * implementations of zlib compression may conceivably produce more data so
+ * if your zlib implementation is not zlib itself redefine this macro
+ * appropriately.
+ */
+#endif
+
+#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\
+ PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))
+ /* An upper bound on the size of the data in the PNG IDAT chunks. */
+
+#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
+ ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
+ (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
+ 12U+3U*(image).colormap_entries/*PLTE data*/+\
+ (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
+ 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
+ 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
+ /* A helper for the following macro; if your compiler cannot handle the
+ * following macro use this one with the result of
+ * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most
+ * compilers should handle this just fine.)
+ */
+
+#define PNG_IMAGE_PNG_SIZE_MAX(image)\
+ PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))
+ /* An upper bound on the total length of the PNG data stream for 'image'.
+ * The result is of type png_alloc_size_t, on 32-bit systems this may
+ * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will
+ * run out of buffer space but return a corrected size which should work.
+ */
#endif /* SIMPLIFIED_WRITE */
/*******************************************************************************
* END OF SIMPLIFIED API
* one to use is one more than this.)
*/
#ifdef PNG_EXPORT_LAST_ORDINAL
- PNG_EXPORT_LAST_ORDINAL(244);
+ PNG_EXPORT_LAST_ORDINAL(245);
#endif
#ifdef __cplusplus
/* pngconf.h - machine configurable file for libpng
*
- * libpng version 1.6.21, January 15, 2016
+ * libpng version 1.6.24, August 4, 2016
*
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
* compatible with GCC or Visual C because of different calling conventions.
*/
# if PNG_API_RULE == 2
- /* If this line results in an error, either because __watcall is not
- * understood or because of a redefine just below you cannot use *this*
- * build of the library with the compiler you are using. *This* build was
- * build using Watcom and applications must also be built using Watcom!
- */
+ /* If this line results in an error, either because __watcall is not
+ * understood or because of a redefine just below you cannot use *this*
+ * build of the library with the compiler you are using. *This* build was
+ * build using Watcom and applications must also be built using Watcom!
+ */
# define PNGCAPI __watcall
# endif
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl
# if PNG_API_RULE == 1
- /* If this line results in an error __stdcall is not understood and
- * PNG_API_RULE should not have been set to '1'.
- */
+ /* If this line results in an error __stdcall is not understood and
+ * PNG_API_RULE should not have been set to '1'.
+ */
# define PNGAPI __stdcall
# endif
# else
- /* An older compiler, or one not detected (erroneously) above,
- * if necessary override on the command line to get the correct
- * variants for the compiler.
- */
+ /* An older compiler, or one not detected (erroneously) above,
+ * if necessary override on the command line to get the correct
+ * variants for the compiler.
+ */
# ifndef PNGCAPI
# define PNGCAPI _cdecl
# endif
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
- /* older Borland and MSC
- * compilers used '__export' and required this to be after
- * the type.
- */
+ /* older Borland and MSC
+ * compilers used '__export' and required this to be after
+ * the type.
+ */
# ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# endif
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */
- /* Use the defaults, or define PNG*API on the command line (but
- * this will have to be done for every compile!)
- */
+ /* Use the defaults, or define PNG*API on the command line (but
+ * this will have to be done for every compile!)
+ */
# endif /* other system, !OS/2 */
#endif /* !Windows/x86 */
*/
#ifndef PNG_IMPEXP
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
- /* This forces use of a DLL, disallowing static linking */
+ /* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
* less efficient code.
*/
# if defined(__clang__) && defined(__has_attribute)
- /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
+ /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
/* pngerror.c - stub functions for i/o and memory allocation
*
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
#ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */
png_default_warning PNGARG((png_const_structrp png_ptr,
- png_const_charp warning_message));
+ png_const_charp warning_message));
#endif /* WARNINGS */
/* This function is called whenever there is a fatal error. This function
#ifdef PNG_ERROR_TEXT_SUPPORTED
PNG_FUNCTION(void,PNGAPI
png_error,(png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN)
+ PNG_NORETURN)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16];
if (png_ptr != NULL)
{
if ((png_ptr->flags &
- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
{
if (*error_message == PNG_LITERAL_SHARP)
{
else
error_message += offset;
- }
+ }
- else
- {
- if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+ else
{
- msg[0] = '0';
- msg[1] = '\0';
- error_message = msg;
+ if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+ {
+ msg[0] = '0';
+ msg[1] = '\0';
+ error_message = msg;
+ }
}
- }
- }
+ }
}
#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
*/
size_t
png_safecat(png_charp buffer, size_t bufsize, size_t pos,
- png_const_charp string)
+ png_const_charp string)
{
if (buffer != NULL && pos < bufsize)
{
*/
png_charp
png_format_number(png_const_charp start, png_charp end, int format,
- png_alloc_size_t number)
+ png_alloc_size_t number)
{
int count = 0; /* number of digits output */
int mincount = 1; /* minimum number required */
}
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
- warning_message + offset);
+ warning_message + offset);
else
png_default_warning(png_ptr, warning_message + offset);
}
*/
void
png_warning_parameter(png_warning_parameters p, int number,
- png_const_charp string)
+ png_const_charp string)
{
if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
(void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
void
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
- png_alloc_size_t value)
+ png_alloc_size_t value)
{
char buffer[PNG_NUMBER_BUFFER_SIZE];
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
void
png_warning_parameter_signed(png_warning_parameters p, int number, int format,
- png_int_32 value)
+ png_int_32 value)
{
png_alloc_size_t u;
png_charp str;
void
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
- png_const_charp message)
+ png_const_charp message)
{
/* The internal buffer is just 192 bytes - enough for all our messages,
* overflow doesn't happen because this code checks! If someone figures
void /* PRIVATE */
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
{
- if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
- png_warning(png_ptr, error_message);
- else
- png_error(png_ptr, error_message);
+ if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message)
void /* PRIVATE */
png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
{
- if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
- png_warning(png_ptr, error_message);
- else
- png_error(png_ptr, error_message);
+ if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message)
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
PNG_FUNCTION(void,PNGAPI
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN)
+ PNG_NORETURN)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
else
{
png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
- png_malloc_warn(png_ptr, jmp_buf_size));
+ png_malloc_warn(png_ptr, jmp_buf_size));
if (png_ptr->jmp_buf_ptr == NULL)
return NULL; /* new NULL return on OOM */
*/
static PNG_FUNCTION(void /* PRIVATE */,
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN)
+ PNG_NORETURN)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
*/
PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
- PNG_NORETURN)
+ PNG_NORETURN)
{
const png_const_structrp png_ptr = png_nonconst_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
/* Missing longjmp buffer, the following is to help debugging: */
{
size_t pos = png_safecat(image->message, (sizeof image->message), 0,
- "bad longjmp: ");
+ "bad longjmp: ");
png_safecat(image->message, (sizeof image->message), pos,
error_message);
}
/* pngget.c - retrieval of values from info struct
*
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
return (retval);
}
#endif /* pHYs */
-#endif /* INCH_CONVERSIONS */
+#endif /* INCH_CONVERSIONS */
/* png_get_channels really belongs in here, too, but it's been around longer */
-#endif /* EASY_ACCESS */
+#endif /* EASY_ACCESS */
png_byte PNGAPI
#ifdef PNG_bKGD_SUPPORTED
png_uint_32 PNGAPI
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
- png_color_16p *background)
+ png_color_16p *background)
{
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_bKGD) != 0 &&
if (white_x != NULL)
*white_x = png_float(png_ptr,
- info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
+ info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
if (white_y != NULL)
*white_y = png_float(png_ptr,
- info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
+ info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
if (red_x != NULL)
*red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
- "cHRM red X");
+ "cHRM red X");
if (red_y != NULL)
*red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
- "cHRM red Y");
+ "cHRM red Y");
if (green_x != NULL)
*green_x = png_float(png_ptr,
- info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
+ info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
if (green_y != NULL)
*green_y = png_float(png_ptr,
- info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
+ info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
if (blue_x != NULL)
*blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
- "cHRM blue X");
+ "cHRM blue X");
if (blue_y != NULL)
*blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
- "cHRM blue Y");
+ "cHRM blue Y");
return (PNG_INFO_cHRM);
}
png_uint_32 PNGAPI
png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *red_X, double *red_Y, double *red_Z, double *green_X,
- double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
- double *blue_Z)
+ double *red_X, double *red_Y, double *red_Z, double *green_X,
+ double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
+ double *blue_Z)
{
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
if (red_X != NULL)
*red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
- "cHRM red X");
+ "cHRM red X");
if (red_Y != NULL)
*red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
- "cHRM red Y");
+ "cHRM red Y");
if (red_Z != NULL)
*red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
- "cHRM red Z");
+ "cHRM red Z");
if (green_X != NULL)
*green_X = png_float(png_ptr,
- info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
+ info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
if (green_Y != NULL)
*green_Y = png_float(png_ptr,
- info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
+ info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
if (green_Z != NULL)
*green_Z = png_float(png_ptr,
- info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
+ info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
if (blue_X != NULL)
*blue_X = png_float(png_ptr,
- info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
+ info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
if (blue_Y != NULL)
*blue_Y = png_float(png_ptr,
- info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
+ info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
if (blue_Z != NULL)
*blue_Z = png_float(png_ptr,
- info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+ info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
return (PNG_INFO_cHRM);
}
png_debug1(1, "in %s retrieval function", "gAMA");
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
- file_gamma != NULL)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+ file_gamma != NULL)
{
*file_gamma = info_ptr->colorspace.gamma;
return (PNG_INFO_gAMA);
file_gamma != NULL)
{
*file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
- "png_get_gAMA");
+ "png_get_gAMA");
return (PNG_INFO_gAMA);
}
*/
*width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
- "sCAL height");
+ "sCAL height");
return (PNG_INFO_sCAL);
}
return 0;
#ifdef PNG_WRITE_SUPPORTED
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
#endif
{
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
- return png_ptr->IDAT_read_size;
+ return png_ptr->IDAT_read_size;
#else
- return PNG_IDAT_READ_SIZE;
+ return PNG_IDAT_READ_SIZE;
#endif
}
#ifdef PNG_WRITE_SUPPORTED
- else
- return png_ptr->zbuffer_size;
+ else
+ return png_ptr->zbuffer_size;
#endif
}
-/* libpng 1.6.21 STANDARD API DEFINITION */
+/* libpng 1.6.24 STANDARD API DEFINITION */
/* pnglibconf.h - library build configuration */
-/* Libpng version 1.6.21 - January 15, 2016 */
+/* Libpng version 1.6.24 - August 4, 2016 */
/* Copyright (c) 1998-2015 Glenn Randers-Pehrson */
#define PNG_SIMPLIFIED_READ_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
#define PNG_STDIO_SUPPORTED
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
/* pngmem.c - stub functions for memory allocation
*
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 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.)
*
*/
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED)
+ PNG_ALLOCATED)
{
/* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
* allocators have also been removed in 1.6.0, so any 16-bit system now has
*/
static png_voidp
png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
- size_t element_size)
+ size_t element_size)
{
png_alloc_size_t req = nelements; /* known to be > 0 */
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_array,(png_const_structrp png_ptr, int nelements,
- size_t element_size),PNG_ALLOCATED)
+ size_t element_size),PNG_ALLOCATED)
{
if (nelements <= 0 || element_size == 0)
png_error(png_ptr, "internal error: array alloc");
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
- int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
+ int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
{
/* These are internal errors: */
if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
if (add_elements <= INT_MAX - old_elements)
{
png_voidp new_array = png_malloc_array_checked(png_ptr,
- old_elements+add_elements, element_size);
+ old_elements+add_elements, element_size);
if (new_array != NULL)
{
memcpy(new_array, old_array, element_size*(unsigned)old_elements);
memset((char*)new_array + element_size*(unsigned)old_elements, 0,
- element_size*(unsigned)add_elements);
+ element_size*(unsigned)add_elements);
return new_array;
}
#ifdef PNG_USER_MEM_SUPPORTED
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED PNG_DEPRECATED)
+ PNG_ALLOCATED PNG_DEPRECATED)
{
png_voidp ret;
*/
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED)
+ PNG_ALLOCATED)
{
if (png_ptr != NULL)
{
/* pngpread.c - read a png file in push mode
*
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
png_uint_32 PNGAPI
png_process_data_skip(png_structrp png_ptr)
{
- /* TODO: Deprecate and remove this API.
- * Somewhere the implementation of this seems to have been lost,
- * or abandoned. It was only to support some internal back-door access
- * to png_struct) in libpng-1.4.x.
- */
+/* TODO: Deprecate and remove this API.
+ * Somewhere the implementation of this seems to have been lost,
+ * or abandoned. It was only to support some internal back-door access
+ * to png_struct) in libpng-1.4.x.
+ */
png_app_warning(png_ptr,
"png_process_data_skip is not implemented in any current version of libpng");
return 0;
(png_ptr->mode & PNG_HAVE_PLTE) == 0)
png_error(png_ptr, "Missing PLTE before IDAT");
- png_ptr->mode |= PNG_HAVE_IDAT;
png_ptr->process_mode = PNG_READ_IDAT_MODE;
- if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
- if (png_ptr->push_length == 0)
- return;
+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
+ if (png_ptr->push_length == 0)
+ return;
+
+ png_ptr->mode |= PNG_HAVE_IDAT;
if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
png_benign_error(png_ptr, "Too many IDATs found");
{
PNG_PUSH_SAVE_BUFFER_IF_FULL
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
- PNG_HANDLE_CHUNK_AS_DEFAULT);
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
}
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
png_error(png_ptr, "Insufficient memory for save_buffer");
}
- memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+ if (old_buffer)
+ memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+ else if (png_ptr->save_buffer_size)
+ png_error(png_ptr, "save_buffer error");
png_free(png_ptr, old_buffer);
png_ptr->save_buffer_max = new_max;
}
void /* PRIVATE */
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
+ png_size_t buffer_length)
{
png_ptr->current_buffer = buffer;
png_ptr->current_buffer_size = buffer_length;
void /* PRIVATE */
png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
- png_size_t buffer_length)
+ png_size_t buffer_length)
{
/* The caller checks for a non-zero buffer length. */
if (!(buffer_length > 0) || buffer == NULL)
{
if (png_ptr->pass < 6)
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
- png_ptr->transformations);
+ png_ptr->transformations);
switch (png_ptr->pass)
{
{
if (png_ptr->row_fn != NULL)
(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
- (int)png_ptr->pass);
+ (int)png_ptr->pass);
}
#ifdef PNG_READ_INTERLACING_SUPPORTED
/* pngpriv.h - private declarations for use inside libpng
*
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
- /* We need to check that <math.h> hasn't already been included earlier
- * as it seems it doesn't agree with <fp.h>, yet we should really use
- * <fp.h> if possible.
- */
+ /* We need to check that <math.h> hasn't already been included earlier
+ * as it seems it doesn't agree with <fp.h>, yet we should really use
+ * <fp.h> if possible.
+ */
# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
# include <fp.h>
# endif
# include <math.h>
# endif
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
- /* Amiga SAS/C: We must include builtin FPU functions when compiling using
- * MATH=68881
- */
+ /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+ * MATH=68881
+ */
# include <m68881.h>
# endif
#endif
#ifdef PNG_WRITE_cHRM_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
const png_xy *xy), PNG_EMPTY);
- /* The xy value must have been previously validated */
+ /* The xy value must have been previously validated */
#endif
#ifdef PNG_WRITE_sRGB_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
+#if PNG_ARM_NEON_OPT > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
/* Choose the best filter to use and filter the row data */
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
png_inforp info_ptr),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
- png_bytep row),PNG_EMPTY);
+ png_bytep row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
png_inforp info_ptr),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
png_inforp info_ptr), PNG_EMPTY);
- /* Synchronize the info 'valid' flags with the colorspace */
+ /* Synchronize the info 'valid' flags with the colorspace */
PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
png_inforp info_ptr), PNG_EMPTY);
- /* Copy the png_struct colorspace to the info_struct and call the above to
- * synchronize the flags. Checks for NULL info_ptr and does nothing.
- */
+ /* Copy the png_struct colorspace to the info_struct and call the above to
+ * synchronize the flags. Checks for NULL info_ptr and does nothing.
+ */
#endif
/* Added at libpng version 1.4.0 */
* the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
* CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
*/
+# if PNG_ARM_NEON_OPT > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+# endif
#endif
PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
/* pngread.c - read a PNG file
*
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
{
#ifndef PNG_USER_MEM_SUPPORTED
png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
- error_fn, warn_fn, NULL, NULL, NULL);
+ error_fn, warn_fn, NULL, NULL, NULL);
#else
return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, NULL, NULL, NULL);
+ warn_fn, NULL, NULL, NULL);
}
/* Alternate create PNG structure for reading, and allocate any memory
png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
{
png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
- error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
#endif /* USER_MEM */
if (png_ptr != NULL)
}
else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
png_ptr->mode |= PNG_AFTER_IDAT;
+ }
/* This should be a binary subdivision search or a hash for
* matching the chunk name rather than a linear search.
else
png_handle_unknown(png_ptr, info_ptr, length,
- PNG_HANDLE_CHUNK_AS_DEFAULT);
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
}
}
#endif /* SEQUENTIAL_READ */
/* New in 1.6.0 this avoids the bug of doing the initializations twice */
else
png_app_error(png_ptr,
- "png_read_update_info/png_start_read_image: duplicate call");
+ "png_read_update_info/png_start_read_image: duplicate call");
}
}
/* New in 1.6.0 this avoids the bug of doing the initializations twice */
else
png_app_error(png_ptr,
- "png_start_read_image/png_read_update_info: duplicate call");
+ "png_start_read_image/png_read_update_info: duplicate call");
}
}
#endif /* SEQUENTIAL_READ */
{
if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
- png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+ png_ptr->prev_row + 1, png_ptr->row_buf[0]);
else
png_error(png_ptr, "bad adaptive filter value");
}
{
if (png_ptr->pass < 6)
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
- png_ptr->transformations);
+ png_ptr->transformations);
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, 1/*display*/);
* but the caller should do it!
*/
png_warning(png_ptr, "Interlace handling should be turned on when "
- "using png_read_image");
+ "using png_read_image");
/* Make sure this is set correctly */
png_ptr->num_rows = png_ptr->height;
}
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Report invalid palette index; added at libng-1.5.10 */
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- png_ptr->num_palette_max > png_ptr->num_palette)
- png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+ png_ptr->num_palette_max > png_ptr->num_palette)
+ png_benign_error(png_ptr, "Read palette index exceeding num_palette");
#endif
do
png_uint_32 length = png_read_chunk_header(png_ptr);
png_uint_32 chunk_name = png_ptr->chunk_name;
+ if (chunk_name != png_IDAT)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
if (chunk_name == png_IEND)
png_handle_IEND(png_ptr, info_ptr, length);
{
if (chunk_name == png_IDAT)
{
- if ((length > 0) ||
- (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
- png_benign_error(png_ptr, "Too many IDATs found");
+ if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+ png_benign_error(png_ptr, ".Too many IDATs found");
}
png_handle_unknown(png_ptr, info_ptr, length, keep);
if (chunk_name == png_PLTE)
else if (chunk_name == png_IDAT)
{
/* Zero length IDATs are legal after the last IDAT has been
- * read, but not after other chunks have been read.
+ * read, but not after other chunks have been read. 1.6 does not
+ * always read all the deflate data; specifically it cannot be relied
+ * upon to read the Adler32 at the end. If it doesn't ignore IDAT
+ * chunks which are longer than zero as well:
*/
- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
- png_benign_error(png_ptr, "Too many IDATs found");
+ if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+ png_benign_error(png_ptr, "..Too many IDATs found");
png_crc_finish(png_ptr, length);
}
else
png_handle_unknown(png_ptr, info_ptr, length,
- PNG_HANDLE_CHUNK_AS_DEFAULT);
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
} while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
}
#endif /* SEQUENTIAL_READ */
#ifdef PNG_INFO_IMAGE_SUPPORTED
void PNGAPI
png_read_png(png_structrp png_ptr, png_inforp info_ptr,
- int transforms,
- voidp params)
+ int transforms, voidp params)
{
if (png_ptr == NULL || info_ptr == NULL)
return;
if (info_ptr != NULL)
{
png_controlp control = png_voidcast(png_controlp,
- png_malloc_warn(png_ptr, (sizeof *control)));
+ png_malloc_warn(png_ptr, (sizeof *control)));
if (control != NULL)
{
else
return png_image_error(image,
- "png_image_begin_read_from_stdio: invalid argument");
+ "png_image_begin_read_from_stdio: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+ "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
return 0;
}
else
return png_image_error(image,
- "png_image_begin_read_from_file: invalid argument");
+ "png_image_begin_read_from_file: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+ "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
return 0;
}
}
int PNGAPI png_image_begin_read_from_memory(png_imagep image,
- png_const_voidp memory, png_size_t size)
+ png_const_voidp memory, png_size_t size)
{
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
else
return png_image_error(image,
- "png_image_begin_read_from_memory: invalid argument");
+ "png_image_begin_read_from_memory: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+ "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
return 0;
}
* IHDR, PLTE, tRNS, IDAT, and IEND chunks.
*/
png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
- NULL, -1);
+ NULL, -1);
/* But do not ignore image data handling chunks */
png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
- chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
- }
+ chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
+ }
}
# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
#ifdef __GNUC__
default:
png_error(display->image->opaque->png_ptr,
- "unexpected encoding (internal error)");
+ "unexpected encoding (internal error)");
#endif
}
static png_uint_32
png_colormap_compose(png_image_read_control *display,
- png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
- png_uint_32 background, int encoding)
+ png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+ png_uint_32 background, int encoding)
{
/* The file value is composed on the background, the background has the given
* encoding and so does the result, the file is encoded with P_FILE and the
*/
static void
png_create_colormap_entry(png_image_read_control *display,
- png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
- png_uint_32 alpha, int encoding)
+ png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+ png_uint_32 alpha, int encoding)
{
png_imagep image = display->image;
const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
- P_LINEAR : P_sRGB;
+ P_LINEAR : P_sRGB;
const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
- (red != green || green != blue);
+ (red != green || green != blue);
if (ip > 255)
png_error(image->opaque->png_ptr, "color-map index out of range");
for (g=0; g<6; ++g)
png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
- P_sRGB);
+ P_sRGB);
}
return i;
for (b=0; b<6; ++b)
png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
- P_sRGB);
+ P_sRGB);
}
}
else if (display->background == NULL /* no way to remove it */)
png_error(png_ptr,
- "a background color must be supplied to remove alpha/transparency");
+ "background color must be supplied to remove alpha/transparency");
/* Get a copy of the background color (this avoids repeating the checks
* below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the
*/
if (i != trans)
png_create_colormap_entry(display, i, val, val, val, 255,
- P_FILE/*8-bit with file gamma*/);
+ P_FILE/*8-bit with file gamma*/);
/* Else this entry is transparent. The colors don't matter if
* there is an alpha channel (back_alpha == 0), but it does no
*/
else
png_create_colormap_entry(display, i, back_r, back_g, back_b,
- back_alpha, output_encoding);
+ back_alpha, output_encoding);
}
/* We need libpng to preserve the original encoding. */
* matches.
*/
png_create_colormap_entry(display, gray, back_g, back_g,
- back_g, 65535, P_LINEAR);
+ back_g, 65535, P_LINEAR);
}
/* The background passed to libpng, however, must be the
* doesn't.
*/
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
output_processing = PNG_CMAP_NONE;
break;
* background color at full precision.
*/
png_create_colormap_entry(display, 254, back_r, back_g, back_b,
- back_alpha, output_encoding);
+ back_alpha, output_encoding);
}
else
/* And make sure the corresponding palette entry matches. */
png_create_colormap_entry(display, gray, back_g, back_g,
- back_g, 65535, P_LINEAR);
+ back_g, 65535, P_LINEAR);
}
/* The background passed to libpng, however, must be the sRGB
c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
output_processing = PNG_CMAP_NONE;
}
{
png_uint_32 gray = (i * 256 + 115) / 231;
png_create_colormap_entry(display, i++, gray, gray, gray,
- 255, P_sRGB);
+ 255, P_sRGB);
}
/* NOTE: this preserves the full precision of the application
background_index = i;
png_create_colormap_entry(display, i++, back_r, back_g, back_b,
#ifdef __COVERITY__
- /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
- * here.
- */ 255U,
+ /* Coverity claims that output_encoding
+ * cannot be 2 (P_LINEAR) here.
+ */ 255U,
#else
- output_encoding == P_LINEAR ? 65535U : 255U,
+ output_encoding == P_LINEAR ? 65535U : 255U,
#endif
- output_encoding);
+ output_encoding);
/* For non-opaque input composite on the sRGB background - this
* requires inverting the encoding for each component. The input
png_uint_32 gray = png_sRGB_table[g*51] * alpha;
png_create_colormap_entry(display, i++,
- PNG_sRGB_FROM_LINEAR(gray + back_rx),
- PNG_sRGB_FROM_LINEAR(gray + back_gx),
- PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
+ PNG_sRGB_FROM_LINEAR(gray + back_rx),
+ PNG_sRGB_FROM_LINEAR(gray + back_gx),
+ PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
}
}
* png_set_tRNS_to_alpha before png_set_background_fixed.
*/
png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
- -1);
+ -1);
data_encoding = P_sRGB;
/* The output will now be one or two 8-bit gray or gray+alpha
gray = png_sRGB_table[gray]; /* now P_LINEAR */
gray = PNG_DIV257(png_gamma_16bit_correct(gray,
- png_ptr->colorspace.gamma)); /* now P_FILE */
+ png_ptr->colorspace.gamma)); /* now P_FILE */
/* And make sure the corresponding palette entry contains
* exactly the required sRGB value.
*/
png_create_colormap_entry(display, gray, back_g, back_g,
- back_g, 0/*unused*/, output_encoding);
+ back_g, 0/*unused*/, output_encoding);
}
else if (output_encoding == P_LINEAR)
*/
expand_tRNS = 1;
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
}
output_processing = PNG_CMAP_NONE;
/* Add a transparent entry. */
png_create_colormap_entry(display, cmap_entries, 255, 255,
- 255, 0, P_sRGB);
+ 255, 0, P_sRGB);
/* This is stored as the background index for the processing
* algorithm.
*/
for (b=0; b<256; b = (b << 1) | 0x7f)
png_create_colormap_entry(display, cmap_entries++,
- r, g, b, 128, P_sRGB);
+ r, g, b, 128, P_sRGB);
}
}
cmap_entries = make_rgb_colormap(display);
png_create_colormap_entry(display, cmap_entries, back_r,
- back_g, back_b, 0/*unused*/, output_encoding);
+ back_g, back_b, 0/*unused*/, output_encoding);
if (output_encoding == P_LINEAR)
{
* index.
*/
if (memcmp((png_const_bytep)display->colormap +
- sample_size * cmap_entries,
- (png_const_bytep)display->colormap +
- sample_size * PNG_RGB_INDEX(r,g,b),
+ sample_size * cmap_entries,
+ (png_const_bytep)display->colormap +
+ sample_size * PNG_RGB_INDEX(r,g,b),
sample_size) != 0)
{
/* The background color must be added. */
*/
for (b=0; b<256; b = (b << 1) | 0x7f)
png_create_colormap_entry(display, cmap_entries++,
- png_colormap_compose(display, r, P_sRGB, 128,
- back_r, output_encoding),
- png_colormap_compose(display, g, P_sRGB, 128,
- back_g, output_encoding),
- png_colormap_compose(display, b, P_sRGB, 128,
- back_b, output_encoding),
- 0/*unused*/, output_encoding);
+ png_colormap_compose(display, r, P_sRGB, 128,
+ back_r, output_encoding),
+ png_colormap_compose(display, g, P_sRGB, 128,
+ back_g, output_encoding),
+ png_colormap_compose(display, b, P_sRGB, 128,
+ back_b, output_encoding),
+ 0/*unused*/, output_encoding);
}
}
c.blue = (png_uint_16)back_b;
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
output_processing = PNG_CMAP_RGB;
}
{
if (trans[i] == 0)
png_create_colormap_entry(display, i, back_r, back_g,
- back_b, 0, output_encoding);
+ back_b, 0, output_encoding);
else
{
* on the sRGB color in 'back'.
*/
png_create_colormap_entry(display, i,
- png_colormap_compose(display, colormap[i].red, P_FILE,
- trans[i], back_r, output_encoding),
- png_colormap_compose(display, colormap[i].green, P_FILE,
- trans[i], back_g, output_encoding),
- png_colormap_compose(display, colormap[i].blue, P_FILE,
- trans[i], back_b, output_encoding),
- output_encoding == P_LINEAR ? trans[i] * 257U :
- trans[i],
- output_encoding);
+ png_colormap_compose(display, colormap[i].red,
+ P_FILE, trans[i], back_r, output_encoding),
+ png_colormap_compose(display, colormap[i].green,
+ P_FILE, trans[i], back_g, output_encoding),
+ png_colormap_compose(display, colormap[i].blue,
+ P_FILE, trans[i], back_b, output_encoding),
+ output_encoding == P_LINEAR ? trans[i] * 257U :
+ trans[i],
+ output_encoding);
}
}
else
png_create_colormap_entry(display, i, colormap[i].red,
- colormap[i].green, colormap[i].blue,
- i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
+ colormap[i].green, colormap[i].blue,
+ i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
}
/* The PNG data may have indices packed in fewer than 8 bits, it
png_image_read_and_map(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
int passes;
if (alpha >= 196)
*outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
- inrow[2]);
+ inrow[2]);
else if (alpha < 64)
*outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
png_image_read_colormapped(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_controlp control = image->opaque;
png_structrp png_ptr = control->png_ptr;
png_image_read_composite(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
int passes;
png_image_read_background(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
for (pass = 0; pass < passes; ++pass)
{
- png_bytep row = png_voidcast(png_bytep,
- display->first_row);
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
unsigned int startx, stepx, stepy;
png_uint_32 y;
for (; y<height; y += stepy)
{
png_bytep inrow = png_voidcast(png_bytep,
- display->local_row);
+ display->local_row);
png_bytep outrow = first_row + y * step_row;
png_const_bytep end_row = outrow + width;
for (; y<height; y += stepy)
{
png_bytep inrow = png_voidcast(png_bytep,
- display->local_row);
+ display->local_row);
png_bytep outrow = first_row + y * step_row;
png_const_bytep end_row = outrow + width;
*/
{
png_uint_16p first_row = png_voidcast(png_uint_16p,
- display->first_row);
+ display->first_row);
/* The division by two is safe because the caller passed in a
* stride which was multiplied by 2 (below) to get row_bytes.
*/
/* Read the row, which is packed: */
png_read_row(png_ptr, png_voidcast(png_bytep,
- display->local_row), NULL);
+ display->local_row), NULL);
inrow = png_voidcast(png_const_uint_16p, display->local_row);
/* Now do the pre-multiplication on each pixel in this row.
png_image_read_direct(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
do_local_background = 1/*maybe*/;
png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
- PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+ PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
}
change &= ~PNG_FORMAT_FLAG_COLOR;
* final value.
*/
if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma,
- PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
+ PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
do_local_background = 0;
else if (mode == PNG_ALPHA_STANDARD)
* pixels.
*/
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
}
else /* compose on row: implemented below. */
else
filler = 255;
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
- {
- where = PNG_FILLER_BEFORE;
- change &= ~PNG_FORMAT_FLAG_AFIRST;
- }
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ {
+ where = PNG_FILLER_BEFORE;
+ change &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
- else
-# endif
- where = PNG_FILLER_AFTER;
+ else
+#endif
+ where = PNG_FILLER_AFTER;
png_set_add_alpha(png_ptr, filler, where);
}
if (info_ptr->bit_depth == 16)
info_format |= PNG_FORMAT_FLAG_LINEAR;
-# ifdef PNG_FORMAT_BGR_SUPPORTED
- if ((png_ptr->transformations & PNG_BGR) != 0)
- info_format |= PNG_FORMAT_FLAG_BGR;
-# endif
+#ifdef PNG_FORMAT_BGR_SUPPORTED
+ if ((png_ptr->transformations & PNG_BGR) != 0)
+ info_format |= PNG_FORMAT_FLAG_BGR;
+#endif
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
if (do_local_background == 2)
{
if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
int PNGAPI
png_image_finish_read(png_imagep image, png_const_colorp background,
- void *buffer, png_int_32 row_stride, void *colormap)
+ void *buffer, png_int_32 row_stride, void *colormap)
{
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
- png_uint_32 check;
+ /* Check for row_stride overflow. This check is not performed on the
+ * original PNG format because it may not occur in the output PNG format
+ * and libpng deals with the issues of reading the original.
+ */
+ const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
- if (row_stride == 0)
- row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+ /* The following checks just the 'row_stride' calculation to ensure it
+ * fits in a signed 32-bit value. Because channels/components can be
+ * either 1 or 2 bytes in size the length of a row can still overflow 32
+ * bits; this is just to verify that the 'row_stride' argument can be
+ * represented.
+ */
+ if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */
+ {
+ png_uint_32 check;
+ const png_uint_32 png_row_stride = image->width * channels;
- if (row_stride < 0)
- check = -row_stride;
+ if (row_stride == 0)
+ row_stride = (png_int_32)/*SAFE*/png_row_stride;
- else
- check = row_stride;
+ if (row_stride < 0)
+ check = -row_stride;
- if (image->opaque != NULL && buffer != NULL &&
- check >= PNG_IMAGE_ROW_STRIDE(*image))
- {
- if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
- (image->colormap_entries > 0 && colormap != NULL))
+ else
+ check = row_stride;
+
+ /* This verifies 'check', the absolute value of the actual stride
+ * passed in and detects overflow in the application calculation (i.e.
+ * if the app did actually pass in a non-zero 'row_stride'.
+ */
+ if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
{
- int result;
- png_image_read_control display;
-
- memset(&display, 0, (sizeof display));
- display.image = image;
- display.buffer = buffer;
- display.row_stride = row_stride;
- display.colormap = colormap;
- display.background = background;
- display.local_row = NULL;
-
- /* Choose the correct 'end' routine; for the color-map case all the
- * setup has already been done.
+ /* Now check for overflow of the image buffer calculation; this
+ * limits the whole image size to 32 bits for API compatibility with
+ * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+ *
+ * The PNG_IMAGE_BUFFER_SIZE macro is:
+ *
+ * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))
+ *
+ * And the component size is always 1 or 2, so make sure that the
+ * number of *bytes* that the application is saying are available
+ * does actually fit into a 32-bit number.
+ *
+ * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE
+ * will be changed to use png_alloc_size_t; bigger images can be
+ * accomodated on 64-bit systems.
*/
- if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
- result =
- png_safe_execute(image, png_image_read_colormap, &display) &&
- png_safe_execute(image, png_image_read_colormapped, &display);
+ if (image->height <=
+ 0xFFFFFFFFU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check)
+ {
+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
+ (image->colormap_entries > 0 && colormap != NULL))
+ {
+ int result;
+ png_image_read_control display;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.background = background;
+ display.local_row = NULL;
+
+ /* Choose the correct 'end' routine; for the color-map case
+ * all the setup has already been done.
+ */
+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
+ result =
+ png_safe_execute(image,
+ png_image_read_colormap, &display) &&
+ png_safe_execute(image,
+ png_image_read_colormapped, &display);
- else
- result =
- png_safe_execute(image, png_image_read_direct, &display);
+ else
+ result =
+ png_safe_execute(image,
+ png_image_read_direct, &display);
+
+ png_image_free(image);
+ return result;
+ }
- png_image_free(image);
- return result;
+ else
+ return png_image_error(image,
+ "png_image_finish_read[color-map]: no color-map");
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_finish_read: image too large");
}
else
return png_image_error(image,
- "png_image_finish_read[color-map]: no color-map");
+ "png_image_finish_read: invalid argument");
}
else
return png_image_error(image,
- "png_image_finish_read: invalid argument");
+ "png_image_finish_read: row_stride too large");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_finish_read: damaged PNG_IMAGE_VERSION");
+ "png_image_finish_read: damaged PNG_IMAGE_VERSION");
return 0;
}
/* pngrio.c - functions for data input
*
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
*/
void PNGAPI
png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
- png_rw_ptr read_data_fn)
+ png_rw_ptr read_data_fn)
{
if (png_ptr == NULL)
return;
/* pngrtran.c - transforms the data in a row for PNG readers
*
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */
png_warning(png_ptr,
- "Can't discard critical data on CRC error");
+ "Can't discard critical data on CRC error");
case PNG_CRC_ERROR_QUIT: /* Error/quit */
case PNG_CRC_DEFAULT:
{
if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
png_app_error(png_ptr,
- "invalid after png_start_read_image or png_read_update_info");
+ "invalid after png_start_read_image or png_read_update_info");
else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
png_app_error(png_ptr, "invalid before the PNG header has been read");
png_set_background_fixed(png_ptr, background_color, background_gamma_code,
need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
}
-# endif /* FLOATING_POINT */
+# endif /* FLOATING_POINT */
#endif /* READ_BACKGROUND */
/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the
#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
static png_fixed_point
translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
- int is_screen)
+ int is_screen)
{
/* Check for flag values. The main reason for having the old Mac value as a
* flag is that it is pretty near impossible to work out what the correct
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
void PNGFAPI
png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
- png_fixed_point output_gamma)
+ png_fixed_point output_gamma)
{
int compose = 0;
png_fixed_point file_gamma;
* is expected to be 1 or greater, but this range test allows for some
* viewing correction values. The intent is to weed out users of this API
* who use the inverse of the gamma value accidentally! Since some of these
- * values are reasonable this may have to be changed.
+ * values are reasonable this may have to be changed:
+ *
+ * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit
+ * gamma of 36, and its reciprocal.)
*/
- if (output_gamma < 70000 || output_gamma > 300000)
+ if (output_gamma < 1000 || output_gamma > 10000000)
png_error(png_ptr, "output gamma out of expected range");
/* The default file gamma is the inverse of the output gamma; the output
if ((png_ptr->transformations & PNG_COMPOSE) != 0)
png_error(png_ptr,
- "conflicting calls to set alpha mode and background");
+ "conflicting calls to set alpha mode and background");
png_ptr->transformations |= PNG_COMPOSE;
}
png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
{
png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
- output_gamma));
+ output_gamma));
}
# endif
#endif
#ifdef PNG_READ_GAMMA_SUPPORTED
void PNGFAPI
png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
- png_fixed_point file_gamma)
+ png_fixed_point file_gamma)
{
png_debug(1, "in png_set_gamma_fixed");
png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
{
png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
- convert_gamma_value(png_ptr, file_gamma));
+ convert_gamma_value(png_ptr, file_gamma));
}
# endif /* FLOATING_POINT */
#endif /* READ_GAMMA */
* that it just worked and get a memory overwrite.
*/
png_error(png_ptr,
- "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
+ "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
/* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
}
{
if (red >= 0 && green >= 0)
png_app_warning(png_ptr,
- "ignoring out of range rgb_to_gray coefficients");
+ "ignoring out of range rgb_to_gray coefficients");
/* Use the defaults, from the cHRM chunk if set, else the historical
* values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
* something has already provided a default.
*/
if (png_ptr->rgb_to_gray_red_coeff == 0 &&
- png_ptr->rgb_to_gray_green_coeff == 0)
+ png_ptr->rgb_to_gray_green_coeff == 0)
{
png_ptr->rgb_to_gray_red_coeff = 6968;
png_ptr->rgb_to_gray_green_coeff = 23434;
void PNGAPI
png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
- double green)
+ double green)
{
png_set_rgb_to_gray_fixed(png_ptr, error_action,
- png_fixed(png_ptr, red, "rgb to gray red coefficient"),
+ png_fixed(png_ptr, red, "rgb to gray red coefficient"),
png_fixed(png_ptr, green, "rgb to gray green coefficient"));
}
#endif /* FLOATING POINT */
{
if (png_ptr->screen_gamma != 0) /* screen set too */
gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
- png_ptr->screen_gamma);
+ png_ptr->screen_gamma);
else
/* Assume the output matches the input; a long time default behavior
*/
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
png_warning(png_ptr,
- "libpng does not support gamma+background+rgb_to_gray");
+ "libpng does not support gamma+background+rgb_to_gray");
if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
{
case PNG_BACKGROUND_GAMMA_FILE:
g = png_reciprocal(png_ptr->colorspace.gamma);
gs = png_reciprocal2(png_ptr->colorspace.gamma,
- png_ptr->screen_gamma);
+ png_ptr->screen_gamma);
break;
case PNG_BACKGROUND_GAMMA_UNIQUE:
g = png_reciprocal(png_ptr->background_gamma);
gs = png_reciprocal2(png_ptr->background_gamma,
- png_ptr->screen_gamma);
+ png_ptr->screen_gamma);
break;
default:
g = PNG_FP_1; /* back_1 */
if (png_gamma_significant(g) != 0)
{
back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
- g);
+ g);
back_1.green = png_gamma_8bit_correct(
- png_ptr->background.green, g);
+ png_ptr->background.green, g);
back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
- g);
+ g);
}
else
case PNG_BACKGROUND_GAMMA_FILE:
g = png_reciprocal(png_ptr->colorspace.gamma);
gs = png_reciprocal2(png_ptr->colorspace.gamma,
- png_ptr->screen_gamma);
+ png_ptr->screen_gamma);
break;
case PNG_BACKGROUND_GAMMA_UNIQUE:
png_ptr->palette[i].blue = (png_byte)component;
}
}
-#endif /* READ_SHIFT */
+#endif /* READ_SHIFT */
}
/* Modify the info structure to reflect the transformations. The
*/
static void
png_do_expand_palette(png_row_infop row_info, png_bytep row,
- png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
+ png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
{
int shift, value;
png_bytep sp, dp;
row_info->channels = 2;
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_width);
+ row_width);
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
- 0 /* at_start == false, because SWAP_ALPHA happens later */);
+ 0 /* at_start == false, because SWAP_ALPHA happens later */);
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
/* pngrutil.c - utilities to read a PNG file
*
- * Last changed in libpng 1.6.20 [December 3, 2014]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */
if ((uval & 0x80000000) == 0) /* no overflow */
- return -(png_int_32)uval;
+ return -(png_int_32)uval;
/* The following has to be safe; this function only gets called on PNG data
* and if we get here that data is invalid. 0 is the most safe value and
* if not then an attacker would surely just generate a PNG with 0 instead.
}
}
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED)
/*
* Decompress trailing data in a chunk. The assumption is that read_buffer
* points at an allocated area holding the contents of a chunk with a
*/
static int
png_decompress_chunk(png_structrp png_ptr,
- png_uint_32 chunklength, png_uint_32 prefix_size,
- png_alloc_size_t *newlength /* must be initialized to the maximum! */,
- int terminate /*add a '\0' to the end of the uncompressed data*/)
+ png_uint_32 chunklength, png_uint_32 prefix_size,
+ png_alloc_size_t *newlength /* must be initialized to the maximum! */,
+ int terminate /*add a '\0' to the end of the uncompressed data*/)
{
/* TODO: implement different limits for different types of chunk.
*
png_uint_32 lzsize = chunklength - prefix_size;
ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
- /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
- /* output: */ NULL, newlength);
+ /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
+ /* output: */ NULL, newlength);
if (ret == Z_STREAM_END)
{
*/
png_alloc_size_t new_size = *newlength;
png_alloc_size_t buffer_size = prefix_size + new_size +
- (terminate != 0);
+ (terminate != 0);
png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
- buffer_size));
+ buffer_size));
if (text != NULL)
{
ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
- png_ptr->read_buffer + prefix_size, &lzsize,
- text + prefix_size, newlength);
+ png_ptr->read_buffer + prefix_size, &lzsize,
+ text + prefix_size, newlength);
if (ret == Z_STREAM_END)
{
return Z_MEM_ERROR;
}
}
+#endif /* READ_zTXt || READ_iTXt */
#endif /* READ_COMPRESSED_TEXT */
#ifdef PNG_READ_iCCP_SUPPORTED
*/
static int
png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
- png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
- int finish)
+ png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
+ int finish)
{
if (png_ptr->zowner == png_ptr->chunk_name)
{
* the available output is produced; this allows reading of truncated
* streams.
*/
- ret = PNG_INFLATE(png_ptr,
- *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
+ ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ?
+ Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
}
while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
(void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
- 1/*prefer cHRM values*/);
+ 1/*prefer cHRM values*/);
png_colorspace_sync(png_ptr, info_ptr);
}
#endif
png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
png_ptr->zstream.avail_in = read_length;
(void)png_inflate_read(png_ptr, local_buffer,
- (sizeof local_buffer), &length, profile_header, &size,
- 0/*finish: don't, because the output is too small*/);
+ (sizeof local_buffer), &length, profile_header, &size,
+ 0/*finish: don't, because the output is too small*/);
if (size == 0)
{
png_get_uint_32(profile_header);
if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
- keyword, profile_length) != 0)
+ keyword, profile_length) != 0)
{
/* The length is apparently ok, so we can check the 132
* byte header.
*/
if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
- keyword, profile_length, profile_header,
- png_ptr->color_type) != 0)
+ keyword, profile_length, profile_header,
+ png_ptr->color_type) != 0)
{
/* Now read the tag table; a variable size buffer is
* needed at this point, allocate one for the whole
* that none of these stuff will overflow.
*/
const png_uint_32 tag_count = png_get_uint_32(
- profile_header+128);
+ profile_header+128);
png_bytep profile = png_read_buffer(png_ptr,
- profile_length, 2/*silent*/);
+ profile_length, 2/*silent*/);
if (profile != NULL)
{
memcpy(profile, profile_header,
- (sizeof profile_header));
+ (sizeof profile_header));
size = 12 * tag_count;
(void)png_inflate_read(png_ptr, local_buffer,
- (sizeof local_buffer), &length,
- profile + (sizeof profile_header), &size, 0);
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header), &size, 0);
/* Still expect a buffer error because we expect
* there to be some tag data!
if (size == 0)
{
if (png_icc_check_tag_table(png_ptr,
- &png_ptr->colorspace, keyword, profile_length,
- profile) != 0)
+ &png_ptr->colorspace, keyword, profile_length,
+ profile) != 0)
{
/* The profile has been validated for basic
* security issues, so read the whole thing in.
*/
size = profile_length - (sizeof profile_header)
- - 12 * tag_count;
+ - 12 * tag_count;
(void)png_inflate_read(png_ptr, local_buffer,
- (sizeof local_buffer), &length,
- profile + (sizeof profile_header) +
- 12 * tag_count, &size, 1/*finish*/);
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header) +
+ 12 * tag_count, &size, 1/*finish*/);
if (length > 0 && !(png_ptr->flags &
- PNG_FLAG_BENIGN_ERRORS_WARN))
+ PNG_FLAG_BENIGN_ERRORS_WARN))
errmsg = "extra compressed data";
/* But otherwise allow extra data: */
* keep going.
*/
png_chunk_warning(png_ptr,
- "extra compressed data");
+ "extra compressed data");
}
png_crc_finish(png_ptr, length);
finished = 1;
-# ifdef PNG_sRGB_SUPPORTED
+# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
/* Check for a match against sRGB */
png_icc_set_sRGB(png_ptr,
- &png_ptr->colorspace, profile,
- png_ptr->zstream.adler);
-# endif
+ &png_ptr->colorspace, profile,
+ png_ptr->zstream.adler);
+# endif
/* Steal the profile for info_ptr. */
if (info_ptr != NULL)
{
png_free_data(png_ptr, info_ptr,
- PNG_FREE_ICCP, 0);
+ PNG_FREE_ICCP, 0);
info_ptr->iccp_name = png_voidcast(char*,
- png_malloc_base(png_ptr,
- keyword_length+1));
+ png_malloc_base(png_ptr,
+ keyword_length+1));
if (info_ptr->iccp_name != NULL)
{
memcpy(info_ptr->iccp_name, keyword,
- keyword_length+1);
+ keyword_length+1);
info_ptr->iccp_proflen =
- profile_length;
+ profile_length;
info_ptr->iccp_profile = profile;
png_ptr->read_buffer = NULL; /*steal*/
info_ptr->free_me |= PNG_FREE_ICCP;
}
png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
- (png_charp)units, params);
+ (png_charp)units, params);
png_free(png_ptr, params);
}
}
png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
- length + 1);
+ length + 1);
buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
else
/* This is the (only) success case. */
png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
- (png_charp)buffer+1, (png_charp)buffer+heighti);
+ (png_charp)buffer+1, (png_charp)buffer+heighti);
}
}
#endif
if (buffer == NULL)
{
- png_chunk_benign_error(png_ptr, "out of memory");
- return;
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
}
png_crc_read(png_ptr, buffer, length);
* and text chunks.
*/
if (png_decompress_chunk(png_ptr, length, keyword_length+2,
- &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
{
png_text text;
* iCCP and text chunks.
*/
if (png_decompress_chunk(png_ptr, length, prefix_length,
- &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
buffer = png_ptr->read_buffer;
else
{
/* Do a 'warn' here - it is handled below. */
png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
- png_malloc_warn(png_ptr, length));
+ png_malloc_warn(png_ptr, length));
}
}
/* Handle an unknown, or known but disabled, chunk */
void /* PRIVATE */
png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
- png_uint_32 length, int keep)
+ png_uint_32 length, int keep)
{
int handled = 0; /* the chunk was handled */
{
/* Callback to user unknown chunk handler */
int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
- &png_ptr->unknown_chunk);
+ &png_ptr->unknown_chunk);
/* ret is:
* negative: An error occurred; png_chunk_error will be called.
{
png_chunk_warning(png_ptr, "Saving unknown chunk:");
png_app_warning(png_ptr,
- "forcing save of an unhandled chunk;"
- " please call png_set_keep_unknown_chunks");
- /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+ "forcing save of an unhandled chunk;"
+ " please call png_set_keep_unknown_chunks");
+ /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
}
# endif
keep = PNG_HANDLE_CHUNK_IF_SAFE;
* out; store the chunk.
*/
png_set_unknown_chunks(png_ptr, info_ptr,
- &png_ptr->unknown_chunk, 1);
+ &png_ptr->unknown_chunk, 1);
handled = 1;
# ifdef PNG_USER_LIMITS_SUPPORTED
break;
/* Everything is aligned for png_uint_16 copies, but try for
* png_uint_32 first.
*/
- if (png_isaligned(dp, png_uint_32) != 0 &&
- png_isaligned(sp, png_uint_32) != 0 &&
+ if (png_isaligned(dp, png_uint_32) &&
+ png_isaligned(sp, png_uint_32) &&
bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
bytes_to_jump % (sizeof (png_uint_32)) == 0)
{
#ifdef PNG_READ_INTERLACING_SUPPORTED
void /* PRIVATE */
png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
- png_uint_32 transformations /* Because these may affect the byte layout */)
+ png_uint_32 transformations /* Because these may affect the byte layout */)
{
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Offset to next interlace block */
static void
png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
png_size_t i;
png_size_t istop = row_info->rowbytes;
static void
png_read_filter_row_up(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
png_size_t i;
png_size_t istop = row_info->rowbytes;
static void
png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
png_size_t i;
png_bytep rp = row;
static void
png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
png_bytep rp_end = row + row_info->rowbytes;
int a, c;
static void
png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
int bpp = (row_info->pixel_depth + 7) >> 3;
png_bytep rp_end = row + bpp;
void /* PRIVATE */
png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row, int filter)
+ png_const_bytep prev_row, int filter)
{
/* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
* PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
void /* PRIVATE */
png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
- png_alloc_size_t avail_out)
+ png_alloc_size_t avail_out)
{
/* Loop reading IDATs and decompressing the result into output[avail_out] */
png_ptr->zstream.next_out = output;
if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
{
- png_free(png_ptr, png_ptr->big_row_buf);
- png_free(png_ptr, png_ptr->big_prev_row);
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->big_prev_row);
- if (png_ptr->interlaced != 0)
- png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
- row_bytes + 48);
+ if (png_ptr->interlaced != 0)
+ png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+ row_bytes + 48);
- else
- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+ else
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
- png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+ png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, 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; treat prev_row similarly.
- * NOTE: the alignment is to the start of the pixels, one beyond the start
- * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this
- * was incorrect; the filter byte was aligned, which had the exact
- * opposite effect of that intended.
- */
- {
- png_bytep temp = png_ptr->big_row_buf + 32;
- int extra = (int)((temp - (png_bytep)0) & 0x0f);
- png_ptr->row_buf = temp - extra - 1/*filter byte*/;
-
- temp = png_ptr->big_prev_row + 32;
- extra = (int)((temp - (png_bytep)0) & 0x0f);
- png_ptr->prev_row = temp - extra - 1/*filter byte*/;
- }
+ /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+ * of padding before and after row_buf; treat prev_row similarly.
+ * NOTE: the alignment is to the start of the pixels, one beyond the start
+ * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this
+ * was incorrect; the filter byte was aligned, which had the exact
+ * opposite effect of that intended.
+ */
+ {
+ png_bytep temp = png_ptr->big_row_buf + 32;
+ int extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+
+ temp = png_ptr->big_prev_row + 32;
+ extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->prev_row = temp - extra - 1/*filter byte*/;
+ }
#else
- /* Use 31 bytes of padding before and 17 bytes after row_buf. */
- png_ptr->row_buf = png_ptr->big_row_buf + 31;
- png_ptr->prev_row = png_ptr->big_prev_row + 31;
+ /* Use 31 bytes of padding before and 17 bytes after row_buf. */
+ png_ptr->row_buf = png_ptr->big_row_buf + 31;
+ png_ptr->prev_row = png_ptr->big_prev_row + 31;
#endif
- png_ptr->old_big_row_buf_size = row_bytes + 48;
+ png_ptr->old_big_row_buf_size = row_bytes + 48;
}
#ifdef PNG_MAX_MALLOC_64K
/* pngset.c - storage of image information into info struct
*
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2016 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.)
*
double green_x, double green_y, double blue_x, double blue_y)
{
png_set_cHRM_fixed(png_ptr, info_ptr,
- png_fixed(png_ptr, white_x, "cHRM White X"),
- png_fixed(png_ptr, white_y, "cHRM White Y"),
- png_fixed(png_ptr, red_x, "cHRM Red X"),
- png_fixed(png_ptr, red_y, "cHRM Red Y"),
- png_fixed(png_ptr, green_x, "cHRM Green X"),
- png_fixed(png_ptr, green_y, "cHRM Green Y"),
- png_fixed(png_ptr, blue_x, "cHRM Blue X"),
- png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
+ png_fixed(png_ptr, white_x, "cHRM White X"),
+ png_fixed(png_ptr, white_y, "cHRM White Y"),
+ png_fixed(png_ptr, red_x, "cHRM Red X"),
+ png_fixed(png_ptr, red_y, "cHRM Red Y"),
+ png_fixed(png_ptr, green_x, "cHRM Green X"),
+ png_fixed(png_ptr, green_y, "cHRM Green Y"),
+ png_fixed(png_ptr, blue_x, "cHRM Blue X"),
+ png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
}
void PNGAPI
double blue_X, double blue_Y, double blue_Z)
{
png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
- png_fixed(png_ptr, red_X, "cHRM Red X"),
- png_fixed(png_ptr, red_Y, "cHRM Red Y"),
- png_fixed(png_ptr, red_Z, "cHRM Red Z"),
- png_fixed(png_ptr, green_X, "cHRM Green X"),
- png_fixed(png_ptr, green_Y, "cHRM Green Y"),
- png_fixed(png_ptr, green_Z, "cHRM Green Z"),
- png_fixed(png_ptr, blue_X, "cHRM Blue X"),
- png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
- png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
+ png_fixed(png_ptr, red_X, "cHRM Red X"),
+ png_fixed(png_ptr, red_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, red_Z, "cHRM Red Z"),
+ png_fixed(png_ptr, green_X, "cHRM Green X"),
+ png_fixed(png_ptr, green_Y, "cHRM Green Y"),
+ png_fixed(png_ptr, green_Z, "cHRM Green Z"),
+ png_fixed(png_ptr, blue_X, "cHRM Blue X"),
+ png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
+ png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
}
# endif /* FLOATING_POINT */
length = strlen(units) + 1;
png_debug1(3, "allocating units for info (%lu bytes)",
- (unsigned long)length);
+ (unsigned long)length);
info_ptr->pcal_units = png_voidcast(png_charp,
- png_malloc_warn(png_ptr, length));
+ png_malloc_warn(png_ptr, length));
if (info_ptr->pcal_units == NULL)
{
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
info_ptr->scal_s_width = png_voidcast(png_charp,
- png_malloc_warn(png_ptr, lengthw));
+ png_malloc_warn(png_ptr, lengthw));
if (info_ptr->scal_s_width == NULL)
{
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
info_ptr->scal_s_height = png_voidcast(png_charp,
- png_malloc_warn(png_ptr, lengthh));
+ png_malloc_warn(png_ptr, lengthh));
if (info_ptr->scal_s_height == NULL)
{
char sheight[PNG_sCAL_MAX_DIGITS+1];
png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
- PNG_sCAL_PRECISION);
+ PNG_sCAL_PRECISION);
png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
- PNG_sCAL_PRECISION);
+ PNG_sCAL_PRECISION);
png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
}
*/
{
int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
- proflen, profile, info_ptr->color_type);
+ proflen, profile, info_ptr->color_type);
png_colorspace_sync_info(png_ptr, info_ptr);
memcpy(new_iccp_name, name, length);
new_iccp_profile = png_voidcast(png_bytep,
- png_malloc_warn(png_ptr, proflen));
+ png_malloc_warn(png_ptr, proflen));
if (new_iccp_profile == NULL)
{
* the overflow checks.
*/
new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
- info_ptr->text, old_num_text, max_text-old_num_text,
- sizeof *new_text));
+ info_ptr->text, old_num_text, max_text-old_num_text,
+ sizeof *new_text));
}
if (new_text == NULL)
{
png_chunk_report(png_ptr, "too many text chunks",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
return 1;
}
text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
{
png_chunk_report(png_ptr, "text compression mode is out of range",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
continue;
}
# else /* iTXt */
{
png_chunk_report(png_ptr, "iTXt chunk not supported",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
continue;
}
# endif
if (textp->key == NULL)
{
png_chunk_report(png_ptr, "text chunk: out of memory",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
return 1;
}
png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
- /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
- png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
- png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
-
if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+ {
+ /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+ info_ptr->trans_alpha = png_voidcast(png_bytep,
+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
+ }
+ png_ptr->trans_alpha = info_ptr->trans_alpha;
}
if (trans_color != NULL)
trans_color->green > sample_max ||
trans_color->blue > sample_max)))
png_warning(png_ptr,
- "tRNS chunk has out-of-range samples for bit_depth");
+ "tRNS chunk has out-of-range samples for bit_depth");
}
#endif
* overflows. Notice that the parameters are (int) and (size_t)
*/
np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
- info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
- sizeof *np));
+ info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
+ sizeof *np));
if (np == NULL)
{
* checked it when doing the allocation.
*/
memcpy(np->entries, entries->entries,
- entries->nentries * sizeof (png_sPLT_entry));
+ entries->nentries * sizeof (png_sPLT_entry));
/* Note that 'continue' skips the advance of the out pointer and out
* count, so an invalid entry is not added.
{
/* Write struct, so unknown chunks come from the app */
png_app_warning(png_ptr,
- "png_set_unknown_chunks now expects a valid location");
+ "png_set_unknown_chunks now expects a valid location");
/* Use the old behavior */
location = (png_byte)(png_ptr->mode &
- (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
+ (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
}
/* This need not be an internal error - if the app calls
void PNGAPI
png_set_unknown_chunks(png_const_structrp png_ptr,
- png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
{
png_unknown_chunkp np;
* appropriate to read or write.
*/
np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
- info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
- sizeof *np));
+ info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
+ sizeof *np));
if (np == NULL)
{
png_chunk_report(png_ptr, "too many unknown chunks",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
return;
}
else
{
np->data = png_voidcast(png_bytep,
- png_malloc_base(png_ptr, unknowns->size));
+ png_malloc_base(png_ptr, unknowns->size));
if (np->data == NULL)
{
png_chunk_report(png_ptr, "unknown chunk: out of memory",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
/* But just skip storing the unknown chunk */
continue;
}
for (i=0; i<num_chunks; ++i)
{
old_num_chunks = add_one_chunk(new_list, old_num_chunks,
- chunk_list+5*i, keep);
+ chunk_list+5*i, keep);
}
/* Now remove any spurious 'default' entries. */
void PNGAPI
png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
{
- if (png_ptr == NULL)
- return;
+ if (png_ptr == NULL)
+ return;
- if (size == 0 || size > PNG_UINT_31_MAX)
- png_error(png_ptr, "invalid compression buffer size");
+ if (size == 0 || size > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid compression buffer size");
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
- {
- png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
- return;
- }
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ {
+ png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
+ return;
+ }
# endif
# ifdef PNG_WRITE_SUPPORTED
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ {
+ if (png_ptr->zowner != 0)
{
- if (png_ptr->zowner != 0)
- {
- png_warning(png_ptr,
- "Compression buffer size cannot be changed because it is in use");
+ png_warning(png_ptr,
+ "Compression buffer size cannot be changed because it is in use");
- return;
- }
+ return;
+ }
#ifndef __COVERITY__
- /* Some compilers complain that this is always false. However, it
- * can be true when integer overflow happens.
- */
- if (size > ZLIB_IO_MAX)
- {
- png_warning(png_ptr,
- "Compression buffer size limited to system maximum");
- size = ZLIB_IO_MAX; /* must fit */
- }
+ /* Some compilers complain that this is always false. However, it
+ * can be true when integer overflow happens.
+ */
+ if (size > ZLIB_IO_MAX)
+ {
+ png_warning(png_ptr,
+ "Compression buffer size limited to system maximum");
+ size = ZLIB_IO_MAX; /* must fit */
+ }
#endif
- if (size < 6)
- {
- /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
- * if this is permitted.
- */
- png_warning(png_ptr,
- "Compression buffer size cannot be reduced below 6");
+ if (size < 6)
+ {
+ /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
+ * if this is permitted.
+ */
+ png_warning(png_ptr,
+ "Compression buffer size cannot be reduced below 6");
- return;
- }
+ return;
+ }
- if (png_ptr->zbuffer_size != size)
- {
- png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
- png_ptr->zbuffer_size = (uInt)size;
- }
+ if (png_ptr->zbuffer_size != size)
+ {
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+ png_ptr->zbuffer_size = (uInt)size;
}
+ }
# endif
}
png_uint_32 /* PRIVATE */
png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
{
+#ifdef PNG_WARNINGS_SUPPORTED
png_const_charp orig_key = key;
+#endif
png_uint_32 key_len = 0;
int bad_character = 0;
int space = 1;
png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
}
-#endif /* WARNINGS */
+#else /* !WARNINGS */
+ PNG_UNUSED(png_ptr)
+#endif /* !WARNINGS */
return key_len;
}
/* pngstruct.h - header file for PNG reference library
*
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
png_byte pass; /* current interlace pass (0 - 6) */
- png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
+ png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */
png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row: write only */
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
* size!
*/
png_app_error(png_ptr,
- "png_set_filler is invalid for low bit depth gray output");
+ "png_set_filler is invalid for"
+ " low bit depth gray output");
return;
}
default:
png_app_error(png_ptr,
- "png_set_filler: inappropriate color type");
+ "png_set_filler: inappropriate color type");
return;
}
# else
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
{
png_app_error(png_ptr,
- "info change after png_start_read_image or png_read_update_info");
+ "info change after png_start_read_image or png_read_update_info");
return;
}
#endif
/* pngwio.c - functions for data output
*
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 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.)
*
/* NOTE: write_data_fn must not change the buffer! */
if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
- length);
+ length);
else
png_error(png_ptr, "Call to NULL write function");
/* pngwrite.c - general routines to write a PNG file
*
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
*/
#include "pngpriv.h"
-#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
# include <errno.h>
-#endif
+#endif /* SIMPLIFIED_WRITE_STDIO */
#ifdef PNG_WRITE_SUPPORTED
/* Write out all the unknown chunks for the current given location */
static void
write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
- unsigned int where)
+ unsigned int where)
{
if (info_ptr->unknown_chunks_num != 0)
{
# ifdef PNG_WRITE_sRGB_SUPPORTED
if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
png_app_warning(png_ptr,
- "profile matches sRGB but writing iCCP instead");
+ "profile matches sRGB but writing iCCP instead");
# endif
png_write_iCCP(png_ptr, info_ptr->iccp_name,
- info_ptr->iccp_profile);
+ info_ptr->iccp_profile);
}
# ifdef PNG_WRITE_sRGB_SUPPORTED
else
for (i = 0; i < info_ptr->num_text; i++)
{
png_debug2(2, "Writing trailer text chunk %d, type %d", i,
- info_ptr->text[i].compression);
+ info_ptr->text[i].compression);
/* An internationalized chunk? */
if (info_ptr->text[i].compression > 0)
{
return;
png_debug2(1, "in png_write_row (row %u, pass %d)",
- png_ptr->row_number, png_ptr->pass);
+ png_ptr->row_number, png_ptr->pass);
/* Initialize transformations and other stuff if first time */
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
* is not available so the filter can't be used. Just warn here.
*/
png_app_warning(png_ptr,
- "png_set_filter: UP/AVG/PAETH cannot be added after start");
+ "png_set_filter: UP/AVG/PAETH cannot be added after start");
filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
}
if (png_ptr->try_row == NULL)
png_ptr->try_row = png_voidcast(png_bytep,
- png_malloc(png_ptr, buf_size));
+ png_malloc(png_ptr, buf_size));
if (num_filters > 1)
{
if (png_ptr->tst_row == NULL)
png_ptr->tst_row = png_voidcast(png_bytep,
- png_malloc(png_ptr, buf_size));
+ png_malloc(png_ptr, buf_size));
}
}
png_ptr->do_filter = (png_byte)filters;
#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
-# ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
/* Initialize the write structure - general purpose utility. */
static int
png_image_write_init(png_imagep image)
png_const_voidp first_row;
ptrdiff_t row_bytes;
png_voidp local_row;
+ /* Byte count for memory writing */
+ png_bytep memory;
+ png_alloc_size_t memory_bytes; /* not used for STDIO */
+ png_alloc_size_t output_bytes; /* running total */
} png_image_write_control;
/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
static png_byte
png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
- png_uint_32 reciprocal/*from the above macro*/)
+ png_uint_32 reciprocal/*from the above macro*/)
{
/* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
* is represented as some other value there is more likely to be a
if (channels >= 3) /* RGB */
{
palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
- alpha, reciprocal);
+ alpha, reciprocal);
palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
- reciprocal);
+ reciprocal);
palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
- reciprocal);
+ reciprocal);
}
else /* gray */
palette[i].blue = palette[i].red = palette[i].green =
- png_unpremultiply(entry[afirst], alpha, reciprocal);
+ png_unpremultiply(entry[afirst], alpha, reciprocal);
}
}
# endif
png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
- entries);
+ entries);
if (num_trans > 0)
png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
- num_trans, NULL);
+ num_trans, NULL);
image->colormap_entries = entries;
}
png_image_write_main(png_voidp argument)
{
png_image_write_control *display = png_voidcast(png_image_write_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
png_set_benign_errors(png_ptr, 0/*error*/);
# endif
- /* Default the 'row_stride' parameter if required. */
- if (display->row_stride == 0)
- display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+ /* Default the 'row_stride' parameter if required, also check the row stride
+ * and total image size to ensure that they are within the system limits.
+ */
+ {
+ const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
+
+ if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */
+ {
+ png_uint_32 check;
+ const png_uint_32 png_row_stride = image->width * channels;
+
+ if (display->row_stride == 0)
+ display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
+
+ if (display->row_stride < 0)
+ check = -display->row_stride;
+
+ else
+ check = display->row_stride;
+
+ if (check >= png_row_stride)
+ {
+ /* Now check for overflow of the image buffer calculation; this
+ * limits the whole image size to 32 bits for API compatibility with
+ * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+ */
+ if (image->height > 0xFFFFFFFF/png_row_stride)
+ png_error(image->opaque->png_ptr, "memory image too large");
+ }
+
+ else
+ png_error(image->opaque->png_ptr, "supplied row stride too small");
+ }
+
+ else
+ png_error(image->opaque->png_ptr, "image row stride too large");
+ }
/* Set the required transforms then write the rows in the correct order. */
if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
png_uint_32 entries = image->colormap_entries;
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
- entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
- PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
+ PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_image_set_PLTE(display);
}
else
png_error(image->opaque->png_ptr,
- "no color-map for color-mapped image");
+ "no color-map for color-mapped image");
}
else
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
- write_16bit ? 16 : 8,
- ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
- ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ write_16bit ? 16 : 8,
+ ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
+ ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
/* Counter-intuitively the data transformations must be called *after*
* png_write_info, not before as in the read code, but the 'set' functions
if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
png_set_cHRM_fixed(png_ptr, info_ptr,
- /* color x y */
- /* white */ 31270, 32900,
- /* red */ 64000, 33000,
- /* green */ 30000, 60000,
- /* blue */ 15000, 6000
+ /* color x y */
+ /* white */ 31270, 32900,
+ /* red */ 64000, 33000,
+ /* green */ 30000, 60000,
+ /* blue */ 15000, 6000
);
}
(colormap == 0 && display->convert_to_8bit != 0))
{
png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
- png_get_rowbytes(png_ptr, info_ptr)));
+ png_get_rowbytes(png_ptr, info_ptr)));
int result;
display->local_row = row;
return 1;
}
+
+static void (PNGCBAPI
+image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data,
+ png_size_t size)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
+ const png_alloc_size_t ob = display->output_bytes;
+
+ /* Check for overflow; this should never happen: */
+ if (size <= ((png_alloc_size_t)-1) - ob)
+ {
+ /* I don't think libpng ever does this, but just in case: */
+ if (size > 0)
+ {
+ if (display->memory_bytes >= ob+size) /* writing */
+ memcpy(display->memory+ob, data, size);
+
+ /* Always update the size: */
+ display->output_bytes = ob+size;
+ }
+ }
+
+ else
+ png_error(png_ptr, "png_image_write_to_memory: PNG too big");
+}
+
+static void (PNGCBAPI
+image_memory_flush)(png_structp png_ptr)
+{
+ PNG_UNUSED(png_ptr)
+}
+
+static int
+png_image_write_memory(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+
+ /* The rest of the memory-specific init and write_main in an error protected
+ * environment. This case needs to use callbacks for the write operations
+ * since libpng has no built in support for writing to memory.
+ */
+ png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
+ image_memory_write, image_memory_flush);
+
+ return png_image_write_main(display);
+}
+
+int PNGAPI
+png_image_write_to_memory(png_imagep image, void *memory,
+ png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
+ const void *buffer, png_int_32 row_stride, const void *colormap)
+{
+ /* Write the image to the given buffer, or count the bytes if it is NULL */
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (memory_bytes != NULL && buffer != NULL)
+ {
+ /* This is to give the caller an easier error detection in the NULL
+ * case and guard against uninitialized variable problems:
+ */
+ if (memory == NULL)
+ *memory_bytes = 0;
+
+ if (png_image_write_init(image) != 0)
+ {
+ png_image_write_control display;
+ int result;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.convert_to_8bit = convert_to_8bit;
+ display.memory = png_voidcast(png_bytep, memory);
+ display.memory_bytes = *memory_bytes;
+ display.output_bytes = 0;
+
+ result = png_safe_execute(image, png_image_write_memory, &display);
+ png_image_free(image);
+
+ /* write_memory returns true even if we ran out of buffer. */
+ if (result)
+ {
+ /* On out-of-buffer this function returns '0' but still updates
+ * memory_bytes:
+ */
+ if (memory != NULL && display.output_bytes > *memory_bytes)
+ result = 0;
+
+ *memory_bytes = display.output_bytes;
+ }
+
+ return result;
+ }
+
+ else
+ return 0;
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_write_to_memory: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
+
+ else
+ return 0;
+}
+
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
int PNGAPI
png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
- const void *buffer, png_int_32 row_stride, const void *colormap)
+ const void *buffer, png_int_32 row_stride, const void *colormap)
{
/* Write the image to the given (FILE*). */
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
- if (file != NULL)
+ if (file != NULL && buffer != NULL)
{
if (png_image_write_init(image) != 0)
{
else
return png_image_error(image,
- "png_image_write_to_stdio: invalid argument");
+ "png_image_write_to_stdio: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
+ "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
else
return 0;
int PNGAPI
png_image_write_to_file(png_imagep image, const char *file_name,
- int convert_to_8bit, const void *buffer, png_int_32 row_stride,
- const void *colormap)
+ int convert_to_8bit, const void *buffer, png_int_32 row_stride,
+ const void *colormap)
{
/* Write the image to the named file. */
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
- if (file_name != NULL)
+ if (file_name != NULL && buffer != NULL)
{
FILE *fp = fopen(file_name, "wb");
if (fp != NULL)
{
if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
- row_stride, colormap) != 0)
+ row_stride, colormap) != 0)
{
int error; /* from fflush/fclose */
else
return png_image_error(image,
- "png_image_write_to_file: invalid argument");
+ "png_image_write_to_file: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
+ "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
else
return 0;
}
-# endif /* STDIO */
+#endif /* SIMPLIFIED_WRITE_STDIO */
#endif /* SIMPLIFIED_WRITE */
#endif /* WRITE */
/* pngwtran.c - transforms the data in a row for PNG writers
*
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
#ifdef PNG_WRITE_FILLER_SUPPORTED
if ((png_ptr->transformations & PNG_FILLER) != 0)
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
- !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+ !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
#endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
#ifdef PNG_WRITE_SHIFT_SUPPORTED
if ((png_ptr->transformations & PNG_SHIFT) != 0)
png_do_shift(row_info, png_ptr->row_buf + 1,
- &(png_ptr->shift));
+ &(png_ptr->shift));
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
/* pngwutil.c - utilities to write a PNG file
*
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
*
void PNGAPI
png_save_uint_32(png_bytep buf, png_uint_32 i)
{
- buf[0] = (png_byte)(i >> 24);
- buf[1] = (png_byte)(i >> 16);
- buf[2] = (png_byte)(i >> 8);
- buf[3] = (png_byte)(i );
+ buf[0] = (png_byte)((i >> 24) & 0xffU);
+ buf[1] = (png_byte)((i >> 16) & 0xffU);
+ buf[2] = (png_byte)((i >> 8) & 0xffU);
+ buf[3] = (png_byte)( i & 0xffU);
}
/* Place a 16-bit number into a buffer in PNG byte order.
void PNGAPI
png_save_uint_16(png_bytep buf, unsigned int i)
{
- buf[0] = (png_byte)(i >> 8);
- buf[1] = (png_byte)(i );
+ buf[0] = (png_byte)((i >> 8) & 0xffU);
+ buf[1] = (png_byte)( i & 0xffU);
}
#endif
/* Write the rest of the 8 byte signature */
png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
- (png_size_t)(8 - png_ptr->sig_bytes));
+ (png_size_t)(8 - png_ptr->sig_bytes));
if (png_ptr->sig_bytes < 3)
png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
*/
static void
png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
- png_const_bytep data, png_size_t length)
+ png_const_bytep data, png_size_t length)
{
if (png_ptr == NULL)
return;
/* This is the API that calls the internal function above. */
void PNGAPI
png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
- png_const_bytep data, png_size_t length)
+ png_const_bytep data, png_size_t length)
{
png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
- length);
+ length);
}
/* This is used below to find the size of an image to pass to png_deflate_claim,
/* Initialize the compressor for the appropriate type of compression. */
static int
png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
- png_alloc_size_t data_size)
+ png_alloc_size_t data_size)
{
if (png_ptr->zowner != 0)
{
else
{
ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
- memLevel, strategy);
+ memLevel, strategy);
if (ret == Z_OK)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
static void
png_text_compress_init(compression_state *comp, png_const_bytep input,
- png_alloc_size_t input_len)
+ png_alloc_size_t input_len)
{
comp->input = input;
comp->input_len = input_len;
/* Compress the data in the compression state input */
static int
png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
- compression_state *comp, png_uint_32 prefix_len)
+ compression_state *comp, png_uint_32 prefix_len)
{
int ret;
/* Compress the data */
ret = deflate(&png_ptr->zstream,
- input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
+ input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
/* Claw back input data that was not consumed (because avail_in is
* reset above every time round the loop).
*/
void /* PRIVATE */
png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
- png_alloc_size_t input_len, int flush)
+ png_alloc_size_t input_len, int flush)
{
if (png_ptr->zowner != png_IDAT)
{
if (png_ptr->zbuffer_list == NULL)
{
png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
- png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+ png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
png_ptr->zbuffer_list->next = NULL;
}
/* Write the chunk out as it is */
png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
- (png_size_t)num_trans);
+ (png_size_t)num_trans);
}
else if (color_type == PNG_COLOR_TYPE_GRAY)
#endif
{
png_app_warning(png_ptr,
- "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
return;
}
#endif
{
png_warning(png_ptr,
- "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+ "Ignoring attempt to write 16-bit bKGD chunk "
+ "when bit_depth is 8");
return;
}
/* Compute the compressed data; do it now for the length */
png_text_compress_init(&comp, (png_const_bytep)text,
- text == NULL ? 0 : strlen(text));
+ text == NULL ? 0 : strlen(text));
if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg);
*/
if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
png_ptr->prev_row = png_voidcast(png_bytep,
- png_calloc(png_ptr, buf_size));
+ png_calloc(png_ptr, buf_size));
#endif /* WRITE_FILTER */
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
*/
static void /* PRIVATE */
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
- png_size_t row_bytes);
+ png_size_t row_bytes);
#ifdef PNG_WRITE_FILTER_SUPPORTED
static png_size_t /* PRIVATE */
i++, rp++, dp++)
{
v = *dp = *rp;
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
}
for (lp = png_ptr->row_buf + 1; i < row_bytes;
i++, rp++, lp++, dp++)
{
v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
return (sum);
}
+static void /* PRIVATE */
+png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes)
+{
+ png_bytep rp, dp, lp;
+ png_size_t i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ *dp = *rp;
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ }
+}
+
static png_size_t /* PRIVATE */
png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
const png_size_t lmins)
i++, rp++, pp++, dp++)
{
v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
return (sum);
}
+static void /* PRIVATE */
+png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes)
+{
+ png_bytep rp, dp, pp;
+ png_size_t i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ }
+}
static png_size_t /* PRIVATE */
png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
- const png_size_t row_bytes, const png_size_t lmins)
+ const png_size_t row_bytes, const png_size_t lmins)
{
png_bytep rp, dp, pp, lp;
png_uint_32 i;
png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
- pp = png_ptr->prev_row + 1; i < bpp; i++)
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
{
v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
}
for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
& 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
return (sum);
}
+static void /* PRIVATE */
+png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes)
+{
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+ }
+}
static png_size_t /* PRIVATE */
png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
{
v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
}
for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
return (sum);
}
+static void /* PRIVATE */
+png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes)
+{
+ png_bytep rp, dp, pp, cp, lp;
+ png_size_t i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+ }
+
+ for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
+ i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+ }
+}
#endif /* WRITE_FILTER */
void /* PRIVATE */
#ifndef PNG_WRITE_FILTER_SUPPORTED
png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
#else
- png_byte filter_to_do = png_ptr->do_filter;
+ unsigned int filter_to_do = png_ptr->do_filter;
png_bytep row_buf;
png_bytep best_row;
png_uint_32 bpp;
*/
best_row = png_ptr->row_buf;
-
- if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE)
+ if (PNG_SIZE_MAX/128 <= row_bytes)
{
+ /* Overflow can occur in the calculation, just select the lowest set
+ * filter.
+ */
+ filter_to_do &= 0U-filter_to_do;
+ }
+ else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
+ filter_to_do != PNG_FILTER_NONE)
+ {
+ /* Overflow not possible and multiple filters in the list, including the
+ * 'none' filter.
+ */
png_bytep rp;
png_size_t sum = 0;
png_size_t i;
int v;
- if (PNG_SIZE_MAX/128 <= row_bytes)
- {
- for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
- {
- /* Check for overflow */
- if (sum > PNG_SIZE_MAX/128 - 256)
- break;
-
- v = *rp;
- sum += (v < 128) ? v : 256 - v;
- }
- }
- else /* Overflow is not possible */
{
for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
{
v = *rp;
+#ifdef PNG_USE_ABS
+ sum += 128 - abs(v - 128);
+#else
sum += (v < 128) ? v : 256 - v;
+#endif
}
}
if (filter_to_do == PNG_FILTER_SUB)
/* It's the only filter so no testing is needed */
{
- (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);
+ png_setup_sub_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row;
}
/* Up filter */
if (filter_to_do == PNG_FILTER_UP)
{
- (void) png_setup_up_row(png_ptr, row_bytes, mins);
+ png_setup_up_row_only(png_ptr, row_bytes);
best_row = png_ptr->try_row;
}
/* Avg filter */
if (filter_to_do == PNG_FILTER_AVG)
{
- (void) png_setup_avg_row(png_ptr, bpp, row_bytes, mins);
+ png_setup_avg_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row;
}
}
/* Paeth filter */
- if ((filter_to_do == PNG_FILTER_PAETH) != 0)
+ if (filter_to_do == PNG_FILTER_PAETH)
{
- (void) png_setup_paeth_row(png_ptr, bpp, row_bytes, mins);
+ png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row;
}
/* Do the actual writing of a previously filtered row. */
static void
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
- png_size_t full_row_length/*includes filter byte*/)
+ png_size_t full_row_length/*includes filter byte*/)
{
png_debug(1, "in png_write_filtered_row");