summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/gregbook/Makefile.mingw327
-rw-r--r--contrib/gregbook/Makefile.sgi5
-rw-r--r--contrib/gregbook/Makefile.unx5
-rw-r--r--contrib/gregbook/Makefile.w325
-rw-r--r--contrib/libtests/pngvalid.c601
-rw-r--r--contrib/pngminim/decoder/makefile2
-rw-r--r--contrib/pngminim/encoder/makefile2
-rw-r--r--contrib/pngminim/preader/makefile2
-rw-r--r--contrib/pngminus/makefile.std7
-rw-r--r--contrib/pngminus/makefile.tc38
-rw-r--r--contrib/tools/pngfix.c5
11 files changed, 478 insertions, 171 deletions
diff --git a/contrib/gregbook/Makefile.mingw32 b/contrib/gregbook/Makefile.mingw32
index e70a59aef..3a3ff607e 100644
--- a/contrib/gregbook/Makefile.mingw32
+++ b/contrib/gregbook/Makefile.mingw32
@@ -47,7 +47,8 @@ CC = gcc
#CC = i386-mingw32msvc-gcc # e.g., Linux -> Win32 cross-compilation
LD = $(CC)
RM = rm -f
-CFLAGS = -O -Wall $(INCS) $(MINGW_CCFLAGS)
+CPPFLAGS = $(INCS)
+CFLAGS = -O -Wall $(MINGW_CCFLAGS)
# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
# [-ansi, -pedantic and -W can also be used]
LDFLAGS = $(MINGW_LDFLAGS)
@@ -85,10 +86,10 @@ EXES = $(STATIC_EXES) $(DYNAMIC_EXES)
# implicit make rules -------------------------------------------------------
.c$(O):
- $(CC) -c $(CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
%.pic$(O): %.c
- $(CC) -c $(CFLAGS) -DPNG_BUILD_DLL -o $@ $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) -DPNG_BUILD_DLL -o $@ $<
# dependencies --------------------------------------------------------------
diff --git a/contrib/gregbook/Makefile.sgi b/contrib/gregbook/Makefile.sgi
index 6c3bdf191..94d61b465 100644
--- a/contrib/gregbook/Makefile.sgi
+++ b/contrib/gregbook/Makefile.sgi
@@ -53,7 +53,8 @@ CC = cc
LD = cc
RM = rm -f
# ABI must be the same as that used to build libpng.
-ABI=
+ABI =
+CPPFLAGS =
CFLAGS = $(ABI) -O -fullwarn $(INCS)
LDFLAGS = $(ABI)
O = .o
@@ -73,7 +74,7 @@ EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
# implicit make rules -------------------------------------------------------
.c$(O):
- $(CC) -c $(CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
# dependencies --------------------------------------------------------------
diff --git a/contrib/gregbook/Makefile.unx b/contrib/gregbook/Makefile.unx
index d5e4f355a..c8cadf87b 100644
--- a/contrib/gregbook/Makefile.unx
+++ b/contrib/gregbook/Makefile.unx
@@ -64,7 +64,8 @@ WLIBSs = $(PNGLIBs) $(ZLIBs)
CC = gcc
LD = gcc
RM = rm -f
-CFLAGS = -O -Wall $(INCS) -DFEATURE_LOOP
+CPPFLAGS = $(INCS) -DFEATURE_LOOP
+CFLAGS = -O -Wall
# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
# [-ansi, -pedantic and -W can also be used]
LDFLAGS =
@@ -92,7 +93,7 @@ EXES = $(STATIC_EXES) $(DYNAMIC_EXES)
# implicit make rules -------------------------------------------------------
.c$(O):
- $(CC) -c $(CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
# dependencies --------------------------------------------------------------
diff --git a/contrib/gregbook/Makefile.w32 b/contrib/gregbook/Makefile.w32
index 41cfb231a..ab7dcf7ca 100644
--- a/contrib/gregbook/Makefile.w32
+++ b/contrib/gregbook/Makefile.w32
@@ -53,7 +53,8 @@ WLIBS = $(PNGLIB) $(ZLIB)
CC = cl
LD = link
RM = del
-CFLAGS = -nologo -O -W3 $(INCS) $(cvars)
+CPPFLAGS = $(INCS)
+CFLAGS = -nologo -O -W3 $(cvars)
# [note that -W3 is an MSVC-specific compilation flag ("all warnings on")]
# [see %devstudio%\vc\include\win32.mak for cvars macro definition]
O = .obj
@@ -76,7 +77,7 @@ EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
# implicit make rules -------------------------------------------------------
.c$(O):
- $(CC) -c $(CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
# dependencies --------------------------------------------------------------
diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c
index 4146c8480..7347c1b5d 100644
--- a/contrib/libtests/pngvalid.c
+++ b/contrib/libtests/pngvalid.c
@@ -1,8 +1,8 @@
/* pngvalid.c - validate libpng by constructing then reading png files.
*
- * Last changed in libpng 1.6.8 [December 19, 2013]
- * Copyright (c) 2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.5.18 [February 6, 2014]
+ * Copyright (c) 2014 Glenn Randers-Pehrson
* Written by John Cunningham Bowler
*
* This code is released under the libpng license.
@@ -43,6 +43,21 @@
# include "../../png.h"
#endif
+#ifdef PNG_ZLIB_HEADER
+# include PNG_ZLIB_HEADER
+#else
+# include <zlib.h> /* For crc32 */
+#endif
+
+/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
+ * a skipped test, in earlier versions we need to succeed on a skipped test, so:
+ */
+#if PNG_LIBPNG_VER < 10601
+# define SKIP 0
+#else
+# define SKIP 77
+#endif
+
/* pngvalid requires write support and one of the fixed or floating point APIs.
*/
#if defined(PNG_WRITE_SUPPORTED) &&\
@@ -91,8 +106,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 +365,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 +1892,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 +1932,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 +1950,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 +2006,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 +2021,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 +2036,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 +2053,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 +2062,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 +2078,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 +2111,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 +2144,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 +2177,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 +2202,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;
@@ -3379,10 +3410,28 @@ transform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX],
#define DEPTH(bd) ((png_byte)(1U << (bd)))
/* This is just a helper for compiling on minimal systems with no write
- * interlacing support.
+ * interlacing support. If there is no write interlacing we can't generate test
+ * cases with interlace:
*/
-#ifndef PNG_WRITE_INTERLACING_SUPPORTED
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+# define INTERLACE_LAST PNG_INTERLACE_LAST
+# define check_interlace_type(type) ((void)(type))
+#else
+# define INTERLACE_LAST (PNG_INTERLACE_NONE+1)
# define png_set_interlace_handling(a) (1)
+
+static void
+check_interlace_type(int PNG_CONST interlace_type)
+{
+ if (interlace_type != PNG_INTERLACE_NONE)
+ {
+ /* This is an internal error - --interlace tests should be skipped, not
+ * attempted.
+ */
+ fprintf(stderr, "pngvalid: no interlace support\n");
+ exit(99);
+ }
+}
#endif
/* Make a standardized image given a an image colour type, bit depth and
@@ -3398,6 +3447,8 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
{
context(ps, fault);
+ check_interlace_type(interlace_type);
+
Try
{
png_infop pi;
@@ -3534,16 +3585,12 @@ 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;
-# ifdef PNG_WRITE_INTERLACING_SUPPORTED
- for (interlace_type = PNG_INTERLACE_NONE;
- interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
-# else
- interlace_type = PNG_INTERLACE_NONE;
-# endif
+ for (interlace_type = PNG_INTERLACE_NONE;
+ interlace_type < INTERLACE_LAST; ++interlace_type)
{
char name[FILE_NAME_SIZE];
@@ -3633,6 +3680,12 @@ make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
{
context(ps, fault);
+ /* At present libpng does not support the write of an interlaced image unless
+ * PNG_WRITE_INTERLACING_SUPPORTED, even with do_interlace so the code here
+ * does the pixel interlace itself, so:
+ */
+ check_interlace_type(interlace_type);
+
Try
{
png_infop pi;
@@ -3842,9 +3895,9 @@ make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo,
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
width, height, 0);
-# endif
make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
width, height, 1);
+# endif
}
}
}
@@ -3935,6 +3988,8 @@ make_error(png_store* volatile psIn, png_byte PNG_CONST colour_type,
context(ps, fault);
+ check_interlace_type(interlace_type);
+
Try
{
png_structp pp;
@@ -4037,12 +4092,8 @@ make_errors(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
{
int interlace_type;
-# ifdef PNG_WRITE_INTERLACING_SUPPORTED
- for (interlace_type = PNG_INTERLACE_NONE;
- interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
-# else
- interlace_type = PNG_INTERLACE_NONE;
-# endif
+ for (interlace_type = PNG_INTERLACE_NONE;
+ interlace_type < INTERLACE_LAST; ++interlace_type)
{
unsigned int test;
char name[FILE_NAME_SIZE];
@@ -4240,6 +4291,7 @@ standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT =
dp->bit_depth;
dp->interlace_type = INTERLACE_FROM_ID(id);
+ check_interlace_type(dp->interlace_type);
dp->id = id;
/* All the rest are filled in after the read_info: */
dp->w = 0;
@@ -4849,7 +4901,7 @@ standard_check_text(png_const_structp pp, png_const_textp tp,
static void
standard_text_validate(standard_display *dp, png_const_structp pp,
- png_infop pi)
+ png_infop pi, int check_end)
{
png_textp tp = NULL;
png_uint_32 num_text = png_get_text(pp, pi, &tp, NULL);
@@ -4857,7 +4909,13 @@ standard_text_validate(standard_display *dp, png_const_structp pp,
if (num_text == 2 && tp != NULL)
{
standard_check_text(pp, tp, "image name", dp->ps->current->name);
- standard_check_text(pp, tp+1, "end marker", "end");
+
+ /* This exists because prior to 1.5.18 the progressive reader left the
+ * png_struct z_stream unreset at the end of the image, so subsequent
+ * attempts to use it simply returns Z_STREAM_END.
+ */
+ if (check_end)
+ standard_check_text(pp, tp+1, "end marker", "end");
}
else
@@ -4870,7 +4928,7 @@ standard_text_validate(standard_display *dp, png_const_structp pp,
}
}
#else
-# define standard_text_validate(dp,pp,pi) ((void)0)
+# define standard_text_validate(dp,pp,pi,check_end) ((void)0)
#endif
static void
@@ -4960,7 +5018,8 @@ standard_end(png_structp ppIn, png_infop pi)
/* Validate the image - progressive reading only produces one variant for
* interlaced images.
*/
- standard_text_validate(dp, pp, pi);
+ standard_text_validate(dp, pp, pi,
+ PNG_LIBPNG_VER >= 10518/*check_end: see comments above*/);
standard_image_validate(dp, pp, 0, -1);
}
@@ -5031,7 +5090,7 @@ standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id,
*/
if (!d.speed)
{
- standard_text_validate(&d, pp, pi);
+ standard_text_validate(&d, pp, pi, 1/*check_end*/);
standard_image_validate(&d, pp, 0, 1);
}
else
@@ -5062,7 +5121,7 @@ test_standard(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
int interlace_type;
for (interlace_type = PNG_INTERLACE_NONE;
- interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
+ interlace_type < INTERLACE_LAST; ++interlace_type)
{
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
interlace_type, 0, 0, 0), 0/*do_interlace*/, pm->use_update_info);
@@ -5137,6 +5196,7 @@ test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
if (fail(pm))
return 0;
+# ifdef PNG_WRITE_INTERLACING_SUPPORTED
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
pm->use_update_info);
@@ -5150,6 +5210,7 @@ test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
if (fail(pm))
return 0;
+# endif
/* Now validate the interlaced read side - do_interlace true,
* in the progressive case this does actually make a difference
@@ -5162,12 +5223,14 @@ test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
if (fail(pm))
return 0;
+# ifdef PNG_WRITE_INTERLACING_SUPPORTED
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
pm->use_update_info);
if (fail(pm))
return 0;
+# endif
}
}
@@ -5879,12 +5942,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;
@@ -5895,7 +5955,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;
@@ -6711,10 +6772,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
@@ -6722,8 +6796,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);
}
}
@@ -6732,7 +6821,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;
}
}
@@ -6877,9 +6966,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;
@@ -6895,28 +6989,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
@@ -6925,16 +7019,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
@@ -6951,18 +7045,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;
}
@@ -6973,8 +7067,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.
@@ -6992,7 +7086,115 @@ 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];
+
+ 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);
+ }
+ }
+ }
+# 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];
@@ -7000,12 +7202,12 @@ 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);
}
}
}
+# endif /* !DIGITIZE */
that->bluef = that->greenf = that->redf = gray;
that->bluee = that->greene = that->rede = err;
@@ -7054,7 +7256,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;
@@ -7065,6 +7267,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
@@ -7082,10 +7285,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*/);
@@ -7106,11 +7313,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);
@@ -7442,7 +7647,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;
@@ -8127,14 +8332,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;
@@ -8153,10 +8369,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);
@@ -8473,7 +8689,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;
@@ -8815,7 +9031,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;
@@ -8876,7 +9092,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;
@@ -8906,7 +9122,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)))
@@ -8941,6 +9157,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.
@@ -8958,28 +9175,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))
@@ -9061,6 +9278,28 @@ static void gamma_composition_test(png_modifier *pm,
r = random_32();
background.blue = (png_uint_16)r;
background.gray = (png_uint_16)(r >> 16);
+
+ /* In earlier libpng versions, those where DIGITIZE is set, any background
+ * gamma correction in the expand16 case was done using 8-bit gamma
+ * correction tables, resulting in larger errors. To cope with those
+ * cases use a 16-bit background value which will handle this gamma
+ * correction.
+ */
+# if DIGITIZE
+ if (expand_16 && (do_background == PNG_BACKGROUND_GAMMA_UNIQUE ||
+ do_background == PNG_BACKGROUND_GAMMA_FILE) &&
+ fabs(bg*screen_gamma-1) > PNG_GAMMA_THRESHOLD)
+ {
+ /* The background values will be looked up in an 8-bit table to do
+ * the gamma correction, so only select values which are an exact
+ * match for the 8-bit table entries:
+ */
+ background.red = (png_uint_16)((background.red >> 8) * 257);
+ background.green = (png_uint_16)((background.green >> 8) * 257);
+ background.blue = (png_uint_16)((background.blue >> 8) * 257);
+ background.gray = (png_uint_16)((background.gray >> 8) * 257);
+ }
+# endif
}
else /* 8 bit colors */
@@ -9125,7 +9364,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;
@@ -9147,31 +9386,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
@@ -9197,18 +9451,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");
@@ -9220,10 +9465,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: */
@@ -9233,7 +9493,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 */
@@ -9245,10 +9508,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
@@ -9272,7 +9540,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
@@ -9297,7 +9568,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
}
@@ -9805,6 +10079,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]);
@@ -9815,13 +10102,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
@@ -9832,11 +10122,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
@@ -9980,16 +10271,26 @@ int main(int argc, char **argv)
++pm.use_update_info; /* Can call multiple times */
else if (strcmp(*argv, "--interlace") == 0)
- pm.interlace_type = PNG_INTERLACE_ADAM7;
+ {
+# ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ pm.interlace_type = PNG_INTERLACE_ADAM7;
+# else
+ fprintf(stderr, "pngvalid: no write interlace support\n");
+ return SKIP;
+# endif
+ }
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 =
@@ -10060,10 +10361,12 @@ int main(int argc, char **argv)
else
#endif
+#ifdef PNG_MAXIMUM_INFLATE_WINDOW
if (strncmp(arg, "max-inflate-window:", 19) == 0)
option = PNG_MAXIMUM_INFLATE_WINDOW, arg += 19;
else
+#endif
{
fprintf(stderr, "pngvalid: %s: %s: unknown option\n", *argv, arg);
exit(99);
@@ -10276,6 +10579,6 @@ int main(void)
fprintf(stderr,
"pngvalid: no low level write support in libpng, all tests skipped\n");
/* So the test is skipped: */
- return 77;
+ return SKIP;
}
#endif
diff --git a/contrib/pngminim/decoder/makefile b/contrib/pngminim/decoder/makefile
index 23e8e5b85..4acf3c177 100644
--- a/contrib/pngminim/decoder/makefile
+++ b/contrib/pngminim/decoder/makefile
@@ -82,7 +82,7 @@ OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
# note: dependencies do not work on implicit rule lines
.c$(O):
- $(CC) $(CPPFLAGS) -c $(CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
# dependencies
diff --git a/contrib/pngminim/encoder/makefile b/contrib/pngminim/encoder/makefile
index ce67a9623..41b205c28 100644
--- a/contrib/pngminim/encoder/makefile
+++ b/contrib/pngminim/encoder/makefile
@@ -81,7 +81,7 @@ OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
# implicit make rules -------------------------------------------------------
.c$(O):
- $(CC) $(CPPFLAGS) -c $(CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
# dependencies
diff --git a/contrib/pngminim/preader/makefile b/contrib/pngminim/preader/makefile
index c6855e8ff..b62519911 100644
--- a/contrib/pngminim/preader/makefile
+++ b/contrib/pngminim/preader/makefile
@@ -97,7 +97,7 @@ OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
# implicit make rules -------------------------------------------------------
.c$(O):
- $(CC) $(CPPFLAGS) -c $(CFLAGS) $<
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
# dependencies
diff --git a/contrib/pngminus/makefile.std b/contrib/pngminus/makefile.std
index 30317b77d..14e25cd64 100644
--- a/contrib/pngminus/makefile.std
+++ b/contrib/pngminus/makefile.std
@@ -23,7 +23,8 @@ ZINC = -I../../../zlib
ZLIB = -L../../../zlib -lz
ZLIBS = ../../../zlib/libz.a
-CFLAGS=$(PNGINC) $(ZINC)
+CPPFLAGS=$(PNGINC) $(ZINC)
+CFLAGS=
LDLIBS=$(PNGLIB) $(ZLIB)
LDLIBSS=$(PNGLIBS) $(ZLIBS)
C=.c
@@ -37,7 +38,7 @@ E=
all: png2pnm$(E) pnm2png$(E) png2pnm-static$(E) pnm2png-static$(E)
png2pnm$(O): png2pnm$(C)
- $(CC) -c $(CFLAGS) png2pnm$(C)
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) png2pnm$(C)
png2pnm$(E): png2pnm$(O)
$(LD) $(LDFLAGS) -o png2pnm$(E) png2pnm$(O) $(LDLIBS) -lm
@@ -46,7 +47,7 @@ png2pnm-static$(E): png2pnm$(O)
$(LD) $(LDFLAGS) -o png2pnm-static$(E) png2pnm$(O) $(LDLIBSS) -lm
pnm2png$(O): pnm2png$(C)
- $(CC) -c $(CFLAGS) pnm2png$(C)
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) pnm2png$(C)
pnm2png$(E): pnm2png$(O)
$(LD) $(LDFLAGS) -o pnm2png$(E) pnm2png$(O) $(LDLIBS) -lm
diff --git a/contrib/pngminus/makefile.tc3 b/contrib/pngminus/makefile.tc3
index 404f18d5b..6a2f4b985 100644
--- a/contrib/pngminus/makefile.tc3
+++ b/contrib/pngminus/makefile.tc3
@@ -7,7 +7,8 @@ LB=tlib
RM=del
CP=copy
MODEL=l
-CCFLAGS=-O -m$(MODEL) -I..\libpng -I..\zlib
+CPPFLAGS=-I..\libpng -I..\zlib
+CFLAGS=-O -m$(MODEL)
LDFLAGS=-m$(MODEL) -L..\libpng -L..\zlib
C=.c
O=.obj
@@ -19,13 +20,13 @@ E=.exe
all: png2pnm$(E) pnm2png$(E)
png2pnm$(O): png2pnm$(C)
- $(CC) -c $(CCFLAGS) png2pnm$(C)
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) png2pnm$(C)
png2pnm$(E): png2pnm$(O)
$(LD) $(LDFLAGS) png2pnm$(O) libpng$(L) zlib$(L)
pnm2png$(O): pnm2png$(C)
- $(CC) -c $(CCFLAGS) pnm2png$(C)
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) pnm2png$(C)
pnm2png$(E): pnm2png$(O)
$(LD) $(LDFLAGS) pnm2png$(O) libpng$(L) zlib$(L)
@@ -35,4 +36,3 @@ clean:
$(RM) *$(E)
# End of makefile for png2pnm / pnm2png
-
diff --git a/contrib/tools/pngfix.c b/contrib/tools/pngfix.c
index 245adb6f2..08b23e73b 100644
--- a/contrib/tools/pngfix.c
+++ b/contrib/tools/pngfix.c
@@ -1,8 +1,8 @@
/* pngfix.c
*
- * Copyright (c) 2013 John Cunningham Bowler
+ * Copyright (c) 2014 John Cunningham Bowler
*
- * Last changed in libpng 1.6.8 [December 19, 2013]
+ * Last changed in libpng 1.6.9 [February 6, 2014]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -32,7 +32,6 @@
# define FIX_GCC volatile
#else
# define FIX_GCC
-# error not tested
#endif
#define PROGRAM_NAME "pngfix"