192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com#!/usr/bin/python 292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# -*- coding: utf-8 -*- 392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comfrom __future__ import print_function 592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comfrom math import * 692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comCOPYRIGHT = '''/* 992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com * Copyright 2013 Google Inc. 1092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com * 1192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com * Use of this source code is governed by a BSD-style license that can be 1292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com * found in the LICENSE file. 1392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com */''' 1492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 1592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 1692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comHELP = '// To regenerate SkPMetricUtil_generated.h, simply run ./generate_pmetric_tables.py' 1792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 1892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 1992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# From Barten SPIE 1989 2092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef contrast_sensitivity(cycles_per_degree, luminance): 2192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com a = 440.0 * pow(1.0 + 0.7 / luminance, -0.2) 2292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com b = 0.3 * pow(1 + 100.0 / luminance, 0.15) 2392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com return a * cycles_per_degree * exp(-b * cycles_per_degree) * sqrt(1.0 + 0.06 * exp(b * cycles_per_degree)) 2492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 2592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 2692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# From Ward Larson Siggraph 1997 2792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef threshold_vs_intensity(adaptation_luminance): 2892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com log_lum = float('-inf') # Works in Python 2.6+ 2992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com try: 3092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com log_lum = log10(adaptation_luminance) 3192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com except ValueError: 3292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com pass 3392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 3492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = 0.0 3592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 3692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com if log_lum < -3.94: 3792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = -2.86 3892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 3992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com elif log_lum < -1.44: 4092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = pow(0.405 * log_lum + 1.6, 2.18) - 2.86 4192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 4292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com elif log_lum < -0.0184: 4392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = log_lum - 0.395 4492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 4592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com elif log_lum < 1.9: 4692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = pow(0.249 * log_lum + 0.65, 2.7) - 0.72 4792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 4892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com else: 4992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = log_lum - 1.255 5092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 5192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com return pow(10.0, x) 5292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 5392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 5492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# From Daly 1993 5592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef visual_mask(contrast): 5692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = pow(392.498 * contrast, 0.7) 5792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com x = pow(0.0153 * x, 4.0) 5892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com return pow(1.0 + x, 0.25) 5992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 6092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 6192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# float gCubeRootTable[] 6292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comCUBE_ROOT_ACCESS_FUNCTION = ''' 6335f02fb9c9f548656e1cb2cc66d3ed20006384f8zachr@google.comstatic float get_cube_root(float value) { 6492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com SkASSERT(value >= 0.0f); 6592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com SkASSERT(value * 1023.0f < 1024.0f); 6692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com return gCubeRootTable[(int)(value * 1023.0f)]; 6792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com} 6892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com''' 6992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef generate_cube_root_table(stream): 7092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('static float gCubeRootTable[] = {', end='', file=stream) 7192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com for i in range(1024): 7292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com if i % 6 == 0: 7392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n ', end='', file=stream) 7492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print("%.10f" % pow(i / 1024.0, 1.0 / 3.0), end='f,', file=stream) 7592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n};', end='', file=stream) 7692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print(CUBE_ROOT_ACCESS_FUNCTION, file=stream) 7792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 7892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 7992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# float gGammaTable[] 8092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comGAMMA_ACCESS_FUNCTION = ''' 8135f02fb9c9f548656e1cb2cc66d3ed20006384f8zachr@google.comstatic float get_gamma(unsigned char value) { 8292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com return gGammaTable[value]; 8392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com} 8492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com''' 8592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef generate_gamma_table(stream): 8692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('static float gGammaTable[] = {', end='', file=stream) 8792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com for i in range(256): 8892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com if i % 6 == 0: 8992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n ', end='', file=stream) 9092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print("%.10f" % pow(i / 255.0, 2.2), end='f,', file=stream) 9192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n};', end='', file=stream) 9292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print(GAMMA_ACCESS_FUNCTION, file=stream) 9392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 9492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 9592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# float gTVITable[] 9692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comTVI_ACCESS_FUNCTION = ''' 9735f02fb9c9f548656e1cb2cc66d3ed20006384f8zachr@google.comstatic float get_threshold_vs_intensity(float value) { 9892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com SkASSERT(value >= 0.0f); 9992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com SkASSERT(value < 100.0f); 10092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com return gTVITable[(int)(value * 100.0f)]; 10192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com} 10292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com''' 10392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef generate_tvi_table(stream): 10492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('static float gTVITable[] = {', end='', file=stream) 10592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com for i in range(10000): 10692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com if i % 6 == 0: 10792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n ', end='', file=stream) 10892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print("%.10f" % threshold_vs_intensity(i / 100.0), end='f,', file=stream) 10992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n};', end='', file=stream) 11092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print(TVI_ACCESS_FUNCTION, file=stream) 11192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 11292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 11392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com# float gVisualMaskTable[] 11492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comVISUAL_MASK_DOMAIN = 4000 11592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comVISUAL_MASK_ACCESS_FUNCTION = ''' 11635f02fb9c9f548656e1cb2cc66d3ed20006384f8zachr@google.comstatic float get_visual_mask(float value) {{ 11792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com SkASSERT(value >= 0.0f); 11892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com SkASSERT(value < {}.0f); 11992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com return gVisualMaskTable[(int)value]; 12092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com}}''' 12192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef generate_visual_mask_table(stream): 12292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('static float gVisualMaskTable[] = {', end='', file=stream) 12392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com for i in range(VISUAL_MASK_DOMAIN): 12492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com if i % 6 == 0: 12592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n ', end='', file=stream) 12692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print("%.10f" % visual_mask(i), end='f,', file=stream) 12792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('\n};', end='', file=stream) 12892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print(VISUAL_MASK_ACCESS_FUNCTION.format(VISUAL_MASK_DOMAIN), file=stream) 12992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 13092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 13192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef generate_lookup_tables(stream): 13292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print(COPYRIGHT, file=stream) 13392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print(HELP, file=stream) 13492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('namespace SkPMetricUtil {', file=stream) 13592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com generate_cube_root_table(stream) 13692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com generate_gamma_table(stream) 13792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com generate_tvi_table(stream) 13892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com generate_visual_mask_table(stream) 13992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com print('}', file=stream) 14092fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 14192fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 14292fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comdef main(): 14392fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com pmetric_util_out = open('SkPMetricUtil_generated.h', 'wb') 14492fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com generate_lookup_tables(pmetric_util_out) 14592fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com pmetric_util_out.close() 14692fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 14792fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com 14892fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.comif __name__ == '__main__': 14992fe073efbd9287cdb4d01a1b9c0664fc5d4fdd0zachr@google.com main() 150