xref: /aosp_15_r20/external/mesa3d/src/util/format_srgb.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard WorkerCopyRight = '''
2*61046927SAndroid Build Coastguard Worker/**************************************************************************
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright 2010 VMware, Inc.
5*61046927SAndroid Build Coastguard Worker * All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker *
7*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the
9*61046927SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
10*61046927SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
11*61046927SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
12*61046927SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
13*61046927SAndroid Build Coastguard Worker * the following conditions:
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
16*61046927SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
17*61046927SAndroid Build Coastguard Worker * of the Software.
18*61046927SAndroid Build Coastguard Worker *
19*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*61046927SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*61046927SAndroid Build Coastguard Worker * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23*61046927SAndroid Build Coastguard Worker * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*61046927SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*61046927SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*61046927SAndroid Build Coastguard Worker *
27*61046927SAndroid Build Coastguard Worker **************************************************************************/
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker/**
30*61046927SAndroid Build Coastguard Worker * @file
31*61046927SAndroid Build Coastguard Worker * SRGB translation.
32*61046927SAndroid Build Coastguard Worker *
33*61046927SAndroid Build Coastguard Worker * @author Brian Paul <[email protected]>
34*61046927SAndroid Build Coastguard Worker * @author Michal Krol <[email protected]>
35*61046927SAndroid Build Coastguard Worker * @author Jose Fonseca <[email protected]>
36*61046927SAndroid Build Coastguard Worker */
37*61046927SAndroid Build Coastguard Worker'''
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Workerimport math
41*61046927SAndroid Build Coastguard Workerimport struct
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Workerdef srgb_to_linear(x):
45*61046927SAndroid Build Coastguard Worker    if x <= 0.04045:
46*61046927SAndroid Build Coastguard Worker        return x / 12.92
47*61046927SAndroid Build Coastguard Worker    else:
48*61046927SAndroid Build Coastguard Worker        return math.pow((x + 0.055) / 1.055, 2.4)
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Workerdef linear_to_srgb(x):
52*61046927SAndroid Build Coastguard Worker    if x >= 0.0031308:
53*61046927SAndroid Build Coastguard Worker        return 1.055 * math.pow(x, 0.41666666) - 0.055
54*61046927SAndroid Build Coastguard Worker    else:
55*61046927SAndroid Build Coastguard Worker        return 12.92 * x
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Workerdef generate_srgb_tables():
59*61046927SAndroid Build Coastguard Worker    print('const float')
60*61046927SAndroid Build Coastguard Worker    print('util_format_srgb_8unorm_to_linear_float_table[256] = {')
61*61046927SAndroid Build Coastguard Worker    for j in range(0, 256, 4):
62*61046927SAndroid Build Coastguard Worker        print('   ', end=' ')
63*61046927SAndroid Build Coastguard Worker        print(' '.join(['%.7ef,' % srgb_to_linear(i / 255.0) for i in range(j, j + 4)]))
64*61046927SAndroid Build Coastguard Worker    print('};')
65*61046927SAndroid Build Coastguard Worker    print()
66*61046927SAndroid Build Coastguard Worker    print('const uint8_t')
67*61046927SAndroid Build Coastguard Worker    print('util_format_srgb_to_linear_8unorm_table[256] = {')
68*61046927SAndroid Build Coastguard Worker    for j in range(0, 256, 16):
69*61046927SAndroid Build Coastguard Worker        print('   ', end=' ')
70*61046927SAndroid Build Coastguard Worker        print(' '.join(['%3u,' % int(srgb_to_linear(i / 255.0) * 255.0 + 0.5) for i in range(j, j + 16)]))
71*61046927SAndroid Build Coastguard Worker    print('};')
72*61046927SAndroid Build Coastguard Worker    print()
73*61046927SAndroid Build Coastguard Worker    print('const uint8_t')
74*61046927SAndroid Build Coastguard Worker    print('util_format_linear_to_srgb_8unorm_table[256] = {')
75*61046927SAndroid Build Coastguard Worker    for j in range(0, 256, 16):
76*61046927SAndroid Build Coastguard Worker        print('   ', end=' ')
77*61046927SAndroid Build Coastguard Worker        print(' '.join(['%3u,' % int(linear_to_srgb(i / 255.0) * 255.0 + 0.5) for i in range(j, j + 16)]))
78*61046927SAndroid Build Coastguard Worker    print('};')
79*61046927SAndroid Build Coastguard Worker    print()
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker# calculate the table interpolation values used in float linear to unorm8 srgb
82*61046927SAndroid Build Coastguard Worker    numexp = 13
83*61046927SAndroid Build Coastguard Worker    mantissa_msb = 3
84*61046927SAndroid Build Coastguard Worker# stepshift is just used to only use every x-th float to make things faster,
85*61046927SAndroid Build Coastguard Worker# 5 is largest value which still gives exact same table as 0
86*61046927SAndroid Build Coastguard Worker    stepshift = 5
87*61046927SAndroid Build Coastguard Worker    nbuckets = numexp << mantissa_msb
88*61046927SAndroid Build Coastguard Worker    bucketsize = (1 << (23 - mantissa_msb)) >> stepshift
89*61046927SAndroid Build Coastguard Worker    mantshift = 12
90*61046927SAndroid Build Coastguard Worker    valtable = []
91*61046927SAndroid Build Coastguard Worker    sum_aa = float(bucketsize)
92*61046927SAndroid Build Coastguard Worker    sum_ab = 0.0
93*61046927SAndroid Build Coastguard Worker    sum_bb = 0.0
94*61046927SAndroid Build Coastguard Worker    for i in range(0, bucketsize):
95*61046927SAndroid Build Coastguard Worker        j = (i << stepshift) >> mantshift
96*61046927SAndroid Build Coastguard Worker        sum_ab += j
97*61046927SAndroid Build Coastguard Worker        sum_bb += j*j
98*61046927SAndroid Build Coastguard Worker    inv_det = 1.0 / (sum_aa * sum_bb - sum_ab * sum_ab)
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker    for bucket in range(0, nbuckets):
101*61046927SAndroid Build Coastguard Worker        start = ((127 - numexp) << 23) + bucket*(bucketsize << stepshift)
102*61046927SAndroid Build Coastguard Worker        sum_a = 0.0
103*61046927SAndroid Build Coastguard Worker        sum_b = 0.0
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker        for i in range(0, bucketsize):
106*61046927SAndroid Build Coastguard Worker            j = (i << stepshift) >> mantshift
107*61046927SAndroid Build Coastguard Worker            fint = start + (i << stepshift)
108*61046927SAndroid Build Coastguard Worker            ffloat = struct.unpack('f', struct.pack('I', fint))[0]
109*61046927SAndroid Build Coastguard Worker            val = linear_to_srgb(ffloat) * 255.0 + 0.5
110*61046927SAndroid Build Coastguard Worker            sum_a += val
111*61046927SAndroid Build Coastguard Worker            sum_b += j*val
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker        solved_a = inv_det * (sum_bb*sum_a - sum_ab*sum_b)
114*61046927SAndroid Build Coastguard Worker        solved_b = inv_det * (sum_aa*sum_b - sum_ab*sum_a)
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker        scaled_a = solved_a * 65536.0 / 512.0
117*61046927SAndroid Build Coastguard Worker        scaled_b = solved_b * 65536.0
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker        int_a = int(scaled_a + 0.5)
120*61046927SAndroid Build Coastguard Worker        int_b = int(scaled_b + 0.5)
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker        valtable.append((int_a << 16) + int_b)
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker    print('const unsigned')
125*61046927SAndroid Build Coastguard Worker    print('util_format_linear_to_srgb_helper_table[104] = {')
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker    for j in range(0, nbuckets, 4):
128*61046927SAndroid Build Coastguard Worker        print('   ', end=' ')
129*61046927SAndroid Build Coastguard Worker        print(' '.join(['0x%08x,' % valtable[i] for i in range(j, j + 4)]))
130*61046927SAndroid Build Coastguard Worker    print('};')
131*61046927SAndroid Build Coastguard Worker    print()
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Workerdef main():
134*61046927SAndroid Build Coastguard Worker    print('/* This file is autogenerated by u_format_srgb.py. Do not edit directly. */')
135*61046927SAndroid Build Coastguard Worker    print()
136*61046927SAndroid Build Coastguard Worker    # This will print the copyright message on the top of this file
137*61046927SAndroid Build Coastguard Worker    print(CopyRight.strip())
138*61046927SAndroid Build Coastguard Worker    print()
139*61046927SAndroid Build Coastguard Worker    print('#include "format_srgb.h"')
140*61046927SAndroid Build Coastguard Worker    print()
141*61046927SAndroid Build Coastguard Worker    generate_srgb_tables()
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Workerif __name__ == '__main__':
145*61046927SAndroid Build Coastguard Worker    main()
146