Separated camera input transforms into separate files.
authorHaarm-Pieter Duiker <hpd1@duikerresearch.com>
Wed, 14 Jan 2015 01:55:21 +0000 (17:55 -0800)
committerHaarm-Pieter Duiker <hpd1@duikerresearch.com>
Wed, 14 Jan 2015 01:55:21 +0000 (17:55 -0800)
aces_1.0.0/python/createARRIColorSpaces.py [new file with mode: 0644]
aces_1.0.0/python/createCanonColorSpaces.py [new file with mode: 0644]
aces_1.0.0/python/createREDColorSpaces.py [new file with mode: 0644]
aces_1.0.0/python/createSonyColorSpaces.py [new file with mode: 0644]
aces_1.0.0/python/create_aces_config.py
aces_1.0.0/python/util.py [new file with mode: 0644]

diff --git a/aces_1.0.0/python/createARRIColorSpaces.py b/aces_1.0.0/python/createARRIColorSpaces.py
new file mode 100644 (file)
index 0000000..31c0fdc
--- /dev/null
@@ -0,0 +1,133 @@
+import math
+import array
+
+from util import *
+import generateLUT as genlut
+
+
+#
+# LogC to ACES
+#
+def createLogC(gamut, transferFunction, exposureIndex, name, lutDir, lutResolution1d):
+    name = "%s (EI%s) - %s" % (transferFunction, exposureIndex, gamut)
+    if transferFunction == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s (EI%s)" % (transferFunction, exposureIndex)
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equalityGroup = ''
+    cs.family = 'ARRI'
+    cs.isData=False
+
+    # Globals
+    IDT_maker_version = "0.08"
+
+    nominalEI = 400.0
+    blackSignal = 0.003907
+    midGraySignal = 0.01
+    encodingGain = 0.256598
+    encodingOffset = 0.391007
+
+    def gainForEI(EI) :
+        return (math.log(EI/nominalEI)/math.log(2) * (0.89 - 1) / 3 + 1) * encodingGain
+
+    def LogCInverseParametersForEI(EI) :
+        cut = 1.0 / 9.0
+        slope = 1.0 / (cut * math.log(10))
+        offset = math.log10(cut) - slope * cut
+        gain = EI / nominalEI
+        gray = midGraySignal / gain
+        # The higher the EI, the lower the gamma
+        encGain = gainForEI(EI)
+        encOffset = encodingOffset
+        for i in range(0,3) :
+            nz = ((95.0 / 1023.0 - encOffset) / encGain - offset) / slope
+            encOffset = encodingOffset - math.log10(1 + nz) * encGain
+        # Calculate some intermediate values
+        a = 1.0 / gray
+        b = nz - blackSignal / gray
+        e = slope * a * encGain
+        f = encGain * (slope * b + offset) + encOffset
+        # Manipulations so we can return relative exposure
+        s = 4 / (0.18 * EI)
+        t = blackSignal
+        b = b + a * t
+        a = a * s
+        f = f + e * t
+        e = e * s
+        return { 'a' : a,
+                 'b' : b,
+                 'cut' : (cut - b) / a,
+                 'c' : encGain,
+                 'd' : encOffset,
+                 'e' : e,
+                 'f' : f }
+
+    def logCtoLinear(codeValue, exposureIndex):
+        p = LogCInverseParametersForEI(exposureIndex)
+        breakpoint = p['e'] * p['cut'] + p['f']
+        if (codeValue > breakpoint):
+            linear = (pow(10,(codeValue/1023.0 - p['d']) / p['c']) - p['b']) / p['a']
+        else:
+            linear = (codeValue/1023.0 - p['f']) / p['e']
+
+        #print( codeValue, linear )
+        return linear
+
+
+    cs.toReferenceTransforms = []
+
+    if transferFunction == "V3 LogC":
+        data = array.array('f', "\0" * lutResolution1d * 4)
+        for c in range(lutResolution1d):
+            data[c] = logCtoLinear(1023.0*c/(lutResolution1d-1), int(exposureIndex))
+
+        lut = "%s_to_linear.spi1d" % ("%s_%s" % (transferFunction, exposureIndex))
+        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
+
+        #print( "Writing %s" % lut)
+        cs.toReferenceTransforms.append( {
+            'type':'lutFile', 
+            'path':lut, 
+            'interpolation':'linear', 
+            'direction':'forward'
+        } )
+
+    if gamut == 'Wide Gamut':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.680206, 0.236137, 0.083658, 
+                        0.085415, 1.017471, -0.102886, 
+                        0.002057, -0.062563, 1.060506]),
+            'direction':'forward'
+        })
+
+    cs.fromReferenceTransforms = []
+    return cs
+
+def createColorSpaces(lutDir, lutResolution1d):
+    colorspaces = []
+
+    transferFunction = "V3 LogC"
+    gamut = "Wide Gamut"
+    #EIs = [160.0, 200.0, 250.0, 320.0, 400.0, 500.0, 640.0, 800.0, 1000.0, 1280.0, 1600.0, 2000.0, 2560.0, 3200.0]
+    EIs = [160, 200, 250, 320, 400, 500, 640, 800, 1000, 1280, 1600, 2000, 2560, 3200]
+    defaultEI = 800
+
+    # Full conversion
+    for EI in EIs:
+        LogCEIfull = createLogC(gamut, transferFunction, EI, "LogC", lutDir, lutResolution1d)
+        colorspaces.append(LogCEIfull)
+
+    # Linearization only
+    for EI in [800]:
+        LogCEIlinearization = createLogC("", transferFunction, EI, "LogC", lutDir, lutResolution1d)
+        colorspaces.append(LogCEIlinearization)
+
+    # Primaries
+    LogCEIprimaries = createLogC(gamut, "", defaultEI, "LogC", lutDir, lutResolution1d)
+    colorspaces.append(LogCEIprimaries)
+
+    return colorspaces
diff --git a/aces_1.0.0/python/createCanonColorSpaces.py b/aces_1.0.0/python/createCanonColorSpaces.py
new file mode 100644 (file)
index 0000000..194cc2e
--- /dev/null
@@ -0,0 +1,158 @@
+import array
+
+from util import *
+import generateLUT as genlut
+
+#
+# Canon-Log to ACES
+#
+def createCanonLog(gamut, transferFunction, name, lutDir, lutResolution1d):
+    name = "%s - %s" % (transferFunction, gamut)
+    if transferFunction == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s" % transferFunction
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equalityGroup = ''
+    cs.family = 'Canon'
+    cs.isData=False
+
+    def legalToFull(codeValue):
+        return (codeValue - 64.0)/(940.0 - 64.0)
+
+    def canonLogToLinear(codeValue):
+        # log = fullToLegal(c1 * log10(c2*linear + 1) + c3)
+        # linear = (pow(10, (legalToFul(log) - c3)/c1) - 1)/c2
+        c1 = 0.529136
+        c2 = 10.1596
+        c3 = 0.0730597
+
+        linear = (pow(10.0, (legalToFull(codeValue) - c3)/c1) -1.0)/c2
+        linear = 0.9 * linear
+        #print( codeValue, linear )
+        return linear
+
+    cs.toReferenceTransforms = []
+
+    if transferFunction == "Canon-Log":
+        data = array.array('f', "\0" * lutResolution1d * 4)
+        for c in range(lutResolution1d):
+            data[c] = canonLogToLinear(1023.0*c/(lutResolution1d-1))
+
+        lut = "%s_to_linear.spi1d" % transferFunction
+        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
+
+        cs.toReferenceTransforms.append( {
+            'type':'lutFile', 
+            'path':lut, 
+            'interpolation':'linear', 
+            'direction':'forward'
+        } )
+
+    if gamut == 'Rec. 709 Daylight':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':[0.561538969, 0.402060105, 0.036400926, 0.0, 
+                        0.092739623, 0.924121198, -0.016860821, 0.0, 
+                        0.084812961, 0.006373835, 0.908813204, 0.0, 
+                        0,0,0,1.0],
+            'direction':'forward'
+        })
+    elif gamut == 'Rec. 709 Tungsten':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':[0.566996399, 0.365079418, 0.067924183, 0.0, 
+                        0.070901044, 0.880331008, 0.048767948, 0.0, 
+                        0.073013542, -0.066540862, 0.99352732, 0.0, 
+                        0,0,0,1.0],
+            'direction':'forward'
+        })
+    elif gamut == 'DCI-P3 Daylight':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':[0.607160575, 0.299507286, 0.093332140, 0.0, 
+                        0.004968120, 1.050982224, -0.055950343, 0.0, 
+                        -0.007839939, 0.000809127, 1.007030813, 0.0, 
+                        0,0,0,1.0],
+            'direction':'forward'
+        })
+    elif gamut == 'DCI-P3 Tungsten':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':[0.650279125, 0.253880169, 0.095840706, 0.0, 
+                        -0.026137986, 1.017900530, 0.008237456, 0.0, 
+                        0.007757558, -0.063081669, 1.055324110, 0.0, 
+                        0,0,0,1.0],
+            'direction':'forward'
+        })
+    elif gamut == 'Cinema Gamut Daylight':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':[0.763064455, 0.149021161, 0.087914384, 0.0, 
+                        0.003657457, 1.10696038, -0.110617837, 0.0, 
+                        -0.009407794,-0.218383305, 1.227791099, 0.0, 
+                        0,0,0,1.0],
+            'direction':'forward'
+        })
+    elif gamut == 'Cinema Gamut Tungsten':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':[0.817416293, 0.090755698, 0.091828009, 0.0, 
+                        -0.035361374, 1.065690585, -0.030329211, 0.0, 
+                        0.010390366, -0.299271107, 1.288880741, 0.0, 
+                        0,0,0,1.0],
+            'direction':'forward'
+        })
+
+    cs.fromReferenceTransforms = []
+    return cs
+
+# Generate all color spaces conversion
+def createColorSpaces(lutDir, lutResolution1d):
+    colorspaces = []
+
+    # Full conversion
+    CanonLog1 = createCanonLog("Rec. 709 Daylight", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog1)
+
+    CanonLog2 = createCanonLog("Rec. 709 Tungsten", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog2)
+
+    CanonLog3 = createCanonLog("DCI-P3 Daylight", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog3)
+
+    CanonLog4 = createCanonLog("DCI-P3 Tungsten", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog4)
+
+    CanonLog5 = createCanonLog("Cinema Gamut Daylight", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog5)
+
+    CanonLog6 = createCanonLog("Cinema Gamut Tungsten", "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog6)
+
+    # Linearization only
+    CanonLog7 = createCanonLog('', "Canon-Log", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog7)
+
+    # Primaries only
+    CanonLog8 = createCanonLog("Rec. 709 Daylight", "", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog8)
+
+    CanonLog9 = createCanonLog("Rec. 709 Tungsten", "", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog9)
+
+    CanonLog10 = createCanonLog("DCI-P3 Daylight", "", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog10)
+
+    CanonLog11 = createCanonLog("DCI-P3 Tungsten", "", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog11)
+
+    CanonLog12 = createCanonLog("Cinema Gamut Daylight", "", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog12)
+
+    CanonLog13 = createCanonLog("Cinema Gamut Tungsten", "", "Canon-Log", lutDir, lutResolution1d)
+    colorspaces.append(CanonLog13)
+
+    return colorspaces
diff --git a/aces_1.0.0/python/createREDColorSpaces.py b/aces_1.0.0/python/createREDColorSpaces.py
new file mode 100644 (file)
index 0000000..0e3823d
--- /dev/null
@@ -0,0 +1,134 @@
+import array
+
+from util import *
+import generateLUT as genlut
+
+#
+# RED color spaces to ACES
+#
+def createREDlogFilm(gamut, transferFunction, name, lutDir, lutResolution1d):
+    name = "%s - %s" % (transferFunction, gamut)
+    if transferFunction == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s" % transferFunction
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equalityGroup = ''
+    cs.family = 'RED'
+    cs.isData=False
+
+    def cineonToLinear(codeValue):
+        nGamma = 0.6
+        blackPoint = 95.0
+        whitePoint = 685.0
+        codeValueToDensity = 0.002
+
+        blackLinear = pow(10.0, (blackPoint - whitePoint) * (codeValueToDensity / nGamma))
+        codeLinear = pow(10.0, (codeValue - whitePoint) * (codeValueToDensity / nGamma))
+
+        return (codeLinear - blackLinear)/(1.0 - blackLinear)
+
+    cs.toReferenceTransforms = []
+
+    if transferFunction == 'REDlogFilm':
+        data = array.array('f', "\0" * lutResolution1d * 4)
+        for c in range(lutResolution1d):
+            data[c] = cineonToLinear(1023.0*c/(lutResolution1d-1))
+
+        lut = "CineonLog_to_linear.spi1d"
+        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
+
+        cs.toReferenceTransforms.append( {
+            'type':'lutFile', 
+            'path':lut, 
+            'interpolation':'linear', 
+            'direction':'forward'
+        } )
+
+    if gamut == 'DRAGONcolor':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.532279,  0.376648,  0.091073, 
+                                     0.046344,  0.974513, -0.020860, 
+                                    -0.053976, -0.000320, 1.054267]),
+            'direction':'forward'
+        })
+    elif gamut == 'DRAGONcolor2':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.468452,  0.331484,  0.200064, 
+                                     0.040787,  0.857658,  0.101553, 
+                                    -0.047504, -0.000282, 1.047756]),
+            'direction':'forward'
+        })
+    elif gamut == 'REDcolor2':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.480997, 0.402289, 0.116714, 
+                                    -0.004938, 1.000154, 0.004781, 
+                                    -0.105257, 0.025320, 1.079907]),
+            'direction':'forward'
+        })
+    elif gamut == 'REDcolor3':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.512136, 0.360370, 0.127494, 
+                                     0.070377, 0.903884, 0.025737, 
+                                    -0.020824, 0.017671, 1.003123]),
+            'direction':'forward'
+        })
+    elif gamut == 'REDcolor4':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.474202, 0.333677, 0.192121, 
+                                     0.065164, 0.836932, 0.097901, 
+                                    -0.019281, 0.016362, 1.002889]),
+            'direction':'forward'
+        })
+
+    cs.fromReferenceTransforms = []
+    return cs
+
+# Generate all color spaces conversion
+def createColorSpaces(lutDir, lutResolution1d):
+    colorspaces = []
+
+    # Full conversion
+    REDlogFilmDRAGON = createREDlogFilm("DRAGONcolor", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmDRAGON)
+
+    REDlogFilmDRAGON2 = createREDlogFilm("DRAGONcolor2", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmDRAGON2)
+
+    REDlogFilmREDcolor2 = createREDlogFilm("REDcolor2", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmREDcolor2)
+
+    REDlogFilmREDcolor3 = createREDlogFilm("REDcolor3", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmREDcolor3)
+
+    REDlogFilmREDcolor4 = createREDlogFilm("REDcolor4", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmREDcolor4)
+
+    # Linearization only
+    REDlogFilmDRAGON = createREDlogFilm("", "REDlogFilm", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmDRAGON)
+
+    # Primaries only
+    REDlogFilmDRAGON = createREDlogFilm("DRAGONcolor", "", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmDRAGON)
+
+    REDlogFilmDRAGON2 = createREDlogFilm("DRAGONcolor2", "", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmDRAGON2)
+
+    REDlogFilmREDcolor2 = createREDlogFilm("REDcolor2", "", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmREDcolor2)
+
+    REDlogFilmREDcolor3 = createREDlogFilm("REDcolor3", "", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmREDcolor3)
+
+    REDlogFilmREDcolor4 = createREDlogFilm("REDcolor4", "", "REDlogFilm", lutDir, lutResolution1d)
+    colorspaces.append(REDlogFilmREDcolor4)
+
+    return colorspaces
diff --git a/aces_1.0.0/python/createSonyColorSpaces.py b/aces_1.0.0/python/createSonyColorSpaces.py
new file mode 100644 (file)
index 0000000..dcfbb43
--- /dev/null
@@ -0,0 +1,198 @@
+import array
+
+from util import *
+import generateLUT as genlut
+
+#
+# SLog to ACES
+#
+def createSlog(gamut, transferFunction, name, lutDir, lutResolution1d):
+    name = "%s - %s" % (transferFunction, gamut)
+    if transferFunction == "":
+        name = "Linear - %s" % gamut
+    if gamut == "":
+        name = "%s" % transferFunction
+
+    cs = ColorSpace(name)
+    cs.description = name
+    cs.equalityGroup = ''
+    cs.family = 'Sony'
+    cs.isData=False
+
+    def sLog1ToLinear(SLog):
+        b = 64.
+        ab = 90.
+        w = 940.
+
+        if (SLog >= ab):
+            lin = ( pow(10., ( ( ( SLog - b) / ( w - b) - 0.616596 - 0.03) / 0.432699)) - 0.037584) * 0.9
+        else:
+            lin = ( ( ( SLog - b) / ( w - b) - 0.030001222851889303) / 5.) * 0.9 
+        return lin
+
+    def sLog2ToLinear(SLog):
+        b = 64.
+        ab = 90.
+        w = 940.
+
+        if (SLog >= ab):
+            lin = ( 219. * ( pow(10., ( ( ( SLog - b) / ( w - b) - 0.616596 - 0.03) / 0.432699)) - 0.037584) / 155.) * 0.9
+        else:
+            lin = ( ( ( SLog - b) / ( w - b) - 0.030001222851889303) / 3.53881278538813) * 0.9
+        return lin
+
+    def sLog3ToLinear(codeValue):
+        if codeValue >= (171.2102946929):
+            linear = pow(10.0, ((codeValue - 420.0) / 261.5)) * (0.18 + 0.01) - 0.01
+        else:
+            linear = (codeValue - 95.0)*0.01125000/(171.2102946929 - 95.0)
+        #print( codeValue, linear )
+        return linear
+
+    cs.toReferenceTransforms = []
+
+    if transferFunction == "S-Log1":
+        data = array.array('f', "\0" * lutResolution1d * 4)
+        for c in range(lutResolution1d):
+            data[c] = sLog1ToLinear(1023.0*c/(lutResolution1d-1))
+
+        lut = "%s_to_linear.spi1d" % transferFunction
+        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
+
+        #print( "Writing %s" % lut)
+
+        cs.toReferenceTransforms.append( {
+            'type':'lutFile', 
+            'path':lut, 
+            'interpolation':'linear', 
+            'direction':'forward'
+        } )
+    elif transferFunction == "S-Log2":
+        data = array.array('f', "\0" * lutResolution1d * 4)
+        for c in range(lutResolution1d):
+            data[c] = sLog2ToLinear(1023.0*c/(lutResolution1d-1))
+
+        lut = "%s_to_linear.spi1d" % transferFunction
+        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
+
+        #print( "Writing %s" % lut)
+
+        cs.toReferenceTransforms.append( {
+            'type':'lutFile', 
+            'path':lut, 
+            'interpolation':'linear', 
+            'direction':'forward'
+        } )
+    elif transferFunction == "S-Log3":
+        data = array.array('f', "\0" * lutResolution1d * 4)
+        for c in range(lutResolution1d):
+            data[c] = sLog3ToLinear(1023.0*c/(lutResolution1d-1))
+
+        lut = "%s_to_linear.spi1d" % transferFunction
+        genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
+
+        #print( "Writing %s" % lut)
+
+        cs.toReferenceTransforms.append( {
+            'type':'lutFile', 
+            'path':lut, 
+            'interpolation':'linear', 
+            'direction':'forward'
+        } )
+
+    if gamut == 'S-Gamut':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.754338638, 0.133697046, 0.111968437,
+                                    0.021198141, 1.005410934, -0.026610548, 
+                                    -0.009756991, 0.004508563, 1.005253201]),
+            'direction':'forward'
+        })
+    elif gamut == 'S-Gamut Daylight':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.8764457030, 0.0145411681, 0.1090131290,
+                                    0.0774075345, 0.9529571767, -0.0303647111, 
+                                    0.0573564351, -0.1151066335, 1.0577501984]),
+            'direction':'forward'
+        })
+    elif gamut == 'S-Gamut Tungsten':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([1.0110238740, -0.1362526051, 0.1252287310, 
+                        0.1011994504, 0.9562196265, -0.0574190769,
+                        0.0600766530, -0.1010185315, 1.0409418785]),
+            'direction':'forward'
+        })
+    elif gamut == 'S-Gamut3.Cine':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.6387886672, 0.2723514337, 0.0888598992, 
+                                    -0.0039159061, 1.0880732308, -0.0841573249, 
+                                    -0.0299072021, -0.0264325799, 1.0563397820]),
+            'direction':'forward'
+        })
+    elif gamut == 'S-Gamut3':
+        cs.toReferenceTransforms.append( {
+            'type':'matrix',
+            'matrix':mat44FromMat33([0.7529825954, 0.1433702162, 0.1036471884, 
+                        0.0217076974, 1.0153188355, -0.0370265329, 
+                        -0.0094160528, 0.0033704179, 1.0060456349]),
+            'direction':'forward'
+        })
+
+    cs.fromReferenceTransforms = []
+    return cs
+
+def createColorSpaces(lutDir, lutResolution1d):
+    colorspaces = []
+
+    # SLog1
+    SLog1SGamut = createSlog("S-Gamut", "S-Log1", "S-Log", lutDir, lutResolution1d)
+    colorspaces.append(SLog1SGamut)
+
+    # SLog2
+    SLog2SGamut = createSlog("S-Gamut", "S-Log2", "S-Log2", lutDir, lutResolution1d)
+    colorspaces.append(SLog2SGamut)
+
+    SLog2SGamutDaylight = createSlog("S-Gamut Daylight", "S-Log2", "S-Log2", lutDir, lutResolution1d)
+    colorspaces.append(SLog2SGamutDaylight)
+
+    SLog2SGamutTungsten = createSlog("S-Gamut Tungsten", "S-Log2", "S-Log2", lutDir, lutResolution1d)
+    colorspaces.append(SLog2SGamutTungsten)
+
+    # SLog3
+    SLog3SGamut3Cine = createSlog("S-Gamut3.Cine", "S-Log3", "S-Log3", lutDir, lutResolution1d)
+    colorspaces.append(SLog3SGamut3Cine)
+
+    SLog3SGamut3 = createSlog("S-Gamut3", "S-Log3", "S-Log3", lutDir, lutResolution1d)
+    colorspaces.append(SLog3SGamut3)
+
+    # Linearization only
+    SLog1 = createSlog("", "S-Log1", "S-Log", lutDir, lutResolution1d)
+    colorspaces.append(SLog1)
+
+    SLog2 = createSlog("", "S-Log2", "S-Log2", lutDir, lutResolution1d)
+    colorspaces.append(SLog2)
+
+    SLog3 = createSlog("", "S-Log3", "S-Log3", lutDir, lutResolution1d)
+    colorspaces.append(SLog3)
+
+    # Primaries only
+    SGamut = createSlog("S-Gamut", "", "S-Log", lutDir, lutResolution1d)
+    colorspaces.append(SGamut)
+
+    SGamutDaylight = createSlog("S-Gamut Daylight", "", "S-Log2", lutDir, lutResolution1d)
+    colorspaces.append(SGamutDaylight)
+
+    SGamutTungsten = createSlog("S-Gamut Tungsten", "", "S-Log2", lutDir, lutResolution1d)
+    colorspaces.append(SGamutTungsten)
+
+    SGamut3Cine = createSlog("S-Gamut3.Cine", "", "S-Log3", lutDir, lutResolution1d)
+    colorspaces.append(SGamut3Cine)
+
+    SGamut3 = createSlog("S-Gamut3", "", "S-Log3", lutDir, lutResolution1d)
+    colorspaces.append(SGamut3)
+
+    return colorspaces
+
index f61002e..7e01865 100755 (executable)
@@ -49,7 +49,13 @@ import OpenImageIO as oiio
 import PyOpenColorIO as OCIO
 
 import process
+from util import *
+
 import generateLUT as genlut
+import createREDColorSpaces as red
+import createCanonColorSpaces as canon
+import createSonyColorSpaces as sony
+import createARRIColorSpaces as arri
 
 #
 # Utility functions
@@ -274,39 +280,6 @@ def createConfig(configData, nuke=False):
 #
 # Functions to generate color space definitions and LUTs for transforms for a specific ACES release
 #
-class ColorSpace:
-    "A container for data needed to define an OCIO 'Color Space' "
-
-    def __init__(self, 
-        name, 
-        description=None, 
-        bitDepth=OCIO.Constants.BIT_DEPTH_F32,
-        equalityGroup=None,
-        family=None,
-        isData=False,
-        toReferenceTransforms=[],
-        fromReferenceTransforms=[],
-        allocationType=OCIO.Constants.ALLOCATION_UNIFORM,
-        allocationVars=[0.0, 1.0]):
-        "Initialize the standard class variables"
-        self.name = name
-        self.bitDepth=bitDepth
-        self.description = description
-        self.equalityGroup=equalityGroup
-        self.family=family 
-        self.isData=isData
-        self.toReferenceTransforms=toReferenceTransforms
-        self.fromReferenceTransforms=fromReferenceTransforms
-        self.allocationType=allocationType
-        self.allocationVars=allocationVars
-
-# Create a 4x4 matrix (list) based on a 3x3 matrix (list) input
-def mat44FromMat33(mat33):
-    return [mat33[0], mat33[1], mat33[2], 0.0, 
-            mat33[3], mat33[4], mat33[5], 0.0, 
-            mat33[6], mat33[7], mat33[8], 0.0, 
-            0,0,0,1.0]
-
 
 # Output is a list of colorspaces and transforms that convert between those
 # colorspaces and reference color space, ACES
@@ -608,588 +581,29 @@ def generateLUTs(odtInfo, lmtInfo, shaperName, acesCTLReleaseDir, lutDir, lutRes
     ADX16 = createADX(bitdepth=16)
     configData['colorSpaces'].append(ADX16)
 
-
     #
-    # REDlogFilm to ACES
+    # Camera Input Transforms
     #
-    def createREDlogFilm(gamut, transferFunction, name='REDlogFilm'):
-        name = "%s - %s" % (transferFunction, gamut)
-        if transferFunction == "":
-            name = "Linear - %s" % gamut
-        if gamut == "":
-            name = "%s" % transferFunction
-
-        cs = ColorSpace(name)
-        cs.description = name
-        cs.equalityGroup = ''
-        cs.family = 'RED'
-        cs.isData=False
-
-        def cineonToLinear(codeValue):
-            nGamma = 0.6
-            blackPoint = 95.0
-            whitePoint = 685.0
-            codeValueToDensity = 0.002
-
-            blackLinear = pow(10.0, (blackPoint - whitePoint) * (codeValueToDensity / nGamma))
-            codeLinear = pow(10.0, (codeValue - whitePoint) * (codeValueToDensity / nGamma))
-
-            return (codeLinear - blackLinear)/(1.0 - blackLinear)
-
-        cs.toReferenceTransforms = []
-
-        if transferFunction == 'REDlogFilm':
-            data = array.array('f', "\0" * lutResolution1d * 4)
-            for c in range(lutResolution1d):
-                data[c] = cineonToLinear(1023.0*c/(lutResolution1d-1))
 
-            lut = "CineonLog_to_linear.spi1d"
-            genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'linear', 
-                'direction':'forward'
-            } )
-
-        if gamut == 'DRAGONcolor':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.532279,  0.376648,  0.091073, 
-                                         0.046344,  0.974513, -0.020860, 
-                                        -0.053976, -0.000320, 1.054267]),
-                'direction':'forward'
-            })
-        elif gamut == 'DRAGONcolor2':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.468452,  0.331484,  0.200064, 
-                                         0.040787,  0.857658,  0.101553, 
-                                        -0.047504, -0.000282, 1.047756]),
-                'direction':'forward'
-            })
-        elif gamut == 'REDcolor2':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.480997, 0.402289, 0.116714, 
-                                        -0.004938, 1.000154, 0.004781, 
-                                        -0.105257, 0.025320, 1.079907]),
-                'direction':'forward'
-            })
-        elif gamut == 'REDcolor3':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.512136, 0.360370, 0.127494, 
-                                         0.070377, 0.903884, 0.025737, 
-                                        -0.020824, 0.017671, 1.003123]),
-                'direction':'forward'
-            })
-        elif gamut == 'REDcolor4':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.474202, 0.333677, 0.192121, 
-                                         0.065164, 0.836932, 0.097901, 
-                                        -0.019281, 0.016362, 1.002889]),
-                'direction':'forward'
-            })
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    # Full conversion
-    REDlogFilmDRAGON = createREDlogFilm("DRAGONcolor", "REDlogFilm", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmDRAGON)
-
-    REDlogFilmDRAGON2 = createREDlogFilm("DRAGONcolor2", "REDlogFilm", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmDRAGON2)
-
-    REDlogFilmREDcolor2 = createREDlogFilm("REDcolor2", "REDlogFilm", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmREDcolor2)
-
-    REDlogFilmREDcolor3 = createREDlogFilm("REDcolor3", "REDlogFilm", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmREDcolor3)
-
-    REDlogFilmREDcolor4 = createREDlogFilm("REDcolor4", "REDlogFilm", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmREDcolor4)
-
-    # Linearization only
-    REDlogFilmDRAGON = createREDlogFilm("", "REDlogFilm", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmDRAGON)
-
-    # Primaries only
-    REDlogFilmDRAGON = createREDlogFilm("DRAGONcolor", "", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmDRAGON)
-
-    REDlogFilmDRAGON2 = createREDlogFilm("DRAGONcolor2", "", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmDRAGON2)
-
-    REDlogFilmREDcolor2 = createREDlogFilm("REDcolor2", "", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmREDcolor2)
-
-    REDlogFilmREDcolor3 = createREDlogFilm("REDcolor3", "", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmREDcolor3)
-
-    REDlogFilmREDcolor4 = createREDlogFilm("REDcolor4", "", name="REDlogFilm")
-    configData['colorSpaces'].append(REDlogFilmREDcolor4)
+    # RED color spaces to ACES
+    redColorSpaces = red.createColorSpaces(lutDir, lutResolution1d)
+    for cs in redColorSpaces:
+        configData['colorSpaces'].append(cs)
 
-    #
     # Canon-Log to ACES
-    #
-    def createCanonLog(gamut, transferFunction, name='Canon-Log'):
-        name = "%s - %s" % (transferFunction, gamut)
-        if transferFunction == "":
-            name = "Linear - %s" % gamut
-        if gamut == "":
-            name = "%s" % transferFunction
-
-        cs = ColorSpace(name)
-        cs.description = name
-        cs.equalityGroup = ''
-        cs.family = 'Canon'
-        cs.isData=False
-
-        def legalToFull(codeValue):
-            return (codeValue - 64.0)/(940.0 - 64.0)
-
-        def canonLogToLinear(codeValue):
-            # log = fullToLegal(c1 * log10(c2*linear + 1) + c3)
-            # linear = (pow(10, (legalToFul(log) - c3)/c1) - 1)/c2
-            c1 = 0.529136
-            c2 = 10.1596
-            c3 = 0.0730597
-
-            linear = (pow(10.0, (legalToFull(codeValue) - c3)/c1) -1.0)/c2
-            linear = 0.9 * linear
-            #print( codeValue, linear )
-            return linear
-
-        cs.toReferenceTransforms = []
-
-        if transferFunction == "Canon-Log":
-            data = array.array('f', "\0" * lutResolution1d * 4)
-            for c in range(lutResolution1d):
-                data[c] = canonLogToLinear(1023.0*c/(lutResolution1d-1))
-
-            lut = "%s_to_linear.spi1d" % transferFunction
-            genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'linear', 
-                'direction':'forward'
-            } )
-
-        if gamut == 'Rec. 709 Daylight':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':[0.561538969, 0.402060105, 0.036400926, 0.0, 
-                            0.092739623, 0.924121198, -0.016860821, 0.0, 
-                            0.084812961, 0.006373835, 0.908813204, 0.0, 
-                            0,0,0,1.0],
-                'direction':'forward'
-            })
-        elif gamut == 'Rec. 709 Tungsten':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':[0.566996399, 0.365079418, 0.067924183, 0.0, 
-                            0.070901044, 0.880331008, 0.048767948, 0.0, 
-                            0.073013542, -0.066540862, 0.99352732, 0.0, 
-                            0,0,0,1.0],
-                'direction':'forward'
-            })
-        elif gamut == 'DCI-P3 Daylight':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':[0.607160575, 0.299507286, 0.093332140, 0.0, 
-                            0.004968120, 1.050982224, -0.055950343, 0.0, 
-                            -0.007839939, 0.000809127, 1.007030813, 0.0, 
-                            0,0,0,1.0],
-                'direction':'forward'
-            })
-        elif gamut == 'DCI-P3 Tungsten':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':[0.650279125, 0.253880169, 0.095840706, 0.0, 
-                            -0.026137986, 1.017900530, 0.008237456, 0.0, 
-                            0.007757558, -0.063081669, 1.055324110, 0.0, 
-                            0,0,0,1.0],
-                'direction':'forward'
-            })
-        elif gamut == 'Cinema Gamut Daylight':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':[0.763064455, 0.149021161, 0.087914384, 0.0, 
-                            0.003657457, 1.10696038, -0.110617837, 0.0, 
-                            -0.009407794,-0.218383305, 1.227791099, 0.0, 
-                            0,0,0,1.0],
-                'direction':'forward'
-            })
-        elif gamut == 'Cinema Gamut Tungsten':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':[0.817416293, 0.090755698, 0.091828009, 0.0, 
-                            -0.035361374, 1.065690585, -0.030329211, 0.0, 
-                            0.010390366, -0.299271107, 1.288880741, 0.0, 
-                            0,0,0,1.0],
-                'direction':'forward'
-            })
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    # Full conversion
-    CanonLog1 = createCanonLog("Rec. 709 Daylight", "Canon-Log", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog1)
-
-    CanonLog2 = createCanonLog("Rec. 709 Tungsten", "Canon-Log", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog2)
-
-    CanonLog3 = createCanonLog("DCI-P3 Daylight", "Canon-Log", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog3)
-
-    CanonLog4 = createCanonLog("DCI-P3 Tungsten", "Canon-Log", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog4)
-
-    CanonLog5 = createCanonLog("Cinema Gamut Daylight", "Canon-Log", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog5)
-
-    CanonLog6 = createCanonLog("Cinema Gamut Tungsten", "Canon-Log", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog6)
-
-    # Linearization only
-    CanonLog7 = createCanonLog('', "Canon-Log", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog7)
-
-    # Primaries only
-    CanonLog8 = createCanonLog("Rec. 709 Daylight", "", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog8)
-
-    CanonLog9 = createCanonLog("Rec. 709 Tungsten", "", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog9)
-
-    CanonLog10 = createCanonLog("DCI-P3 Daylight", "", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog10)
-
-    CanonLog11 = createCanonLog("DCI-P3 Tungsten", "", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog11)
-
-    CanonLog12 = createCanonLog("Cinema Gamut Daylight", "", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog12)
-
-    CanonLog13 = createCanonLog("Cinema Gamut Tungsten", "", name="Canon-Log")
-    configData['colorSpaces'].append(CanonLog13)
+    canonColorSpaces = canon.createColorSpaces(lutDir, lutResolution1d)
+    for cs in canonColorSpaces:
+        configData['colorSpaces'].append(cs)
 
-    #
     # SLog to ACES
-    #
-    def createSlog(gamut, transferFunction, name='S-Log3'):
-        name = "%s - %s" % (transferFunction, gamut)
-        if transferFunction == "":
-            name = "Linear - %s" % gamut
-        if gamut == "":
-            name = "%s" % transferFunction
-
-        cs = ColorSpace(name)
-        cs.description = name
-        cs.equalityGroup = ''
-        cs.family = 'Sony'
-        cs.isData=False
-
-        def sLog1ToLinear(SLog):
-            b = 64.
-            ab = 90.
-            w = 940.
-
-            if (SLog >= ab):
-                lin = ( pow(10., ( ( ( SLog - b) / ( w - b) - 0.616596 - 0.03) / 0.432699)) - 0.037584) * 0.9
-            else:
-                lin = ( ( ( SLog - b) / ( w - b) - 0.030001222851889303) / 5.) * 0.9 
-            return lin
-
-        def sLog2ToLinear(SLog):
-            b = 64.
-            ab = 90.
-            w = 940.
-
-            if (SLog >= ab):
-                lin = ( 219. * ( pow(10., ( ( ( SLog - b) / ( w - b) - 0.616596 - 0.03) / 0.432699)) - 0.037584) / 155.) * 0.9
-            else:
-                lin = ( ( ( SLog - b) / ( w - b) - 0.030001222851889303) / 3.53881278538813) * 0.9
-            return lin
-
-        def sLog3ToLinear(codeValue):
-            if codeValue >= (171.2102946929):
-                linear = pow(10.0, ((codeValue - 420.0) / 261.5)) * (0.18 + 0.01) - 0.01
-            else:
-                linear = (codeValue - 95.0)*0.01125000/(171.2102946929 - 95.0)
-            #print( codeValue, linear )
-            return linear
-
-        cs.toReferenceTransforms = []
-
-        if transferFunction == "S-Log1":
-            data = array.array('f', "\0" * lutResolution1d * 4)
-            for c in range(lutResolution1d):
-                data[c] = sLog1ToLinear(1023.0*c/(lutResolution1d-1))
-
-            lut = "%s_to_linear.spi1d" % transferFunction
-            genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-            #print( "Writing %s" % lut)
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'linear', 
-                'direction':'forward'
-            } )
-        elif transferFunction == "S-Log2":
-            data = array.array('f', "\0" * lutResolution1d * 4)
-            for c in range(lutResolution1d):
-                data[c] = sLog2ToLinear(1023.0*c/(lutResolution1d-1))
-
-            lut = "%s_to_linear.spi1d" % transferFunction
-            genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-            #print( "Writing %s" % lut)
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'linear', 
-                'direction':'forward'
-            } )
-        elif transferFunction == "S-Log3":
-            data = array.array('f', "\0" * lutResolution1d * 4)
-            for c in range(lutResolution1d):
-                data[c] = sLog3ToLinear(1023.0*c/(lutResolution1d-1))
-
-            lut = "%s_to_linear.spi1d" % transferFunction
-            genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-            #print( "Writing %s" % lut)
-
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'linear', 
-                'direction':'forward'
-            } )
-
-        if gamut == 'S-Gamut':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.754338638, 0.133697046, 0.111968437,
-                                        0.021198141, 1.005410934, -0.026610548, 
-                                        -0.009756991, 0.004508563, 1.005253201]),
-                'direction':'forward'
-            })
-        elif gamut == 'S-Gamut Daylight':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.8764457030, 0.0145411681, 0.1090131290,
-                                        0.0774075345, 0.9529571767, -0.0303647111, 
-                                        0.0573564351, -0.1151066335, 1.0577501984]),
-                'direction':'forward'
-            })
-        elif gamut == 'S-Gamut Tungsten':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([1.0110238740, -0.1362526051, 0.1252287310, 
-                            0.1011994504, 0.9562196265, -0.0574190769,
-                            0.0600766530, -0.1010185315, 1.0409418785]),
-                'direction':'forward'
-            })
-        elif gamut == 'S-Gamut3.Cine':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.6387886672, 0.2723514337, 0.0888598992, 
-                                        -0.0039159061, 1.0880732308, -0.0841573249, 
-                                        -0.0299072021, -0.0264325799, 1.0563397820]),
-                'direction':'forward'
-            })
-        elif gamut == 'S-Gamut3':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.7529825954, 0.1433702162, 0.1036471884, 
-                            0.0217076974, 1.0153188355, -0.0370265329, 
-                            -0.0094160528, 0.0033704179, 1.0060456349]),
-                'direction':'forward'
-            })
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    # SLog1
-    SLog1SGamut = createSlog("S-Gamut", "S-Log1", name="S-Log")
-    configData['colorSpaces'].append(SLog1SGamut)
-
-    # SLog2
-    SLog2SGamut = createSlog("S-Gamut", "S-Log2", name="S-Log2")
-    configData['colorSpaces'].append(SLog2SGamut)
-
-    SLog2SGamutDaylight = createSlog("S-Gamut Daylight", "S-Log2", name="S-Log2")
-    configData['colorSpaces'].append(SLog2SGamutDaylight)
-
-    SLog2SGamutTungsten = createSlog("S-Gamut Tungsten", "S-Log2", name="S-Log2")
-    configData['colorSpaces'].append(SLog2SGamutTungsten)
-
-    # SLog3
-    SLog3SGamut3Cine = createSlog("S-Gamut3.Cine", "S-Log3", name="S-Log3")
-    configData['colorSpaces'].append(SLog3SGamut3Cine)
-
-    SLog3SGamut3 = createSlog("S-Gamut3", "S-Log3", name="S-Log3")
-    configData['colorSpaces'].append(SLog3SGamut3)
-
-    # Linearization only
-    SLog1 = createSlog("", "S-Log1", name="S-Log")
-    configData['colorSpaces'].append(SLog1)
-
-    SLog2 = createSlog("", "S-Log2", name="S-Log2")
-    configData['colorSpaces'].append(SLog2)
-
-    SLog3 = createSlog("", "S-Log3", name="S-Log3")
-    configData['colorSpaces'].append(SLog3)
-
-    # Primaries only
-    SGamut = createSlog("S-Gamut", "", name="S-Log")
-    configData['colorSpaces'].append(SGamut)
-
-    SGamutDaylight = createSlog("S-Gamut Daylight", "", name="S-Log2")
-    configData['colorSpaces'].append(SGamutDaylight)
-
-    SGamutTungsten = createSlog("S-Gamut Tungsten", "", name="S-Log2")
-    configData['colorSpaces'].append(SGamutTungsten)
-
-    SGamut3Cine = createSlog("S-Gamut3.Cine", "", name="S-Log3")
-    configData['colorSpaces'].append(SGamut3Cine)
-
-    SGamut3 = createSlog("S-Gamut3", "", name="S-Log3")
-    configData['colorSpaces'].append(SGamut3)
+    sonyColorSpaces = sony.createColorSpaces(lutDir, lutResolution1d)
+    for cs in sonyColorSpaces:
+        configData['colorSpaces'].append(cs)
 
-    #
     # LogC to ACES
-    #
-    def createLogC(gamut, transferFunction, exposureIndex, name='LogC'):
-        name = "%s (EI%s) - %s" % (transferFunction, exposureIndex, gamut)
-        if transferFunction == "":
-            name = "Linear - %s" % gamut
-        if gamut == "":
-            name = "%s (EI%s)" % (transferFunction, exposureIndex)
-
-        cs = ColorSpace(name)
-        cs.description = name
-        cs.equalityGroup = ''
-        cs.family = 'ARRI'
-        cs.isData=False
-
-        # Globals
-        IDT_maker_version = "0.08"
-
-        nominalEI = 400.0
-        blackSignal = 0.003907
-        midGraySignal = 0.01
-        encodingGain = 0.256598
-        encodingOffset = 0.391007
-
-        def gainForEI(EI) :
-            return (math.log(EI/nominalEI)/math.log(2) * (0.89 - 1) / 3 + 1) * encodingGain
-
-        def LogCInverseParametersForEI(EI) :
-            cut = 1.0 / 9.0
-            slope = 1.0 / (cut * math.log(10))
-            offset = math.log10(cut) - slope * cut
-            gain = EI / nominalEI
-            gray = midGraySignal / gain
-            # The higher the EI, the lower the gamma
-            encGain = gainForEI(EI)
-            encOffset = encodingOffset
-            for i in range(0,3) :
-                nz = ((95.0 / 1023.0 - encOffset) / encGain - offset) / slope
-                encOffset = encodingOffset - math.log10(1 + nz) * encGain
-            # Calculate some intermediate values
-            a = 1.0 / gray
-            b = nz - blackSignal / gray
-            e = slope * a * encGain
-            f = encGain * (slope * b + offset) + encOffset
-            # Manipulations so we can return relative exposure
-            s = 4 / (0.18 * EI)
-            t = blackSignal
-            b = b + a * t
-            a = a * s
-            f = f + e * t
-            e = e * s
-            return { 'a' : a,
-                     'b' : b,
-                     'cut' : (cut - b) / a,
-                     'c' : encGain,
-                     'd' : encOffset,
-                     'e' : e,
-                     'f' : f }
-
-        def logCtoLinear(codeValue, exposureIndex):
-            p = LogCInverseParametersForEI(exposureIndex)
-            breakpoint = p['e'] * p['cut'] + p['f']
-            if (codeValue > breakpoint):
-                linear = (pow(10,(codeValue/1023.0 - p['d']) / p['c']) - p['b']) / p['a']
-            else:
-                linear = (codeValue/1023.0 - p['f']) / p['e']
-
-            #print( codeValue, linear )
-            return linear
-
-
-        cs.toReferenceTransforms = []
-
-        if transferFunction == "V3 LogC":
-            data = array.array('f', "\0" * lutResolution1d * 4)
-            for c in range(lutResolution1d):
-                data[c] = logCtoLinear(1023.0*c/(lutResolution1d-1), int(exposureIndex))
-
-            lut = "%s_to_linear.spi1d" % ("%s_%s" % (transferFunction, exposureIndex))
-            genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
-
-            #print( "Writing %s" % lut)
-            cs.toReferenceTransforms.append( {
-                'type':'lutFile', 
-                'path':lut, 
-                'interpolation':'linear', 
-                'direction':'forward'
-            } )
-
-        if gamut == 'Wide Gamut':
-            cs.toReferenceTransforms.append( {
-                'type':'matrix',
-                'matrix':mat44FromMat33([0.680206, 0.236137, 0.083658, 
-                            0.085415, 1.017471, -0.102886, 
-                            0.002057, -0.062563, 1.060506]),
-                'direction':'forward'
-            })
-
-        cs.fromReferenceTransforms = []
-        return cs
-
-    transferFunction = "V3 LogC"
-    gamut = "Wide Gamut"
-    #EIs = [160.0, 200.0, 250.0, 320.0, 400.0, 500.0, 640.0, 800.0, 1000.0, 1280.0, 1600.0, 2000.0, 2560.0, 3200.0]
-    EIs = [160, 200, 250, 320, 400, 500, 640, 800, 1000, 1280, 1600, 2000, 2560, 3200]
-    defaultEI = 800
-
-    # Full conversion
-    for EI in EIs:
-        LogCEIfull = createLogC(gamut, transferFunction, EI, name="LogC")
-        configData['colorSpaces'].append(LogCEIfull)
-
-    # Linearization only
-    for EI in [800]:
-        LogCEIlinearization = createLogC("", transferFunction, EI, name="LogC")
-        configData['colorSpaces'].append(LogCEIlinearization)
-
-    # Primaries
-    LogCEIprimaries = createLogC(gamut, "", defaultEI, name="LogC")
-    configData['colorSpaces'].append(LogCEIprimaries)
+    arriColorSpaces = arri.createColorSpaces(lutDir, lutResolution1d)
+    for cs in arriColorSpaces:
+        configData['colorSpaces'].append(cs)
 
     #
     # Generic log transform
@@ -1750,7 +1164,6 @@ def generateLUTs(odtInfo, lmtInfo, shaperName, acesCTLReleaseDir, lutDir, lutRes
     return configData
 
 def generateBakedLUTs(odtInfo, shaperName, bakedDir, configPath, lutResolution1d, lutResolution3d, lutResolutionShaper=1024):
-
     # Add the legal and full variations into this list
     odtInfoC = dict(odtInfo)
     for odtCTLName, odtValues in odtInfo.iteritems():
diff --git a/aces_1.0.0/python/util.py b/aces_1.0.0/python/util.py
new file mode 100644 (file)
index 0000000..aa891d3
--- /dev/null
@@ -0,0 +1,37 @@
+import PyOpenColorIO as OCIO
+
+#
+# Utility classes and functions
+#
+class ColorSpace:
+    "A container for data needed to define an OCIO 'Color Space' "
+
+    def __init__(self, 
+        name, 
+        description=None, 
+        bitDepth=OCIO.Constants.BIT_DEPTH_F32,
+        equalityGroup=None,
+        family=None,
+        isData=False,
+        toReferenceTransforms=[],
+        fromReferenceTransforms=[],
+        allocationType=OCIO.Constants.ALLOCATION_UNIFORM,
+        allocationVars=[0.0, 1.0]):
+        "Initialize the standard class variables"
+        self.name = name
+        self.bitDepth=bitDepth
+        self.description = description
+        self.equalityGroup=equalityGroup
+        self.family=family 
+        self.isData=isData
+        self.toReferenceTransforms=toReferenceTransforms
+        self.fromReferenceTransforms=fromReferenceTransforms
+        self.allocationType=allocationType
+        self.allocationVars=allocationVars
+
+# Create a 4x4 matrix (list) based on a 3x3 matrix (list) input
+def mat44FromMat33(mat33):
+    return [mat33[0], mat33[1], mat33[2], 0.0, 
+            mat33[3], mat33[4], mat33[5], 0.0, 
+            mat33[6], mat33[7], mat33[8], 0.0, 
+            0,0,0,1.0]
\ No newline at end of file