[libpng16] Merged with pngvalid.c from libpng-1.7 changes to create a single
pngvalid.c
This commit is contained in:
parent
1d3c990425
commit
a80e864faa
2
ANNOUNCE
2
ANNOUNCE
@ -45,6 +45,8 @@ Version 1.6.9beta01 [December 26, 2013]
|
||||
Version 1.6.9beta02 [December 27, 2013]
|
||||
Added checks for libpng 1.5 to pngvalid.c. This supports the use of
|
||||
this version of pngvalid in libpng 1.5
|
||||
Merged with pngvalid.c from libpng-1.7 changes to create a single
|
||||
pngvalid.c
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
|
2
CHANGES
2
CHANGES
@ -4770,6 +4770,8 @@ Version 1.6.9beta01 [December 26, 2013]
|
||||
Version 1.6.9beta02 [December 27, 2013]
|
||||
Added checks for libpng 1.5 to pngvalid.c. This supports the use of
|
||||
this version of pngvalid in libpng 1.5
|
||||
Merged with pngvalid.c from libpng-1.7 changes to create a single
|
||||
pngvalid.c
|
||||
|
||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||
(subscription required; visit
|
||||
|
@ -43,6 +43,12 @@
|
||||
# include "../../png.h"
|
||||
#endif
|
||||
|
||||
#ifdef PNG_ZLIB_HEADER
|
||||
# include PNG_ZLIB_HEADER
|
||||
#else
|
||||
# include <zlib.h> /* For crc32 */
|
||||
#endif
|
||||
|
||||
/* pngvalid requires write support and one of the fixed or floating point APIs.
|
||||
*/
|
||||
#if defined(PNG_WRITE_SUPPORTED) &&\
|
||||
@ -91,8 +97,6 @@ typedef png_byte *png_const_bytep;
|
||||
# define png_const_structp png_structp
|
||||
#endif
|
||||
|
||||
#include <zlib.h> /* For crc32 */
|
||||
|
||||
#include <float.h> /* For floating point constants */
|
||||
#include <stdlib.h> /* For malloc */
|
||||
#include <string.h> /* For memcpy, memset */
|
||||
@ -352,11 +356,16 @@ standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
|
||||
|
||||
static int
|
||||
next_format(png_bytep colour_type, png_bytep bit_depth,
|
||||
unsigned int* palette_number)
|
||||
unsigned int* palette_number, int no_low_depth_gray)
|
||||
{
|
||||
if (*bit_depth == 0)
|
||||
{
|
||||
*colour_type = 0, *bit_depth = 1, *palette_number = 0;
|
||||
*colour_type = 0;
|
||||
if (no_low_depth_gray)
|
||||
*bit_depth = 8;
|
||||
else
|
||||
*bit_depth = 1;
|
||||
*palette_number = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1874,6 +1883,7 @@ typedef struct png_modifier
|
||||
double maxout16; /* Maximum output value error */
|
||||
double maxabs16; /* Absolute sample error 0..1 */
|
||||
double maxcalc16;/* Absolute sample error 0..1 */
|
||||
double maxcalcG; /* Absolute sample error 0..1 */
|
||||
double maxpc16; /* Percentage sample error 0..100% */
|
||||
|
||||
/* This is set by transforms that need to allow a higher limit, it is an
|
||||
@ -1913,10 +1923,15 @@ typedef struct png_modifier
|
||||
/* Run the odd-sized image and interlace read/write tests? */
|
||||
unsigned int test_size :1;
|
||||
|
||||
/* Run tests on reading with a combiniation of transforms, */
|
||||
/* Run tests on reading with a combination of transforms, */
|
||||
unsigned int test_transform :1;
|
||||
|
||||
/* When to use the use_input_precision option: */
|
||||
/* When to use the use_input_precision option, this controls the gamma
|
||||
* validation code checks. If set any value that is within the transformed
|
||||
* range input-.5 to input+.5 will be accepted, otherwise the value must be
|
||||
* within the normal limits. It should not be necessary to set this; the
|
||||
* result should always be exact within the permitted error limits.
|
||||
*/
|
||||
unsigned int use_input_precision :1;
|
||||
unsigned int use_input_precision_sbit :1;
|
||||
unsigned int use_input_precision_16to8 :1;
|
||||
@ -1926,8 +1941,8 @@ typedef struct png_modifier
|
||||
*/
|
||||
unsigned int calculations_use_input_precision :1;
|
||||
|
||||
/* If set assume that the calculations are done in 16 bits even if both input
|
||||
* and output are 8 bit or less.
|
||||
/* If set assume that the calculations are done in 16 bits even if the sample
|
||||
* depth is 8 bits.
|
||||
*/
|
||||
unsigned int assume_16_bit_calculations :1;
|
||||
|
||||
@ -1982,6 +1997,7 @@ modifier_init(png_modifier *pm)
|
||||
pm->test_uses_encoding = 0;
|
||||
pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0;
|
||||
pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0;
|
||||
pm->maxcalcG = 0;
|
||||
pm->limit = 4E-3;
|
||||
pm->log8 = pm->log16 = 0; /* Means 'off' */
|
||||
pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
|
||||
@ -1996,6 +2012,7 @@ modifier_init(png_modifier *pm)
|
||||
pm->use_input_precision_sbit = 0;
|
||||
pm->use_input_precision_16to8 = 0;
|
||||
pm->calculations_use_input_precision = 0;
|
||||
pm->assume_16_bit_calculations = 0;
|
||||
pm->test_gamma_threshold = 0;
|
||||
pm->test_gamma_transform = 0;
|
||||
pm->test_gamma_sbit = 0;
|
||||
@ -2010,8 +2027,16 @@ modifier_init(png_modifier *pm)
|
||||
}
|
||||
|
||||
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
|
||||
|
||||
/* This controls use of checks that explicitly know how libpng digitizes the
|
||||
* samples in calculations; setting this circumvents simple error limit checking
|
||||
* in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5
|
||||
* algorithm.
|
||||
*/
|
||||
#define DIGITIZE PNG_LIBPNG_VER < 10700
|
||||
|
||||
/* If pm->calculations_use_input_precision is set then operations will happen
|
||||
* with only 8 bit precision unless both the input and output bit depth are 16.
|
||||
* with the precision of the input, not the precision of the output depth.
|
||||
*
|
||||
* If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16
|
||||
* bit precision. This only affects those of the following limits that pertain
|
||||
@ -2019,8 +2044,8 @@ modifier_init(png_modifier *pm)
|
||||
* called directly.
|
||||
*/
|
||||
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
|
||||
static double digitize(PNG_CONST png_modifier *pm, double value,
|
||||
int sample_depth, int do_round)
|
||||
#if DIGITIZE
|
||||
static double digitize(double value, int depth, int do_round)
|
||||
{
|
||||
/* 'value' is in the range 0 to 1, the result is the same value rounded to a
|
||||
* multiple of the digitization factor - 8 or 16 bits depending on both the
|
||||
@ -2028,14 +2053,14 @@ static double digitize(PNG_CONST png_modifier *pm, double value,
|
||||
* rounding and 'do_round' should be 1, if it is 0 the digitized value will
|
||||
* be truncated.
|
||||
*/
|
||||
PNG_CONST unsigned int digitization_factor =
|
||||
(pm->assume_16_bit_calculations || sample_depth == 16) ? 65535 : 255;
|
||||
PNG_CONST unsigned int digitization_factor = (1U << depth) -1;
|
||||
|
||||
/* Limiting the range is done as a convenience to the caller - it's easier to
|
||||
* do it once here than every time at the call site.
|
||||
*/
|
||||
if (value <= 0)
|
||||
value = 0;
|
||||
|
||||
else if (value >= 1)
|
||||
value = 1;
|
||||
|
||||
@ -2044,31 +2069,30 @@ static double digitize(PNG_CONST png_modifier *pm, double value,
|
||||
return floor(value)/digitization_factor;
|
||||
}
|
||||
#endif
|
||||
#endif /* RGB_TO_GRAY */
|
||||
|
||||
#if defined(PNG_READ_GAMMA_SUPPORTED) ||\
|
||||
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
|
||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
||||
static double abserr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
|
||||
{
|
||||
/* Absolute error permitted in linear values - affected by the bit depth of
|
||||
* the calculations.
|
||||
*/
|
||||
if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 ||
|
||||
!pm->calculations_use_input_precision)))
|
||||
if (pm->assume_16_bit_calculations ||
|
||||
(pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
|
||||
return pm->maxabs16;
|
||||
else
|
||||
return pm->maxabs8;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
||||
static double calcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
|
||||
{
|
||||
/* Error in the linear composition arithmetic - only relevant when
|
||||
* composition actually happens (0 < alpha < 1).
|
||||
*/
|
||||
if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 ||
|
||||
!pm->calculations_use_input_precision)))
|
||||
if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
|
||||
return pm->maxcalc16;
|
||||
else if (pm->assume_16_bit_calculations)
|
||||
return pm->maxcalcG;
|
||||
else
|
||||
return pm->maxcalc8;
|
||||
}
|
||||
@ -2078,8 +2102,8 @@ static double pcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
|
||||
/* Percentage error permitted in the linear values. Note that the specified
|
||||
* value is a percentage but this routine returns a simple number.
|
||||
*/
|
||||
if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 ||
|
||||
!pm->calculations_use_input_precision)))
|
||||
if (pm->assume_16_bit_calculations ||
|
||||
(pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
|
||||
return pm->maxpc16 * .01;
|
||||
else
|
||||
return pm->maxpc8 * .01;
|
||||
@ -2111,8 +2135,7 @@ static double outerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
|
||||
if (out_depth == 4)
|
||||
return .90644-.5;
|
||||
|
||||
if (out_depth == 16 && (in_depth == 16 ||
|
||||
!pm->calculations_use_input_precision))
|
||||
if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
|
||||
return pm->maxout16;
|
||||
|
||||
/* This is the case where the value was calculated at 8-bit precision then
|
||||
@ -2145,8 +2168,7 @@ static double outlog(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
|
||||
return pm->log8;
|
||||
}
|
||||
|
||||
if (out_depth == 16 && (in_depth == 16 ||
|
||||
!pm->calculations_use_input_precision))
|
||||
if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
|
||||
{
|
||||
if (pm->log16 == 0)
|
||||
return 65536;
|
||||
@ -2171,8 +2193,8 @@ static double outlog(PNG_CONST png_modifier *pm, int in_depth, int out_depth)
|
||||
static int output_quantization_factor(PNG_CONST png_modifier *pm, int in_depth,
|
||||
int out_depth)
|
||||
{
|
||||
if (out_depth == 16 && in_depth != 16
|
||||
&& pm->calculations_use_input_precision)
|
||||
if (out_depth == 16 && in_depth != 16 &&
|
||||
pm->calculations_use_input_precision)
|
||||
return 257;
|
||||
else
|
||||
return 1;
|
||||
@ -3534,7 +3556,7 @@ make_transform_images(png_store *ps)
|
||||
/* Use next_format to enumerate all the combinations we test, including
|
||||
* generating multiple low bit depth palette images.
|
||||
*/
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number))
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number, 0))
|
||||
{
|
||||
int interlace_type;
|
||||
|
||||
@ -3843,8 +3865,15 @@ make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo,
|
||||
make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
|
||||
width, height, 0);
|
||||
# endif
|
||||
# if defined(PNG_WRITE_INTERLACING_SUPPORTED) || PNG_LIBPNG_VER > 10518
|
||||
/* This fails in 1.5.8 with a zlib stream error writing the rows of
|
||||
* the internally generated interlaced images, but only when the
|
||||
* read code is disabled: to be investigated. Probably an erroneous
|
||||
* #define out of the zlib deflate reset.
|
||||
*/
|
||||
make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
|
||||
width, height, 1);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5886,12 +5915,9 @@ transform_image_validate(transform_display *dp, png_const_structp pp,
|
||||
|
||||
memset(out_palette, 0x5e, sizeof out_palette);
|
||||
|
||||
/* assume-8-bit-calculations means assume that if the input has 8 bit
|
||||
* (or less) samples and the output has 16 bit samples the calculations
|
||||
* will be done with 8 bit precision, not 16.
|
||||
*
|
||||
* TODO: fix this in libpng; png_set_expand_16 should cause 16 bit
|
||||
* calculations to be used throughout.
|
||||
/* use-input-precision means assume that if the input has 8 bit (or less)
|
||||
* samples and the output has 16 bit samples the calculations will be done
|
||||
* with 8 bit precision, not 16.
|
||||
*/
|
||||
if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16)
|
||||
in_sample_depth = 8;
|
||||
@ -5902,7 +5928,8 @@ transform_image_validate(transform_display *dp, png_const_structp pp,
|
||||
!dp->pm->calculations_use_input_precision)
|
||||
digitization_error = .5;
|
||||
|
||||
/* Else errors are at 8 bit precision, scale .5 in 8 bits to the 16 bits:
|
||||
/* Else calculations are at 8 bit precision, and the output actually
|
||||
* consists of scaled 8-bit values, so scale .5 in 8 bits to the 16 bits:
|
||||
*/
|
||||
else
|
||||
digitization_error = .5 * 257;
|
||||
@ -6718,10 +6745,23 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this,
|
||||
{
|
||||
if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations)
|
||||
{
|
||||
/* The 16 bit case ends up producing a maximum error of about
|
||||
* +/-5 in 65535, allow for +/-8 with the given gamma.
|
||||
/* The computations have the form:
|
||||
*
|
||||
* r * rc + g * gc + b * bc
|
||||
*
|
||||
* Each component of which is +/-1/65535 from the gamma_to_1 table
|
||||
* lookup, resulting in a base error of +/-6. The gamma_from_1
|
||||
* conversion adds another +/-2 in the 16-bit case and
|
||||
* +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case.
|
||||
*/
|
||||
that->pm->limit += pow(8./65535, data.gamma);
|
||||
that->pm->limit += pow(
|
||||
# if PNG_MAX_GAMMA_8 < 14
|
||||
(that->this.bit_depth == 16 ? 8. :
|
||||
6. + (1<<(15-PNG_MAX_GAMMA_8)))
|
||||
# else
|
||||
8.
|
||||
# endif
|
||||
/65535, data.gamma);
|
||||
}
|
||||
|
||||
else
|
||||
@ -6729,8 +6769,23 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this,
|
||||
/* Rounding to 8 bits in the linear space causes massive errors which
|
||||
* will trigger the error check in transform_range_check. Fix that
|
||||
* here by taking the gamma encoding into account.
|
||||
*
|
||||
* When DIGITIZE is set because a pre-1.7 version of libpng is being
|
||||
* tested allow a bigger slack.
|
||||
*
|
||||
* NOTE: this magic number was determined by experiment to be 1.1 (when
|
||||
* using fixed point arithmetic). There's no great merit to the value
|
||||
* below, however it only affects the limit used for checking for
|
||||
* internal calculation errors, not the actual limit imposed by
|
||||
* pngvalid on the output errors.
|
||||
*/
|
||||
that->pm->limit += pow(1./255, data.gamma);
|
||||
that->pm->limit += pow(
|
||||
# if DIGITIZE
|
||||
1.1
|
||||
# else
|
||||
1.
|
||||
# endif
|
||||
/255, data.gamma);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6739,7 +6794,7 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this,
|
||||
/* With no gamma correction a large error comes from the truncation of the
|
||||
* calculation in the 8 bit case, allow for that here.
|
||||
*/
|
||||
if (that->this.bit_depth != 16)
|
||||
if (that->this.bit_depth != 16 && !pm->assume_16_bit_calculations)
|
||||
that->pm->limit += 4E-3;
|
||||
}
|
||||
}
|
||||
@ -6884,9 +6939,14 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
|
||||
image_pixel_convert_PLTE(that);
|
||||
|
||||
/* Image now has RGB channels... */
|
||||
# if DIGITIZE
|
||||
{
|
||||
PNG_CONST png_modifier *pm = display->pm;
|
||||
PNG_CONST unsigned int sample_depth = that->sample_depth;
|
||||
const unsigned int sample_depth = that->sample_depth;
|
||||
const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
|
||||
sample_depth);
|
||||
const unsigned int gamma_depth = (sample_depth == 16 ? 16 :
|
||||
(pm->assume_16_bit_calculations ? PNG_MAX_GAMMA_8 : sample_depth));
|
||||
int isgray;
|
||||
double r, g, b;
|
||||
double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi;
|
||||
@ -6902,28 +6962,28 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
|
||||
*/
|
||||
r = rlo = rhi = that->redf;
|
||||
rlo -= that->rede;
|
||||
rlo = digitize(pm, rlo, sample_depth, 1/*round*/);
|
||||
rlo = digitize(rlo, calc_depth, 1/*round*/);
|
||||
rhi += that->rede;
|
||||
rhi = digitize(pm, rhi, sample_depth, 1/*round*/);
|
||||
rhi = digitize(rhi, calc_depth, 1/*round*/);
|
||||
|
||||
g = glo = ghi = that->greenf;
|
||||
glo -= that->greene;
|
||||
glo = digitize(pm, glo, sample_depth, 1/*round*/);
|
||||
glo = digitize(glo, calc_depth, 1/*round*/);
|
||||
ghi += that->greene;
|
||||
ghi = digitize(pm, ghi, sample_depth, 1/*round*/);
|
||||
ghi = digitize(ghi, calc_depth, 1/*round*/);
|
||||
|
||||
b = blo = bhi = that->bluef;
|
||||
blo -= that->bluee;
|
||||
blo = digitize(pm, blo, sample_depth, 1/*round*/);
|
||||
blo = digitize(blo, calc_depth, 1/*round*/);
|
||||
bhi += that->greene;
|
||||
bhi = digitize(pm, bhi, sample_depth, 1/*round*/);
|
||||
bhi = digitize(bhi, calc_depth, 1/*round*/);
|
||||
|
||||
isgray = r==g && g==b;
|
||||
|
||||
if (data.gamma != 1)
|
||||
{
|
||||
PNG_CONST double power = 1/data.gamma;
|
||||
PNG_CONST double abse = abserr(pm, sample_depth, sample_depth);
|
||||
PNG_CONST double abse = calc_depth == 16 ? .5/65535 : .5/255;
|
||||
|
||||
/* 'abse' is the absolute error permitted in linear calculations. It
|
||||
* is used here to capture the error permitted in the handling
|
||||
@ -6932,16 +6992,16 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
|
||||
* where the real errors are introduced.
|
||||
*/
|
||||
r = pow(r, power);
|
||||
rlo = digitize(pm, pow(rlo, power)-abse, sample_depth, 1);
|
||||
rhi = digitize(pm, pow(rhi, power)+abse, sample_depth, 1);
|
||||
rlo = digitize(pow(rlo, power)-abse, calc_depth, 1);
|
||||
rhi = digitize(pow(rhi, power)+abse, calc_depth, 1);
|
||||
|
||||
g = pow(g, power);
|
||||
glo = digitize(pm, pow(glo, power)-abse, sample_depth, 1);
|
||||
ghi = digitize(pm, pow(ghi, power)+abse, sample_depth, 1);
|
||||
glo = digitize(pow(glo, power)-abse, calc_depth, 1);
|
||||
ghi = digitize(pow(ghi, power)+abse, calc_depth, 1);
|
||||
|
||||
b = pow(b, power);
|
||||
blo = digitize(pm, pow(blo, power)-abse, sample_depth, 1);
|
||||
bhi = digitize(pm, pow(bhi, power)+abse, sample_depth, 1);
|
||||
blo = digitize(pow(blo, power)-abse, calc_depth, 1);
|
||||
bhi = digitize(pow(bhi, power)+abse, calc_depth, 1);
|
||||
}
|
||||
|
||||
/* Now calculate the actual gray values. Although the error in the
|
||||
@ -6958,18 +7018,18 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
|
||||
b * data.blue_coefficient;
|
||||
|
||||
{
|
||||
PNG_CONST int do_round = data.gamma != 1 || sample_depth == 16;
|
||||
PNG_CONST int do_round = data.gamma != 1 || calc_depth == 16;
|
||||
PNG_CONST double ce = 1. / 32768;
|
||||
|
||||
graylo = digitize(pm, rlo * (data.red_coefficient-ce) +
|
||||
graylo = digitize(rlo * (data.red_coefficient-ce) +
|
||||
glo * (data.green_coefficient-ce) +
|
||||
blo * (data.blue_coefficient-ce), sample_depth, do_round);
|
||||
blo * (data.blue_coefficient-ce), gamma_depth, do_round);
|
||||
if (graylo <= 0)
|
||||
graylo = 0;
|
||||
|
||||
grayhi = digitize(pm, rhi * (data.red_coefficient+ce) +
|
||||
grayhi = digitize(rhi * (data.red_coefficient+ce) +
|
||||
ghi * (data.green_coefficient+ce) +
|
||||
bhi * (data.blue_coefficient+ce), sample_depth, do_round);
|
||||
bhi * (data.blue_coefficient+ce), gamma_depth, do_round);
|
||||
if (grayhi >= 1)
|
||||
grayhi = 1;
|
||||
}
|
||||
@ -6980,8 +7040,8 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
|
||||
PNG_CONST double power = data.gamma;
|
||||
|
||||
gray = pow(gray, power);
|
||||
graylo = digitize(pm, pow(graylo, power), sample_depth, 1);
|
||||
grayhi = digitize(pm, pow(grayhi, power), sample_depth, 1);
|
||||
graylo = digitize(pow(graylo, power), sample_depth, 1);
|
||||
grayhi = digitize(pow(grayhi, power), sample_depth, 1);
|
||||
}
|
||||
|
||||
/* Now the error can be calculated.
|
||||
@ -6999,7 +7059,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
|
||||
err = fabs(graylo-gray);
|
||||
|
||||
/* Check that this worked: */
|
||||
if (err > display->pm->limit)
|
||||
if (err > pm->limit)
|
||||
{
|
||||
size_t pos = 0;
|
||||
char buffer[128];
|
||||
@ -7007,12 +7067,120 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
|
||||
pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error ");
|
||||
pos = safecatd(buffer, sizeof buffer, pos, err, 6);
|
||||
pos = safecat(buffer, sizeof buffer, pos, " exceeds limit ");
|
||||
pos = safecatd(buffer, sizeof buffer, pos,
|
||||
display->pm->limit, 6);
|
||||
pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);
|
||||
png_error(pp, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
# else /* DIGITIZE */
|
||||
{
|
||||
double r = that->redf;
|
||||
double re = that->rede;
|
||||
double g = that->greenf;
|
||||
double ge = that->greene;
|
||||
double b = that->bluef;
|
||||
double be = that->bluee;
|
||||
|
||||
/* The true gray case involves no math. */
|
||||
if (r == g && r == b)
|
||||
{
|
||||
gray = r;
|
||||
err = re;
|
||||
if (err < ge) err = ge;
|
||||
if (err < be) err = be;
|
||||
}
|
||||
|
||||
else if (data.gamma == 1)
|
||||
{
|
||||
/* There is no need to do the conversions to and from linear space,
|
||||
* so the calculation should be a lot more accurate. There is a
|
||||
* built in 1/32768 error in the coefficients because they only have
|
||||
* 15 bits and are adjusted to make sure they add up to 32768, so
|
||||
* the result may have an additional error up to 1/32768. (Note
|
||||
* that adding the 1/32768 here avoids needing to increase the
|
||||
* global error limits to take this into account.)
|
||||
*/
|
||||
gray = r * data.red_coefficient + g * data.green_coefficient +
|
||||
b * data.blue_coefficient;
|
||||
err = re * data.red_coefficient + ge * data.green_coefficient +
|
||||
be * data.blue_coefficient + 1./32768 + gray * 5 * DBL_EPSILON;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* The calculation happens in linear space, and this produces much
|
||||
* wider errors in the encoded space. These are handled here by
|
||||
* factoring the errors in to the calculation. There are two table
|
||||
* lookups in the calculation and each introduces a quantization
|
||||
* error defined by the table size.
|
||||
*/
|
||||
PNG_CONST png_modifier *pm = display->pm;
|
||||
double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255);
|
||||
double out_qe = (that->sample_depth > 8 ? .5/65535 :
|
||||
(pm->assume_16_bit_calculations ? .5/(1<<PNG_MAX_GAMMA_8) :
|
||||
.5/255));
|
||||
double rhi, ghi, bhi, grayhi;
|
||||
double g1 = 1/data.gamma;
|
||||
|
||||
rhi = r + re + in_qe; if (rhi > 1) rhi = 1;
|
||||
r -= re + in_qe; if (r < 0) r = 0;
|
||||
ghi = g + ge + in_qe; if (ghi > 1) ghi = 1;
|
||||
g -= ge + in_qe; if (g < 0) g = 0;
|
||||
bhi = b + be + in_qe; if (bhi > 1) bhi = 1;
|
||||
b -= be + in_qe; if (b < 0) b = 0;
|
||||
|
||||
r = pow(r, g1)*(1-DBL_EPSILON); rhi = pow(rhi, g1)*(1+DBL_EPSILON);
|
||||
g = pow(g, g1)*(1-DBL_EPSILON); ghi = pow(ghi, g1)*(1+DBL_EPSILON);
|
||||
b = pow(b, g1)*(1-DBL_EPSILON); bhi = pow(bhi, g1)*(1+DBL_EPSILON);
|
||||
|
||||
/* Work out the lower and upper bounds for the gray value in the
|
||||
* encoded space, then work out an average and error. Remove the
|
||||
* previously added input quantization error at this point.
|
||||
*/
|
||||
gray = r * data.red_coefficient + g * data.green_coefficient +
|
||||
b * data.blue_coefficient - 1./32768 - out_qe;
|
||||
if (gray <= 0)
|
||||
gray = 0;
|
||||
else
|
||||
{
|
||||
gray *= (1 - 6 * DBL_EPSILON);
|
||||
gray = pow(gray, data.gamma) * (1-DBL_EPSILON);
|
||||
}
|
||||
|
||||
grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient +
|
||||
bhi * data.blue_coefficient + 1./32768 + out_qe;
|
||||
grayhi *= (1 + 6 * DBL_EPSILON);
|
||||
if (grayhi >= 1)
|
||||
grayhi = 1;
|
||||
else
|
||||
grayhi = pow(grayhi, data.gamma) * (1+DBL_EPSILON);
|
||||
|
||||
err = (grayhi - gray) / 2;
|
||||
gray = (grayhi + gray) / 2;
|
||||
|
||||
if (err <= in_qe)
|
||||
err = gray * DBL_EPSILON;
|
||||
|
||||
else
|
||||
err -= in_qe;
|
||||
|
||||
/* Validate that the error is within limits (this has caused
|
||||
* problems before, it's much easier to detect them here.)
|
||||
*/
|
||||
if (err > pm->limit)
|
||||
{
|
||||
size_t pos = 0;
|
||||
char buffer[128];
|
||||
|
||||
pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error ");
|
||||
pos = safecatd(buffer, sizeof buffer, pos, err, 6);
|
||||
pos = safecat(buffer, sizeof buffer, pos, " exceeds limit ");
|
||||
pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);
|
||||
png_error(pp, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif /* !DIGITIZE */
|
||||
|
||||
that->bluef = that->greenf = that->redf = gray;
|
||||
that->bluee = that->greene = that->rede = err;
|
||||
@ -7061,7 +7229,7 @@ IT(rgb_to_gray);
|
||||
* int background_gamma_code, int need_expand,
|
||||
* png_fixed_point background_gamma)
|
||||
*
|
||||
* As with rgb_to_gray this ignores the gamma (at present.)
|
||||
* This ignores the gamma (at present.)
|
||||
*/
|
||||
#define data ITDATA(background)
|
||||
static image_pixel data;
|
||||
@ -7072,6 +7240,7 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this,
|
||||
{
|
||||
png_byte colour_type, bit_depth;
|
||||
png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */
|
||||
int expand;
|
||||
png_color_16 back;
|
||||
|
||||
/* We need a background colour, because we don't know exactly what transforms
|
||||
@ -7089,10 +7258,14 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this,
|
||||
{
|
||||
colour_type = PNG_COLOR_TYPE_RGB;
|
||||
bit_depth = 8;
|
||||
expand = 0; /* passing in an RGB not a pixel index */
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
bit_depth = that->this.bit_depth;
|
||||
expand = 1;
|
||||
}
|
||||
|
||||
image_pixel_init(&data, random_bytes, colour_type,
|
||||
bit_depth, 0/*x*/, 0/*unused: palette*/);
|
||||
@ -7113,11 +7286,9 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this,
|
||||
back.gray = (png_uint_16)data.red;
|
||||
|
||||
# ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1/*need expand*/,
|
||||
0);
|
||||
png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
|
||||
# else
|
||||
png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE,
|
||||
1/*need expand*/, 0);
|
||||
png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
|
||||
# endif
|
||||
|
||||
this->next->set(this->next, that, pp, pi);
|
||||
@ -7449,7 +7620,7 @@ perform_transform_test(png_modifier *pm)
|
||||
png_byte bit_depth = 0;
|
||||
unsigned int palette_number = 0;
|
||||
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number))
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number, 0))
|
||||
{
|
||||
png_uint_32 counter = 0;
|
||||
size_t base_pos;
|
||||
@ -8134,14 +8305,25 @@ gamma_component_validate(PNG_CONST char *name, PNG_CONST validate_info *vi,
|
||||
* passed. Don't do these additional tests here - just log the
|
||||
* original [es_lo..es_hi] values.
|
||||
*/
|
||||
if (pass == 0 && vi->use_input_precision)
|
||||
if (pass == 0 && vi->use_input_precision && vi->dp->sbit)
|
||||
{
|
||||
/* Ok, something is wrong - this actually happens in current libpng
|
||||
* 16-to-8 processing. Assume that the input value (id, adjusted
|
||||
* for sbit) can be anywhere between value-.5 and value+.5 - quite a
|
||||
* large range if sbit is low.
|
||||
*
|
||||
* NOTE: at present because the libpng gamma table stuff has been
|
||||
* changed to use a rounding algorithm to correct errors in 8-bit
|
||||
* calculations the precise sbit calculation (a shift) has been
|
||||
* lost. This can result in up to a +/-1 error in the presence of
|
||||
* an sbit less than the bit depth.
|
||||
*/
|
||||
double tmp = (isbit - .5)/sbit_max;
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# define SBIT_ERROR .5
|
||||
# else
|
||||
# define SBIT_ERROR 1.
|
||||
# endif
|
||||
double tmp = (isbit - SBIT_ERROR)/sbit_max;
|
||||
|
||||
if (tmp <= 0)
|
||||
tmp = 0;
|
||||
@ -8160,10 +8342,10 @@ gamma_component_validate(PNG_CONST char *name, PNG_CONST validate_info *vi,
|
||||
if (is_lo < 0)
|
||||
is_lo = 0;
|
||||
|
||||
tmp = (isbit + .5)/sbit_max;
|
||||
tmp = (isbit + SBIT_ERROR)/sbit_max;
|
||||
|
||||
if (tmp <= 0)
|
||||
tmp = 0;
|
||||
if (tmp >= 1)
|
||||
tmp = 1;
|
||||
|
||||
else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)
|
||||
tmp = pow(tmp, vi->file_inverse);
|
||||
@ -8480,7 +8662,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
|
||||
* Because there is limited precision in the input it is arguable that
|
||||
* an acceptable result is any valid result from input-.5 to input+.5.
|
||||
* The basic tests below do not do this, however if 'use_input_precision'
|
||||
* is set a subsequent test is performed below.
|
||||
* is set a subsequent test is performed above.
|
||||
*/
|
||||
PNG_CONST unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
|
||||
int processing;
|
||||
@ -8822,7 +9004,7 @@ perform_gamma_threshold_tests(png_modifier *pm)
|
||||
* fact this test is somewhat excessive since libpng doesn't make this
|
||||
* decision based on colour type or bit depth!
|
||||
*/
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number))
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
|
||||
if (palette_number == 0)
|
||||
{
|
||||
double test_gamma = 1.0;
|
||||
@ -8883,7 +9065,7 @@ static void perform_gamma_transform_tests(png_modifier *pm)
|
||||
png_byte bit_depth = 0;
|
||||
unsigned int palette_number = 0;
|
||||
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number))
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
@ -8913,7 +9095,7 @@ static void perform_gamma_sbit_tests(png_modifier *pm)
|
||||
png_byte colour_type = 0, bit_depth = 0;
|
||||
unsigned int npalette = 0;
|
||||
|
||||
while (next_format(&colour_type, &bit_depth, &npalette))
|
||||
while (next_format(&colour_type, &bit_depth, &npalette, 1/*gamma*/))
|
||||
if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&
|
||||
((colour_type == 3 && sbit < 8) ||
|
||||
(colour_type != 3 && sbit < bit_depth)))
|
||||
@ -8948,6 +9130,7 @@ static void perform_gamma_scale16_tests(png_modifier *pm)
|
||||
# ifndef PNG_MAX_GAMMA_8
|
||||
# define PNG_MAX_GAMMA_8 11
|
||||
# endif
|
||||
# define SBIT_16_TO_8 PNG_MAX_GAMMA_8
|
||||
/* Include the alpha cases here. Note that sbit matches the internal value
|
||||
* used by the library - otherwise we will get spurious errors from the
|
||||
* internal sbit style approximation.
|
||||
@ -8965,28 +9148,28 @@ static void perform_gamma_scale16_tests(png_modifier *pm)
|
||||
fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD)
|
||||
{
|
||||
gamma_transform_test(pm, 0, 16, 0, pm->interlace_type,
|
||||
1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
|
||||
1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
|
||||
pm->use_input_precision_16to8, 1 /*scale16*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
|
||||
gamma_transform_test(pm, 2, 16, 0, pm->interlace_type,
|
||||
1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
|
||||
1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
|
||||
pm->use_input_precision_16to8, 1 /*scale16*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
|
||||
gamma_transform_test(pm, 4, 16, 0, pm->interlace_type,
|
||||
1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
|
||||
1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
|
||||
pm->use_input_precision_16to8, 1 /*scale16*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
|
||||
gamma_transform_test(pm, 6, 16, 0, pm->interlace_type,
|
||||
1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8,
|
||||
1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
|
||||
pm->use_input_precision_16to8, 1 /*scale16*/);
|
||||
|
||||
if (fail(pm))
|
||||
@ -9132,7 +9315,7 @@ perform_gamma_composition_tests(png_modifier *pm, int do_background,
|
||||
/* Skip the non-alpha cases - there is no setting of a transparency colour at
|
||||
* present.
|
||||
*/
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number))
|
||||
while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
|
||||
if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0)
|
||||
{
|
||||
unsigned int i, j;
|
||||
@ -9154,31 +9337,46 @@ perform_gamma_composition_tests(png_modifier *pm, int do_background,
|
||||
static void
|
||||
init_gamma_errors(png_modifier *pm)
|
||||
{
|
||||
pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
|
||||
pm->error_color_8 = 0;
|
||||
pm->error_indexed = 0;
|
||||
pm->error_gray_16 = pm->error_color_16 = 0;
|
||||
/* Use -1 to catch tests that were not actually run */
|
||||
pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = -1.;
|
||||
pm->error_color_8 = -1.;
|
||||
pm->error_indexed = -1.;
|
||||
pm->error_gray_16 = pm->error_color_16 = -1.;
|
||||
}
|
||||
|
||||
static void
|
||||
summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth)
|
||||
print_one(const char *leader, double err)
|
||||
{
|
||||
if (err != -1.)
|
||||
printf(" %s %.5f\n", leader, err);
|
||||
}
|
||||
|
||||
static void
|
||||
summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth,
|
||||
int indexed)
|
||||
{
|
||||
fflush(stderr);
|
||||
|
||||
if (who)
|
||||
printf("Gamma correction with %s:\n", who);
|
||||
printf("\nGamma correction with %s:\n", who);
|
||||
|
||||
else
|
||||
printf("\nBasic gamma correction:\n");
|
||||
|
||||
if (low_bit_depth)
|
||||
{
|
||||
printf(" 2 bit gray: %.5f\n", pm->error_gray_2);
|
||||
printf(" 4 bit gray: %.5f\n", pm->error_gray_4);
|
||||
printf(" 8 bit gray: %.5f\n", pm->error_gray_8);
|
||||
printf(" 8 bit color: %.5f\n", pm->error_color_8);
|
||||
printf(" indexed: %.5f\n", pm->error_indexed);
|
||||
print_one(" 2 bit gray: ", pm->error_gray_2);
|
||||
print_one(" 4 bit gray: ", pm->error_gray_4);
|
||||
print_one(" 8 bit gray: ", pm->error_gray_8);
|
||||
print_one(" 8 bit color:", pm->error_color_8);
|
||||
if (indexed)
|
||||
print_one(" indexed: ", pm->error_indexed);
|
||||
}
|
||||
|
||||
#ifdef DO_16BIT
|
||||
printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
|
||||
printf(" 16 bit color: %.5f\n", pm->error_color_16);
|
||||
#endif
|
||||
print_one("16 bit gray: ", pm->error_gray_16);
|
||||
print_one("16 bit color:", pm->error_color_16);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -9204,18 +9402,9 @@ perform_gamma_test(png_modifier *pm, int summary)
|
||||
/* Now some real transforms. */
|
||||
if (pm->test_gamma_transform)
|
||||
{
|
||||
init_gamma_errors(pm);
|
||||
/*TODO: remove this. Necessary because the current libpng
|
||||
* implementation works in 8 bits:
|
||||
*/
|
||||
if (pm->test_gamma_expand16)
|
||||
pm->calculations_use_input_precision = 1;
|
||||
perform_gamma_transform_tests(pm);
|
||||
if (!calculations_use_input_precision)
|
||||
pm->calculations_use_input_precision = 0;
|
||||
|
||||
if (summary)
|
||||
{
|
||||
fflush(stderr);
|
||||
printf("Gamma correction error summary\n\n");
|
||||
printf("The printed value is the maximum error in the pixel values\n");
|
||||
printf("calculated by the libpng gamma correction code. The error\n");
|
||||
@ -9227,10 +9416,25 @@ perform_gamma_test(png_modifier *pm, int summary)
|
||||
printf("less than 1 for formats with fewer than 8 bits and a small\n");
|
||||
printf("number (typically less than 5) for the 16 bit formats.\n");
|
||||
printf("For performance reasons the value for 16 bit formats\n");
|
||||
printf("increases when the image file includes an sBIT chunk.\n\n");
|
||||
|
||||
summarize_gamma_errors(pm, 0/*who*/, 1);
|
||||
printf("increases when the image file includes an sBIT chunk.\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
init_gamma_errors(pm);
|
||||
/*TODO: remove this. Necessary because the current libpng
|
||||
* implementation works in 8 bits:
|
||||
*/
|
||||
if (pm->test_gamma_expand16)
|
||||
pm->calculations_use_input_precision = 1;
|
||||
perform_gamma_transform_tests(pm);
|
||||
if (!calculations_use_input_precision)
|
||||
pm->calculations_use_input_precision = 0;
|
||||
|
||||
if (summary)
|
||||
summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
|
||||
/* The sbit tests produce much larger errors: */
|
||||
@ -9240,7 +9444,10 @@ perform_gamma_test(png_modifier *pm, int summary)
|
||||
perform_gamma_sbit_tests(pm);
|
||||
|
||||
if (summary)
|
||||
summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U);
|
||||
summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U, 1/*indexed*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */
|
||||
@ -9252,10 +9459,15 @@ perform_gamma_test(png_modifier *pm, int summary)
|
||||
|
||||
if (summary)
|
||||
{
|
||||
printf("Gamma correction with 16 to 8 bit reduction:\n");
|
||||
fflush(stderr);
|
||||
printf("\nGamma correction with 16 to 8 bit reduction:\n");
|
||||
printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
|
||||
printf(" 16 bit color: %.5f\n", pm->error_color_16);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -9279,7 +9491,10 @@ perform_gamma_test(png_modifier *pm, int summary)
|
||||
pm->maxout8 = maxout8;
|
||||
|
||||
if (summary)
|
||||
summarize_gamma_errors(pm, "background", 1);
|
||||
summarize_gamma_errors(pm, "background", 1, 0/*indexed*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -9304,7 +9519,10 @@ perform_gamma_test(png_modifier *pm, int summary)
|
||||
pm->calculations_use_input_precision = 0;
|
||||
|
||||
if (summary)
|
||||
summarize_gamma_errors(pm, "alpha mode", 1);
|
||||
summarize_gamma_errors(pm, "alpha mode", 1, 0/*indexed*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -9812,6 +10030,19 @@ int main(int argc, char **argv)
|
||||
/* Default to error on warning: */
|
||||
pm.this.treat_warnings_as_errors = 1;
|
||||
|
||||
/* Default assume_16_bit_calculations appropriately; this tells the checking
|
||||
* code that 16-bit arithmetic is used for 8-bit samples when it would make a
|
||||
* difference.
|
||||
*/
|
||||
pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700;
|
||||
|
||||
/* Currently 16 bit expansion happens at the end of the pipeline, so the
|
||||
* calculations are done in the input bit depth not the output.
|
||||
*
|
||||
* TODO: fix this
|
||||
*/
|
||||
pm.calculations_use_input_precision = 1U;
|
||||
|
||||
/* Store the test gammas */
|
||||
pm.gammas = gammas;
|
||||
pm.ngammas = (sizeof gammas) / (sizeof gammas[0]);
|
||||
@ -9822,13 +10053,16 @@ int main(int argc, char **argv)
|
||||
pm.nencodings = (sizeof test_encodings) / (sizeof test_encodings[0]);
|
||||
|
||||
pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
|
||||
|
||||
/* The following allows results to pass if they correspond to anything in the
|
||||
* transformed range [input-.5,input+.5]; this is is required because of the
|
||||
* way libpng treates the 16_TO_8 flag when building the gamma tables.
|
||||
* way libpng treates the 16_TO_8 flag when building the gamma tables in
|
||||
* releases up to 1.6.0.
|
||||
*
|
||||
* TODO: review this
|
||||
*/
|
||||
pm.use_input_precision_16to8 = 1U;
|
||||
pm.use_input_precision_sbit = 1U; /* because libpng now rounds sBIT */
|
||||
|
||||
/* Some default values (set the behavior for 'make check' here).
|
||||
* These values simply control the maximum error permitted in the gamma
|
||||
@ -9839,11 +10073,12 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
pm.maxout8 = .1; /* Arithmetic error in *encoded* value */
|
||||
pm.maxabs8 = .00005; /* 1/20000 */
|
||||
pm.maxcalc8 = .004; /* +/-1 in 8 bits for compose errors */
|
||||
pm.maxcalc8 = 1./255; /* +/-1 in 8 bits for compose errors */
|
||||
pm.maxpc8 = .499; /* I.e., .499% fractional error */
|
||||
pm.maxout16 = .499; /* Error in *encoded* value */
|
||||
pm.maxabs16 = .00005;/* 1/20000 */
|
||||
pm.maxcalc16 =.000015;/* +/-1 in 16 bits for compose errors */
|
||||
pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */
|
||||
pm.maxcalcG = 1./((1<<PNG_MAX_GAMMA_8)-1);
|
||||
|
||||
/* NOTE: this is a reasonable perceptual limit. We assume that humans can
|
||||
* perceive light level differences of 1% over a 100:1 range, so we need to
|
||||
@ -9990,13 +10225,16 @@ int main(int argc, char **argv)
|
||||
pm.interlace_type = PNG_INTERLACE_ADAM7;
|
||||
|
||||
else if (strcmp(*argv, "--use-input-precision") == 0)
|
||||
pm.use_input_precision = 1;
|
||||
pm.use_input_precision = 1U;
|
||||
|
||||
else if (strcmp(*argv, "--use-calculation-precision") == 0)
|
||||
pm.use_input_precision = 0;
|
||||
|
||||
else if (strcmp(*argv, "--calculations-use-input-precision") == 0)
|
||||
pm.calculations_use_input_precision = 1;
|
||||
pm.calculations_use_input_precision = 1U;
|
||||
|
||||
else if (strcmp(*argv, "--assume-16-bit-calculations") == 0)
|
||||
pm.assume_16_bit_calculations = 1;
|
||||
pm.assume_16_bit_calculations = 1U;
|
||||
|
||||
else if (strcmp(*argv, "--calculations-follow-bit-depth") == 0)
|
||||
pm.calculations_use_input_precision =
|
||||
|
Loading…
Reference in New Issue
Block a user