xref: /aosp_15_r20/external/libpng/contrib/tools/intgamma.sh (revision a67afe4df73cf47866eedc69947994b8ff839aba)
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