mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[libpng16] Recognize known sRGB ICC profiles while reading; prefer writing the
iCCP profile over writing the sRGB chunk, controlled by the
PNG_sRGB_PROFILE_CHECKS option.
This commit is contained in:
parent
23a30f8583
commit
921648a997
10
ANNOUNCE
10
ANNOUNCE
@ -1,5 +1,5 @@
|
||||
|
||||
Libpng 1.6.0beta20 - March 28, 2012
|
||||
Libpng 1.6.0beta20 - March 29, 2012
|
||||
|
||||
This is not intended to be a public release. It will be replaced
|
||||
within a few weeks by a public version or by another test version.
|
||||
@ -339,12 +339,14 @@ Version 1.6.0beta19 [March 18,2012]
|
||||
Avoid the double gamma correction warning in the simplified API.
|
||||
This allows the --strict option to pass in the pngstest checks
|
||||
|
||||
Version 1.6.0beta20 [March 28, 2012]
|
||||
Version 1.6.0beta20 [March 29, 2012]
|
||||
Changed chunk handler warnings into benign errors, incrementally load iCCP
|
||||
Recognize known sRGB ICC profiles while reading and issue a warning about
|
||||
it, if PNG_WARN_IF_iCCP_IS_sRGB_SUPPORTED is defined.
|
||||
Added checksum-icc.c to contrib/tools
|
||||
Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice.
|
||||
Recognize known sRGB ICC profiles while reading; prefer writing the
|
||||
iCCP profile over writing the sRGB chunk, controlled by the
|
||||
PNG_sRGB_PROFILE_CHECKS option.
|
||||
Revised png_set_text_2() to avoid potential memory corruption.
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
|
||||
8
CHANGES
8
CHANGES
@ -4090,12 +4090,14 @@ Version 1.6.0beta19 [March 18, 2012]
|
||||
Avoid the double gamma correction warning in the simplified API.
|
||||
This allows the --strict option to pass in the pngstest checks
|
||||
|
||||
Version 1.6.0beta20 [March 28, 2012]
|
||||
Version 1.6.0beta20 [March 29, 2012]
|
||||
Changed chunk handler warnings into benign errors, incrementally load iCCP
|
||||
Recognize known sRGB ICC profiles while reading and issue a warning about
|
||||
it, if PNG_WARN_IF_iCCP_IS_sRGB_SUPPORTED is defined.
|
||||
Added checksum-icc.c to contrib/tools
|
||||
Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice.
|
||||
Recognize known sRGB ICC profiles while reading; prefer writing the
|
||||
iCCP profile over writing the sRGB chunk, controlled by the
|
||||
PNG_sRGB_PROFILE_CHECKS option.
|
||||
Revised png_set_text_2() to avoid potential memory corruption.
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
|
||||
198
png.c
198
png.c
@ -747,13 +747,13 @@ png_get_copyright(png_const_structrp png_ptr)
|
||||
#else
|
||||
# ifdef __STDC__
|
||||
return PNG_STRING_NEWLINE \
|
||||
"libpng version 1.6.0beta20 - March 21, 2012" PNG_STRING_NEWLINE \
|
||||
"libpng version 1.6.0beta20 - March 29, 2012" PNG_STRING_NEWLINE \
|
||||
"Copyright (c) 1998-2012 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.0beta20 - March 21, 2012\
|
||||
return "libpng version 1.6.0beta20 - March 29, 2012\
|
||||
Copyright (c) 1998-2012 Glenn Randers-Pehrson\
|
||||
Copyright (c) 1996-1997 Andreas Dilger\
|
||||
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
|
||||
@ -1974,17 +1974,192 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void /* PRIVATE */
|
||||
#ifdef PNG_sRGB_SUPPORTED
|
||||
/* Information about the known ICC sRGB profiles */
|
||||
static const struct
|
||||
{
|
||||
png_uint_32 adler, crc, length;
|
||||
png_uint_32 md5[4];
|
||||
png_uint_16 have_md5;
|
||||
png_uint_16 intent;
|
||||
|
||||
# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
|
||||
# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, date, length, fname)\
|
||||
{ adler, crc, length, md5, intent },
|
||||
|
||||
} png_sRGB_checks[] =
|
||||
{
|
||||
/* This data comes from contrib/tools/checksum-icc run on downloads of
|
||||
* all four ICC sRGB profiles from www.color.org.
|
||||
*/
|
||||
/* adler32, crc32, MD5[4], intent, date, length, file-name */
|
||||
PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
|
||||
PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 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,
|
||||
"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,
|
||||
"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,
|
||||
"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
|
||||
* a warning is produced. The first two of these profiles have a 'cprt' tag
|
||||
* which suggests that they were also made by Hewlett Packard.
|
||||
*/
|
||||
PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
|
||||
PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1,
|
||||
"2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
|
||||
|
||||
PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
|
||||
PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0,
|
||||
"1998/02/09 06:49:00", 3144, "sRGB Profile.icc")
|
||||
|
||||
PNG_ICC_CHECKSUM(0x0398f3fcUL, 0xf29e526dUL,
|
||||
PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0,
|
||||
"unknown", 3144, "HP-Microsoft sRGB v2 perceptual")
|
||||
};
|
||||
|
||||
static int
|
||||
png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
|
||||
png_const_bytep profile, uLong adler)
|
||||
{
|
||||
/* The quick check is to verify just the MD5 signature and trust to the
|
||||
* rest of the data. Because the profile has already been verified for
|
||||
* correctness this is safe. png_colorspace_set_sRGB will check the 'intent'
|
||||
* field too, so if the profile has been editted with an intent not defined
|
||||
* by sRGB (but maybe defined by a later ICC specification) the read of
|
||||
* the profile will fail at that point.
|
||||
*/
|
||||
png_uint_32 length = 0;
|
||||
png_uint_32 intent = 0x10000; /* invalid */
|
||||
#if PNG_sRGB_PROFILE_CHECKS > 1
|
||||
uLong crc = 0; /* the value for 0 length data */
|
||||
#endif
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
|
||||
{
|
||||
if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
|
||||
png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
|
||||
png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
|
||||
png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
|
||||
{
|
||||
/* This may be one of the old HP profiles without an MD5, in that
|
||||
* case we can only use the length and Adler32 (note that these
|
||||
* are not used by default if there is an MD5!)
|
||||
*/
|
||||
# if PNG_sRGB_PROFILE_CHECKS == 0
|
||||
if (png_sRGB_checks[i].have_md5)
|
||||
return 1;
|
||||
# endif
|
||||
|
||||
/* Profile is unsigned or more checks have been configured in. */
|
||||
if (length == 0)
|
||||
{
|
||||
length = png_get_uint_32(profile);
|
||||
intent = png_get_uint_32(profile+64);
|
||||
}
|
||||
|
||||
/* Length *and* intent must match */
|
||||
if (length == png_sRGB_checks[i].length &&
|
||||
intent == png_sRGB_checks[i].intent)
|
||||
{
|
||||
/* Now calculate the alder32 if not done already. */
|
||||
if (adler == 0)
|
||||
{
|
||||
adler = adler32(0, NULL, 0);
|
||||
adler = adler32(adler, profile, length);
|
||||
}
|
||||
|
||||
if (adler == png_sRGB_checks[i].adler)
|
||||
{
|
||||
/* These basic checks suggest that the data has not been
|
||||
* modified, but if the check level is more than 1 perform
|
||||
* our own crc32 checksum on the data.
|
||||
*/
|
||||
# if PNG_sRGB_PROFILE_CHECKS > 1
|
||||
if (crc == 0)
|
||||
{
|
||||
crc = crc32(0, NULL, 0);
|
||||
crc = crc32(crc, profile, length);
|
||||
}
|
||||
|
||||
/* So this check must pass for the 'return' below to happen.
|
||||
*/
|
||||
if (crc == png_sRGB_checks[i].crc)
|
||||
# endif
|
||||
{
|
||||
/* Warn that this being done; this isn't even an error since
|
||||
* the profile is perfectly valid, but it would be nice if
|
||||
* people used the up-to-date ones.
|
||||
*/
|
||||
if (!png_sRGB_checks[i].have_md5)
|
||||
{
|
||||
# ifdef PNG_READ_SUPPORTED
|
||||
if (png_ptr->mode & PNG_IS_READ_STRUCT)
|
||||
png_chunk_warning(png_ptr,
|
||||
"out-of-date sRGB profile with no signature");
|
||||
else
|
||||
# endif
|
||||
png_app_warning(png_ptr,
|
||||
"out-of-date sRGB profile with no signature");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# if PNG_sRGB_PROFILE_CHECKS > 0
|
||||
/* The signature matched, but the profile had been changed in some
|
||||
* way. This is an apparent violation of the ICC terms of use and,
|
||||
* anyway, the rejection may be unexpected.
|
||||
*/
|
||||
if (png_sRGB_checks[i].have_md5)
|
||||
png_benign_error(png_ptr,
|
||||
"copyright violation: edited ICC profile ignored");
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* no match */
|
||||
}
|
||||
#endif
|
||||
|
||||
int /* PRIVATE */
|
||||
png_icc_set_gAMA_and_cHRM(png_const_structrp png_ptr,
|
||||
png_colorspacerp colorspace, png_const_charp name, png_const_bytep profile,
|
||||
int preferred)
|
||||
uLong adler, int preferred)
|
||||
{
|
||||
/* TODO: implement this! */
|
||||
PNG_UNUSED(png_ptr)
|
||||
PNG_UNUSED(colorspace)
|
||||
PNG_UNUSED(name)
|
||||
PNG_UNUSED(profile)
|
||||
PNG_UNUSED(preferred)
|
||||
# ifdef PNG_sRGB_SUPPORTED
|
||||
/* 1) Is this profile one of the known ICC sRGB profiles? If it is just
|
||||
* set the sRGB information.
|
||||
*/
|
||||
if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler))
|
||||
return png_colorspace_set_sRGB(png_ptr, colorspace,
|
||||
(int)/*already checked*/png_get_uint_32(profile+64), preferred);
|
||||
|
||||
else
|
||||
# endif
|
||||
|
||||
/* 2) Attempt to extract the gAMA and cHRM information from non-sRGB
|
||||
* profiles.
|
||||
*/
|
||||
{
|
||||
/* TODO: implement this! */
|
||||
PNG_UNUSED(name) /* NYI */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int /* PRIVATE */
|
||||
@ -2000,7 +2175,8 @@ png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
|
||||
&& png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
|
||||
profile))
|
||||
{
|
||||
png_icc_set_gAMA_and_cHRM(png_ptr, colorspace, name, profile, preferred);
|
||||
png_icc_set_gAMA_and_cHRM(png_ptr, colorspace, name, profile, 0,
|
||||
preferred);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -1443,9 +1443,14 @@ PNG_INTERNAL_FUNCTION(int,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_EMPTY);
|
||||
PNG_INTERNAL_FUNCTION(void,png_icc_set_gAMA_and_cHRM,(
|
||||
PNG_INTERNAL_FUNCTION(int,png_icc_set_gAMA_and_cHRM,(
|
||||
png_const_structrp png_ptr, png_colorspacerp colorspace,
|
||||
png_const_charp name, png_const_bytep profile, int preferred), PNG_EMPTY);
|
||||
png_const_charp name, png_const_bytep profile, uLong adler, int preferred),
|
||||
PNG_EMPTY);
|
||||
/* 'adler' is the Adler32 checksum of the uncompressed profile data, it may
|
||||
* be 0 to indicate that it is not available. It is used, if provided, as a
|
||||
* fast check on the profile when checking to see if it is sRGB.
|
||||
*/
|
||||
#endif /* iCCP */
|
||||
|
||||
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
|
||||
@ -63,7 +63,7 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
|
||||
/* In stable builds only warn if an application error can be completely
|
||||
* handled.
|
||||
*/
|
||||
# if PNG_LIBPNG_BUILD_BASE_TYPE == PNG_LIBPNG_BUILD_STABLE
|
||||
# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
||||
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
189
pngrutil.c
189
pngrutil.c
@ -338,7 +338,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner, int window_bits)
|
||||
* are minimal.
|
||||
*/
|
||||
(void)png_safecat(msg, sizeof msg, 4, " using zstream");
|
||||
# if PNG_LIBPNG_BUILD_BASE_TYPE == PNG_LIBPNG_BUILD_STABLE
|
||||
# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
||||
png_chunk_warning(png_ptr, msg);
|
||||
png_ptr->zowner = 0;
|
||||
# else
|
||||
@ -1314,72 +1314,12 @@ png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
#endif /* PNG_READ_sRGB_SUPPORTED */
|
||||
|
||||
#ifdef PNG_READ_iCCP_SUPPORTED
|
||||
#ifdef PNG_WARN_IF_iCCP_IS_sRGB_SUPPORTED
|
||||
int /* PRIVATE */
|
||||
png_compare_ICC_profile_with_sRGB(png_structrp png_ptr, png_bytep profile,
|
||||
png_uint_32 length)
|
||||
{
|
||||
/* See if it's a known sRGB profile. If it is, return intent;
|
||||
* if not, return -1.
|
||||
*/
|
||||
|
||||
int
|
||||
icheck;
|
||||
|
||||
/* Known sRGB profiles:
|
||||
* 0: not a known sRGB profile
|
||||
* 1: HP-Microsoft sRGB v2 perceptual
|
||||
* 2: ICC sRGB v4 perceptual
|
||||
* 3: ICC sRGB v2 perceptual
|
||||
* no black-compensation
|
||||
*/
|
||||
|
||||
typedef struct png_sRGB_check_struct
|
||||
{
|
||||
uLong crc;
|
||||
uLong adler;
|
||||
png_uint_32 check_len;
|
||||
int intent;
|
||||
} png_sRGB_check;
|
||||
|
||||
png_sRGB_check check[3] =
|
||||
{
|
||||
{ 0xf29e526dUL, 0x0398f3fcUL, 3144UL, 0 },
|
||||
{ 0xbbef7812UL, 0x209c35d2UL, 60960UL, 0 },
|
||||
{ 0x427ebb21UL, 0x4909e5e1UL, 3052UL, 0 }
|
||||
};
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return -1;
|
||||
|
||||
for (icheck = 2; icheck >= 0; icheck--)
|
||||
{
|
||||
if (length == check[icheck].check_len)
|
||||
{
|
||||
uLong profile_adler = adler32(1, profile, length);
|
||||
|
||||
if (profile_adler == (uLong) check[icheck].adler)
|
||||
{
|
||||
uLong profile_crc = crc32(0, profile, length);
|
||||
|
||||
if (profile_crc == (uLong) check[icheck].crc)
|
||||
return check[icheck].intent;
|
||||
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void /* PRIVATE */
|
||||
png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
/* Note: this does not properly handle profiles that are > 64K under DOS */
|
||||
{
|
||||
png_const_charp errmsg;
|
||||
png_const_charp errmsg = NULL; /* error message output, or no error */
|
||||
int finished = 0; /* crc checked */
|
||||
|
||||
png_debug(1, "in png_handle_iCCP");
|
||||
|
||||
@ -1452,14 +1392,13 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
if (png_inflate_claim(png_ptr, png_iCCP,
|
||||
png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN ? 15 : 0) == Z_OK)
|
||||
{
|
||||
int ret;
|
||||
Byte profile_header[132];
|
||||
Byte local_buffer[PNG_INFLATE_BUF_SIZE];
|
||||
png_alloc_size_t size = sizeof profile_header;
|
||||
|
||||
png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
|
||||
png_ptr->zstream.avail_in = read_length;
|
||||
ret = png_inflate_read(png_ptr, local_buffer,
|
||||
(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*/);
|
||||
|
||||
@ -1470,8 +1409,6 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
const png_uint_32 profile_length =
|
||||
png_get_uint_32(profile_header);
|
||||
|
||||
errmsg = NULL; /* flag to say error message output */
|
||||
|
||||
if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
|
||||
keyword, profile_length))
|
||||
{
|
||||
@ -1498,10 +1435,13 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
|
||||
size = 12 * tag_count;
|
||||
|
||||
ret = png_inflate_read(png_ptr, local_buffer,
|
||||
(void)png_inflate_read(png_ptr, local_buffer,
|
||||
sizeof local_buffer, &length,
|
||||
profile + (sizeof profile_header), &size, 0);
|
||||
|
||||
/* Still expect a a buffer error because we expect
|
||||
* there to be some tag data!
|
||||
*/
|
||||
if (size == 0)
|
||||
{
|
||||
if (png_icc_check_tag_table(png_ptr,
|
||||
@ -1514,53 +1454,43 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
size = profile_length - (sizeof profile_header)
|
||||
- 12 * tag_count;
|
||||
|
||||
ret = png_inflate_read(png_ptr, local_buffer,
|
||||
(void)png_inflate_read(png_ptr, local_buffer,
|
||||
sizeof local_buffer, &length,
|
||||
profile + (sizeof profile_header) +
|
||||
12 * tag_count, &size, 1/*finish*/);
|
||||
|
||||
if (size == 0)
|
||||
if (length > 0 && !(png_ptr->flags &
|
||||
PNG_FLAG_BENIGN_ERRORS_WARN))
|
||||
errmsg = "extra compressed data";
|
||||
|
||||
/* But otherwise allow extra data: */
|
||||
else if (size == 0)
|
||||
{
|
||||
#ifdef PNG_WARN_IF_iCCP_IS_sRGB_SUPPORTED
|
||||
int
|
||||
intent;
|
||||
#endif
|
||||
int ok;
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
png_chunk_warning(png_ptr,
|
||||
png_ptr->zstream.msg);
|
||||
|
||||
else if (length > 0)
|
||||
if (length > 0)
|
||||
{
|
||||
/* This can be handled completely, so
|
||||
* keep going.
|
||||
*/
|
||||
png_chunk_warning(png_ptr,
|
||||
"extra compressed data");
|
||||
}
|
||||
|
||||
/* But, because we got the whole profile,
|
||||
* assume it is ok.
|
||||
png_crc_finish(png_ptr, length);
|
||||
finished = 1;
|
||||
|
||||
/* Set the gAMA and cHRM information, this
|
||||
* checks for a known sRGB profile. The
|
||||
* result is 0 on error.
|
||||
*/
|
||||
png_ptr->zowner = 0;
|
||||
|
||||
/* Yet the CRC should still be correct */
|
||||
if (png_crc_finish(png_ptr, length))
|
||||
return;
|
||||
|
||||
#ifdef PNG_WARN_IF_iCCP_IS_sRGB_SUPPORTED
|
||||
/* See if it's a known sRGB profile. */
|
||||
intent =
|
||||
png_compare_ICC_profile_with_sRGB(
|
||||
png_ptr, profile, profile_length);
|
||||
|
||||
if (intent >= 0)
|
||||
png_chunk_warning(png_ptr,
|
||||
"describes sRGB\n");
|
||||
#endif
|
||||
|
||||
/* Set the gAMA and cHRM information */
|
||||
png_icc_set_gAMA_and_cHRM(png_ptr,
|
||||
ok = png_icc_set_gAMA_and_cHRM(png_ptr,
|
||||
&png_ptr->colorspace, keyword, profile,
|
||||
png_ptr->zstream.adler,
|
||||
0/*prefer explicit gAMA/cHRM*/);
|
||||
|
||||
/* Steal the profile for info_ptr. */
|
||||
if (info_ptr != NULL)
|
||||
if (ok && info_ptr != NULL)
|
||||
{
|
||||
png_free_data(png_ptr, info_ptr,
|
||||
PNG_FREE_ICCP, 0);
|
||||
@ -1568,33 +1498,50 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
info_ptr->iccp_name = png_voidcast(char*,
|
||||
png_malloc_base(png_ptr,
|
||||
keyword_length+1));
|
||||
if (info_ptr->iccp_name == NULL)
|
||||
if (info_ptr->iccp_name != NULL)
|
||||
{
|
||||
memcpy(info_ptr->iccp_name, keyword,
|
||||
keyword_length+1);
|
||||
info_ptr->iccp_proflen =
|
||||
profile_length;
|
||||
info_ptr->iccp_profile = profile;
|
||||
png_ptr->read_buffer = NULL; /*steal*/
|
||||
info_ptr->free_me |= PNG_FREE_ICCP;
|
||||
info_ptr->valid |= PNG_INFO_iCCP;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
png_ptr->colorspace.flags |=
|
||||
PNG_COLORSPACE_INVALID;
|
||||
png_colorspace_sync(png_ptr,
|
||||
info_ptr);
|
||||
png_chunk_benign_error(png_ptr,
|
||||
"out of memory");
|
||||
return;
|
||||
errmsg = "out of memory";
|
||||
}
|
||||
|
||||
memcpy(info_ptr->iccp_name, keyword,
|
||||
keyword_length+1);
|
||||
info_ptr->iccp_proflen = profile_length;
|
||||
info_ptr->iccp_profile = profile;
|
||||
png_ptr->read_buffer = NULL; /*steal*/
|
||||
info_ptr->free_me |= PNG_FREE_ICCP;
|
||||
info_ptr->valid |= PNG_INFO_iCCP;
|
||||
|
||||
png_colorspace_sync(png_ptr, info_ptr);
|
||||
}
|
||||
|
||||
return;
|
||||
/* else the profile remains in the read
|
||||
* buffer which gets reused for subsequent
|
||||
* chunks.
|
||||
*/
|
||||
|
||||
if (info_ptr != NULL)
|
||||
png_colorspace_sync(png_ptr, info_ptr);
|
||||
|
||||
if (errmsg == NULL && ok)
|
||||
{
|
||||
png_ptr->zowner = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* else png_icc_set_gAMA_and_cHRM has
|
||||
* already output an error.
|
||||
*/
|
||||
}
|
||||
|
||||
else
|
||||
else if (size > 0)
|
||||
errmsg = "truncated";
|
||||
|
||||
else
|
||||
errmsg = png_ptr->zstream.msg;
|
||||
}
|
||||
|
||||
/* else png_icc_check_tag_table output an error */
|
||||
@ -1637,7 +1584,9 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
|
||||
errmsg = "too many profiles";
|
||||
|
||||
/* Failure: the reason is in 'errmsg' */
|
||||
png_crc_finish(png_ptr, length);
|
||||
if (!finished)
|
||||
png_crc_finish(png_ptr, length);
|
||||
|
||||
png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
|
||||
png_colorspace_sync(png_ptr, info_ptr);
|
||||
if (errmsg != NULL) /* else already output */
|
||||
|
||||
43
pngwrite.c
43
pngwrite.c
@ -82,25 +82,32 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
|
||||
#endif
|
||||
|
||||
#ifdef PNG_COLORSPACE_SUPPORTED
|
||||
/* Write only one of sRGB or an ICC profile, favour sRGB if the profile
|
||||
* matches sRGB.
|
||||
/* Write only one of sRGB or an ICC profile. If a profile was supplied
|
||||
* and it matches one of the known sRGB ones issue a warning.
|
||||
*/
|
||||
# ifdef PNG_WRITE_iCCP_SUPPORTED
|
||||
if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
|
||||
(info_ptr->valid & PNG_INFO_iCCP))
|
||||
{
|
||||
# ifdef PNG_WRITE_sRGB_SUPPORTED
|
||||
if (info_ptr->valid & PNG_INFO_sRGB)
|
||||
png_app_warning(png_ptr,
|
||||
"profile matches sRGB but writing iCCP instead");
|
||||
# endif
|
||||
|
||||
png_write_iCCP(png_ptr, info_ptr->iccp_name,
|
||||
info_ptr->iccp_profile);
|
||||
}
|
||||
# ifdef PNG_WRITE_sRGB_SUPPORTED
|
||||
else
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef PNG_WRITE_sRGB_SUPPORTED
|
||||
if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
|
||||
(info_ptr->valid & PNG_INFO_sRGB))
|
||||
png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
|
||||
|
||||
# ifdef PNG_WRITE_iCCP_SUPPORTED
|
||||
else
|
||||
# endif
|
||||
# endif /* WRITE_sRGB */
|
||||
|
||||
# ifdef PNG_WRITE_iCCP_SUPPORTED
|
||||
if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
|
||||
(info_ptr->valid & PNG_INFO_iCCP))
|
||||
png_write_iCCP(png_ptr, info_ptr->iccp_name,
|
||||
info_ptr->iccp_profile);
|
||||
# endif
|
||||
#endif /* COLORSPACE */
|
||||
|
||||
#ifdef PNG_WRITE_sBIT_SUPPORTED
|
||||
@ -527,6 +534,16 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
|
||||
*/
|
||||
# ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
|
||||
png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
|
||||
/* In stable builds only warn if an application error can be completely
|
||||
* handled.
|
||||
*/
|
||||
# endif
|
||||
|
||||
/* App warnings are warnings in release (or release candidate) builds but
|
||||
* are errors during development.
|
||||
*/
|
||||
# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
||||
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
|
||||
# endif
|
||||
|
||||
if (png_ptr != NULL)
|
||||
|
||||
@ -325,7 +325,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
|
||||
* are minimal.
|
||||
*/
|
||||
(void)png_safecat(msg, sizeof msg, 10, " using zstream");
|
||||
# if PNG_LIBPNG_BUILD_BASE_TYPE == PNG_LIBPNG_BUILD_STABLE
|
||||
# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
||||
png_warning(png_ptr, msg);
|
||||
|
||||
/* Attempt sane error recovery */
|
||||
|
||||
@ -478,7 +478,46 @@ option WRITE_TEXT requires WRITE_ANCILLARY_CHUNKS enables TEXT
|
||||
option GAMMA disabled
|
||||
option COLORSPACE enables GAMMA disabled
|
||||
|
||||
# When an ICC profile is read, or png_set, it will be checked for a match
|
||||
# against known sRGB profiles if the sRGB handling is enabled. This
|
||||
# setting controls how much work is done during the check:
|
||||
#
|
||||
# 0: Just validate the profile MD5 signature if present, otherwise use
|
||||
# the checks in option 1.
|
||||
#
|
||||
# 1: Additionally check the length, intent and adler32 checksum of the
|
||||
# actual data. If enabled this will reject known profiles that have
|
||||
# had the rendering intent in the header changed as well as other edits
|
||||
# done without updating the checksum. See the discussion below.
|
||||
#
|
||||
# 2: Additionally checksum all the data using the ethernet CRC32 algorithm.
|
||||
# This makes it more difficult to fake profiles and makes it less likely
|
||||
# to get a false positive on profiles with no signature, but is probably
|
||||
# just a waste of time since all currently approved ICC sRGB profiles have
|
||||
# a secure MD5 signature.
|
||||
#
|
||||
# The rendering intent. An ICC profile stores an intended rendering intent,
|
||||
# but does not include the value in the signature. The intent is documented
|
||||
# as the intent that should be used when combining two profiles. The sRGB
|
||||
# profile is intended, however, to be used with any of the four defined intents.
|
||||
# For this reason the sRGB chunk includes an 'intent' to be used when displaying
|
||||
# the image (intent is really a property of the image not the profile.)
|
||||
#
|
||||
# Unfortunately the iCCP chunk does not. It may therefore be that some
|
||||
# applications modify the intent in profiles (including sRGB profiles) to work
|
||||
# round this problem. Selecting an option other than option '0' will cause such
|
||||
# modified profiles to be rejected.
|
||||
#
|
||||
# Security. The use of Adler32 and CRC32 checksums does not help significantly
|
||||
# with any security issues. It is relatively easy to produce arbitrary profiles
|
||||
# with the required checksums on current computer systems. Nevertheless
|
||||
# security does not seem to be an issue because the only consequence of a false
|
||||
# positive is a false assertion that the profile is an sRGB profile. This might
|
||||
# be used to hide data from libpng using applications, but it doesn't seem
|
||||
# possible to damage them.
|
||||
|
||||
setting sRGB_PROFILE_CHECKS default 2
|
||||
|
||||
# Artificially align memory - the code typically aligns to 8 byte
|
||||
# boundaries if this is switched on, it's a small waste of space
|
||||
# but can help (in theory) on some architectures. Only affects
|
||||
@ -650,9 +689,6 @@ option CHECK_FOR_INVALID_INDEX enables WRITE_CHECK_FOR_INVALID_INDEX
|
||||
option READ_CHECK_FOR_INVALID_INDEX requires READ CHECK_FOR_INVALID_INDEX
|
||||
option WRITE_CHECK_FOR_INVALID_INDEX requires WRITE CHECK_FOR_INVALID_INDEX
|
||||
|
||||
# added at libpng-1.6.0
|
||||
option WARN_IF_iCCP_IS_sRGB requires READ iCCP
|
||||
|
||||
# Simplified API options (added at libpng-1.6.0)
|
||||
# Read:
|
||||
option SIMPLIFIED_READ requires SEQUENTIAL_READ READ_TRANSFORMS SETJMP
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
/* pnglibconf.h - library build configuration */
|
||||
|
||||
/* Libpng 1.6.0beta20 - March 28, 2012 */
|
||||
/* Libpng 1.6.0beta20 - March 29, 2012 */
|
||||
|
||||
/* Copyright (c) 1998-2012 Glenn Randers-Pehrson */
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#define PNG_QUANTIZE_GREEN_BITS 5
|
||||
#define PNG_QUANTIZE_RED_BITS 5
|
||||
#define PNG_sCAL_PRECISION 5
|
||||
#define PNG_sRGB_PROFILE_CHECKS 2
|
||||
#define PNG_WEIGHT_SHIFT 8
|
||||
#define PNG_ZBUF_SIZE 8192
|
||||
/* end of settings */
|
||||
@ -138,7 +139,6 @@
|
||||
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
|
||||
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
|
||||
#define PNG_WARN_IF_iCCP_IS_sRGB_SUPPORTED
|
||||
#define PNG_sPLT_SUPPORTED
|
||||
#define PNG_sRGB_SUPPORTED
|
||||
#define PNG_STDIO_SUPPORTED
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user