Update ".gitignore" file.
[OpenColorIO-Configs.git] / aces_1.0.0 / python / createARRIColorSpaces.py
1 import math
2 import array
3
4 from util import *
5 import generateLUT as genlut
6
7
8 #
9 # LogC to ACES
10 #
11 def createLogC(gamut, transferFunction, exposureIndex, name, lutDir, lutResolution1d):
12     name = "%s (EI%s) - %s" % (transferFunction, exposureIndex, gamut)
13     if transferFunction == "":
14         name = "Linear - %s" % gamut
15     if gamut == "":
16         name = "%s (EI%s)" % (transferFunction, exposureIndex)
17
18     cs = ColorSpace(name)
19     cs.description = name
20     cs.equalityGroup = ''
21     cs.family = 'ARRI'
22     cs.isData=False
23
24     # Globals
25     IDT_maker_version = "0.08"
26
27     nominalEI = 400.0
28     blackSignal = 0.003907
29     midGraySignal = 0.01
30     encodingGain = 0.256598
31     encodingOffset = 0.391007
32
33     def gainForEI(EI) :
34         return (math.log(EI/nominalEI)/math.log(2) * (0.89 - 1) / 3 + 1) * encodingGain
35
36     def LogCInverseParametersForEI(EI) :
37         cut = 1.0 / 9.0
38         slope = 1.0 / (cut * math.log(10))
39         offset = math.log10(cut) - slope * cut
40         gain = EI / nominalEI
41         gray = midGraySignal / gain
42         # The higher the EI, the lower the gamma
43         encGain = gainForEI(EI)
44         encOffset = encodingOffset
45         for i in range(0,3) :
46             nz = ((95.0 / 1023.0 - encOffset) / encGain - offset) / slope
47             encOffset = encodingOffset - math.log10(1 + nz) * encGain
48         # Calculate some intermediate values
49         a = 1.0 / gray
50         b = nz - blackSignal / gray
51         e = slope * a * encGain
52         f = encGain * (slope * b + offset) + encOffset
53         # Manipulations so we can return relative exposure
54         s = 4 / (0.18 * EI)
55         t = blackSignal
56         b = b + a * t
57         a = a * s
58         f = f + e * t
59         e = e * s
60         return { 'a' : a,
61                  'b' : b,
62                  'cut' : (cut - b) / a,
63                  'c' : encGain,
64                  'd' : encOffset,
65                  'e' : e,
66                  'f' : f }
67
68     def logCtoLinear(codeValue, exposureIndex):
69         p = LogCInverseParametersForEI(exposureIndex)
70         breakpoint = p['e'] * p['cut'] + p['f']
71         if (codeValue > breakpoint):
72             linear = (pow(10,(codeValue/1023.0 - p['d']) / p['c']) - p['b']) / p['a']
73         else:
74             linear = (codeValue/1023.0 - p['f']) / p['e']
75
76         #print( codeValue, linear )
77         return linear
78
79
80     cs.toReferenceTransforms = []
81
82     if transferFunction == "V3 LogC":
83         data = array.array('f', "\0" * lutResolution1d * 4)
84         for c in range(lutResolution1d):
85             data[c] = logCtoLinear(1023.0*c/(lutResolution1d-1), int(exposureIndex))
86
87         lut = "%s_to_linear.spi1d" % ("%s_%s" % (transferFunction, exposureIndex))
88
89         # Remove spaces and parentheses
90         lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
91
92         genlut.writeSPI1D(lutDir + "/" + lut, 0.0, 1.0, data, lutResolution1d, 1)
93
94         #print( "Writing %s" % lut)
95         cs.toReferenceTransforms.append( {
96             'type':'lutFile', 
97             'path':lut, 
98             'interpolation':'linear', 
99             'direction':'forward'
100         } )
101
102     if gamut == 'Wide Gamut':
103         cs.toReferenceTransforms.append( {
104             'type':'matrix',
105             'matrix':mat44FromMat33([0.680206, 0.236137, 0.083658, 
106                         0.085415, 1.017471, -0.102886, 
107                         0.002057, -0.062563, 1.060506]),
108             'direction':'forward'
109         })
110
111     cs.fromReferenceTransforms = []
112     return cs
113
114 def createColorSpaces(lutDir, lutResolution1d):
115     colorspaces = []
116
117     transferFunction = "V3 LogC"
118     gamut = "Wide Gamut"
119     #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]
120     EIs = [160, 200, 250, 320, 400, 500, 640, 800, 1000, 1280, 1600, 2000, 2560, 3200]
121     defaultEI = 800
122
123     # Full conversion
124     for EI in EIs:
125         LogCEIfull = createLogC(gamut, transferFunction, EI, "LogC", lutDir, lutResolution1d)
126         colorspaces.append(LogCEIfull)
127
128     # Linearization only
129     for EI in [800]:
130         LogCEIlinearization = createLogC("", transferFunction, EI, "LogC", lutDir, lutResolution1d)
131         colorspaces.append(LogCEIlinearization)
132
133     # Primaries
134     LogCEIprimaries = createLogC(gamut, "", defaultEI, "LogC", lutDir, lutResolution1d)
135     colorspaces.append(LogCEIprimaries)
136
137     return colorspaces