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