2 # -*- coding: utf-8 -*-
5 Implements support for *ARRI* colorspaces conversions and transfer functions.
11 import aces_ocio.generateLUT as genlut
12 from aces_ocio.util import ColorSpace, mat44FromMat33
15 __author__ = 'ACES Developers'
16 __copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
18 __maintainer__ = 'ACES Developers'
19 __email__ = 'aces@oscars.org'
20 __status__ = 'Production'
22 __all__ = ['createLogC',
40 Parameter description.
45 Return value description.
48 name = "%s (EI%s) - %s" % (transferFunction, exposureIndex, gamut)
49 if transferFunction == "":
50 name = "Linear - %s" % gamut
52 name = "%s (EI%s)" % (transferFunction, exposureIndex)
61 IDT_maker_version = "0.08"
64 blackSignal = 0.003907
66 encodingGain = 0.256598
67 encodingOffset = 0.391007
70 return (math.log(EI / nominalEI) / math.log(2) * (
71 0.89 - 1) / 3 + 1) * encodingGain
73 def LogCInverseParametersForEI(EI):
75 slope = 1.0 / (cut * math.log(10))
76 offset = math.log10(cut) - slope * cut
78 gray = midGraySignal / gain
79 # The higher the EI, the lower the gamma
80 encGain = gainForEI(EI)
81 encOffset = encodingOffset
83 nz = ((95.0 / 1023.0 - encOffset) / encGain - offset) / slope
84 encOffset = encodingOffset - math.log10(1 + nz) * encGain
85 # Calculate some intermediate values
87 b = nz - blackSignal / gray
88 e = slope * a * encGain
89 f = encGain * (slope * b + offset) + encOffset
90 # Manipulations so we can return relative exposure
105 def logCtoLinear(codeValue, exposureIndex):
106 p = LogCInverseParametersForEI(exposureIndex)
107 breakpoint = p['e'] * p['cut'] + p['f']
108 if (codeValue > breakpoint):
109 linear = ((pow(10, (codeValue / 1023.0 - p['d']) / p['c']) -
112 linear = (codeValue / 1023.0 - p['f']) / p['e']
114 # print(codeValue, linear)
118 cs.toReferenceTransforms = []
120 if transferFunction == "V3 LogC":
121 data = array.array('f', "\0" * lutResolution1d * 4)
122 for c in range(lutResolution1d):
123 data[c] = logCtoLinear(1023.0 * c / (lutResolution1d - 1),
126 lut = "%s_to_linear.spi1d" % (
127 "%s_%s" % (transferFunction, exposureIndex))
129 # Remove spaces and parentheses
130 lut = lut.replace(' ', '_').replace(')', '_').replace('(', '_')
132 genlut.writeSPI1D(lutDir + "/" + lut,
139 # print("Writing %s" % lut)
140 cs.toReferenceTransforms.append({
143 'interpolation': 'linear',
144 'direction': 'forward'
147 if gamut == 'Wide Gamut':
148 cs.toReferenceTransforms.append({
150 'matrix': mat44FromMat33([0.680206, 0.236137, 0.083658,
151 0.085415, 1.017471, -0.102886,
152 0.002057, -0.062563, 1.060506]),
153 'direction': 'forward'
156 cs.fromReferenceTransforms = []
160 def createColorSpaces(lutDir, lutResolution1d):
162 Generates the colorspace conversions.
167 Parameter description.
172 Return value description.
177 transferFunction = "V3 LogC"
179 # EIs = [160.0, 200.0, 250.0, 320.0, 400.0, 500.0, 640.0, 800.0,
180 # 1000.0, 1280.0, 1600.0, 2000.0, 2560.0, 3200.0]
181 EIs = [160, 200, 250, 320, 400, 500, 640, 800,
182 1000, 1280, 1600, 2000, 2560, 3200]
187 LogCEIfull = createLogC(
188 gamut, transferFunction, EI, "LogC", lutDir, lutResolution1d)
189 colorspaces.append(LogCEIfull)
193 LogCEIlinearization = createLogC(
194 "", transferFunction, EI, "LogC", lutDir, lutResolution1d)
195 colorspaces.append(LogCEIlinearization)
198 LogCEIprimaries = createLogC(
199 gamut, "", defaultEI, "LogC", lutDir, lutResolution1d)
200 colorspaces.append(LogCEIprimaries)