Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibPNG/png.c view on Meta::CPAN
*/
Y = XYZ->red_Y;
if (0x7fffffff - Y < XYZ->green_X)
return 1;
Y += XYZ->green_Y;
if (0x7fffffff - Y < XYZ->blue_X)
return 1;
Y += XYZ->blue_Y;
if (Y != PNG_FP_1)
{
if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
return 1;
if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
return 1;
}
return 0;
}
static int
png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
{
/* Allow an error of +/-0.01 (absolute value) on each chromaticity */
if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) ||
PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) ||
PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) ||
PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta))
return 0;
return 1;
}
/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
* chunk chromaticities. Earlier checks used to simply look for the overflow
* condition (where the determinant of the matrix to solve for XYZ ends up zero
* because the chromaticity values are not all distinct.) Despite this it is
* theoretically possible to produce chromaticities that are apparently valid
* but that rapidly degrade to invalid, potentially crashing, sets because of
* arithmetic inaccuracies when calculations are performed on them. The new
* check is to round-trip xy -> XYZ -> xy and then check that the result is
* within a small percentage of the original.
*/
static int
png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
{
int result;
png_xy xy_test;
/* As a side-effect this routine also returns the XYZ endpoints. */
result = png_XYZ_from_xy(XYZ, xy);
if (result != 0)
return result;
result = png_xy_from_XYZ(&xy_test, XYZ);
if (result != 0)
return result;
if (png_colorspace_endpoints_match(xy, &xy_test,
5/*actually, the math is pretty accurate*/) != 0)
return 0;
/* Too much slip */
return 1;
}
/* This is the check going the other way. The XYZ is modified to normalize it
* (another side-effect) and the xy chromaticities are returned.
*/
static int
png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
{
int result;
png_XYZ XYZtemp;
result = png_XYZ_normalize(XYZ);
if (result != 0)
return result;
result = png_xy_from_XYZ(xy, XYZ);
if (result != 0)
return result;
XYZtemp = *XYZ;
return png_colorspace_check_xy(&XYZtemp, xy);
}
/* Used to check for an endpoint match against sRGB */
static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
{
/* color x y */
/* red */ 64000, 33000,
/* green */ 30000, 60000,
/* blue */ 15000, 6000,
/* white */ 31270, 32900
};
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)
{
( run in 0.985 second using v1.01-cache-2.11-cpan-13bb782fe5a )