Skip to content
This repository was archived by the owner on Nov 22, 2019. It is now read-only.

Commit 9773da9

Browse files
committed
LUT concatenation in lut_to_lut
1 parent 1b82bbc commit 9773da9

File tree

5 files changed

+67
-24
lines changed

5 files changed

+67
-24
lines changed

lutLab/lut_to_lut.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ class LutToLutException(Exception):
3838
pass
3939

4040

41-
def lut_to_lut(inlutfile, out_type=None, out_format=None, outlutfile=None,
41+
def lut_to_lut(inlutfiles, out_type=None, out_format=None, outlutfile=None,
4242
input_range=None, output_range=None, out_bit_depth=None,
4343
inverse=False, out_cube_size=None, verbose=False,
4444
smooth_size=None, preset=None, overwrite_preset=False):
4545
""" Concert a LUT in another LUT
4646
Arguments testing are delegated to LUT helpers
4747
4848
Args:
49-
inlutfile (str): path to input LUT
49+
lutfiles (str or [str]): path to a LUT or list of LUT paths
5050
5151
out_type (str): 1D, 2D or 3D
5252
@@ -98,26 +98,28 @@ def lut_to_lut(inlutfile, out_type=None, out_format=None, outlutfile=None,
9898
out_bit_depth,
9999
out_cube_size)
100100
ext = preset[presets.EXT]
101+
if not isinstance(inlutfiles, (list, tuple)):
102+
inlutfiles = [inlutfiles]
101103
if not outlutfile:
102-
outlutfile = get_default_out_path(inlutfile, ext)
104+
outlutfile = get_default_out_path(inlutfiles, ext)
103105
elif os.path.isdir(outlutfile):
104-
filename = os.path.splitext(ntpath.basename(inlutfile))[0] + ext
106+
filename = os.path.splitext(ntpath.basename(inlutfiles[0]))[0] + ext
105107
outlutfile = os.path.join(outlutfile, filename)
106108
else:
107109
check_extension(outlutfile, ext)
108110
# smooth
109111
if smooth_size:
110112
preset[presets.SMOOTH] = smooth_size
111113
if verbose:
112-
print "{0} will be converted into {1}.".format(inlutfile,
114+
print "{0} will be converted into {1}.".format(inlutfiles,
113115
outlutfile)
114116
print "Final setting:\n{0}".format(presets.string_preset(preset))
115-
processor = create_ocio_processor(inlutfile,
117+
processor = create_ocio_processor(inlutfiles,
116118
interpolation=INTERP_LINEAR,
117119
inverse=inverse)
118120
# change interpolation if 3D LUT
119-
if is_3d_lut(processor, inlutfile):
120-
processor = create_ocio_processor(inlutfile,
121+
if is_3d_lut(processor, inlutfiles[0]):
122+
processor = create_ocio_processor(inlutfiles,
121123
interpolation=INTERP_TETRAHEDRAL,
122124
inverse=inverse)
123125
# write LUT
@@ -137,7 +139,7 @@ def __get_options():
137139
description = 'Convert a LUT into another format'
138140
parser = argparse.ArgumentParser(description=description)
139141
# input lut
140-
add_inlutfile_option(parser)
142+
add_inlutfile_option(parser, is_list=True)
141143
add_outlutfile_option(parser)
142144
# type, format, ranges, out bit depth, out cube size
143145
add_export_lut_options(parser)
@@ -167,7 +169,7 @@ def __get_options():
167169
if not ARGS.preset is None:
168170
ARGS.preset = presets.get_presets_from_env()[ARGS.preset]
169171
try:
170-
lut_to_lut(ARGS.inlutfile,
172+
lut_to_lut(ARGS.inlutfiles,
171173
ARGS.out_type,
172174
ARGS.out_format,
173175
ARGS.outlutfile,

test/lut_to_lut_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,17 @@ def test_export_ascii(self):
108108
self.failUnlessRaises(AsciiHelperException, lut_to_lut, self.lut1d,
109109
"1D", "lut", outlutfile, out_bit_depth=12)
110110

111+
def test_concatenate_luts(self):
112+
""" Test concatenation
113+
114+
"""
115+
# contact in a 2D LUT
116+
lut_to_lut([self.lut1d, self.lut3d], "2D", "lut", self.tmp_dir)
117+
# concat in a 3D LUT
118+
outlutfile = os.path.join(self.tmp_dir, "concat.csp")
119+
lut_to_lut([self.lut3d, self.lut3d, self.lut1d],
120+
"3D", "csp", outlutfile)
121+
lut_to_lut(outlutfile, "2D", "lut", self.tmp_dir)
111122
def tearDown(self):
112123
#Remove test directory
113124
shutil.rmtree(self.tmp_dir)

utils/export_tool_helper.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,24 @@ class ExportLutException(Exception):
3737
# Argparse options
3838

3939

40-
def add_inlutfile_option(parser):
40+
def add_inlutfile_option(parser, is_list=False):
4141
""" Add inlutfile argument
4242
4343
Args:
4444
parser (argparse.ArgumentParser): parser on which option will be add
4545
4646
"""
47-
parser.add_argument("inlutfile",
48-
help=("path to a LUT.\n Available input formats : {0}"
49-
).format(str(OCIO_LUTS_FORMATS)),
50-
type=str)
47+
help_message = (" to LUTs.\n Available input formats : {0}"
48+
).format(str(OCIO_LUTS_FORMATS))
49+
if is_list:
50+
parser.add_argument("inlutfiles",
51+
help="paths{0}".format(help_message),
52+
type=str,
53+
nargs='+')
54+
else:
55+
parser.add_argument("inlutfile",
56+
help="path{0}".format(help_message),
57+
type=str)
5158

5259

5360
def add_outlutfile_option(parser, required=False):

utils/lut_utils.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,25 @@ def get_default_out_path(filepath, ext):
4444
""" Return a defaut output LUT path from an input LUT path
4545
4646
Args:
47-
filepath (str): input LUT file path
47+
filepath (str or [str]): path to a LUT or list of LUT paths
4848
ext (str): output file extension
4949
5050
Returns:
5151
.str
5252
5353
"""
54-
split_filename = os.path.splitext(filepath)
55-
return "{0}_export{1}".format(split_filename[0], ext)
54+
if isinstance(filepath, (list, tuple)):
55+
filepaths = filepath
56+
new_filepath = None
57+
for filepath in filepaths:
58+
if not new_filepath:
59+
new_filepath = os.path.splitext(filepath)[0]
60+
else:
61+
basename = os.path.splitext(ntpath.basename(filepath))[0]
62+
new_filepath += "+{0}".format(basename)
63+
else:
64+
new_filepath = os.path.splitext(filepath)[0]
65+
return "{0}_export{1}".format(new_filepath, ext)
5666

5767

5868
def get_3d_list_values(cubesize, processor, hexa_values=False):

utils/ocio_helper.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
- set(OCIO_1D_LUTS_FORMATS)))
2626

2727

28-
def create_ocio_processor(lutfile, interpolation=INTERP_LINEAR, inverse=False,
28+
def create_ocio_processor(lutfiles, interpolation=INTERP_LINEAR, inverse=False,
2929
prelutfile=None, postlutfile=None):
3030
"""Create an OpenColorIO processor for lutfile
3131
3232
Args:
33-
lutfile (str): path to a LUT
33+
lutfiles (str or [str]): path to a LUT or list of LUT paths
3434
3535
interpolation (int): can be INTERP_NEAREST, INTERP_LINEAR or
3636
INTERP_TETRAHEDRAL (only for 3D LUT)
@@ -53,15 +53,18 @@ def create_ocio_processor(lutfile, interpolation=INTERP_LINEAR, inverse=False,
5353
config = Config()
5454
# In colorspace (LUT)
5555
colorspace = ColorSpace(name='RawInput')
56-
main_lut = FileTransform(lutfile, interpolation=interpolation,
57-
direction=direction)
5856
group = GroupTransform()
5957
# Prelut
6058
if prelutfile:
6159
prelut = FileTransform(prelutfile, interpolation=interpolation)
6260
group.push_back(prelut)
6361
# Mainlut
64-
group.push_back(main_lut)
62+
if not isinstance(lutfiles, (list, tuple)):
63+
lutfiles = [lutfiles]
64+
for lutfile in lutfiles:
65+
main_lut = FileTransform(lutfile, interpolation=interpolation,
66+
direction=direction)
67+
group.push_back(main_lut)
6568
# Postlut
6669
if postlutfile:
6770
postlut = FileTransform(postlutfile, interpolation=interpolation)
@@ -72,7 +75,17 @@ def create_ocio_processor(lutfile, interpolation=INTERP_LINEAR, inverse=False,
7275
colorspace = ColorSpace(name='ProcessedOutput')
7376
config.addColorSpace(colorspace)
7477
# Create a processor corresponding to the LUT transformation
75-
return config.getProcessor('RawInput', 'ProcessedOutput')
78+
try:
79+
return config.getProcessor('RawInput', 'ProcessedOutput')
80+
except Exception, e:
81+
# tetrahedral interpolation is only allowed with 3D LUT
82+
# TODO set interpo mode by LUT
83+
if "tetrahedral interpolation is not allowed" in str(e):
84+
return create_ocio_processor(lutfiles, interpolation=INTERP_LINEAR,
85+
inverse=inverse,
86+
prelutfile=prelutfile,
87+
postlutfile=postlutfile)
88+
raise
7689

7790

7891
def is_3d_lut(processor, lutfile):

0 commit comments

Comments
 (0)