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