5 PYTHONPATH=/net/soft_scratch/users/jeremys/git/ocio.js/build/src/pyglue/
6 LD_LIBRARY_PATH=/net/soft_scratch/users/jeremys/git/ocio.js/build/src/core/
10 import PyOpenColorIO as OCIO
12 print "OCIO",OCIO.version
14 outputfilename = "config.ocio"
16 def WriteSPI1D(filename, fromMin, fromMax, data):
17 f = file(filename,'w')
18 f.write("Version 1\n")
19 f.write("From %s %s\n" % (fromMin, fromMax))
20 f.write("Length %d\n" % len(data))
21 f.write("Components 1\n")
24 f.write(" %s\n" % value)
28 def Fit(value, fromMin, fromMax, toMin, toMax):
29 if fromMin == fromMax:
30 raise ValueError("fromMin == fromMax")
31 return (value - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin
34 ###############################################################################
37 config = OCIO.Config()
38 config.setSearchPath('luts')
40 config.setRole(OCIO.Constants.ROLE_SCENE_LINEAR, "linear")
41 config.setRole(OCIO.Constants.ROLE_REFERENCE, "linear")
42 config.setRole(OCIO.Constants.ROLE_COLOR_TIMING, "Cineon")
43 config.setRole(OCIO.Constants.ROLE_COMPOSITING_LOG, "Cineon")
44 config.setRole(OCIO.Constants.ROLE_DATA,"raw")
45 config.setRole(OCIO.Constants.ROLE_DEFAULT,"raw")
46 config.setRole(OCIO.Constants.ROLE_COLOR_PICKING,"sRGB")
47 config.setRole(OCIO.Constants.ROLE_MATTE_PAINT,"sRGB")
48 config.setRole(OCIO.Constants.ROLE_TEXTURE_PAINT,"sRGB")
51 ###############################################################################
53 cs = OCIO.ColorSpace(name='linear')
54 cs.setDescription("Scene-linear, high dynamic range. Used for rendering and compositing.")
55 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
56 cs.setAllocation(OCIO.Constants.ALLOCATION_LG2)
57 cs.setAllocationVars([-15.0, 6.0])
58 config.addColorSpace(cs)
61 ###############################################################################
66 return 1.055 * v**(1.0/2.4) - 0.055
71 return ((v + .055) / 1.055) ** 2.4
73 # These samples and range have been chosen to write out this colorspace with
74 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
78 RANGE = (-0.125, 1.125)
80 for i in xrange(NUM_SAMPLES):
81 x = i/(NUM_SAMPLES-1.0)
82 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
83 data.append(fromSRGB(x))
85 # Data is srgb->linear
86 WriteSPI1D('luts/srgb.spi1d', RANGE[0], RANGE[1], data)
88 cs = OCIO.ColorSpace(name='sRGB')
89 cs.setDescription("Standard RGB Display Space")
90 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
91 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
92 cs.setAllocationVars([RANGE[0], RANGE[1]])
94 t = OCIO.FileTransform('srgb.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
95 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
96 config.addColorSpace(cs)
99 NUM_SAMPLES = 2**16+25
100 RANGE = (-0.125, 4.875)
102 for i in xrange(NUM_SAMPLES):
103 x = i/(NUM_SAMPLES-1.0)
104 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
105 data.append(fromSRGB(x))
107 # Data is srgb->linear
108 WriteSPI1D('luts/srgbf.spi1d', RANGE[0], RANGE[1], data)
110 cs = OCIO.ColorSpace(name='sRGBf')
111 cs.setDescription("Standard RGB Display Space, but with additional range to preserve float highlights.")
112 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
113 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
114 cs.setAllocationVars([RANGE[0], RANGE[1]])
116 t = OCIO.FileTransform('srgbf.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
117 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
118 config.addColorSpace(cs)
121 ###############################################################################
126 return 1.099 * v**0.45 - 0.099
131 return ((v + .099) / 1.099) ** (1.0/0.45)
133 # These samples and range have been chosen to write out this colorspace with
134 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
137 NUM_SAMPLES = 2**12+5
138 RANGE = (-0.125, 1.125)
140 for i in xrange(NUM_SAMPLES):
141 x = i/(NUM_SAMPLES-1.0)
142 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
143 data.append(fromRec709(x))
145 # Data is srgb->linear
146 WriteSPI1D('luts/rec709.spi1d', RANGE[0], RANGE[1], data)
148 cs = OCIO.ColorSpace(name='rec709')
149 cs.setDescription("Rec. 709 (Full Range) Display Space")
150 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
151 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
152 cs.setAllocationVars([RANGE[0], RANGE[1]])
154 t = OCIO.FileTransform('rec709.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
155 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
156 config.addColorSpace(cs)
159 ###############################################################################
161 cineonBlackOffset = 10.0 ** ((95.0 - 685.0)/300.0)
164 return (10.0**((1023.0 * x - 685.0) / 300.0) - cineonBlackOffset) / (1.0 - cineonBlackOffset)
166 # These samples and range have been chosen to write out this colorspace with
167 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
170 NUM_SAMPLES = 2**12+5
171 RANGE = (-0.125, 1.125)
173 for i in xrange(NUM_SAMPLES):
174 x = i/(NUM_SAMPLES-1.0)
175 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
176 data.append(fromCineon(x))
178 # Data is srgb->linear
179 WriteSPI1D('luts/cineon.spi1d', RANGE[0], RANGE[1], data)
181 cs = OCIO.ColorSpace(name='Cineon')
182 cs.setDescription("Cineon (Log Film Scan)")
183 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
184 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
185 cs.setAllocationVars([RANGE[0], RANGE[1]])
187 t = OCIO.FileTransform('cineon.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
188 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
189 config.addColorSpace(cs)
193 ###############################################################################
195 cs = OCIO.ColorSpace(name='Gamma1.8')
196 cs.setDescription("Emulates a idealized Gamma 1.8 display device.")
197 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
198 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
199 cs.setAllocationVars([0.0, 1.0])
201 t = OCIO.ExponentTransform(value=(1.8,1.8,1.8,1.0))
202 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
203 config.addColorSpace(cs)
205 cs = OCIO.ColorSpace(name='Gamma2.2')
206 cs.setDescription("Emulates a idealized Gamma 2.2 display device.")
207 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
208 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
209 cs.setAllocationVars([0.0, 1.0])
211 t = OCIO.ExponentTransform(value=(2.2,2.2,2.2,1.0))
212 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
213 config.addColorSpace(cs)
216 ###############################################################################
219 # Log to Linear light conversions for Panalog
220 # WARNING: these are estimations known to be close enough.
221 # The actual transfer functions are not published
223 panalogBlackOffset = 10.0 ** ((64.0 - 681.0) / 444.0)
226 return (10.0**((1023 * x - 681.0) / 444.0) - panalogBlackOffset) / (1.0 - panalogBlackOffset)
228 # These samples and range have been chosen to write out this colorspace with
229 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
232 NUM_SAMPLES = 2**12+5
233 RANGE = (-0.125, 1.125)
235 for i in xrange(NUM_SAMPLES):
236 x = i/(NUM_SAMPLES-1.0)
237 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
238 data.append(fromPanalog(x))
240 # Data is srgb->linear
241 WriteSPI1D('luts/panalog.spi1d', RANGE[0], RANGE[1], data)
243 cs = OCIO.ColorSpace(name='Panalog')
244 cs.setDescription("Sony/Panavision Genesis Log Space")
245 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
246 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
247 cs.setAllocationVars([RANGE[0], RANGE[1]])
249 t = OCIO.FileTransform('panalog.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
250 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
251 config.addColorSpace(cs)
255 ###############################################################################
259 redBlackOffset = 10.0 ** ((0.0 - 1023.0) / 511.0)
262 return ((10.0 ** ((1023.0 * x - 1023.0) / 511.0)) - redBlackOffset) / (1.0 - redBlackOffset)
264 # These samples and range have been chosen to write out this colorspace with
265 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
269 NUM_SAMPLES = 2**12+5
270 RANGE = (-0.125, 1.125)
272 for i in xrange(NUM_SAMPLES):
273 x = i/(NUM_SAMPLES-1.0)
274 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
275 data.append(fromREDLog(x))
277 # Data is srgb->linear
278 WriteSPI1D('luts/redlog.spi1d', RANGE[0], RANGE[1], data)
280 cs = OCIO.ColorSpace(name='REDLog')
281 cs.setDescription("RED Log Space")
282 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
283 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
284 cs.setAllocationVars([RANGE[0], RANGE[1]])
286 t = OCIO.FileTransform('redlog.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
287 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
288 config.addColorSpace(cs)
292 ###############################################################################
295 return 10.0**((1023.0 * x - 1023.0) / 500.0)
297 # These samples and range have been chosen to write out this colorspace with
298 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
302 NUM_SAMPLES = 2**12+5
303 RANGE = (-0.125, 1.125)
305 for i in xrange(NUM_SAMPLES):
306 x = i/(NUM_SAMPLES-1.0)
307 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
308 data.append(fromViperLog(x))
310 # Data is srgb->linear
311 WriteSPI1D('luts/viperlog.spi1d', RANGE[0], RANGE[1], data)
313 cs = OCIO.ColorSpace(name='ViperLog')
314 cs.setDescription("Viper Log Space")
315 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
316 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
317 cs.setAllocationVars([RANGE[0], RANGE[1]])
319 t = OCIO.FileTransform('viperlog.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
320 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
321 config.addColorSpace(cs)
325 ###############################################################################
328 alexav3logc_a = 5.555556
329 alexav3logc_b = 0.052272
330 alexav3logc_c = 0.247190
331 alexav3logc_d = 0.385537
332 alexav3logc_e = 5.367655
333 alexav3logc_f = 0.092809
334 alexav3logc_cut = 0.010591
335 alexav3logc_eCutF = alexav3logc_e*alexav3logc_cut + alexav3logc_f
337 # This corresponds to EI800 per Arri Doc
338 # http://www.arridigital.com/forum/index.php?topic=6372.0
339 # http://www.arri.com/?eID=registration&file_uid=7775
340 def fromAlexaV3LogC(x):
341 if x > alexav3logc_eCutF:
342 return (10.0 **((x - alexav3logc_d) / alexav3logc_c) - alexav3logc_b) / alexav3logc_a
344 return (x - alexav3logc_f) / alexav3logc_e
347 # These samples and range have been chosen to write out this colorspace with
348 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
352 NUM_SAMPLES = 2**12+5
353 RANGE = (-0.125, 1.125)
355 for i in xrange(NUM_SAMPLES):
356 x = i/(NUM_SAMPLES-1.0)
357 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
358 data.append(fromAlexaV3LogC(x))
360 # Data is srgb->linear
361 WriteSPI1D('luts/alexalogc.spi1d', RANGE[0], RANGE[1], data)
363 cs = OCIO.ColorSpace(name='AlexaV3LogC')
364 cs.setDescription("Alexa Log C")
365 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
366 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
367 cs.setAllocationVars([RANGE[0], RANGE[1]])
369 t = OCIO.FileTransform('alexalogc.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
370 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
371 config.addColorSpace(cs)
374 ###############################################################################
378 # Josh Pines style pivoted log/lin conversion
383 densityPerCodeValue = 0.002
384 ngOverDpcv = negativeGamma/densityPerCodeValue
385 dpcvOverNg = densityPerCodeValue/negativeGamma
388 return (10.0**((x*1023.0 - logReference)*dpcvOverNg ) * linReference)
391 # These samples and range have been chosen to write out this colorspace with
392 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
395 NUM_SAMPLES = 2**12+5
396 RANGE = (-0.125, 1.125)
398 for i in xrange(NUM_SAMPLES):
399 x = i/(NUM_SAMPLES-1.0)
400 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
401 data.append(fromPLogLin(x))
403 # Data is srgb->linear
404 WriteSPI1D('luts/ploglin.spi1d', RANGE[0], RANGE[1], data)
406 cs = OCIO.ColorSpace(name='PLogLin')
407 cs.setDescription("Josh Pines style pivoted log/lin conversion. 445->0.18")
408 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
409 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
410 cs.setAllocationVars([RANGE[0], RANGE[1]])
412 t = OCIO.FileTransform('ploglin.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
413 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
414 config.addColorSpace(cs)
417 ###############################################################################
420 return (10.0 ** (((x - 0.616596 - 0.03) / 0.432699)) - 0.037584)
422 # These samples and range have been chosen to write out this colorspace with
423 # a limited over/undershoot range, which also exactly samples the 0.0,1.0
426 NUM_SAMPLES = 2**12+5
427 RANGE = (-0.125, 1.125)
429 for i in xrange(NUM_SAMPLES):
430 x = i/(NUM_SAMPLES-1.0)
431 x = Fit(x, 0.0, 1.0, RANGE[0], RANGE[1])
432 data.append(fromSLog(x))
434 # Data is srgb->linear
435 WriteSPI1D('luts/slog.spi1d', RANGE[0], RANGE[1], data)
437 cs = OCIO.ColorSpace(name='SLog')
438 cs.setDescription("Sony SLog")
439 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
440 cs.setAllocation(OCIO.Constants.ALLOCATION_UNIFORM)
441 cs.setAllocationVars([RANGE[0], RANGE[1]])
443 t = OCIO.FileTransform('slog.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)
444 cs.setTransform(t, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE)
445 config.addColorSpace(cs)
448 ###############################################################################
454 ###############################################################################
456 cs = OCIO.ColorSpace(name='raw')
457 cs.setDescription("Raw Data. Used for normals, points, etc.")
458 cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F32)
460 config.addColorSpace(cs)
463 ###############################################################################
466 config.addDisplay(display, 'None', 'raw')
467 config.addDisplay(display, 'sRGB', 'sRGB')
468 config.addDisplay(display, 'rec709', 'rec709')
470 config.setActiveDisplays('default')
471 config.setActiveViews('sRGB')
474 ###############################################################################
483 f = file(outputfilename,"w")
484 f.write(config.serialize())
486 print "Wrote",outputfilename
488 # Core/LUT/include/LUT/fnLUTConversions.h