[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.
diff --git a/png.c b/png.c
index 524ac7c..c44cdb6 100644
--- a/png.c
+++ b/png.c
@@ -645,13 +645,13 @@
#else
# ifdef __STDC__
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) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# 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) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@@ -2858,173 +2858,21 @@
/* sRGB support */
#if defined PNG_SIMPLIFIED_READ_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
/* The convert-to-sRGB table is only currently required for read. */
@@ -3063,6 +2911,7 @@
57105,57646,58190,58737,59287,59840,60396,60955,
61517,62082,62650,63221,63795,64372,64952,65535
};
+
#endif /* simplified read only */
/* The base/delta tables are required for both read and write (but currently
@@ -3070,52 +2919,52 @@
*/
PNG_CONST png_uint_16 png_sRGB_base[512] =
{
- 128,1782,3382,4641,5673,6563,7355,8072,
- 8732,9346,9920,10463,10977,11466,11935,12384,
- 12815,13232,13634,14024,14402,14768,15125,15473,
- 15811,16142,16465,16781,17090,17393,17689,17980,
+ 128,1782,3383,4644,5675,6564,7357,8074,
+ 8732,9346,9921,10463,10977,11466,11935,12384,
+ 12816,13233,13634,14024,14402,14769,15125,15473,
+ 15812,16142,16466,16781,17090,17393,17690,17981,
18266,18546,18822,19093,19359,19621,19879,20133,
- 20383,20630,20873,21113,21349,21583,21813,22040,
- 22265,22487,22706,22923,23138,23350,23559,23767,
+ 20383,20630,20873,21113,21349,21583,21813,22041,
+ 22265,22487,22707,22923,23138,23350,23559,23767,
23972,24175,24376,24575,24772,24967,25160,25352,
- 25541,25729,25916,26100,26283,26465,26645,26823,
- 27000,27176,27350,27523,27694,27865,28033,28201,
+ 25542,25730,25916,26101,26284,26465,26645,26823,
+ 27000,27176,27350,27523,27695,27865,28034,28201,
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,
- 32044,32186,32327,32468,32607,32746,32884,33021,
- 33158,33294,33429,33563,33697,33830,33963,34095,
- 34226,34356,34486,34616,34744,34872,35000,35127,
+ 32045,32186,32327,32468,32607,32746,32884,33021,
+ 33158,33294,33429,33564,33697,33831,33963,34095,
+ 34226,34357,34486,34616,34744,34873,35000,35127,
35253,35379,35504,35629,35753,35876,35999,36122,
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,
- 39025,39136,39246,39356,39465,39574,39682,39790,
+ 39026,39136,39246,39356,39465,39574,39682,39790,
39898,40005,40112,40219,40325,40431,40537,40642,
40747,40851,40955,41059,41163,41266,41369,41471,
- 41573,41675,41776,41878,41978,42079,42179,42279,
- 42379,42478,42577,42676,42774,42873,42970,43068,
- 43165,43262,43359,43455,43552,43647,43743,43838,
- 43934,44028,44123,44217,44311,44405,44498,44592,
- 44685,44777,44870,44962,45054,45146,45238,45329,
+ 41573,41675,41777,41878,41979,42079,42179,42279,
+ 42379,42478,42577,42676,42775,42873,42971,43068,
+ 43165,43262,43359,43456,43552,43648,43743,43839,
+ 43934,44028,44123,44217,44311,44405,44499,44592,
+ 44685,44778,44870,44962,45054,45146,45238,45329,
45420,45511,45601,45692,45782,45872,45961,46051,
- 46140,46229,46318,46406,46494,46582,46670,46758,
- 46845,46933,47020,47107,47193,47280,47366,47452,
- 47538,47623,47708,47794,47879,47963,48048,48132,
- 48217,48301,48384,48468,48552,48635,48718,48801,
- 48884,48966,49048,49131,49213,49294,49376,49457,
- 49539,49620,49701,49781,49862,49942,50023,50103,
- 50183,50262,50342,50421,50501,50580,50659,50738,
- 50816,50895,50973,51051,51129,51207,51284,51362,
- 51439,51517,51594,51670,51747,51824,51900,51977,
- 52053,52129,52205,52280,52356,52431,52507,52582,
+ 46140,46229,46318,46406,46494,46583,46670,46758,
+ 46846,46933,47020,47107,47193,47280,47366,47452,
+ 47538,47623,47709,47794,47879,47964,48048,48133,
+ 48217,48301,48385,48468,48552,48635,48718,48801,
+ 48884,48966,49048,49131,49213,49294,49376,49458,
+ 49539,49620,49701,49782,49862,49943,50023,50103,
+ 50183,50263,50342,50422,50501,50580,50659,50738,
+ 50816,50895,50973,51051,51129,51207,51285,51362,
+ 51439,51517,51594,51671,51747,51824,51900,51977,
+ 52053,52129,52205,52280,52356,52432,52507,52582,
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,
54417,54489,54560,54632,54703,54774,54845,54916,
- 54987,55058,55128,55199,55269,55340,55410,55480,
- 55550,55619,55689,55759,55828,55897,55967,56036,
- 56105,56174,56242,56311,56380,56448,56516,56585,
+ 54987,55058,55129,55199,55269,55340,55410,55480,
+ 55550,55620,55689,55759,55828,55898,55967,56036,
+ 56105,56174,56243,56311,56380,56448,56517,56585,
56653,56721,56789,56857,56924,56992,57059,57127,
57194,57261,57328,57395,57462,57529,57595,57662,
57728,57795,57861,57927,57993,58059,58125,58191,
@@ -3126,22 +2975,22 @@
60308,60370,60433,60495,60558,60620,60682,60744,
60806,60868,60930,60992,61054,61115,61177,61238,
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,
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,
- 64155,64212,64270,64328,64385,64442,64500,64557,
- 64614,64671,64729,64786,64843,64899,64956,65013,
- 65070,65126,65183,65239,65296,65352,65408,65465
+ 64155,64212,64270,64328,64385,64443,64500,64557,
+ 64614,64672,64729,64786,64843,64900,64956,65013,
+ 65070,65126,65183,65239,65296,65352,65409,65465
};
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,
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,
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,
@@ -3171,11 +3020,6 @@
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 */
/* SIMPLIFIED READ/WRITE SUPPORT */