contrib: Apply various fixes to libtests

pngimage.c:
Initialize sig_bits on a NOTREACHED path to avoid warnings about using
uninitialized variables.

pngstest.c:
Enlarge buffers and fix signedness to avoid legitimate warnings about
potential buffer overflows.

pngunknown.c:
pngvalid.c:
Use NULL instead of 0 for pointers and apply other style fixes.

makepng.c:
tarith.c:
Apply various style fixes.

Also remove the "last changed" version info from source comments.
The version control system maintains this information automatically.
This commit is contained in:
Cosmin Truta 2021-03-12 22:54:32 -05:00
parent d6e13b2acd
commit e2bb5e7512
9 changed files with 360 additions and 273 deletions

View File

@ -2,8 +2,6 @@
# #
# Copyright (c) 2013 John Cunningham Bowler # Copyright (c) 2013 John Cunningham Bowler
# #
# Last changed in libpng 1.6.0 [February 14, 2013]
#
# This code is released under the libpng license. # This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer # For conditions of distribution and use, see the disclaimer
# and license in png.h # and license in png.h

View File

@ -3,8 +3,6 @@
/* Copyright: */ /* Copyright: */
#define COPYRIGHT "\251 2013,2015 John Cunningham Bowler" #define COPYRIGHT "\251 2013,2015 John Cunningham Bowler"
/* /*
* Last changed in libpng 1.6.20 [November 24, 2015]
*
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
* and license in png.h * and license in png.h
@ -299,25 +297,28 @@ generate_palette(png_colorp palette, png_bytep trans, int bit_depth,
unsigned int x, y; unsigned int x, y;
volatile unsigned int ip = 0; volatile unsigned int ip = 0;
for (x=0; x<size; ++x) for (y=0; y<size; ++y) for (x=0; x<size; ++x)
{ {
ip = x + (size * y); for (y=0; y<size; ++y)
{
ip = x + (size * y);
/* size is at most 16, so the scaled value below fits in 16 bits /* size is at most 16, so the scaled value below fits in 16 bits
*/ */
# define interp(pos, c1, c2) ((pos * c1) + ((size-pos) * c2)) # define interp(pos, c1, c2) ((pos * c1) + ((size-pos) * c2))
# define xyinterp(x, y, c1, c2, c3, c4) (((size * size / 2) +\ # define xyinterp(x, y, c1, c2, c3, c4) (((size * size / 2) +\
(interp(x, c1, c2) * y + (size-y) * interp(x, c3, c4))) /\ (interp(x, c1, c2) * y + (size-y) * interp(x, c3, c4))) /\
(size*size)) (size*size))
set_color(palette+ip, trans+ip, set_color(palette+ip, trans+ip,
/* color: green, red,blue,white */ /* color: green, red,blue,white */
xyinterp(x, y, 0, 255, 0, 255), xyinterp(x, y, 0, 255, 0, 255),
xyinterp(x, y, 255, 0, 0, 255), xyinterp(x, y, 255, 0, 0, 255),
xyinterp(x, y, 0, 0, 255, 255), xyinterp(x, y, 0, 0, 255, 255),
/* alpha: 0, 102, 204, 255) */ /* alpha: 0, 102, 204, 255) */
xyinterp(x, y, 0, 102, 204, 255), xyinterp(x, y, 0, 102, 204, 255),
gamma_table); gamma_table);
}
} }
return ip+1; return ip+1;
@ -396,7 +397,7 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
image_size_of_type(color_type, bit_depth, colors, small)-1; image_size_of_type(color_type, bit_depth, colors, small)-1;
png_uint_32 depth_max = (1U << bit_depth)-1; /* up to 65536 */ png_uint_32 depth_max = (1U << bit_depth)-1; /* up to 65536 */
if (colors[0] == 0) if (small) if (colors[0] == 0 && small)
{ {
unsigned int pixel_depth = pixel_depth_of_type(color_type, bit_depth); unsigned int pixel_depth = pixel_depth_of_type(color_type, bit_depth);
@ -858,10 +859,13 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth,
{ {
unsigned int i; unsigned int i;
if (real_gamma == 45455) for (i=0; i<256; ++i) if (real_gamma == 45455)
{ {
gamma_table[i] = (png_byte)i; for (i=0; i<256; ++i)
conv = 1.; {
gamma_table[i] = (png_byte)i;
conv = 1.;
}
} }
else else
@ -1430,10 +1434,13 @@ find_parameters(png_const_charp what, png_charp param, png_charp *list,
for (i=0; *param && i<nparams; ++i) for (i=0; *param && i<nparams; ++i)
{ {
list[i] = param; list[i] = param;
while (*++param) if (*param == '\n' || *param == ':') while (*++param)
{ {
*param++ = 0; /* Terminate last parameter */ if (*param == '\n' || *param == ':')
break; /* And start a new one. */ {
*param++ = 0; /* Terminate last parameter */
break; /* And start a new one. */
}
} }
} }

View File

@ -1,9 +1,9 @@
/* pngimage.c /* pngimage.c
* *
* Copyright (c) 2021 Cosmin Truta
* Copyright (c) 2015,2016 John Cunningham Bowler * Copyright (c) 2015,2016 John Cunningham Bowler
* *
* Last changed in libpng 1.6.24 [August 4, 2016]
*
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
* and license in png.h * and license in png.h
@ -12,6 +12,7 @@
* using png_read_png and then write with png_write_png. Test all possible * using png_read_png and then write with png_write_png. Test all possible
* transforms. * transforms.
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -317,11 +318,10 @@ transform_name(int t)
t &= -t; /* first set bit */ t &= -t; /* first set bit */
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL) for (i=0; i<TTABLE_SIZE; ++i)
{ if (transform_info[i].name != NULL)
if ((transform_info[i].transform & t) != 0) if ((transform_info[i].transform & t) != 0)
return transform_info[i].name; return transform_info[i].name;
}
return "invalid transform"; return "invalid transform";
} }
@ -338,13 +338,16 @@ validate_T(void)
{ {
unsigned int i; unsigned int i;
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL) for (i=0; i<TTABLE_SIZE; ++i)
{ {
if (transform_info[i].when & TRANSFORM_R) if (transform_info[i].name != NULL)
read_transforms |= transform_info[i].transform; {
if (transform_info[i].when & TRANSFORM_R)
read_transforms |= transform_info[i].transform;
if (transform_info[i].when & TRANSFORM_W) if (transform_info[i].when & TRANSFORM_W)
write_transforms |= transform_info[i].transform; write_transforms |= transform_info[i].transform;
}
} }
/* Reversible transforms are those which are supported on both read and /* Reversible transforms are those which are supported on both read and
@ -962,21 +965,24 @@ update_display(struct display *dp)
int bd = dp->bit_depth; int bd = dp->bit_depth;
unsigned int i; unsigned int i;
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL) for (i=0; i<TTABLE_SIZE; ++i)
{ {
int transform = transform_info[i].transform; if (transform_info[i].name != NULL)
{
int transform = transform_info[i].transform;
if ((transform_info[i].valid_chunks == 0 || if ((transform_info[i].valid_chunks == 0 ||
(transform_info[i].valid_chunks & chunks) != 0) && (transform_info[i].valid_chunks & chunks) != 0) &&
(transform_info[i].color_mask_required & ct) == (transform_info[i].color_mask_required & ct) ==
transform_info[i].color_mask_required && transform_info[i].color_mask_required &&
(transform_info[i].color_mask_absent & ct) == 0 && (transform_info[i].color_mask_absent & ct) == 0 &&
(transform_info[i].bit_depths & bd) != 0 && (transform_info[i].bit_depths & bd) != 0 &&
(transform_info[i].when & TRANSFORM_R) != 0) (transform_info[i].when & TRANSFORM_R) != 0)
active |= transform; active |= transform;
else if ((transform_info[i].when & TRANSFORM_R) != 0) else if ((transform_info[i].when & TRANSFORM_R) != 0)
inactive |= transform; inactive |= transform;
}
} }
/* Some transforms appear multiple times in the table; the 'active' status /* Some transforms appear multiple times in the table; the 'active' status
@ -1081,8 +1087,9 @@ compare_read(struct display *dp, int applied_transforms)
size_t x; size_t x;
/* Find the first error */ /* Find the first error */
for (x=0; x<rowbytes-1; ++x) if (row[x] != orig[x]) for (x=0; x<rowbytes-1; ++x)
break; if (row[x] != orig[x])
break;
display_log(dp, APP_FAIL, display_log(dp, APP_FAIL,
"byte(%lu,%lu) changed 0x%.2x -> 0x%.2x", "byte(%lu,%lu) changed 0x%.2x -> 0x%.2x",
@ -1137,6 +1144,7 @@ compare_read(struct display *dp, int applied_transforms)
display_log(dp, LIBPNG_ERROR, "invalid colour type %d", display_log(dp, LIBPNG_ERROR, "invalid colour type %d",
color_type); color_type);
/*NOTREACHED*/ /*NOTREACHED*/
memset(sig_bits, 0, sizeof(sig_bits));
bpp = 0; bpp = 0;
break; break;
} }
@ -1198,7 +1206,7 @@ compare_read(struct display *dp, int applied_transforms)
sig_bits[0] = (png_byte)b; sig_bits[0] = (png_byte)b;
break; break;
case 4: /* Relicate twice */ case 4: /* Replicate twice */
/* Value is 1, 2, 3 or 4 */ /* Value is 1, 2, 3 or 4 */
b = 0xf & ((0xf << 4) >> sig_bits[0]); b = 0xf & ((0xf << 4) >> sig_bits[0]);
b |= b << 4; b |= b << 4;
@ -1686,8 +1694,9 @@ main(int argc, char **argv)
printf("%s: pngimage ", pass ? "PASS" : "FAIL"); printf("%s: pngimage ", pass ? "PASS" : "FAIL");
for (j=1; j<option_end; ++j) if (j != ilog) for (j=1; j<option_end; ++j)
printf("%s ", argv[j]); if (j != ilog)
printf("%s ", argv[j]);
printf("%s\n", d.filename); printf("%s\n", d.filename);
} }

View File

@ -1,7 +1,7 @@
/*-
* pngstest.c /* pngstest.c
* *
* Last changed in libpng 1.6.31 [July 27, 2017] * Copyright (c) 2021 Cosmin Truta
* Copyright (c) 2013-2017 John Cunningham Bowler * Copyright (c) 2013-2017 John Cunningham Bowler
* *
* This code is released under the libpng license. * This code is released under the libpng license.
@ -10,8 +10,9 @@
* *
* Test for the PNG 'simplified' APIs. * Test for the PNG 'simplified' APIs.
*/ */
#define _ISOC90_SOURCE 1 #define _ISOC90_SOURCE 1
#define MALLOC_CHECK_ 2/*glibc facility: turn on debugging*/ #define MALLOC_CHECK_ 2 /*glibc facility: turn on debugging*/
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
@ -2701,7 +2702,7 @@ compare_two_images(Image *a, Image *b, int via_linear,
{ {
if ((a->opts & ACCUMULATE) == 0) if ((a->opts & ACCUMULATE) == 0)
{ {
char pindex[9]; char pindex[16];
sprintf(pindex, "%lu[%lu]", (unsigned long)y, sprintf(pindex, "%lu[%lu]", (unsigned long)y,
(unsigned long)a->image.colormap_entries); (unsigned long)a->image.colormap_entries);
logerror(a, a->file_name, ": bad pixel index: ", pindex); logerror(a, a->file_name, ": bad pixel index: ", pindex);
@ -2712,12 +2713,12 @@ compare_two_images(Image *a, Image *b, int via_linear,
else if (y >= b->image.colormap_entries) else if (y >= b->image.colormap_entries)
{ {
if ((b->opts & ACCUMULATE) == 0) if ((b->opts & ACCUMULATE) == 0)
{ {
char pindex[9]; char pindex[16];
sprintf(pindex, "%lu[%lu]", (unsigned long)y, sprintf(pindex, "%lu[%lu]", (unsigned long)y,
(unsigned long)b->image.colormap_entries); (unsigned long)b->image.colormap_entries);
logerror(b, b->file_name, ": bad pixel index: ", pindex); logerror(b, b->file_name, ": bad pixel index: ", pindex);
} }
result = 0; result = 0;
} }
@ -2820,8 +2821,11 @@ compare_two_images(Image *a, Image *b, int via_linear,
bchannels = component_loc(bloc, formatb); bchannels = component_loc(bloc, formatb);
/* Hence the btoa array. */ /* Hence the btoa array. */
for (i=0; i<4; ++i) if (bloc[i] < 4) for (i=0; i<4; ++i)
btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */ {
if (bloc[i] < 4)
btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */
}
if (alpha_added) if (alpha_added)
alpha_added = bloc[0]; /* location of alpha channel in image b */ alpha_added = bloc[0]; /* location of alpha channel in image b */
@ -3209,10 +3213,10 @@ write_one_file(Image *output, Image *image, int convert_to_8bit)
else if (image->opts & USE_FILE) else if (image->opts & USE_FILE)
{ {
#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
static int counter = 0; static unsigned int counter = 0;
char name[32]; char name[32];
sprintf(name, "%s%d.png", tmpf, ++counter); sprintf(name, "%s%u.png", tmpf, ++counter);
if (png_image_write_to_file(&image->image, name, convert_to_8bit, if (png_image_write_to_file(&image->image, name, convert_to_8bit,
image->buffer+16, (png_int_32)image->stride, image->colormap)) image->buffer+16, (png_int_32)image->stride, image->colormap))

View File

@ -1,7 +1,7 @@
/* pngunknown.c - test the read side unknown chunk handling /* pngunknown.c - test the read side unknown chunk handling
* *
* Last changed in libpng 1.6.32 [August 24, 2017] * Copyright (c) 2021 Cosmin Truta
* Copyright (c) 2015,2017 Glenn Randers-Pehrson * Copyright (c) 2015,2017 Glenn Randers-Pehrson
* Written by John Cunningham Bowler * Written by John Cunningham Bowler
* *
@ -370,7 +370,9 @@ find_by_flag(png_uint_32 flag)
{ {
int i = NINFO; int i = NINFO;
while (--i >= 0) if (chunk_info[i].flag == flag) return i; while (--i >= 0)
if (chunk_info[i].flag == flag)
return i;
fprintf(stderr, "pngunknown: internal error\n"); fprintf(stderr, "pngunknown: internal error\n");
exit(4); exit(4);
@ -547,27 +549,30 @@ read_callback(png_structp pp, png_unknown_chunkp pc)
case PNG_HANDLE_CHUNK_AS_DEFAULT: case PNG_HANDLE_CHUNK_AS_DEFAULT:
case PNG_HANDLE_CHUNK_NEVER: case PNG_HANDLE_CHUNK_NEVER:
discard = 1/*handled; discard*/; discard = 1; /*handled; discard*/
break; break;
case PNG_HANDLE_CHUNK_IF_SAFE: case PNG_HANDLE_CHUNK_IF_SAFE:
case PNG_HANDLE_CHUNK_ALWAYS: case PNG_HANDLE_CHUNK_ALWAYS:
discard = 0/*not handled; keep*/; discard = 0; /*not handled; keep*/
break; break;
} }
/* Also store information about this chunk in the display, the relevant flag /* Also store information about this chunk in the display, the relevant flag
* is set if the chunk is to be kept ('not handled'.) * is set if the chunk is to be kept ('not handled'.)
*/ */
if (chunk >= 0) if (!discard) /* stupidity to stop a GCC warning */ if (chunk >= 0)
{ {
png_uint_32 flag = chunk_info[chunk].flag; if (!discard) /* stupidity to stop a GCC warning */
{
png_uint_32 flag = chunk_info[chunk].flag;
if (pc->location & PNG_AFTER_IDAT) if (pc->location & PNG_AFTER_IDAT)
d->after_IDAT |= flag; d->after_IDAT |= flag;
else else
d->before_IDAT |= flag; d->before_IDAT |= flag;
}
} }
/* However if there is no support to store unknown chunks don't ask libpng to /* However if there is no support to store unknown chunks don't ask libpng to
@ -841,8 +846,9 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/,
{ {
png_uint_32 y; png_uint_32 y;
for (y=0; y<height; ++y) if (PNG_ROW_IN_INTERLACE_PASS(y, ipass)) for (y=0; y<height; ++y)
png_read_row(d->png_ptr, NULL, NULL); if (PNG_ROW_IN_INTERLACE_PASS(y, ipass))
png_read_row(d->png_ptr, NULL, NULL);
} }
} }
} /* interlaced */ } /* interlaced */
@ -1091,15 +1097,15 @@ perform_one_test_safe(FILE *fp, int argc, const char **argv,
static const char *standard_tests[] = static const char *standard_tests[] =
{ {
"discard", "default=discard", 0, "discard", "default=discard", NULL,
"save", "default=save", 0, "save", "default=save", NULL,
"if-safe", "default=if-safe", 0, "if-safe", "default=if-safe", NULL,
"vpAg", "vpAg=if-safe", 0, "vpAg", "vpAg=if-safe", NULL,
"sTER", "sTER=if-safe", 0, "sTER", "sTER=if-safe", NULL,
"IDAT", "default=discard", "IDAT=save", 0, "IDAT", "default=discard", "IDAT=save", NULL,
"sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save", "sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save",
"sBIT=save", "sRGB=save", "eXIf=save", 0, "sBIT=save", "sRGB=save", "eXIf=save", NULL,
0/*end*/ NULL /*end*/
}; };
static PNG_NORETURN void static PNG_NORETURN void
@ -1115,7 +1121,7 @@ int
main(int argc, const char **argv) main(int argc, const char **argv)
{ {
FILE *fp; FILE *fp;
png_uint_32 default_flags[4/*valid,unknown{before,after}*/]; png_uint_32 default_flags[4]; /*valid,unknown{before,after}*/
int strict = 0, default_tests = 0; int strict = 0, default_tests = 0;
const char *count_argv = "default=save"; const char *count_argv = "default=save";
const char *touch_file = NULL; const char *touch_file = NULL;
@ -1153,8 +1159,9 @@ main(int argc, const char **argv)
/* GCC BUG: if (default_tests && argc != 1) triggers some weird GCC argc /* GCC BUG: if (default_tests && argc != 1) triggers some weird GCC argc
* optimization which causes warnings with -Wstrict-overflow! * optimization which causes warnings with -Wstrict-overflow!
*/ */
else if (default_tests) if (argc != 1) else if (default_tests)
usage(d.program, "extra arguments"); if (argc != 1)
usage(d.program, "extra arguments");
/* The name of the test file is the last argument; remove it. */ /* The name of the test file is the last argument; remove it. */
d.file = argv[--argc]; d.file = argv[--argc];
@ -1216,7 +1223,11 @@ main(int argc, const char **argv)
const char *result; const char *result;
int arg_count = 0; int arg_count = 0;
while (*next) ++next, ++arg_count; while (*next != NULL)
{
++next;
++arg_count;
}
perform_one_test_safe(fp, arg_count, test, default_flags, &d, perform_one_test_safe(fp, arg_count, test, default_flags, &d,
this_test); this_test);

View File

@ -1,7 +1,7 @@
/* pngvalid.c - validate libpng by constructing then reading png files. /* pngvalid.c - validate libpng by constructing then reading png files.
* *
* Last changed in libpng 1.6.31 [July 27, 2017] * Copyright (c) 2021 Cosmin Truta
* Copyright (c) 2014-2017 John Cunningham Bowler * Copyright (c) 2014-2017 John Cunningham Bowler
* *
* This code is released under the libpng license. * This code is released under the libpng license.
@ -5823,8 +5823,9 @@ test_standard(png_modifier* const pm, png_byte const colour_type,
for (interlace_type = PNG_INTERLACE_NONE; for (interlace_type = PNG_INTERLACE_NONE;
interlace_type < INTERLACE_LAST; ++interlace_type) interlace_type < INTERLACE_LAST; ++interlace_type)
{ {
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info); 0/*palette*/, interlace_type, 0, 0, 0), do_read_interlace,
pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
@ -5877,47 +5878,50 @@ test_size(png_modifier* const pm, png_byte const colour_type,
{ {
png_uint_32 h, w; png_uint_32 h, w;
for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo]) for (h=1; h<=16; h+=hinc[bdlo])
{ {
/* First test all the 'size' images against the sequential for (w=1; w<=16; w+=winc[bdlo])
* reader using libpng to deinterlace (where required.) This {
* validates the write side of libpng. There are four possibilities /* First test all the 'size' images against the sequential
* to validate. * reader using libpng to deinterlace (where required.) This
*/ * validates the write side of libpng. There are four possibilities
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, * to validate.
PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/, */
pm->use_update_info); standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
0/*palette*/, PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,
pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/, 0/*palette*/, PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,
pm->use_update_info); pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
/* Now validate the interlaced read side - do_interlace true, /* Now validate the interlaced read side - do_interlace true,
* in the progressive case this does actually make a difference * in the progressive case this does actually make a difference
* to the code used in the non-interlaced case too. * to the code used in the non-interlaced case too.
*/ */
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/, 0/*palette*/, PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,
pm->use_update_info); pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
# if CAN_WRITE_INTERLACE # if CAN_WRITE_INTERLACE
/* Validate the pngvalid code itself: */ /* Validate the pngvalid code itself: */
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/, 0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/,
pm->use_update_info); pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
# endif # endif
}
} }
} }
@ -5928,45 +5932,48 @@ test_size(png_modifier* const pm, png_byte const colour_type,
{ {
png_uint_32 h, w; png_uint_32 h, w;
for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo]) for (h=1; h<=16; h+=hinc[bdlo])
{ {
# ifdef PNG_READ_INTERLACING_SUPPORTED for (w=1; w<=16; w+=winc[bdlo])
/* Test with pngvalid generated interlaced images first; we have {
* already verify these are ok (unless pngvalid has self-consistent # ifdef PNG_READ_INTERLACING_SUPPORTED
* read/write errors, which is unlikely), so this detects errors in the /* Test with pngvalid generated interlaced images first; we have
* read side first: * already verify these are ok (unless pngvalid has self-consistent
*/ * read/write errors, which is unlikely), so this detects errors in
# if CAN_WRITE_INTERLACE * the read side first:
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, */
PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/, # if CAN_WRITE_INTERLACE
pm->use_update_info); standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,
pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
# endif # endif
# endif /* READ_INTERLACING */ # endif /* READ_INTERLACING */
# ifdef PNG_WRITE_INTERLACING_SUPPORTED # ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* Test the libpng write side against the pngvalid read side: */ /* Test the libpng write side against the pngvalid read side: */
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/, 0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
pm->use_update_info); pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
# endif # endif
# ifdef PNG_READ_INTERLACING_SUPPORTED # ifdef PNG_READ_INTERLACING_SUPPORTED
# ifdef PNG_WRITE_INTERLACING_SUPPORTED # ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* Test both together: */ /* Test both together: */
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/, 0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
pm->use_update_info); pm->use_update_info);
if (fail(pm)) if (fail(pm))
return 0; return 0;
# endif # endif
# endif /* READ_INTERLACING */ # endif /* READ_INTERLACING */
}
} }
} }
@ -10650,16 +10657,21 @@ static void perform_gamma_transform_tests(png_modifier *pm)
{ {
unsigned int i, j; unsigned int i, j;
for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j) for (i=0; i<pm->ngamma_tests; ++i)
if (i != j) {
for (j=0; j<pm->ngamma_tests; ++j)
{ {
gamma_transform_test(pm, colour_type, bit_depth, palette_number, if (i != j)
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/, {
pm->use_input_precision, 0 /*do not scale16*/); gamma_transform_test(pm, colour_type, bit_depth, palette_number,
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
0/*sBIT*/, pm->use_input_precision, 0/*do not scale16*/);
if (fail(pm)) if (fail(pm))
return; return;
}
} }
}
} }
} }
@ -10688,14 +10700,17 @@ static void perform_gamma_sbit_tests(png_modifier *pm)
{ {
unsigned int j; unsigned int j;
for (j=0; j<pm->ngamma_tests; ++j) if (i != j) for (j=0; j<pm->ngamma_tests; ++j)
{ {
gamma_transform_test(pm, colour_type, bit_depth, npalette, if (i != j)
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], {
sbit, pm->use_input_precision_sbit, 0 /*scale16*/); gamma_transform_test(pm, colour_type, bit_depth, npalette,
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
sbit, pm->use_input_precision_sbit, 0 /*scale16*/);
if (fail(pm)) if (fail(pm))
return; return;
}
} }
} }
} }
@ -10947,14 +10962,17 @@ perform_gamma_composition_tests(png_modifier *pm, int do_background,
unsigned int i, j; unsigned int i, j;
/* Don't skip the i==j case here - it's relevant. */ /* Don't skip the i==j case here - it's relevant. */
for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j) for (i=0; i<pm->ngamma_tests; ++i)
{ {
gamma_composition_test(pm, colour_type, bit_depth, palette_number, for (j=0; j<pm->ngamma_tests; ++j)
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], {
pm->use_input_precision, do_background, expand_16); gamma_composition_test(pm, colour_type, bit_depth, palette_number,
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
pm->use_input_precision, do_background, expand_16);
if (fail(pm)) if (fail(pm))
return; return;
}
} }
} }
} }
@ -11057,7 +11075,7 @@ perform_gamma_test(png_modifier *pm, int summary)
pm->calculations_use_input_precision = 0; pm->calculations_use_input_precision = 0;
if (summary) if (summary)
summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/); summarize_gamma_errors(pm, NULL/*who*/, 1/*low bit depth*/, 1/*indexed*/);
if (fail(pm)) if (fail(pm))
return; return;
@ -11183,8 +11201,10 @@ png_pass_start_row(int pass)
{ {
int x, y; int x, y;
++pass; ++pass;
for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) for (y=0; y<8; ++y)
return y; for (x=0; x<8; ++x)
if (adam7[y][x] == pass)
return y;
return 0xf; return 0xf;
} }
@ -11193,8 +11213,10 @@ png_pass_start_col(int pass)
{ {
int x, y; int x, y;
++pass; ++pass;
for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) for (x=0; x<8; ++x)
return x; for (y=0; y<8; ++y)
if (adam7[y][x] == pass)
return x;
return 0xf; return 0xf;
} }
@ -11203,18 +11225,24 @@ png_pass_row_shift(int pass)
{ {
int x, y, base=(-1), inc=8; int x, y, base=(-1), inc=8;
++pass; ++pass;
for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) for (y=0; y<8; ++y)
{ {
if (base == (-1)) for (x=0; x<8; ++x)
base = y; {
else if (base == y) if (adam7[y][x] == pass)
{} {
else if (inc == y-base) if (base == (-1))
base=y; base = y;
else if (inc == 8) else if (base == y)
inc = y-base, base=y; {}
else if (inc != y-base) else if (inc == y-base)
return 0xff; /* error - more than one 'inc' value! */ base=y;
else if (inc == 8)
inc = y-base, base=y;
else if (inc != y-base)
return 0xff; /* error - more than one 'inc' value! */
}
}
} }
if (base == (-1)) return 0xfe; /* error - no row in pass! */ if (base == (-1)) return 0xfe; /* error - no row in pass! */
@ -11237,18 +11265,24 @@ png_pass_col_shift(int pass)
{ {
int x, y, base=(-1), inc=8; int x, y, base=(-1), inc=8;
++pass; ++pass;
for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) for (x=0; x<8; ++x)
{ {
if (base == (-1)) for (y=0; y<8; ++y)
base = x; {
else if (base == x) if (adam7[y][x] == pass)
{} {
else if (inc == x-base) if (base == (-1))
base=x; base = x;
else if (inc == 8) else if (base == x)
inc = x-base, base=x; {}
else if (inc != x-base) else if (inc == x-base)
return 0xff; /* error - more than one 'inc' value! */ base=x;
else if (inc == 8)
inc = x-base, base=x;
else if (inc != x-base)
return 0xff; /* error - more than one 'inc' value! */
}
}
} }
if (base == (-1)) return 0xfe; /* error - no row in pass! */ if (base == (-1)) return 0xfe; /* error - no row in pass! */
@ -11312,8 +11346,9 @@ png_row_in_interlace_pass(png_uint_32 y, int pass)
int x; int x;
y &= 7; y &= 7;
++pass; ++pass;
for (x=0; x<8; ++x) if (adam7[y][x] == pass) for (x=0; x<8; ++x)
return 1; if (adam7[y][x] == pass)
return 1;
return 0; return 0;
} }
@ -11325,8 +11360,9 @@ png_col_in_interlace_pass(png_uint_32 x, int pass)
int y; int y;
x &= 7; x &= 7;
++pass; ++pass;
for (y=0; y<8; ++y) if (adam7[y][x] == pass) for (y=0; y<8; ++y)
return 1; if (adam7[y][x] == pass)
return 1;
return 0; return 0;
} }
@ -11340,11 +11376,17 @@ png_pass_rows(png_uint_32 height, int pass)
height &= 7; height &= 7;
++pass; ++pass;
for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) for (y=0; y<8; ++y)
{ {
rows += tiles; for (x=0; x<8; ++x)
if (y < height) ++rows; {
break; /* i.e. break the 'x', column, loop. */ if (adam7[y][x] == pass)
{
rows += tiles;
if (y < height) ++rows;
break; /* i.e. break the 'x', column, loop. */
}
}
} }
return rows; return rows;
@ -11359,11 +11401,17 @@ png_pass_cols(png_uint_32 width, int pass)
width &= 7; width &= 7;
++pass; ++pass;
for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) for (x=0; x<8; ++x)
{ {
cols += tiles; for (y=0; y<8; ++y)
if (x < width) ++cols; {
break; /* i.e. break the 'y', row, loop. */ if (adam7[y][x] == pass)
{
cols += tiles;
if (x < width) ++cols;
break; /* i.e. break the 'y', row, loop. */
}
}
} }
return cols; return cols;
@ -11811,21 +11859,21 @@ int main(int argc, char **argv)
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
else if (strncmp(*argv, "--transform-disable=", else if (strncmp(*argv, "--transform-disable=",
sizeof "--transform-disable") == 0) sizeof "--transform-disable") == 0)
{ {
pm.test_transform = 1; pm.test_transform = 1;
transform_disable(*argv + sizeof "--transform-disable"); transform_disable(*argv + sizeof "--transform-disable");
} }
else if (strncmp(*argv, "--transform-enable=", else if (strncmp(*argv, "--transform-enable=",
sizeof "--transform-enable") == 0) sizeof "--transform-enable") == 0)
{ {
pm.test_transform = 1; pm.test_transform = 1;
transform_enable(*argv + sizeof "--transform-enable"); transform_enable(*argv + sizeof "--transform-enable");
} }
#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
else if (strcmp(*argv, "--gamma") == 0) else if (strcmp(*argv, "--gamma") == 0)
{ {
/* Just do two gamma tests here (2.2 and linear) for speed: */ /* Just do two gamma tests here (2.2 and linear) for speed: */
pm.ngamma_tests = 2U; pm.ngamma_tests = 2U;
pm.test_gamma_threshold = 1; pm.test_gamma_threshold = 1;
@ -11834,7 +11882,7 @@ int main(int argc, char **argv)
pm.test_gamma_scale16 = 1; pm.test_gamma_scale16 = 1;
pm.test_gamma_background = 1; /* composition */ pm.test_gamma_background = 1; /* composition */
pm.test_gamma_alpha_mode = 1; pm.test_gamma_alpha_mode = 1;
} }
else if (strcmp(*argv, "--nogamma") == 0) else if (strcmp(*argv, "--nogamma") == 0)
pm.ngamma_tests = 0; pm.ngamma_tests = 0;

View File

@ -1,9 +1,8 @@
/* readpng.c /* readpng.c
* *
* Copyright (c) 2013 John Cunningham Bowler * Copyright (c) 2013 John Cunningham Bowler
* *
* Last changed in libpng 1.6.1 [March 28, 2013]
*
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
* and license in png.h * and license in png.h

View File

@ -1,10 +1,9 @@
/* tarith.c /* tarith.c
* *
* Copyright (c) 2021 Cosmin Truta
* Copyright (c) 2011-2013 John Cunningham Bowler * Copyright (c) 2011-2013 John Cunningham Bowler
* *
* Last changed in libpng 1.6.0 [February 14, 2013]
*
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
* and license in png.h * and license in png.h
@ -88,6 +87,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
int minorarith = 0; int minorarith = 0;
while (--argc > 0) while (--argc > 0)
{
if (strcmp(*++argv, "-a") == 0) if (strcmp(*++argv, "-a") == 0)
showall = 1; showall = 1;
else if (strcmp(*argv, "-e") == 0 && argc > 0) else if (strcmp(*argv, "-e") == 0 && argc > 0)
@ -105,6 +105,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
fprintf(stderr, "unknown argument %s\n", *argv); fprintf(stderr, "unknown argument %s\n", *argv);
return 1; return 1;
} }
}
do do
{ {
@ -130,8 +131,8 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
*/ */
if (buffer[precision+7] != 71) if (buffer[precision+7] != 71)
{ {
fprintf(stderr, "%g[%d] -> '%s'[%lu] buffer overflow\n", test, fprintf(stderr, "%g[%d] -> '%s'[%lu] buffer overflow\n",
precision, buffer, (unsigned long)strlen(buffer)); test, precision, buffer, (unsigned long)strlen(buffer));
failed = 1; failed = 1;
} }
@ -146,16 +147,16 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
if (test >= 0 && strcmp(buffer, "inf") || if (test >= 0 && strcmp(buffer, "inf") ||
test < 0 && strcmp(buffer, "-inf")) test < 0 && strcmp(buffer, "-inf"))
{ {
fprintf(stderr, "%g[%d] -> '%s' but expected 'inf'\n", test, fprintf(stderr, "%g[%d] -> '%s' but expected 'inf'\n",
precision, buffer); test, precision, buffer);
failed = 1; failed = 1;
} }
} }
else if (!png_check_fp_number(buffer, precision+10, &state, &index) || else if (!png_check_fp_number(buffer, precision+10, &state, &index) ||
buffer[index] != 0) buffer[index] != 0)
{ {
fprintf(stderr, "%g[%d] -> '%s' but has bad format ('%c')\n", test, fprintf(stderr, "%g[%d] -> '%s' but has bad format ('%c')\n",
precision, buffer, buffer[index]); test, precision, buffer, buffer[index]);
failed = 1; failed = 1;
} }
else if (PNG_FP_IS_NEGATIVE(state) && !(test < 0)) else if (PNG_FP_IS_NEGATIVE(state) && !(test < 0))
@ -187,7 +188,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
/* Check the result against the original. */ /* Check the result against the original. */
double out = atof(buffer); double out = atof(buffer);
double change = fabs((out - test)/test); double change = fabs((out - test)/test);
double allow = .5/pow(10, double allow = .5 / pow(10,
(precision >= DBL_DIG) ? DBL_DIG-1 : precision-1); (precision >= DBL_DIG) ? DBL_DIG-1 : precision-1);
/* NOTE: if you hit this error case are you compiling with gcc /* NOTE: if you hit this error case are you compiling with gcc
@ -257,8 +258,9 @@ skip:
} }
while (--count); while (--count);
printf("Tested %d finite values, %d non-finite, %d OK (%d failed) %d minor " printf("Tested %d finite values, %d non-finite, %d OK (%d failed) "
"arithmetic errors\n", finite, nonfinite, ok, failcount, minorarith); "%d minor arithmetic errors\n",
finite, nonfinite, ok, failcount, minorarith);
printf(" Error with >=%d digit precision %.2f%%\n", DBL_DIG, max_abs); printf(" Error with >=%d digit precision %.2f%%\n", DBL_DIG, max_abs);
printf(" Error with < %d digit precision %.2f%%\n", DBL_DIG, max); printf(" Error with < %d digit precision %.2f%%\n", DBL_DIG, max);
@ -371,8 +373,8 @@ static int check_one_character(checkfp_command *co, checkfp_control c, int ch)
/* This should never fail (it's a serious bug if it does): */ /* This should never fail (it's a serious bug if it does): */
if (index != 0 && index != 1) if (index != 0 && index != 1)
{ {
fprintf(stderr, "%s: read beyond end of string (%lu)\n", co->number, fprintf(stderr, "%s: read beyond end of string (%lu)\n",
(unsigned long)index); co->number, (unsigned long)index);
return 0; return 0;
} }
@ -503,8 +505,8 @@ static int check_one_character(checkfp_command *co, checkfp_control c, int ch)
if (number_is_valid != c.number_was_valid) if (number_is_valid != c.number_was_valid)
{ {
fprintf(stderr, fprintf(stderr,
"%s: character '%c' [0x%.2x] changed number validity\n", co->number, "%s: character '%c' [0x%.2x] changed number validity\n",
ch, ch); co->number, ch, ch);
return 0; return 0;
} }
@ -521,10 +523,13 @@ static int check_all_characters(checkfp_command *co, checkfp_control c)
{ {
int ch; int ch;
if (c.cnumber+4 < sizeof co->number) for (ch=0; ch<256; ++ch) if (c.cnumber+4 < sizeof co->number)
{ {
if (!check_one_character(co, c, ch)) for (ch=0; ch<256; ++ch)
return 0; {
if (!check_one_character(co, c, ch))
return 0;
}
} }
return 1; return 1;
@ -539,10 +544,13 @@ static int check_some_characters(checkfp_command *co, checkfp_control c,
if (c.cnumber+4 < sizeof co->number && c.limit >= 0) if (c.cnumber+4 < sizeof co->number && c.limit >= 0)
{ {
if (c.limit > 0) for (i=0; tests[i]; ++i) if (c.limit > 0)
{ {
if (!check_one_character(co, c, tests[i])) for (i=0; tests[i]; ++i)
return 0; {
if (!check_one_character(co, c, tests[i]))
return 0;
}
} }
/* At the end check all the characters. */ /* At the end check all the characters. */
@ -616,10 +624,10 @@ int validation_muldiv(int count, int argc, char **argv)
png_int_32 times, div; png_int_32 times, div;
while (--argc > 0) while (--argc > 0)
{ {
fprintf(stderr, "unknown argument %s\n", *++argv); fprintf(stderr, "unknown argument %s\n", *++argv);
return 1; return 1;
} }
/* Find out about the random number generator. */ /* Find out about the random number generator. */
randbuffer = RAND_MAX; randbuffer = RAND_MAX;
@ -687,25 +695,25 @@ int validation_muldiv(int count, int argc, char **argv)
ok = 0, ++overflow, fpround = fp/*misleading*/; ok = 0, ++overflow, fpround = fp/*misleading*/;
if (verbose) if (verbose)
fprintf(stderr, "TEST %d * %d / %d -> %lld (%s)\n", a, times, div, fprintf(stderr, "TEST %d * %d / %d -> %lld (%s)\n",
fp, ok ? "ok" : "overflow"); a, times, div, fp, ok ? "ok" : "overflow");
++tested; ++tested;
if (png_muldiv(&result, a, times, div) != ok) if (png_muldiv(&result, a, times, div) != ok)
{ {
++error; ++error;
if (ok) if (ok)
fprintf(stderr, "%d * %d / %d -> overflow (expected %lld)\n", a, fprintf(stderr, "%d * %d / %d -> overflow (expected %lld)\n",
times, div, fp); a, times, div, fp);
else else
fprintf(stderr, "%d * %d / %d -> %d (expected overflow %lld)\n", a, fprintf(stderr, "%d * %d / %d -> %d (expected overflow %lld)\n",
times, div, result, fp); a, times, div, result, fp);
} }
else if (ok && result != fpround) else if (ok && result != fpround)
{ {
++error; ++error;
fprintf(stderr, "%d * %d / %d -> %d not %lld\n", a, times, div, result, fprintf(stderr, "%d * %d / %d -> %d not %lld\n",
fp); a, times, div, result, fp);
} }
else else
++passed; ++passed;
@ -721,8 +729,8 @@ int validation_muldiv(int count, int argc, char **argv)
} }
while (--count > 0); while (--count > 0);
printf("%d tests including %d overflows, %d passed, %d failed (%d 64-bit " printf("%d tests including %d overflows, %d passed, %d failed "
"errors)\n", tested, overflow, passed, error, error64); "(%d 64-bit errors)\n", tested, overflow, passed, error, error64);
return 0; return 0;
} }
@ -821,8 +829,9 @@ int validation_gamma(int argc, char **argv)
{ {
if (error > .68) /* By experiment error is less than .68 */ if (error > .68) /* By experiment error is less than .68 */
{ {
fprintf(stderr, "16-bit log error: %d: got %u, expected %f" fprintf(stderr,
" error: %f\n", i, png_log16bit(i), correct, error); "16-bit log error: %d: got %u, expected %f error: %f\n",
i, png_log16bit(i), correct, error);
} }
} }
} }
@ -841,8 +850,9 @@ int validation_gamma(int argc, char **argv)
maxerr = fabs(error); maxerr = fabs(error);
if (fabs(error) > 1883) /* By experiment. */ if (fabs(error) > 1883) /* By experiment. */
{ {
fprintf(stderr, "32-bit exp error: %d: got %u, expected %f" fprintf(stderr,
" error: %f\n", i, png_exp(i), correct, error); "32-bit exp error: %d: got %u, expected %f error: %f\n",
i, png_exp(i), correct, error);
} }
} }
@ -859,8 +869,9 @@ int validation_gamma(int argc, char **argv)
maxerr = fabs(error); maxerr = fabs(error);
if (fabs(error) > .50002) /* By experiment */ if (fabs(error) > .50002) /* By experiment */
{ {
fprintf(stderr, "8-bit exp error: %d: got %u, expected %f" fprintf(stderr,
" error: %f\n", i, png_exp8bit(i), correct, error); "8-bit exp error: %d: got %u, expected %f error: %f\n",
i, png_exp8bit(i), correct, error);
} }
} }
@ -877,8 +888,9 @@ int validation_gamma(int argc, char **argv)
maxerr = fabs(error); maxerr = fabs(error);
if (fabs(error) > .524) /* By experiment */ if (fabs(error) > .524) /* By experiment */
{ {
fprintf(stderr, "16-bit exp error: %d: got %u, expected %f" fprintf(stderr,
" error: %f\n", i, png_exp16bit(i), correct, error); "16-bit exp error: %d: got %u, expected %f error: %f\n",
i, png_exp16bit(i), correct, error);
} }
} }

View File

@ -1,9 +1,8 @@
/* timepng.c /* timepng.c
* *
* Copyright (c) 2013,2016 John Cunningham Bowler * Copyright (c) 2013,2016 John Cunningham Bowler
* *
* Last changed in libpng 1.6.22 [May 26, 2016]
*
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
* and license in png.h * and license in png.h