[libpng15] Installed more accurate linear to sRGB conversion tables.

The slightly modified tables reduce the number of 16-bit values that
convert to an off-by-one 8-bit value.  The "makesRGB.c" code that was used
to generate the tables is now in a contrib/sRGBtables sub-directory.
This commit is contained in:
John Bowler 2011-11-11 18:14:59 -06:00 committed by Glenn Randers-Pehrson
parent d3feb52955
commit 0a521d3785
4 changed files with 519 additions and 216 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.5.7beta02 - November 8, 2011 Libpng 1.5.7beta02 - November 12, 2011
This is not intended to be a public release. It will be replaced This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version. within a few weeks by a public version or by another test version.
@ -43,7 +43,7 @@ Version 1.5.7beta01 [November 4, 2011]
just the changes that definitely improve speed and remain simple. just the changes that definitely improve speed and remain simple.
The changes also slightly increase the clarity of the code. The changes also slightly increase the clarity of the code.
Version 1.5.7beta02 [November 8, 2011] Version 1.5.7beta02 [November 12, 2011]
Check compression_type parameter in png_get_iCCP and remove spurious Check compression_type parameter in png_get_iCCP and remove spurious
casts. The compression_type parameter is always assigned to, so must casts. The compression_type parameter is always assigned to, so must
be non-NULL. The cast of the profile length potentially truncated the be non-NULL. The cast of the profile length potentially truncated the
@ -60,6 +60,10 @@ Version 1.5.7beta02 [November 8, 2011]
Added versioning to pnglibconf.h comments. Added versioning to pnglibconf.h comments.
Simplified read/write API initial version; basic read/write tested on Simplified read/write API initial version; basic read/write tested on
a variety of images, limited documentation (in the header file.) a variety of images, limited documentation (in the header file.)
Installed more accurate linear to sRGB conversion tables. The slightly
modified tables reduce the number of 16-bit values that
convert to an off-by-one 8-bit value. The "makesRGB.c" code that was used
to generate the tables is now in a contrib/sRGBtables sub-directory.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net: Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
(subscription required; visit (subscription required; visit

View File

@ -3688,7 +3688,7 @@ Version 1.5.7beta01 [November 4, 2011]
just the changes that definitely improve speed and remain simple. just the changes that definitely improve speed and remain simple.
The changes also slightly increase the clarity of the code. The changes also slightly increase the clarity of the code.
Version 1.5.7beta02 [November 8, 2011] Version 1.5.7beta02 [November 12, 2011]
Check compression_type parameter in png_get_iCCP and remove spurious Check compression_type parameter in png_get_iCCP and remove spurious
casts. The compression_type parameter is always assigned to, so must casts. The compression_type parameter is always assigned to, so must
be non-NULL. The cast of the profile length potentially truncated the be non-NULL. The cast of the profile length potentially truncated the
@ -3705,6 +3705,10 @@ Version 1.5.7beta02 [November 8, 2011]
Added versioning to pnglibconf.h comments. Added versioning to pnglibconf.h comments.
Simplified read/write API initial version; basic read/write tested on Simplified read/write API initial version; basic read/write tested on
a variety of images, limited documentation (in the header file.) a variety of images, limited documentation (in the header file.)
Installed more accurate linear to sRGB conversion tables. The slightly
modified tables reduce the number of 16-bit values that
convert to an off-by-one 8-bit value. The "makesRGB.c" code that was used
to generate the tables is now in a contrib/sRGBtables sub-directory.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -0,0 +1,451 @@
/*-
* makesRGB.c
*
* Make a table to convert 8-bit sRGB encoding values into the closest 16-bit
* linear value.
*
* Make two tables to take a linear value scaled to 255*65535 and return an
* approximation to the 8-bit sRGB encoded value. Calculate the error in these
* tables and display it.
*/
#define _C99_SOURCE 1
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/* pngpriv.h includes the definition of 'PNG_sRGB_FROM_LINEAR' which is required
* to verify the actual code.
*/
#include "../pngpriv.h"
/*
* Utility sRGB calculation functions.
*
* Both routines take and return a floating point value in the range 0 to 1.0,
* doing a calculation according to the sRGB specification. (In fact the source
* of the numbers is the wikipedia article.)
*/
double
sRGB_from_linear(double l)
{
if (l <= 0.0031308)
l *= 12.92;
else
l = 1.055 * pow(l, 1/2.4) - 0.055;
return l;
}
double
linear_from_sRGB(double s)
{
if (s <= 0.04045)
return s / 12.92;
else
return pow((s+0.055)/1.055, 2.4);
}
/* The tables are declared 'const' in pngpriv.h, so this redefines the tables to
* be used.
*/
#define png_sRGB_table sRGB_table
#define png_sRGB_base sRGB_base
#define png_sRGB_delta sRGB_delta
static png_uint_16 png_sRGB_table[256];
static png_uint_16 png_sRGB_base[512];
static png_byte png_sRGB_delta[512];
static const unsigned int max_input = 255*65535;
double
fsRGB(double l)
{
return sRGB_from_linear(l/max_input);
}
double
sRGB(unsigned int i)
{
return fsRGB(i);
}
double
finvsRGB(unsigned int i)
{
return 65535 * linear_from_sRGB(i/255.);
}
png_uint_16
invsRGB(unsigned int i)
{
unsigned int x = nearbyint(finvsRGB(i));
if (x > 65535)
{
fprintf(stderr, "invsRGB(%u) overflows to %u\n", i, x);
exit(1);
}
return (png_uint_16)x;
}
int
main(int argc, char **argv)
{
unsigned int i, i16, ibase;
double min_error = 0;
double max_error = 0;
double min_error16 = 0;
double max_error16 = 0;
double adjust;
double adjust_lo = 0.4, adjust_hi = 0.6, adjust_mid = 0.5;
unsigned int ec_lo = 0, ec_hi = 0, ec_mid = 0;
unsigned int error_count = 0;
unsigned int error_count16 = 0;
int test_only = 0;
if (argc > 1)
test_only = strcmp("--test", argv[1]) == 0;
/* Initialize the encoding table first. */
for (i=0; i<256; ++i)
{
png_sRGB_table[i] = invsRGB(i);
}
/* Now work out the decoding tables (this is where the error comes in because
* there are 512 set points and 512 straight lines between them.)
*/
for (;;)
{
if (ec_lo == 0)
adjust = adjust_lo;
else if (ec_hi == 0)
adjust = adjust_hi;
else if (ec_mid == 0)
adjust = adjust_mid;
else if (ec_mid < ec_hi)
adjust = (adjust_mid + adjust_hi)/2;
else if (ec_mid < ec_lo)
adjust = (adjust_mid + adjust_lo)/2;
else
{
fprintf(stderr, "not reached: %u .. %u .. %u\n", ec_lo, ec_mid, ec_hi);
exit(1);
}
/* Calculate the table using the current 'adjust' */
for (i=0; i<=511; ++i)
{
double lo = 255 * sRGB(i << 15);
double hi = 255 * sRGB((i+1) << 15);
unsigned int calc;
calc = nearbyint((lo+adjust) * 256);
if (calc > 65535)
{
fprintf(stderr, "table[%d][0]: overflow %08x (%d)\n", i, calc,
calc);
exit(1);
}
png_sRGB_base[i] = calc;
calc = nearbyint((hi-lo) * 32);
if (calc > 255)
{
fprintf(stderr, "table[%d][1]: overflow %08x (%d)\n", i, calc,
calc);
exit(1);
}
png_sRGB_delta[i] = calc;
}
/* Check the 16-bit linear values alone: */
error_count16 = 0;
for (i16=0; i16 <= 65535; ++i16)
{
unsigned int i = 255*i16;
unsigned int iexact = nearbyint(255*sRGB(i));
unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
if (icalc != iexact)
++error_count16;
}
/* Now try changing the adjustment. */
if (ec_lo == 0)
ec_lo = error_count16;
else if (ec_hi == 0)
ec_hi = error_count16;
else if (ec_mid == 0)
{
ec_mid = error_count16;
printf("/* initial error counts: %u .. %u .. %u */\n", ec_lo, ec_mid,
ec_hi);
}
else if (error_count16 < ec_mid)
{
printf("/* adjust (mid ): %f: %u -> %u */\n", adjust, ec_mid,
error_count16);
ec_mid = error_count16;
adjust_mid = adjust;
}
else if (adjust < adjust_mid && error_count16 < ec_lo)
{
printf("/* adjust (low ): %f: %u -> %u */\n", adjust, ec_lo,
error_count16);
ec_lo = error_count16;
adjust_lo = adjust;
}
else if (adjust > adjust_mid && error_count16 < ec_hi)
{
printf("/* adjust (high): %f: %u -> %u */\n", adjust, ec_hi,
error_count16);
ec_hi = error_count16;
adjust_hi = adjust;
}
else
{
adjust = adjust_mid;
printf("/* adjust: %f: %u */\n", adjust, ec_mid);
break;
}
}
/* For each entry in the table try to adjust it to minimize the error count
* in that entry. Each entry corresponds to 128 input values.
*/
for (ibase=0; ibase<65536; ibase+=128)
{
png_uint_16 base = png_sRGB_base[ibase >> 7], trybase = base, ob=base;
png_byte delta = png_sRGB_delta[ibase >> 7], trydelta = delta, od=delta;
unsigned int ecbase = 0, eco;
for (;;)
{
png_sRGB_base[ibase >> 7] = trybase;
png_sRGB_delta[ibase >> 7] = trydelta;
/* Check the 16-bit linear values alone: */
error_count16 = 0;
for (i16=ibase; i16 < ibase+128; ++i16)
{
unsigned int i = 255*i16;
unsigned int iexact = nearbyint(255*sRGB(i));
unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
if (icalc != iexact)
++error_count16;
}
if (error_count16 == 0)
break;
if (ecbase == 0)
{
eco = ecbase = error_count16;
++trybase; /* First test */
}
else if (error_count16 < ecbase)
{
if (trybase > base)
{
base = trybase;
++trybase;
}
else if (trybase < base)
{
base = trybase;
--trybase;
}
else if (trydelta > delta)
{
delta = trydelta;
++trydelta;
}
else if (trydelta < delta)
{
delta = trydelta;
--trydelta;
}
else
{
fprintf(stderr, "makesRGB: impossible\n");
exit(1);
}
ecbase = error_count16;
}
else
{
if (trybase > base)
trybase = base-1;
else if (trybase < base)
{
trybase = base;
++trydelta;
}
else if (trydelta > delta)
trydelta = delta-1;
else if (trydelta < delta)
break; /* end of tests */
}
}
png_sRGB_base[ibase >> 7] = base;
png_sRGB_delta[ibase >> 7] = delta;
if (base != ob || delta != od)
{
printf("/* table[%u]={%u,%u} -> {%u,%u} %u -> %u errors */\n",
ibase>>7, ob, od, base, delta, eco, ecbase);
}
else if (0)
printf("/* table[%u]={%u,%u} %u errors */\n", ibase>>7, ob, od,
ecbase);
}
/* Only do the full (slow) test at the end: */
min_error = -.4999;
max_error = .4999;
error_count = 0;
for (i=0; i <= max_input; ++i)
{
unsigned int iexact = nearbyint(255*sRGB(i));
unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
if (icalc != iexact)
{
double err = 255*sRGB(i) - icalc;
if (err > (max_error+.001) || err < (min_error-.001))
{
printf(
"/* 0x%08x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\n",
i, iexact, icalc, png_sRGB_base[i>>15],
png_sRGB_delta[i>>15], err);
}
++error_count;
if (err > max_error)
max_error = err;
else if (err < min_error)
min_error = err;
}
}
/* Re-check the 16-bit cases too, including the warning if there is an error
* bigger than 1.
*/
error_count16 = 0;
max_error16 = 0;
min_error16 = 0;
for (i16=0; i16 <= 65535; ++i16)
{
unsigned int i = 255*i16;
unsigned int iexact = nearbyint(255*sRGB(i));
unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
if (icalc != iexact)
{
double err = 255*sRGB(i) - icalc;
++error_count16;
if (err > max_error16)
max_error16 = err;
else if (err < min_error16)
min_error16 = err;
if (abs(icalc - iexact) > 1)
printf(
"/* 0x%04x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\n",
i16, iexact, icalc, png_sRGB_base[i>>15],
png_sRGB_delta[i>>15], err);
}
}
/* Check the round trip for each 8-bit sRGB value. */
for (i16=0; i16 <= 255; ++i16)
{
unsigned int i = 255 * png_sRGB_table[i16];
unsigned int iexact = nearbyint(255*sRGB(i));
unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
if (i16 != iexact)
{
fprintf(stderr, "8-bit rounding error: %d -> %d\n", i16, iexact);
exit(1);
}
if (icalc != i16)
{
double finv = finvsRGB(i16);
printf("/* 8-bit roundtrip error: %d -> %f -> %d(%f) */\n",
i16, finv, icalc, fsRGB(255*finv));
}
}
printf("/* error: %g - %g, %u (%g%%) of readings inexact */\n",
min_error, max_error, error_count, (100.*error_count)/max_input);
printf("/* 16-bit error: %g - %g, %u (%g%%) of readings inexact */\n",
min_error16, max_error16, error_count16, (100.*error_count16)/65535);
if (!test_only)
{
printf("PNG_CONST png_uint_16 png_sRGB_table[256] =\n{\n ");
for (i=0; i<255; )
{
do
{
printf("%d,", png_sRGB_table[i++]);
}
while ((i & 0x7) != 0 && i<255);
if (i<255) printf("\n ");
}
printf("%d\n};\n\n", png_sRGB_table[i]);
printf("PNG_CONST png_uint_16 png_sRGB_base[512] =\n{\n ");
for (i=0; i<511; )
{
do
{
printf("%d,", png_sRGB_base[i++]);
}
while ((i & 0x7) != 0 && i<511);
if (i<511) printf("\n ");
}
printf("%d\n};\n\n", png_sRGB_base[i]);
printf("PNG_CONST png_byte png_sRGB_delta[512] =\n{\n ");
for (i=0; i<511; )
{
do
{
printf("%d,", png_sRGB_delta[i++]);
}
while ((i & 0xf) != 0 && i<511);
if (i<511) printf("\n ");
}
printf("%d\n};\n\n", png_sRGB_delta[i]);
}
return 0;
}

270
png.c
View File

@ -645,13 +645,13 @@ png_get_copyright(png_const_structp png_ptr)
#else #else
# ifdef __STDC__ # ifdef __STDC__
return PNG_STRING_NEWLINE \ return PNG_STRING_NEWLINE \
"libpng version 1.5.7beta02 - November 10, 2011" PNG_STRING_NEWLINE \ "libpng version 1.5.7beta02 - November 12, 2011" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE; PNG_STRING_NEWLINE;
# else # else
return "libpng version 1.5.7beta02 - November 10, 2011\ return "libpng version 1.5.7beta02 - November 12, 2011\
Copyright (c) 1998-2011 Glenn Randers-Pehrson\ Copyright (c) 1998-2011 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@ -2858,173 +2858,21 @@ png_build_gamma_table(png_structp png_ptr, int bit_depth)
/* sRGB support */ /* sRGB support */
#if defined PNG_SIMPLIFIED_READ_SUPPORTED ||\ #if defined PNG_SIMPLIFIED_READ_SUPPORTED ||\
defined PNG_SIMPLIFIED_WRITE_SUPPORTED defined PNG_SIMPLIFIED_WRITE_SUPPORTED
/* sRGB conversion tables; these are machine generated with the following code. /* sRGB conversion tables; these are machine generated with the code in
* contrib/sRGBtables/makesRGB.c. The sRGB to linear table is exact (to the
* nearest 16 bit linear fraction). The inverse (linear to sRGB) table has
* accuracies as follows:
*
* For all possible (255*65535+1) input values:
*
* error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
*
* For the input values corresponding to the 65536 16-bit values:
*
* error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
*
* In all cases the inexact readings are off by one.
*/ */
#ifdef PNG_INCLUDE_SELF_GENERATING_AND_SELF_DOCUMENTING_CODE
#define _C99_SOURCE 1
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
static unsigned int max_input = 255*65535;
double sRGB(unsigned int i)
{
double l = i;
l /= max_input;
if (l <= 0.0031308)
l *= 12.92;
else
l = 1.055 * pow(l, 1/2.4) - 0.055;
return l;
}
unsigned int invsRGB(unsigned int i)
{
double l = i/255.;
if (l <= 0.04045)
l /= 12.92;
else
l = pow((l+0.055)/1.055, 2.4);
l *= 65535;
return nearbyint(l);
}
int main(void)
{
unsigned int i, i16;
unsigned short base[512];
unsigned char delta[512];
double max_error = 0;
double max_error16 = 0;
unsigned int error_count = 0;
unsigned int error_count16 = 0;
for (i=0; i<=511; ++i)
{
double lo = 255 * sRGB(i << 15);
double hi = 255 * sRGB((i+1) << 15);
unsigned int calc;
calc = nearbyint((lo+.5) * 256);
if (calc > 65535)
{
fprintf(stderr, "table[%d][0]: overflow %08x (%d)\n", i, calc, calc);
exit(1);
}
base[i] = calc;
calc = nearbyint((hi-lo) * 32);
if (calc > 255)
{
fprintf(stderr, "table[%d][1]: overflow %08x (%d)\n", i, calc, calc);
exit(1);
}
delta[i] = calc;
}
for (i=0; i <= max_input; ++i)
{
unsigned int iexact = nearbyint(255*sRGB(i));
unsigned int icalc = base[i>>15] + (((i&0x7fff)*delta[i>>15])>>12);
icalc >>= 8;
if (icalc != iexact)
{
double err = fabs(255*sRGB(i) - icalc);
++error_count;
if (err > .646)
{
printf(
"/* 0x%08x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\n",
i, iexact, icalc, base[i>>15], delta[i>>15], err);
if (err > max_error)
max_error = err;
}
}
}
for (i16=0; i16 <= 65535; ++i16)
{
unsigned int i = 255*i16;
unsigned int iexact = nearbyint(255*sRGB(i));
unsigned int icalc = base[i>>15] + (((i&0x7fff)*delta[i>>15])>>12);
icalc >>= 8;
if (icalc != iexact)
{
double err = fabs(255*sRGB(i) - icalc);
++error_count16;
if (err > max_error16)
max_error16 = err;
if (abs(icalc - iexact) > 1)
printf(
"/* 0x%04x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\n",
i16, iexact, icalc, base[i>>15], delta[i>>15], err);
}
}
printf("/* maximum error: %g, %g%% of readings */\n", max_error,
(100.*error_count)/max_input);
printf("/* maximum 16-bit error: %g, %g%% of readings */\n", max_error16,
(100.*error_count16)/65535);
printf("PNG_CONST png_uint_16 png_sRGB_table[256] =\n{\n ");
for (i=0; i<255; )
{
do
{
printf("%d,", invsRGB(i++));
}
while ((i & 0x7) != 0 && i<255);
if (i<255) printf("\n ");
}
printf("%d\n};\n\n", invsRGB(i));
printf("PNG_CONST png_uint_16 png_sRGB_base[512] =\n{\n ");
for (i=0; i<511; )
{
do
{
printf("%d,", base[i++]);
}
while ((i & 0x7) != 0 && i<511);
if (i<511) printf("\n ");
}
printf("%d\n};\n\n", base[i]);
printf("PNG_CONST png_byte png_sRGB_delta[512] =\n{\n ");
for (i=0; i<511; )
{
do
{
printf("%d,", delta[i++]);
}
while ((i & 0xf) != 0 && i<511);
if (i<511) printf("\n ");
}
printf("%d\n};\n\n", delta[i]);
return 0;
}
#endif /* self documenting code */
/* The result is a set of tables with the following errors: */
/* 0x000148c1: exact: 16, got: 15 [tables: 00000d36, 0000009d] (0.646071) */
/* 0x000148c2: exact: 16, got: 15 [tables: 00000d36, 0000009d] (0.646218) */
/* 0x000148c3: exact: 16, got: 15 [tables: 00000d36, 0000009d] (0.646365) */
/* maximum error: 0.646365, 0.494416% of readings */
/* maximum 16-bit error: 0.644455, 0.5066% of readings */
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED #ifdef PNG_SIMPLIFIED_READ_SUPPORTED
/* The convert-to-sRGB table is only currently required for read. */ /* The convert-to-sRGB table is only currently required for read. */
@ -3063,6 +2911,7 @@ PNG_CONST png_uint_16 png_sRGB_table[256] =
57105,57646,58190,58737,59287,59840,60396,60955, 57105,57646,58190,58737,59287,59840,60396,60955,
61517,62082,62650,63221,63795,64372,64952,65535 61517,62082,62650,63221,63795,64372,64952,65535
}; };
#endif /* simplified read only */ #endif /* simplified read only */
/* The base/delta tables are required for both read and write (but currently /* The base/delta tables are required for both read and write (but currently
@ -3070,52 +2919,52 @@ PNG_CONST png_uint_16 png_sRGB_table[256] =
*/ */
PNG_CONST png_uint_16 png_sRGB_base[512] = PNG_CONST png_uint_16 png_sRGB_base[512] =
{ {
128,1782,3382,4641,5673,6563,7355,8072, 128,1782,3383,4644,5675,6564,7357,8074,
8732,9346,9920,10463,10977,11466,11935,12384, 8732,9346,9921,10463,10977,11466,11935,12384,
12815,13232,13634,14024,14402,14768,15125,15473, 12816,13233,13634,14024,14402,14769,15125,15473,
15811,16142,16465,16781,17090,17393,17689,17980, 15812,16142,16466,16781,17090,17393,17690,17981,
18266,18546,18822,19093,19359,19621,19879,20133, 18266,18546,18822,19093,19359,19621,19879,20133,
20383,20630,20873,21113,21349,21583,21813,22040, 20383,20630,20873,21113,21349,21583,21813,22041,
22265,22487,22706,22923,23138,23350,23559,23767, 22265,22487,22707,22923,23138,23350,23559,23767,
23972,24175,24376,24575,24772,24967,25160,25352, 23972,24175,24376,24575,24772,24967,25160,25352,
25541,25729,25916,26100,26283,26465,26645,26823, 25542,25730,25916,26101,26284,26465,26645,26823,
27000,27176,27350,27523,27694,27865,28033,28201, 27000,27176,27350,27523,27695,27865,28034,28201,
28368,28533,28697,28860,29021,29182,29341,29500, 28368,28533,28697,28860,29021,29182,29341,29500,
29657,29813,29969,30123,30276,30428,30580,30730, 29657,29813,29969,30123,30276,30429,30580,30730,
30880,31028,31176,31323,31469,31614,31758,31902, 30880,31028,31176,31323,31469,31614,31758,31902,
32044,32186,32327,32468,32607,32746,32884,33021, 32045,32186,32327,32468,32607,32746,32884,33021,
33158,33294,33429,33563,33697,33830,33963,34095, 33158,33294,33429,33564,33697,33831,33963,34095,
34226,34356,34486,34616,34744,34872,35000,35127, 34226,34357,34486,34616,34744,34873,35000,35127,
35253,35379,35504,35629,35753,35876,35999,36122, 35253,35379,35504,35629,35753,35876,35999,36122,
36244,36365,36486,36606,36726,36845,36964,37083, 36244,36365,36486,36606,36726,36845,36964,37083,
37201,37318,37435,37551,37667,37783,37898,38013, 37201,37318,37435,37551,37668,37783,37898,38013,
38127,38241,38354,38467,38580,38692,38803,38915, 38127,38241,38354,38467,38580,38692,38803,38915,
39025,39136,39246,39356,39465,39574,39682,39790, 39026,39136,39246,39356,39465,39574,39682,39790,
39898,40005,40112,40219,40325,40431,40537,40642, 39898,40005,40112,40219,40325,40431,40537,40642,
40747,40851,40955,41059,41163,41266,41369,41471, 40747,40851,40955,41059,41163,41266,41369,41471,
41573,41675,41776,41878,41978,42079,42179,42279, 41573,41675,41777,41878,41979,42079,42179,42279,
42379,42478,42577,42676,42774,42873,42970,43068, 42379,42478,42577,42676,42775,42873,42971,43068,
43165,43262,43359,43455,43552,43647,43743,43838, 43165,43262,43359,43456,43552,43648,43743,43839,
43934,44028,44123,44217,44311,44405,44498,44592, 43934,44028,44123,44217,44311,44405,44499,44592,
44685,44777,44870,44962,45054,45146,45238,45329, 44685,44778,44870,44962,45054,45146,45238,45329,
45420,45511,45601,45692,45782,45872,45961,46051, 45420,45511,45601,45692,45782,45872,45961,46051,
46140,46229,46318,46406,46494,46582,46670,46758, 46140,46229,46318,46406,46494,46583,46670,46758,
46845,46933,47020,47107,47193,47280,47366,47452, 46846,46933,47020,47107,47193,47280,47366,47452,
47538,47623,47708,47794,47879,47963,48048,48132, 47538,47623,47709,47794,47879,47964,48048,48133,
48217,48301,48384,48468,48552,48635,48718,48801, 48217,48301,48385,48468,48552,48635,48718,48801,
48884,48966,49048,49131,49213,49294,49376,49457, 48884,48966,49048,49131,49213,49294,49376,49458,
49539,49620,49701,49781,49862,49942,50023,50103, 49539,49620,49701,49782,49862,49943,50023,50103,
50183,50262,50342,50421,50501,50580,50659,50738, 50183,50263,50342,50422,50501,50580,50659,50738,
50816,50895,50973,51051,51129,51207,51284,51362, 50816,50895,50973,51051,51129,51207,51285,51362,
51439,51517,51594,51670,51747,51824,51900,51977, 51439,51517,51594,51671,51747,51824,51900,51977,
52053,52129,52205,52280,52356,52431,52507,52582, 52053,52129,52205,52280,52356,52432,52507,52582,
52657,52732,52807,52881,52956,53030,53104,53178, 52657,52732,52807,52881,52956,53030,53104,53178,
53252,53326,53399,53473,53546,53620,53693,53766, 53252,53326,53400,53473,53546,53620,53693,53766,
53839,53911,53984,54056,54129,54201,54273,54345, 53839,53911,53984,54056,54129,54201,54273,54345,
54417,54489,54560,54632,54703,54774,54845,54916, 54417,54489,54560,54632,54703,54774,54845,54916,
54987,55058,55128,55199,55269,55340,55410,55480, 54987,55058,55129,55199,55269,55340,55410,55480,
55550,55619,55689,55759,55828,55897,55967,56036, 55550,55620,55689,55759,55828,55898,55967,56036,
56105,56174,56242,56311,56380,56448,56516,56585, 56105,56174,56243,56311,56380,56448,56517,56585,
56653,56721,56789,56857,56924,56992,57059,57127, 56653,56721,56789,56857,56924,56992,57059,57127,
57194,57261,57328,57395,57462,57529,57595,57662, 57194,57261,57328,57395,57462,57529,57595,57662,
57728,57795,57861,57927,57993,58059,58125,58191, 57728,57795,57861,57927,57993,58059,58125,58191,
@ -3126,22 +2975,22 @@ PNG_CONST png_uint_16 png_sRGB_base[512] =
60308,60370,60433,60495,60558,60620,60682,60744, 60308,60370,60433,60495,60558,60620,60682,60744,
60806,60868,60930,60992,61054,61115,61177,61238, 60806,60868,60930,60992,61054,61115,61177,61238,
61300,61361,61422,61483,61544,61605,61666,61727, 61300,61361,61422,61483,61544,61605,61666,61727,
61788,61848,61909,61969,62030,62090,62150,62210, 61788,61848,61909,61969,62030,62090,62150,62211,
62271,62331,62391,62450,62510,62570,62630,62689, 62271,62331,62391,62450,62510,62570,62630,62689,
62749,62808,62867,62927,62986,63045,63104,63163, 62749,62808,62867,62927,62986,63045,63104,63163,
63222,63281,63339,63398,63457,63515,63574,63632, 63222,63281,63340,63398,63457,63515,63574,63632,
63691,63749,63807,63865,63923,63981,64039,64097, 63691,63749,63807,63865,63923,63981,64039,64097,
64155,64212,64270,64328,64385,64442,64500,64557, 64155,64212,64270,64328,64385,64443,64500,64557,
64614,64671,64729,64786,64843,64899,64956,65013, 64614,64672,64729,64786,64843,64900,64956,65013,
65070,65126,65183,65239,65296,65352,65408,65465 65070,65126,65183,65239,65296,65352,65409,65465
}; };
PNG_CONST png_byte png_sRGB_delta[512] = PNG_CONST png_byte png_sRGB_delta[512] =
{ {
207,200,157,129,111,99,90,82,77,72,68,64,61,59,56,54, 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
28,27,27,27,26,26,26,26,25,25,25,25,24,24,24,24, 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
@ -3171,11 +3020,6 @@ PNG_CONST png_byte png_sRGB_delta[512] =
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
}; };
/* Hence the define in pngpriv.h to calculate the sRGB value of a linear value
* expressed as a fixed point integer scaled by 255*65535 (note that the tables
* include the +.5 to do rounding correctly.)
*/
#endif /* SIMPLIFIED READ/WRITE sRGB support */ #endif /* SIMPLIFIED READ/WRITE sRGB support */
/* SIMPLIFIED READ/WRITE SUPPORT */ /* SIMPLIFIED READ/WRITE SUPPORT */