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