Ejemplo n.º 1
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)
Ejemplo n.º 2
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
Ejemplo n.º 3
0
    def writeCLF1D3D1D(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 = Sampling.generateLUT1DInverseIndexMap(
                    [lutResolution1dIn, 3], samples1dIn, inputMin, inputMax)
            elif inversesUseHalfDomain:
                #print( "Generating full half-domain inverse of 1D LUT")
                lutpnInverses = Sampling.generateLUT1DInverseHalfDomain(
                    [lutResolution1dIn, 3],
                    samples1dIn,
                    inputMin,
                    inputMax,
                    rawHalfs=True)
            else:
                #print( "Generating resampled inverse of 1D LUT")
                lutpnInverses = Sampling.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)

        return True
Ejemplo n.º 4
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)
Ejemplo n.º 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."
        )
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
def write_lut(lut_type,
              lut_3D,
              lut_1D_exists,
              lut_name,
              lut_size,
              lut_min,
              lut_max,
              lut_1D=None):

    time = str(datetime.datetime.now)

    if lut_type == 'cube':

        filename = os.path.join(lut_name + "." + lut_type)

        f = open(filename, "w+")
        f.write('# DaVinci Resolve Cube\n')
        f.write('# Made from ' + filename + ' by Me\n')
        f.write('# Generated on %s \n' % (datetime.datetime.now()))
        f.write('\n')
        f.write('LUT_3D_Size ' + str(lut_size) + '\n')
        f.write('LUT_3D_INPUT_RANGE ' + str(lut_min) + ' ' + str(lut_max) +
                '\n')
        f.write('\n')

        if lut_1D_exists == True:
            for i in range(len(lut_1D)):
                f.write(str(lut_1D[i]) + '\n')
            f.write('\n')

        for i in range(lut_size**3):
            f.write(
                str(lut_3D[0, i]) + ' ' + str(lut_3D[1, i]) + ' ' +
                str(lut_3D[2, i]) + '\n')

    if lut_type == 'cub':

        filename = os.path.join(lut_name + "." + lut_type)

        f = open(filename, "w+")
        f.write('#@ Truelight Cube v2.1\n')
        #####################################FIND OUT WHAT THESE RESPRESENT
        f.write('#@ inLength 101\n')
        f.write('#@ lutLength 101\n')
        f.write('#@ iDims 3\n')
        f.write('#@ oDims 3\n')
        f.write('#@ width' + ' ' + str(lut_size) + ' ' + str(lut_size) + ' ' +
                str(lut_size) + '\n')
        f.write('\n')

        f.write('# inGamut\n')
        #write some lut here
        f.write('\n')

        f.write('# InputLut\n')
        #write some lut here
        f.write('\n')

        f.write('# Cube\n')
        for i in range(lut_size):
            f.write(
                str(lut_3D[0, i]) + ' ' + str(lut_3D[1, i]) + ' ' +
                str(lut_3D[2, i]) + '\n')

    if lut_type == 'clf':

        #####please fix me

        filename = os.path.join(lut_name + "." + lut_type)

        pl = clf.ProcessList()

        if lut_1D_exists == True:

            l1d1 = LUT1D(bitDepths["16f"], bitDepths["16f"], "someId",
                         "Transform5")
            l1d1.setArray(lut_size, lut_1D)
            pl.addProcess(l1d1)

        l3d16 = clf.LUT3D("16f", "16f", "someId", "Transform")

        #not sure what these values should be
        indexMapR = [[0, 128, 1023], [0, 1, 2]]
        indexMapG = [[0, 768], [0, 1]]
        indexMapB = [[0, 64, 512, 1023], [0, 64, 128, 1023]]
        l3d16.setIndexMaps(indexMapR, indexMapG, indexMapB)
        l3d16.setArray([lut_size, lut_size, lut_size], lut_3D)
        pl.addProcess(l3d16)

        pl.writeFile(filename)

    ###values between 0 and 1
    if lut_type == 'csp':

        filename = os.path.join(lut_name + "." + lut_type)

        f = open(filename, "w+")
        f.write('CSPLUTV100')
        f.write('3D')
        f.write('BEGIN METADATA')
        f.write('Generated by AMPAS\n')
        f.write('END METADATA')

        f.write('2\n')
        f.write('0.0000 1.0000\n 0 1')
        f.write('0.0, 1.0\n')
        f.write('2\n')
        f.write('0.0000 1.0000\n 0 1')
        f.write('0.0 1.0\n')
        f.write('2\n')
        f.write('0.0000 1.0000\n 0 1')
        f.write('0.0 1.0\n\n')

        for i in range(lut_size):
            f.write(
                str(lut_3D[0, i]) + ' ' + str(lut_3D[1, i]) + ' ' +
                str(lut_3D[2, i]) + '\n')