Image-PNG-Simple
view release on metacpan or search on metacpan
libpng-1.6.17/contrib/libtests/pngvalid.c view on Meta::CPAN
/* Modifications (not necessarily used.) */
gama_modification gama_mod;
chrm_modification chrm_mod;
srgb_modification srgb_mod;
} transform_display;
/* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */
static void
transform_set_encoding(transform_display *this)
{
/* Set up the png_modifier '_current' fields then use these to determine how
* to add appropriate chunks.
*/
png_modifier *pm = this->pm;
modifier_set_encoding(pm);
if (modifier_color_encoding_is_set(pm))
{
if (modifier_color_encoding_is_sRGB(pm))
srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE);
else
{
/* Set gAMA and cHRM separately. */
gama_modification_init(&this->gama_mod, pm, pm->current_gamma);
if (pm->current_encoding != 0)
chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding);
}
}
}
/* Three functions to end the list: */
static void
image_transform_ini_end(PNG_CONST image_transform *this,
transform_display *that)
{
UNUSED(this)
UNUSED(that)
}
static void
image_transform_set_end(PNG_CONST image_transform *this,
transform_display *that, png_structp pp, png_infop pi)
{
UNUSED(this)
UNUSED(that)
UNUSED(pp)
UNUSED(pi)
}
/* At the end of the list recalculate the output image pixel value from the
* double precision values set up by the preceding 'mod' calls:
*/
static unsigned int
sample_scale(double sample_value, unsigned int scale)
{
sample_value = floor(sample_value * scale + .5);
/* Return NaN as 0: */
if (!(sample_value > 0))
sample_value = 0;
else if (sample_value > scale)
sample_value = scale;
return (unsigned int)sample_value;
}
static void
image_transform_mod_end(PNG_CONST image_transform *this, image_pixel *that,
png_const_structp pp, PNG_CONST transform_display *display)
{
PNG_CONST unsigned int scale = (1U<<that->sample_depth)-1;
PNG_CONST int sig_bits = that->sig_bits;
UNUSED(this)
UNUSED(pp)
UNUSED(display)
/* At the end recalculate the digitized red green and blue values according
* to the current sample_depth of the pixel.
*
* The sample value is simply scaled to the maximum, checking for over
* and underflow (which can both happen for some image transforms,
* including simple size scaling, though libpng doesn't do that at present.
*/
that->red = sample_scale(that->redf, scale);
/* This is a bit bogus; really the above calculation should use the red_sBIT
* value, not sample_depth, but because libpng does png_set_shift by just
* shifting the bits we get errors if we don't do it the same way.
*/
if (sig_bits && that->red_sBIT < that->sample_depth)
that->red >>= that->sample_depth - that->red_sBIT;
/* The error value is increased, at the end, according to the lowest sBIT
* value seen. Common sense tells us that the intermediate integer
* representations are no more accurate than +/- 0.5 in the integral values,
* the sBIT allows the implementation to be worse than this. In addition the
* PNG specification actually permits any error within the range (-1..+1),
* but that is ignored here. Instead the final digitized value is compared,
* below to the digitized value of the error limits - this has the net effect
* of allowing (almost) +/-1 in the output value. It's difficult to see how
* any algorithm that digitizes intermediate results can be more accurate.
*/
that->rede += 1./(2*((1U<<that->red_sBIT)-1));
if (that->colour_type & PNG_COLOR_MASK_COLOR)
{
that->green = sample_scale(that->greenf, scale);
if (sig_bits && that->green_sBIT < that->sample_depth)
that->green >>= that->sample_depth - that->green_sBIT;
that->blue = sample_scale(that->bluef, scale);
if (sig_bits && that->blue_sBIT < that->sample_depth)
that->blue >>= that->sample_depth - that->blue_sBIT;
that->greene += 1./(2*((1U<<that->green_sBIT)-1));
that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));
}
( run in 2.441 seconds using v1.01-cache-2.11-cpan-5c0b1e786e0 )