Example #1
0
def convertCLFtoLUT(clfPath,
                    lutPath,
                    lutFileFormat,
                    lutDataFormat=LUTDATAFORMAT_1D,
                    lutResolution1d=1024,
                    lutResolution3d=33,
                    lutResolution1d3d1d=[1024, 33, 2],
                    inputMin=0.0,
                    inputMax=1.0,
                    shaperIn=['linear', 0.0, 1.0],
                    shaperOut=['linear', 0.0, 1.0]):

    # Load CLF
    print("Reading CLF : %s" % clfPath)
    processList = clf.ProcessList(clfPath)

    # For each data format, do something different
    if lutDataFormat == LUTDATAFORMAT_1D:
        sampleAndWrite1D(processList, lutPath, lutFileFormat, lutResolution1d,
                         inputMin, inputMax)
    elif lutDataFormat == LUTDATAFORMAT_3D:
        sampleAndWrite3D(processList, lutPath, lutFileFormat, lutResolution3d,
                         inputMin, inputMax)
    elif lutDataFormat == LUTDATAFORMAT_1D_3D_1D:
        sampleAndWrite1D3D1D(processList, lutPath, lutFileFormat,
                             lutResolution1d3d1d, shaperIn, shaperOut)
    else:
        print("Unsupported LUT data format : %s" % lutDataFormat)
Example #2
0
def convertLUTtoCLF(lutPath,
                    clfPath,
                    inverse=False,
                    inversesUseIndexMaps=False,
                    inversesUseHalfDomain=True):
    direction = 'forward'
    if inverse:
        direction = 'inverse'

    # Load the LUT and convert to a CLF ProcessNode
    lutpns = convertLUTToProcessNode(
        lutPath,
        direction=direction,
        inversesUseIndexMaps=inversesUseIndexMaps,
        inversesUseHalfDomain=inversesUseHalfDomain)

    # Create a CLF ProcessList and populate contents
    if lutpns != []:
        pl = clf.ProcessList()

        # Populate
        pl.setID('Converted lut')
        pl.setCompCLFversion(1.0)
        pl.setName('Converted lut')

        for lutpn in lutpns:
            pl.addProcess(lutpn)

        # Write CLF to disk
        pl.writeFile(clfPath)
Example #3
0
def convertCLFtoLUT(clfPath,
                    lutPath,
                    lutFileFormat,
                    lutDataFormat=lutFormats.LUTDATAFORMAT_1D,
                    lutResolution1d=1024,
                    lutResolution3d=33,
                    lutResolution1d3d1d=[1024, 33, 2],
                    inputMin=0.0,
                    inputMax=1.0,
                    shaperIn=['linear', 0.0, 1.0],
                    shaperOut=['linear', 0.0, 1.0]):

    # Load CLF
    print("Reading CLF : %s" % clfPath)
    processList = clf.ProcessList(clfPath)

    # Write new LUT format
    print("Writing LUT : %s" % lutPath)
    lutFormats.Registry.write(
        processList,
        lutPath,
        #lutFileFormat,    # Currently not used
        lutDataFormat,
        lutResolution1d,
        lutResolution3d,
        lutResolution1d3d1d,
        inputMin,
        inputMax,
        shaperIn,
        shaperOut)
Example #4
0
    def read(lutPath, 
             inverse=False, 
             interpolation='linear',
             inversesUseIndexMaps=True, 
             inversesUseHalfDomain=True,
             returnProcessNodes=False):
        extension = os.path.splitext(lutPath)[1][1:].strip().lower()

        #print( "Reading lut %s" % lutPath )

        # Step through each of the lut format classes
        for cls in Registry.getFormats():
            #print( "Lut format class %s can load extensions %s" % (
            #    cls, cls.extensions()) )

            # If the class can read files and it can read this extension
            # Note: More than one format may use the same extension
            if extension in cls.extensions() and cls.canRead(extension):
                #print( "Reading lut %s" % lutPath )

                # Call reader class read method
                lutProcessNodes = cls.read(lutPath, inverse, interpolation, 
                    inversesUseIndexMaps, inversesUseHalfDomain)

                #print( "Read lut %s" % lutPath )

                # Create the CLF/ProcessList
                if lutProcessNodes:
                    # Return the list of ProcessNodes
                    if returnProcessNodes:
                        return lutProcessNodes

                    else:
                    # Wrap the ProcessNodes in a ProcessList
                        # Initialize
                        pl = clf.ProcessList()

                        # Populate
                        pl.setID('Converted lut')
                        pl.setCompCLFversion(1.0)
                        pl.setName('Converted lut')

                        for lutpn in lutProcessNodes:
                            pl.addProcess(lutpn)

                        return pl

                # Or warn the user and keep trying
                else:
                    print( "Reading failed for some reason. We'll keep trying." )

        print( "Reading LUTs in the %s format is not currently supported" % extension )
        return None
Example #5
0
def convertOCIOtoCLF(configPath, sourceColorSpaceNames, destColorSpaceNames,
                     clfPath, inversesUseIndexMaps, inversesUseHalfDomain):
    # Load the config
    config = OCIO.Config.CreateFromFile(configPath)

    configBasePath = os.path.split(configPath)[0]
    configLUTPath = os.path.join(configBasePath, config.getSearchPath())

    description = "CLF converted from OCIO config.\n"
    description += "Config Path : %s\n" % configPath

    #print( configLUTPath )

    # List that process nodes will be appended to
    lutpns = []

    # Generate the source color space to reference color space transforms
    for sourceColorSpaceName in sourceColorSpaceNames:
        # Get the OCIO transforms
        sourceColorSpace = config.getColorSpace(sourceColorSpaceName)
        sourceTransform = sourceColorSpace.getTransform(
            OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)

        # Convert to CLF ProcessNodes
        pns = convertTransformsToProcessNodes(
            sourceTransform,
            lutSearchPath=configLUTPath,
            inversesUseIndexMaps=inversesUseIndexMaps,
            inversesUseHalfDomain=inversesUseHalfDomain)

        # Rename and add a description to each ProcessNode
        specificDescription = "Convert %s to reference" % sourceColorSpaceName

        count = 0
        for pn in pns:
            ds2 = clf.Description(specificDescription)
            pn.addElement(ds2)

            name = "%s to reference - node %d" % (sourceColorSpaceName, count)
            pn.setAttribute("name", name)
            count += 1

        # Append to the overall CLF ProcessNode list
        lutpns.extend(pns)

        # Extend the overall description
        description += "Source color space : %s\n" % sourceColorSpaceName

    # Generate the reference color space to destination color space transforms
    for destColorSpaceName in destColorSpaceNames:
        # Get the OCIO transforms
        destColorSpace = config.getColorSpace(destColorSpaceName)
        destTransform = destColorSpace.getTransform(
            OCIO.Constants.COLORSPACE_DIR_FROM_REFERENCE)

        # Convert to CLF ProcessNodes
        pns = convertTransformsToProcessNodes(
            destTransform,
            lutSearchPath=configLUTPath,
            inversesUseIndexMaps=inversesUseIndexMaps,
            inversesUseHalfDomain=inversesUseHalfDomain)

        # Rename and add a description to each ProcessNode
        specificDescription = "Convert reference to %s" % destColorSpaceName

        count = 0
        for pn in pns:
            ds2 = clf.Description(specificDescription)
            pn.addElement(ds2)

            name = "reference to %s - node %d" % (destColorSpaceName, count)
            pn.setAttribute("name", name)
            count += 1

        # Append to the overall CLF ProcessNode list
        lutpns.extend(pns)

        # Extend the overall description
        description += "Destination color space name : %s\n" % destColorSpaceName

    # Create a CLF ProcessList and populate contents
    if lutpns != []:
        print("Creating ProcessList")
        pl = clf.ProcessList()

        # Populate
        pl.setID('Converted lut')
        pl.setCompCLFversion(1.0)
        pl.setName('Converted lut')

        ds1 = clf.Description(description)
        pl.addElement(ds1)

        for lutpn in lutpns:
            pl.addProcess(lutpn)

        # Write CLF to disk
        print("Writing CLF : %s" % clfPath)
        pl.writeFile(clfPath)
    else:
        print(
            "No ProcessNodes created for this transform. Skipping writing CLF."
        )
Example #6
0
def createShaper(shaperType, shaperMin, shaperMax):
    #
    # Create the forward and inverse input shaper ProcessLists
    #
    shaperPL = clf.ProcessList()
    shaperPLInverse = clf.ProcessList()

    # Log shaper
    if shaperType == 'log2':
        #print( "log shaper - %f, %f" % (shaperMin, shaperMax))

        # Forward ProcessNodes
        logPn = clf.Log(style='log2')
        shaperPL.addProcess(logPn)

        rangePn = clf.Range()
        rangePn.setMinInValue(shaperMin)
        rangePn.setMaxInValue(shaperMax)
        rangePn.setMinOutValue(0.0)
        rangePn.setMaxOutValue(1.0)
        shaperPL.addProcess(rangePn)

        # Input min and max
        inputMin = pow(2, shaperMin)
        inputMax = pow(2, shaperMax)

        # Inverse ProcessNodes
        rangePn2 = clf.Range()
        rangePn2.setMinInValue(0.0)
        rangePn2.setMaxInValue(1.0)
        rangePn2.setMinOutValue(shaperMin)
        rangePn2.setMaxOutValue(shaperMax)
        shaperPLInverse.addProcess(rangePn2)

        logPn2 = clf.Log(style='antiLog2')
        shaperPLInverse.addProcess(logPn2)

    # Linear shaper
    elif shaperType == 'linear':
        #print( "linear shaper - %f, %f" % (shaperMin, shaperMax))

        # Forward ProcessNodes
        rangePn = clf.Range()
        rangePn.setMinInValue(shaperMin)
        rangePn.setMaxInValue(shaperMax)
        rangePn.setMinOutValue(0.0)
        rangePn.setMaxOutValue(1.0)
        shaperPL.addProcess(rangePn)

        # Input min and max
        inputMin = shaperMin
        inputMax = shaperMax

        # Inverse ProcessNodes
        rangePn2 = clf.Range()
        rangePn2.setMinInValue(0.0)
        rangePn2.setMaxInValue(1.0)
        rangePn2.setMinOutValue(shaperMin)
        rangePn2.setMaxOutValue(shaperMax)
        shaperPLInverse.addProcess(rangePn2)

    # No shaper
    else:
        inputMin = 0.0
        inputMax = 1.0

    return (shaperPL, shaperPLInverse, inputMin, inputMax)
Example #7
0
def main():
    import optparse

    usage = "%prog [options]\n"
    usage += "\n"
    usage += "compression options:\n"
    usage += " exr format compression options  : none, rle, zip, zips(default), piz, pxr24, b44, b44a, dwaa, or dwab\n"
    usage += "   dwaa and dwab compression support depends on the version of OpenImageIO that you're using."
    usage += " tiff format compression options : none, lzw, zip(default), packbits\n"
    usage += " tga format compression options  : none, rle\n"
    usage += " sgi format compression options  : none, rle\n"
    usage += "\n"
    usage += "compression quality options:\n"
    usage += " jpg format compression quality options  : 0 to 100\n"

    p = optparse.OptionParser(
        description='Filter an image using the Common LUT Format',
        prog='clfFilter',
        version='clfFilter',
        usage=usage)

    p.add_option('--input', '-i', default=None)
    p.add_option('--output', '-o', default=None)
    p.add_option('--clf', '-c', default=None)
    p.add_option('--verbose', '-v', action="store_true")
    p.add_option('--outputBitDepth', '', default=None)
    p.add_option('--multithreaded', '-m', type='int', default=cpu_count())
    p.add_option("--compression")
    p.add_option("--quality", type="int", dest="quality", default=-1)

    options, arguments = p.parse_args()

    #
    # Get options
    #
    clfPath = options.clf
    inputPath = options.input
    outputPath = options.output
    verbose = options.verbose == True
    outputBitDepth = options.outputBitDepth
    multithreaded = options.multithreaded
    multithreaded = min(cpu_count(), max(1, multithreaded))
    compression = options.compression
    compressionQuality = options.quality

    try:
        argsStart = sys.argv.index('--') + 1
        args = sys.argv[argsStart:]
    except:
        argsStart = len(sys.argv) + 1
        args = []

    if verbose:
        print("command line : \n%s\n" % " ".join(sys.argv))

    if outputBitDepth and not (outputBitDepth in clf.bitDepths.values()):
        print(
            "Output bit depth %s is not a valid CLF bit depth. It will be ignored."
            % outputBitDepth)
        print("Valid values are %s." % ", ".join(clf.bitDepths.values()))
        outputBitDepth = None
        return

    #
    # Load a CLF
    #
    processList = None
    if clfPath != None:
        processList = clf.ProcessList(clfPath)
        print("Loaded CLF - title: %s, path: %s" %
              (processList.getName(), clfPath))

    #
    # Filter an image
    #
    if processList != None and outputPath != None and inputPath != None:
        filterImageWithCLF(inputPath,
                           outputPath,
                           processList,
                           verbose,
                           outBitDepth=outputBitDepth,
                           multithreaded=multithreaded,
                           compression=compression,
                           compressionQuality=compressionQuality)
Example #8
0
def write_CLF_1d_3d_1d(lutPath,
                       samples1dIn,
                       lutResolution1dIn,
                       inputMin,
                       inputMax,
                       samples3d,
                       lutResolution3d,
                       samples1dOut,
                       lutResolution1dOut,
                       outputMin,
                       outputMax,
                       inversesUseIndexMaps=True,
                       inversesUseHalfDomain=True):

    lutpns = []

    # Create the input shaper
    if samples1dIn:
        if inversesUseIndexMaps:
            print("Generating inverse of 1D LUT using Index Maps")
            lutpnInverses = convertLUTtoCLF.generateLUT1DInverseIndexMap(
                [lutResolution1dIn, 3], samples1dIn, inputMin, inputMax)
        elif inversesUseHalfDomain:
            print("Generating full half-domain inverse of 1D LUT")
            lutpnInverses = convertLUTtoCLF.generateLUT1DInverseHalfDomain(
                [lutResolution1dIn, 3],
                samples1dIn,
                inputMin,
                inputMax,
                rawHalfs=True)
        else:
            print("Generating resampled inverse of 1D LUT")
            lutpnInverses = convertLUTtoCLF.generateLUT1DInverseResampled(
                [lutResolution1dIn, 3], samples1dIn, inputMin, inputMax)
        lutpns.extend(lutpnInverses)

    # Create the 3D LUT
    clfSamples = [0.0] * (lutResolution3d[0] * lutResolution3d[1] *
                          lutResolution3d[2]) * 3
    index = 0
    for r in range(lutResolution3d[0]):
        for g in range(lutResolution3d[1]):
            for b in range(lutResolution3d[2]):
                for c in range(3):
                    clfSamples[index] = samples3d[r][g][b][c]
                    index += 1

    interpolation = 'trilinear'
    lut3dpn = clf.LUT3D(clf.bitDepths["FLOAT16"],
                        clf.bitDepths["FLOAT16"],
                        "lut3d",
                        "lut3d",
                        interpolation=interpolation)
    lut3dpn.setArray(
        [lutResolution3d[0], lutResolution3d[1], lutResolution3d[2]],
        clfSamples)

    lutpns.append(lut3dpn)

    # Create the output shaper
    if samples1dOut:
        interpolation = 'linear'
        lutpn = clf.LUT1D(clf.bitDepths["FLOAT16"],
                          clf.bitDepths["FLOAT16"],
                          "lut1d",
                          "lut1d",
                          interpolation=interpolation)
        lutpn.setArray(3, samples1dOut)

        lutpns.append(lutpn)

    # Wrap in a ProcessList and write to disk
    pl = clf.ProcessList()

    # Populate
    pl.setID('Converted lut')
    pl.setCompCLFversion(1.0)
    pl.setName('Converted lut')

    for lutpn in lutpns:
        pl.addProcess(lutpn)

    # Write CLF to disk
    pl.writeFile(lutPath)
Example #9
0
def main():
    import optparse

    p = optparse.OptionParser(
        description='Filter an image using the Common LUT Format',
        prog='clfFilter',
        version='clfFilter',
        usage='%prog [options]')

    p.add_option('--input', '-i', default=None)
    p.add_option('--output', '-o', default=None)
    p.add_option('--clf', '-c', default=None)
    p.add_option('--verbose', '-v', action="store_true")
    p.add_option('--outputBitDepth', '', default=None)

    options, arguments = p.parse_args()

    #
    # Get options
    #
    clfPath = options.clf
    inputPath = options.input
    outputPath = options.output
    verbose = options.verbose == True
    outputBitDepth = options.outputBitDepth

    try:
        argsStart = sys.argv.index('--') + 1
        args = sys.argv[argsStart:]
    except:
        argsStart = len(sys.argv) + 1
        args = []

    if verbose:
        print("command line : \n%s\n" % " ".join(sys.argv))

    if not outputBitDepth in clf.bitDepths.values():
        print(
            "Output bit depth %s is not a valid CLF bit depth. It will be ignored."
            % outputBitDepth)
        print("Valid values are %s." % ", ".join(clf.bitDepths.values()))
        outputBitDepth = None
        return

    #
    # Load a CLF
    #
    processList = None
    if clfPath != None:
        processList = clf.ProcessList(clfPath)
        print("Loaded CLF - title: %s, path: %s" %
              (processList.getName(), clfPath))

    #
    # Filter an image
    #
    if processList != None and outputPath != None and inputPath != None:
        filterImageWithCLF(inputPath,
                           outputPath,
                           processList,
                           verbose,
                           outBitDepth=outputBitDepth)