#!/bin/sh # # intgamma.sh # # Last changed in libpng 1.6.0 [February 14, 2013] # # 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. This work is published from: # 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'