1#!/usr/bin/env python 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 ' ', 65 for i in range(j, j + 4): 66 print '%.7e,' % (srgb_to_linear(i / 255.0),), 67 print 68 print '};' 69 print 70 print 'const uint8_t' 71 print 'util_format_srgb_to_linear_8unorm_table[256] = {' 72 for j in range(0, 256, 16): 73 print ' ', 74 for i in range(j, j + 16): 75 print '%3u,' % (int(srgb_to_linear(i / 255.0) * 255.0 + 0.5),), 76 print 77 print '};' 78 print 79 print 'const uint8_t' 80 print 'util_format_linear_to_srgb_8unorm_table[256] = {' 81 for j in range(0, 256, 16): 82 print ' ', 83 for i in range(j, j + 16): 84 print '%3u,' % (int(linear_to_srgb(i / 255.0) * 255.0 + 0.5),), 85 print 86 print '};' 87 print 88 89# calculate the table interpolation values used in float linear to unorm8 srgb 90 numexp = 13 91 mantissa_msb = 3 92# stepshift is just used to only use every x-th float to make things faster, 93# 5 is largest value which still gives exact same table as 0 94 stepshift = 5 95 nbuckets = numexp << mantissa_msb 96 bucketsize = (1 << (23 - mantissa_msb)) >> stepshift 97 mantshift = 12 98 valtable = [] 99 sum_aa = float(bucketsize) 100 sum_ab = 0.0 101 sum_bb = 0.0 102 for i in range(0, bucketsize): 103 j = (i << stepshift) >> mantshift 104 sum_ab += j 105 sum_bb += j*j 106 inv_det = 1.0 / (sum_aa * sum_bb - sum_ab * sum_ab) 107 108 for bucket in range(0, nbuckets): 109 start = ((127 - numexp) << 23) + bucket*(bucketsize << stepshift) 110 sum_a = 0.0 111 sum_b = 0.0 112 113 for i in range(0, bucketsize): 114 j = (i << stepshift) >> mantshift 115 fint = start + (i << stepshift) 116 ffloat = struct.unpack('f', struct.pack('I', fint))[0] 117 val = linear_to_srgb(ffloat) * 255.0 + 0.5 118 sum_a += val 119 sum_b += j*val 120 121 solved_a = inv_det * (sum_bb*sum_a - sum_ab*sum_b) 122 solved_b = inv_det * (sum_aa*sum_b - sum_ab*sum_a) 123 124 scaled_a = solved_a * 65536.0 / 512.0 125 scaled_b = solved_b * 65536.0 126 127 int_a = int(scaled_a + 0.5) 128 int_b = int(scaled_b + 0.5) 129 130 valtable.append((int_a << 16) + int_b) 131 132 print 'const unsigned' 133 print 'util_format_linear_to_srgb_helper_table[104] = {' 134 135 for j in range(0, nbuckets, 4): 136 print ' ', 137 for i in range(j, j + 4): 138 print '0x%08x,' % (valtable[i],), 139 print 140 print '};' 141 print 142 143def main(): 144 print '/* This file is autogenerated by u_format_srgb.py. Do not edit directly. */' 145 print 146 # This will print the copyright message on the top of this file 147 print CopyRight.strip() 148 print 149 print '#include "format_srgb.h"' 150 print 151 generate_srgb_tables() 152 153 154if __name__ == '__main__': 155 main() 156