Skip to content

Commit eb8e338

Browse files
hodoulpdoug-walker
andauthored
Update CLF test files, add CLF python scripts (#1436) (#1447)
* Update CLF test files, add CLF python scripts Signed-off-by: Doug Walker <[email protected]> * Fix issue with large Lut1D neg values Signed-off-by: Doug Walker <[email protected]> * Add two more parse tests Signed-off-by: Doug Walker <[email protected]> * Fix non-SSE test tolerance Signed-off-by: Doug Walker <[email protected]> Co-authored-by: Patrick Hodoul <[email protected]> Signed-off-by: Patrick Hodoul <[email protected]> Co-authored-by: doug-walker <[email protected]>
1 parent d7b41f6 commit eb8e338

32 files changed

+269694
-65850
lines changed

share/clf/CLF_testImage.exr

197 KB
Binary file not shown.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright Contributors to the OpenColorIO Project.
3+
4+
# Use OpenImageIO's oiiotool to compare the reference image set to the actual image set produced
5+
# by a CLF implementation.
6+
#
7+
# The script iterates over the images in the directory and prints the oiiotool command being run.
8+
# It will then print either 'Test passed' or 'Test failed' after each command and then at the end
9+
# will summarize with 'All tests passed' or 'These tests failed' with a list of the failed images.
10+
#
11+
# Usage:
12+
# > python compare_clf_test_frames.py <PATH-TO-REFERENCE-IMAGES> <PATH-TO-ACTUAL-IMAGES>
13+
14+
# This script is python 2.7 and python 3 compatible.
15+
16+
import os
17+
import subprocess
18+
import tempfile
19+
20+
def process_frames( ref_path, act_path ):
21+
22+
# Check the arguments are as expected.
23+
if not os.path.isdir( ref_path ):
24+
raise ValueError( "Reference image directory must exist: " + ref_path )
25+
if not os.path.isdir( act_path ):
26+
raise ValueError( "Actual image directory must exist: " + act_path )
27+
28+
# Take the aim and actual images and compute abs(aim - act) / max(abs(aim), 0.1).
29+
base_cmd = 'oiiotool %s --dup %s --absdiff --swap --abs --maxc 0.1 --div '
30+
31+
# Mask out the Inf and NaN values in the CLF test kit target image.
32+
box_cmd = '--box:color=0,0,0:fill=1 1008,771,1023,798 --box:color=0,0,0:fill=1 0,1023,1,1023 '
33+
34+
# Error out if there are any new NaNs generated (there should not be).
35+
nan_err_cmd = '--fixnan error '
36+
37+
# Print out how many pixels are greater than the test threshold of 0.002.
38+
range_cmd = '--rangecheck 0,0,0 .002,.002,.002 '
39+
40+
# Oiiotool seems to need a -o to avoid issuing a useless warning, so add an output file
41+
# even though it is not used. (Note that trying to write to /dev/null here doesn't work.)
42+
avoid_warning_cmd = '-o ' + os.path.join(tempfile.gettempdir(), 'tmp.exr') + ' '
43+
44+
oiio_cmd = base_cmd + box_cmd + nan_err_cmd + range_cmd + avoid_warning_cmd
45+
46+
# Iterate over each pair of test images.
47+
failed_tests = []
48+
for f in sorted(os.listdir( ref_path )):
49+
fname, ext = os.path.splitext( f )
50+
if ext == '.exr':
51+
52+
# Build the full path to the files.
53+
ref = os.path.join( ref_path, f )
54+
act = os.path.join( act_path, f )
55+
56+
# Build the command.
57+
cmd = oiio_cmd % (ref, act)
58+
59+
print(''); print( cmd )
60+
61+
# Process the image.
62+
try:
63+
result = subprocess.check_output(cmd, shell=True)
64+
65+
ind = str(result).find('0 > .002,.002,.002')
66+
if ind > -1:
67+
print('** Test passed **')
68+
else:
69+
failed_tests.append(f)
70+
print('\n** TEST FAILED **')
71+
print(result)
72+
73+
except:
74+
failed_tests.append(f)
75+
print('\n** TEST FAILED **')
76+
print(result)
77+
78+
if len(failed_tests) == 0:
79+
print("\n\nALL TESTS PASSED SUCCESSFULLY!\n\n")
80+
else:
81+
print("\n\nTHESE TESTS FAILED!\n")
82+
for s in failed_tests:
83+
print(s)
84+
print('')
85+
86+
87+
if __name__=='__main__':
88+
import sys
89+
if len( sys.argv ) != 3:
90+
raise ValueError( "USAGE: python compare_clf_test_frames.py <REF_IMAGE_DIR> <ACTUAL_IMAGE_DIR>" )
91+
process_frames( sys.argv[1], sys.argv[2] )
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright Contributors to the OpenColorIO Project.
3+
4+
# Use OpenColorIO to apply the CLF files from the CLF test kit to the CLF target image
5+
# and produce a directory of processed OpenEXR images at the specified location.
6+
# Run the script with "-h" for usage information.
7+
8+
# This script is python 2.7 and python 3 compatible.
9+
10+
import os
11+
import argparse
12+
13+
def process_frames( options ):
14+
15+
dst_path = options.dst_dir
16+
use_gpu = options.gpu
17+
opt_level = options.opt
18+
19+
# Check the arguments are as expected.
20+
if not os.path.exists( dst_path ):
21+
os.mkdir( dst_path )
22+
if not os.path.isdir( dst_path ):
23+
raise ValueError( "Destination path must be a directory: " + dst_path )
24+
25+
# Get the path to the CLF target image, relative to the path of this script.
26+
script_path = os.path.abspath( __file__ )
27+
parts = script_path.split( os.sep )
28+
ocio_base_path = os.path.join( os.sep, *parts[0:-3] )
29+
src_image = os.path.join( ocio_base_path, 'share', 'clf', 'CLF_testimage.exr' )
30+
31+
# Get the path to the CLF files, relative to the path of this script.
32+
clf_path = os.path.join( ocio_base_path, 'tests', 'data', 'files', 'clf' )
33+
34+
# Set the optimization level. None or lossless avoids the fast SSE log/exponent.
35+
# (Note that the decimal value is available by simply printing the enum in Python.)
36+
if (opt_level == 'none') or (opt_level is None):
37+
# For default for this script, use no optimization rather than OCIO's default optimization
38+
# in order to apply the operators exactly as they appear in the CLF file with no attempt
39+
# to speed up the processing.
40+
print( 'Optimization level: None' )
41+
os.environ["OCIO_OPTIMIZATION_FLAGS"] = "0"
42+
elif opt_level == 'lossless':
43+
print( 'Optimization level: Lossless' )
44+
os.environ["OCIO_OPTIMIZATION_FLAGS"] = "144457667"
45+
elif opt_level == 'default':
46+
print( 'Optimization level: Default' )
47+
else:
48+
raise ValueError( 'Unexpected --opt argument.' )
49+
50+
# TODO: Add an option to turn on only SSE without removing any ops.
51+
52+
if use_gpu:
53+
print( 'Processing on the GPU\n' )
54+
cmd_base = 'ocioconvert --gpu --lut %s %s %s'
55+
else:
56+
print( 'Processing on the CPU\n' )
57+
cmd_base = 'ocioconvert --lut %s %s %s'
58+
59+
# Iterate over each legal CLF file in the suite.
60+
for f in os.listdir( clf_path ):
61+
fname, ext = os.path.splitext( f )
62+
if ext == '.clf':
63+
64+
# Build the full path to the file.
65+
p = os.path.join( clf_path, f )
66+
67+
# Build the name of the destination image.
68+
dst_image = os.path.join( dst_path, fname + '.exr' )
69+
70+
# Build the command.
71+
cmd = cmd_base % (p, src_image, dst_image)
72+
print('================='); print( cmd )
73+
74+
# Process the image.
75+
os.system( cmd )
76+
77+
78+
if __name__=='__main__':
79+
import sys
80+
81+
import argparse
82+
parser = argparse.ArgumentParser(description='Process CLF test images using OCIO.')
83+
parser.add_argument('dst_dir',
84+
help='Path to a directory where the result images will be stored.')
85+
parser.add_argument('--gpu', action='store_true',
86+
help='Process using the GPU rather than the CPU.')
87+
parser.add_argument('--opt', choices=['none','lossless','default'],
88+
help='Specify the OCIO optimization level. If not specified, "none" will be used.')
89+
options = parser.parse_args(sys.argv[1:])
90+
91+
process_frames(options)
92+

src/OpenColorIO/ops/lut1d/Lut1DOpGPU.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,9 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
262262
}
263263
else
264264
{
265-
// Need min() to protect against f > 1 causing a bogus x value.
266-
// min( f, 1.) * (dim - 1)
267-
ss.newLine() << "float dep = min(f, 1.0) * " << float(length - 1) << ";";
265+
// Need clamp() to protect against f outside [0,1] causing a bogus x value.
266+
// clamp( f, 0., 1.) * (dim - 1)
267+
ss.newLine() << "float dep = clamp(f, 0.0, 1.0) * " << float(length - 1) << ";";
268268

269269
ss.newLine() << ss.float2Decl("retVal") << ";";
270270
// float(int( dep / (width-1) ))

0 commit comments

Comments
 (0)