def test_float_luts(self): """ Test float LUT transparency """ helpers_float_to_test = [(CSP_HELPER, '.csp'), (SPI_HELPER, '.spi1d')] colorspace_to_test = [REC709, SGAMUTSLOG, ALEXALOGCV3] delta = 0.00001 for helper, ext in helpers_float_to_test: for colorspace in colorspace_to_test: # define file name name = colorspace.__class__.__name__ encode_filename = "linTo{0}_1D{1}".format(name, ext) decode_filename = "{0}ToLin_1D{1}".format(name, ext) encode_filepath = os.path.join(self.tmp_dir, encode_filename) decode_filepath = os.path.join(self.tmp_dir, decode_filename) # set preset args_1d = CSP_HELPER.get_default_preset() args_1d[presets.OUT_BITDEPTH] = 16 decode_min = colorspace.decode_gradation(0) decode_max = colorspace.decode_gradation(1) args_1d[presets.IN_RANGE] = get_input_range(colorspace, "encode", 10) # write encode LUT helper.write_2d_lut(colorspace.encode_gradation, encode_filepath, args_1d) # write decode LUT args_1d[presets.IN_RANGE] = get_input_range(colorspace, "decode", 10) helper.write_2d_lut(colorspace.decode_gradation, decode_filepath, args_1d) # test transparency proc = create_ocio_processor(encode_filepath, postlutfile=decode_filepath, interpolation=INTERP_LINEAR) test_values = [[decode_min] * 3, [decode_max] * 3, [0] * 3, [0.5] * 3, [1] * 3] for rgb in test_values: res = proc.applyRGB(rgb) abs_value = abs(rgb[0] - res[0]) self.assert_(abs_value < delta, "{0} transparency test failed : {1:8f} >" " acceptable delta ({2:8f})".format(name, abs_value, delta) )
def curve_to_lut(colorspace, gamma, outlutfile, out_type=None, out_format=None, input_range=None, output_range=None, out_bit_depth=None, out_cube_size=None, verbose=False, direction=Direction.ENCODE, preset=None, overwrite_preset=False, process_input_range=False): """Export a LUT from a colorspace gradation function Args: colorspace (str): input colorspace. Mutually exclusive with gamma. See list of colorspaces in utils.colorspaces gamma (float): input gamma. Mutually exclusive with colorspace. out_type (str): 1D, 2D or 3D out_format (str): '3dl', 'csp', 'cube', 'lut', 'spi', 'clcc', 'json'... outlutfile (str): path to output LUT Kwargs: input_range ([int/float, int/float]): input range. Ex: [0.0, 1.0] or [0, 4095] output_range ([int/float, int/float]): output range. Ex: [0.0, 1.0] or [0, 4095] out_bit_depth (int): output lut bit precision (1D only). Ex : 10, 16, 32. out_cube_size (int): output cube size (3D only). Ex : 17, 32. verbose (bool): print log if true direction (Direction): encode or decode preset (dict): lut generic and sampling informations process_input_range (bool): If true, input range will be computed from colorspace gradation functions. Colorspace only" """ # get colorspace function if colorspace is None and gamma is None: raise AttributeError("A colorspace or a gamma should be specified") if colorspace is not None and gamma is not None: raise AttributeError("Choose between a colorspace or a gamma") elif gamma is not None: # gamma mode if direction == Direction.DECODE: gradation = lambda value: gamma_to_lin(value, gamma) title = "Gamma{0}_to_lin".format(gamma) else: gradation = lambda value: lin_to_gamma(value, gamma) title = "Lin_to_gamma{0}".format(gamma) else: # colorspace mode try: colorspace_obj = dict(list(COLORSPACES.items()) + list(PRIVATE_COLORSPACES.items()))[colorspace] except KeyError: raise CurveToLUTException(("Unsupported {0} " "Colorspace!").format(colorspace)) if direction == Direction.DECODE: gradation = colorspace_obj.decode_gradation title = "{0}_to_lin".format(colorspace) else: gradation = colorspace_obj.encode_gradation title = "Lin_to_{0}".format(colorspace) # get preset and write function if preset: write_function = get_write_function(preset, overwrite_preset, out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size, verbose) elif out_type is None or out_format is None: raise CurveToLUTException("Specify out_type/out_format or a preset.") else: preset, write_function = get_preset_and_write_function(out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size) if preset[presets.TYPE] == '3D': print_warning_message(("Gradations and gamma functions are 1D / 2D" " transformations. Baking them in a 3D LUT " "may not be efficient. Are you sure ?")) # process file output if os.path.isdir(outlutfile): filename = "{0}{1}".format(title, preset[presets.EXT]) outlutfile = os.path.join(outlutfile, filename) else: try: check_extension(outlutfile, preset[presets.EXT]) outlutfile = outlutfile except LUTException as error: raise CurveToLUTException(("Directory doesn't exist " "or {0}").format(error)) preset[presets.TITLE] = title if process_input_range: if colorspace: preset[presets.IN_RANGE] = get_input_range(colorspace_obj, direction, 8) else: raise CurveToLUTException(("--process-input-range must be used" " with --colorspace.")) if verbose: print("{0} will be written in {1}.".format(title, outlutfile)) print("Final setting:\n{0}".format(presets.string_preset(preset))) # write message = write_function(gradation, outlutfile, preset) if verbose: print_success_message(message)
def curve_to_lut(colorspace, gamma, outlutfile, out_type=None, out_format=None, input_range=None, output_range=None, out_bit_depth=None, out_cube_size=None, verbose=False, direction=Direction.ENCODE, preset=None, overwrite_preset=False, process_input_range=False): """Export a LUT from a colorspace gradation function Args: colorspace (str): input colorspace. Mutually exclusive with gamma. See list of colorspaces in utils.colorspaces gamma (float): input gamma. Mutually exclusive with colorspace. out_type (str): 1D, 2D or 3D out_format (str): '3dl', 'csp', 'cube', 'lut', 'spi', 'clcc', 'json'... outlutfile (str): path to output LUT Kwargs: input_range ([int/float, int/float]): input range. Ex: [0.0, 1.0] or [0, 4095] output_range ([int/float, int/float]): output range. Ex: [0.0, 1.0] or [0, 4095] out_bit_depth (int): output lut bit precision (1D only). Ex : 10, 16, 32. out_cube_size (int): output cube size (3D only). Ex : 17, 32. verbose (bool): print log if true direction (Direction): encode or decode preset (dict): lut generic and sampling informations process_input_range (bool): If true, input range will be computed from colorspace gradation functions. Colorspace only" """ # get colorspace function if colorspace is None and gamma is None: raise AttributeError("A colorspace or a gamma should be specified") if colorspace is not None and gamma is not None: raise AttributeError("Choose between a colorspace or a gamma") elif gamma is not None: # gamma mode if direction == Direction.DECODE: gradation = lambda value: gamma_to_lin(value, gamma) title = "Gamma{0}_to_lin".format(gamma) else: gradation = lambda value: lin_to_gamma(value, gamma) title = "Lin_to_gamma{0}".format(gamma) else: # colorspace mode try: colorspace_obj = dict(COLORSPACES.items() + PRIVATE_COLORSPACES.items())[colorspace] except KeyError: raise CurveToLUTException(("Unsupported {0} " "Colorspace!").format(colorspace)) if direction == Direction.DECODE: gradation = colorspace_obj.decode_gradation title = "{0}_to_lin".format(colorspace) else: gradation = colorspace_obj.encode_gradation title = "Lin_to_{0}".format(colorspace) # get preset and write function if preset: write_function = get_write_function(preset, overwrite_preset, out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size, verbose) elif out_type is None or out_format is None: raise CurveToLUTException("Specify out_type/out_format or a preset.") else: preset, write_function = get_preset_and_write_function(out_type, out_format, input_range, output_range, out_bit_depth, out_cube_size) if preset[presets.TYPE] == '3D': print_warning_message(("Gradations and gamma functions are 1D / 2D" " transformations. Baking them in a 3D LUT " "may not be efficient. Are you sure ?")) # process file output if os.path.isdir(outlutfile): filename = "{0}{1}".format(title, preset[presets.EXT]) outlutfile = os.path.join(outlutfile, filename) else: try: check_extension(outlutfile, preset[presets.EXT]) outlutfile = outlutfile except LUTException as error: raise CurveToLUTException(("Directory doesn't exist " "or {0}").format(error)) preset[presets.TITLE] = title if process_input_range: if colorspace: preset[presets.IN_RANGE] = get_input_range(colorspace_obj, direction, 8) else: raise CurveToLUTException(("--process-input-range must be used" " with --colorspace.")) if verbose: print "{0} will be written in {1}.".format(title, outlutfile) print "Final setting:\n{0}".format(presets.string_preset(preset)) # write message = write_function(gradation, outlutfile, preset) if verbose: print_success_message(message)