1*a67afe4dSAndroid Build Coastguard Worker#!/bin/sh 2*a67afe4dSAndroid Build Coastguard Worker 3*a67afe4dSAndroid Build Coastguard Worker# intgamma.sh 4*a67afe4dSAndroid Build Coastguard Worker# 5*a67afe4dSAndroid Build Coastguard Worker# COPYRIGHT: Written by John Cunningham Bowler, 2013. 6*a67afe4dSAndroid Build Coastguard Worker# To the extent possible under law, the author has waived all copyright and 7*a67afe4dSAndroid Build Coastguard Worker# related or neighboring rights to this work. The author published this work 8*a67afe4dSAndroid Build Coastguard Worker# from the United States. 9*a67afe4dSAndroid Build Coastguard Worker# 10*a67afe4dSAndroid Build Coastguard Worker# Shell script to generate png.c 8-bit and 16-bit log tables (see the code in 11*a67afe4dSAndroid Build Coastguard Worker# png.c for details). 12*a67afe4dSAndroid Build Coastguard Worker# 13*a67afe4dSAndroid Build Coastguard Worker# This script uses the "bc" arbitrary precision calculator to calculate 32-bit 14*a67afe4dSAndroid Build Coastguard Worker# fixed point values of logarithms appropriate to finding the log of an 8-bit 15*a67afe4dSAndroid Build Coastguard Worker# (0..255) value and a similar table for the exponent calculation. 16*a67afe4dSAndroid Build Coastguard Worker# 17*a67afe4dSAndroid Build Coastguard Worker# "bc" must be on the path when the script is executed, and the math library 18*a67afe4dSAndroid Build Coastguard Worker# (-lm) must be available. 19*a67afe4dSAndroid Build Coastguard Worker 20*a67afe4dSAndroid Build Coastguard Worker# Function to print out a list of numbers as integers; the function truncates 21*a67afe4dSAndroid Build Coastguard Worker# the integers which must be one-per-line. 22*a67afe4dSAndroid Build Coastguard Workerprint(){ 23*a67afe4dSAndroid Build Coastguard Worker awk 'BEGIN{ 24*a67afe4dSAndroid Build Coastguard Worker str = "" 25*a67afe4dSAndroid Build Coastguard Worker } 26*a67afe4dSAndroid Build Coastguard Worker { 27*a67afe4dSAndroid Build Coastguard Worker sub("\\.[0-9]*$", "") 28*a67afe4dSAndroid Build Coastguard Worker if ($0 == "") 29*a67afe4dSAndroid Build Coastguard Worker $0 = "0" 30*a67afe4dSAndroid Build Coastguard Worker 31*a67afe4dSAndroid Build Coastguard Worker if (str == "") 32*a67afe4dSAndroid Build Coastguard Worker t = " " $0 "U" 33*a67afe4dSAndroid Build Coastguard Worker else 34*a67afe4dSAndroid Build Coastguard Worker t = str ", " $0 "U" 35*a67afe4dSAndroid Build Coastguard Worker 36*a67afe4dSAndroid Build Coastguard Worker if (length(t) >= 80) { 37*a67afe4dSAndroid Build Coastguard Worker print str "," 38*a67afe4dSAndroid Build Coastguard Worker str = " " $0 "U" 39*a67afe4dSAndroid Build Coastguard Worker } else 40*a67afe4dSAndroid Build Coastguard Worker str = t 41*a67afe4dSAndroid Build Coastguard Worker } 42*a67afe4dSAndroid Build Coastguard Worker END{ 43*a67afe4dSAndroid Build Coastguard Worker print str 44*a67afe4dSAndroid Build Coastguard Worker }' 45*a67afe4dSAndroid Build Coastguard Worker} 46*a67afe4dSAndroid Build Coastguard Worker# 47*a67afe4dSAndroid Build Coastguard Worker# The logarithm table. 48*a67afe4dSAndroid Build Coastguard Workercat <<END 49*a67afe4dSAndroid Build Coastguard Worker/* 8-bit log table: png_8bit_l2[128] 50*a67afe4dSAndroid Build Coastguard Worker * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to 51*a67afe4dSAndroid Build Coastguard Worker * 255, so it's the base 2 logarithm of a normalized 8-bit floating point 52*a67afe4dSAndroid Build Coastguard Worker * mantissa. The numbers are 32-bit fractions. 53*a67afe4dSAndroid Build Coastguard Worker */ 54*a67afe4dSAndroid Build Coastguard Workerstatic const png_uint_32 55*a67afe4dSAndroid Build Coastguard Workerpng_8bit_l2[128] = 56*a67afe4dSAndroid Build Coastguard Worker{ 57*a67afe4dSAndroid Build Coastguard WorkerEND 58*a67afe4dSAndroid Build Coastguard Worker# 59*a67afe4dSAndroid Build Coastguard Workerbc -lqws <<END | print 60*a67afe4dSAndroid Build Coastguard Workerf=65536*65536/l(2) 61*a67afe4dSAndroid Build Coastguard Workerfor (i=128;i<256;++i) { .5 - l(i/255)*f; } 62*a67afe4dSAndroid Build Coastguard WorkerEND 63*a67afe4dSAndroid Build Coastguard Workerecho '};' 64*a67afe4dSAndroid Build Coastguard Workerecho 65*a67afe4dSAndroid Build Coastguard Worker# 66*a67afe4dSAndroid Build Coastguard Worker# The exponent table. 67*a67afe4dSAndroid Build Coastguard Workercat <<END 68*a67afe4dSAndroid Build Coastguard Worker/* The 'exp()' case must invert the above, taking a 20-bit fixed point 69*a67afe4dSAndroid Build Coastguard Worker * logarithmic value and returning a 16 or 8-bit number as appropriate. In 70*a67afe4dSAndroid Build Coastguard Worker * each case only the low 16 bits are relevant - the fraction - since the 71*a67afe4dSAndroid Build Coastguard Worker * integer bits (the top 4) simply determine a shift. 72*a67afe4dSAndroid Build Coastguard Worker * 73*a67afe4dSAndroid Build Coastguard Worker * The worst case is the 16-bit distinction between 65535 and 65534; this 74*a67afe4dSAndroid Build Coastguard Worker * requires perhaps spurious accuracy in the decoding of the logarithm to 75*a67afe4dSAndroid Build Coastguard Worker * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance 76*a67afe4dSAndroid Build Coastguard Worker * of getting this accuracy in practice. 77*a67afe4dSAndroid Build Coastguard Worker * 78*a67afe4dSAndroid Build Coastguard Worker * To deal with this the following exp() function works out the exponent of the 79*a67afe4dSAndroid Build Coastguard Worker * frational part of the logarithm by using an accurate 32-bit value from the 80*a67afe4dSAndroid Build Coastguard Worker * top four fractional bits then multiplying in the remaining bits. 81*a67afe4dSAndroid Build Coastguard Worker */ 82*a67afe4dSAndroid Build Coastguard Workerstatic const png_uint_32 83*a67afe4dSAndroid Build Coastguard Workerpng_32bit_exp[16] = 84*a67afe4dSAndroid Build Coastguard Worker{ 85*a67afe4dSAndroid Build Coastguard WorkerEND 86*a67afe4dSAndroid Build Coastguard Worker# 87*a67afe4dSAndroid Build Coastguard Workerbc -lqws <<END | print 88*a67afe4dSAndroid Build Coastguard Workerf=l(2)/16 89*a67afe4dSAndroid Build Coastguard Workerfor (i=0;i<16;++i) { 90*a67afe4dSAndroid Build Coastguard Worker x = .5 + e(-i*f)*2^32; 91*a67afe4dSAndroid Build Coastguard Worker if (x >= 2^32) x = 2^32-1; 92*a67afe4dSAndroid Build Coastguard Worker x; 93*a67afe4dSAndroid Build Coastguard Worker} 94*a67afe4dSAndroid Build Coastguard WorkerEND 95*a67afe4dSAndroid Build Coastguard Workerecho '};' 96*a67afe4dSAndroid Build Coastguard Workerecho 97*a67afe4dSAndroid Build Coastguard Worker# 98*a67afe4dSAndroid Build Coastguard Worker# And the table of adjustment values. 99*a67afe4dSAndroid Build Coastguard Workercat <<END 100*a67afe4dSAndroid Build Coastguard Worker/* Adjustment table; provided to explain the numbers in the code below. */ 101*a67afe4dSAndroid Build Coastguard Worker#if 0 102*a67afe4dSAndroid Build Coastguard WorkerEND 103*a67afe4dSAndroid Build Coastguard Workerbc -lqws <<END | awk '{ printf "%5d %s\n", 12-NR, $0 }' 104*a67afe4dSAndroid Build Coastguard Workerfor (i=11;i>=0;--i){ 105*a67afe4dSAndroid Build Coastguard Worker (1 - e(-(2^i)/65536*l(2))) * 2^(32-i) 106*a67afe4dSAndroid Build Coastguard Worker} 107*a67afe4dSAndroid Build Coastguard WorkerEND 108*a67afe4dSAndroid Build Coastguard Workerecho '#endif' 109