blob: 71c9114c06d0afd1f9f5b93ff0ff680fa1535cc5 [file] [log] [blame]
zachr@google.com92fe0732013-07-16 15:47:07 +00001#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4from __future__ import print_function
5from math import *
6
7
8COPYRIGHT = '''/*
9 * Copyright 2013 Google Inc.
10 *
11 * Use of this source code is governed by a BSD-style license that can be
12 * found in the LICENSE file.
13 */'''
14
15
16HELP = '// To regenerate SkPMetricUtil_generated.h, simply run ./generate_pmetric_tables.py'
17
18
19# From Barten SPIE 1989
20def contrast_sensitivity(cycles_per_degree, luminance):
21 a = 440.0 * pow(1.0 + 0.7 / luminance, -0.2)
22 b = 0.3 * pow(1 + 100.0 / luminance, 0.15)
23 return a * cycles_per_degree * exp(-b * cycles_per_degree) * sqrt(1.0 + 0.06 * exp(b * cycles_per_degree))
24
25
26# From Ward Larson Siggraph 1997
27def threshold_vs_intensity(adaptation_luminance):
28 log_lum = float('-inf') # Works in Python 2.6+
29 try:
30 log_lum = log10(adaptation_luminance)
31 except ValueError:
32 pass
33
34 x = 0.0
35
36 if log_lum < -3.94:
37 x = -2.86
38
39 elif log_lum < -1.44:
40 x = pow(0.405 * log_lum + 1.6, 2.18) - 2.86
41
42 elif log_lum < -0.0184:
43 x = log_lum - 0.395
44
45 elif log_lum < 1.9:
46 x = pow(0.249 * log_lum + 0.65, 2.7) - 0.72
47
48 else:
49 x = log_lum - 1.255
50
51 return pow(10.0, x)
52
53
54# From Daly 1993
55def visual_mask(contrast):
56 x = pow(392.498 * contrast, 0.7)
57 x = pow(0.0153 * x, 4.0)
58 return pow(1.0 + x, 0.25)
59
60
61# float gCubeRootTable[]
62CUBE_ROOT_ACCESS_FUNCTION = '''
zachr@google.com35f02fb2013-07-22 17:05:24 +000063static float get_cube_root(float value) {
zachr@google.com92fe0732013-07-16 15:47:07 +000064 SkASSERT(value >= 0.0f);
65 SkASSERT(value * 1023.0f < 1024.0f);
66 return gCubeRootTable[(int)(value * 1023.0f)];
67}
68'''
69def generate_cube_root_table(stream):
70 print('static float gCubeRootTable[] = {', end='', file=stream)
71 for i in range(1024):
72 if i % 6 == 0:
73 print('\n ', end='', file=stream)
74 print("%.10f" % pow(i / 1024.0, 1.0 / 3.0), end='f,', file=stream)
75 print('\n};', end='', file=stream)
76 print(CUBE_ROOT_ACCESS_FUNCTION, file=stream)
77
78
79# float gGammaTable[]
80GAMMA_ACCESS_FUNCTION = '''
zachr@google.com35f02fb2013-07-22 17:05:24 +000081static float get_gamma(unsigned char value) {
zachr@google.com92fe0732013-07-16 15:47:07 +000082 return gGammaTable[value];
83}
84'''
85def generate_gamma_table(stream):
86 print('static float gGammaTable[] = {', end='', file=stream)
87 for i in range(256):
88 if i % 6 == 0:
89 print('\n ', end='', file=stream)
90 print("%.10f" % pow(i / 255.0, 2.2), end='f,', file=stream)
91 print('\n};', end='', file=stream)
92 print(GAMMA_ACCESS_FUNCTION, file=stream)
93
94
95# float gTVITable[]
96TVI_ACCESS_FUNCTION = '''
zachr@google.com35f02fb2013-07-22 17:05:24 +000097static float get_threshold_vs_intensity(float value) {
zachr@google.com92fe0732013-07-16 15:47:07 +000098 SkASSERT(value >= 0.0f);
99 SkASSERT(value < 100.0f);
100 return gTVITable[(int)(value * 100.0f)];
101}
102'''
103def generate_tvi_table(stream):
104 print('static float gTVITable[] = {', end='', file=stream)
105 for i in range(10000):
106 if i % 6 == 0:
107 print('\n ', end='', file=stream)
108 print("%.10f" % threshold_vs_intensity(i / 100.0), end='f,', file=stream)
109 print('\n};', end='', file=stream)
110 print(TVI_ACCESS_FUNCTION, file=stream)
111
112
113# float gVisualMaskTable[]
114VISUAL_MASK_DOMAIN = 4000
115VISUAL_MASK_ACCESS_FUNCTION = '''
zachr@google.com35f02fb2013-07-22 17:05:24 +0000116static float get_visual_mask(float value) {{
zachr@google.com92fe0732013-07-16 15:47:07 +0000117 SkASSERT(value >= 0.0f);
118 SkASSERT(value < {}.0f);
119 return gVisualMaskTable[(int)value];
120}}'''
121def generate_visual_mask_table(stream):
122 print('static float gVisualMaskTable[] = {', end='', file=stream)
123 for i in range(VISUAL_MASK_DOMAIN):
124 if i % 6 == 0:
125 print('\n ', end='', file=stream)
126 print("%.10f" % visual_mask(i), end='f,', file=stream)
127 print('\n};', end='', file=stream)
128 print(VISUAL_MASK_ACCESS_FUNCTION.format(VISUAL_MASK_DOMAIN), file=stream)
129
130
131def generate_lookup_tables(stream):
132 print(COPYRIGHT, file=stream)
133 print(HELP, file=stream)
134 print('namespace SkPMetricUtil {', file=stream)
135 generate_cube_root_table(stream)
136 generate_gamma_table(stream)
137 generate_tvi_table(stream)
138 generate_visual_mask_table(stream)
139 print('}', file=stream)
140
141
142def main():
143 pmetric_util_out = open('SkPMetricUtil_generated.h', 'wb')
144 generate_lookup_tables(pmetric_util_out)
145 pmetric_util_out.close()
146
147
148if __name__ == '__main__':
149 main()