| #!/bin/sh |
| |
| # intgamma.sh |
| # |
| # COPYRIGHT: Written by John Cunningham Bowler, 2013. |
| # To the extent possible under law, the author has waived all copyright and |
| # related or neighboring rights to this work. The author published this work |
| # from the United States. |
| # |
| # Shell script to generate png.c 8-bit and 16-bit log tables (see the code in |
| # png.c for details). |
| # |
| # This script uses the "bc" arbitrary precision calculator to calculate 32-bit |
| # fixed point values of logarithms appropriate to finding the log of an 8-bit |
| # (0..255) value and a similar table for the exponent calculation. |
| # |
| # "bc" must be on the path when the script is executed, and the math library |
| # (-lm) must be available. |
| |
| # Function to print out a list of numbers as integers; the function truncates |
| # the integers which must be one-per-line. |
| function print(){ |
| awk 'BEGIN{ |
| str = "" |
| } |
| { |
| sub("\\.[0-9]*$", "") |
| if ($0 == "") |
| $0 = "0" |
| |
| if (str == "") |
| t = " " $0 "U" |
| else |
| t = str ", " $0 "U" |
| |
| if (length(t) >= 80) { |
| print str "," |
| str = " " $0 "U" |
| } else |
| str = t |
| } |
| END{ |
| print str |
| }' |
| } |
| # |
| # The logarithm table. |
| cat <<END |
| /* 8-bit log table: png_8bit_l2[128] |
| * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to |
| * 255, so it's the base 2 logarithm of a normalized 8-bit floating point |
| * mantissa. The numbers are 32-bit fractions. |
| */ |
| static const png_uint_32 |
| png_8bit_l2[128] = |
| { |
| END |
| # |
| bc -lqws <<END | print |
| f=65536*65536/l(2) |
| for (i=128;i<256;++i) { .5 - l(i/255)*f; } |
| END |
| echo '};' |
| echo |
| # |
| # The exponent table. |
| cat <<END |
| /* The 'exp()' case must invert the above, taking a 20-bit fixed point |
| * logarithmic value and returning a 16 or 8-bit number as appropriate. In |
| * each case only the low 16 bits are relevant - the fraction - since the |
| * integer bits (the top 4) simply determine a shift. |
| * |
| * The worst case is the 16-bit distinction between 65535 and 65534; this |
| * requires perhaps spurious accuracy in the decoding of the logarithm to |
| * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance |
| * of getting this accuracy in practice. |
| * |
| * To deal with this the following exp() function works out the exponent of the |
| * frational part of the logarithm by using an accurate 32-bit value from the |
| * top four fractional bits then multiplying in the remaining bits. |
| */ |
| static const png_uint_32 |
| png_32bit_exp[16] = |
| { |
| END |
| # |
| bc -lqws <<END | print |
| f=l(2)/16 |
| for (i=0;i<16;++i) { |
| x = .5 + e(-i*f)*2^32; |
| if (x >= 2^32) x = 2^32-1; |
| x; |
| } |
| END |
| echo '};' |
| echo |
| # |
| # And the table of adjustment values. |
| cat <<END |
| /* Adjustment table; provided to explain the numbers in the code below. */ |
| #if 0 |
| END |
| bc -lqws <<END | awk '{ printf "%5d %s\n", 12-NR, $0 }' |
| for (i=11;i>=0;--i){ |
| (1 - e(-(2^i)/65536*l(2))) * 2^(32-i) |
| } |
| END |
| echo '#endif' |