#!/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. | |

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' |