981b6875ffec343413fd740653f970f716118c98
[OpenColorIO-Configs.git] / aces_1.0.1 / python / aces_ocio / colorspaces / sony.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 Implements support for *Sony* colorspaces conversions and transfer functions.
6 """
7
8 from __future__ import division
9
10 import array
11 import os
12
13 import PyOpenColorIO as ocio
14
15 import aces_ocio.generate_lut as genlut
16 from aces_ocio.utilities import ColorSpace, mat44_from_mat33
17
18 __author__ = 'ACES Developers'
19 __copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
20 __license__ = ''
21 __maintainer__ = 'ACES Developers'
22 __email__ = 'aces@oscars.org'
23 __status__ = 'Production'
24
25 __all__ = ['create_s_log',
26            'create_colorspaces']
27
28
29 def create_s_log(gamut,
30                  transfer_function,
31                  lut_directory,
32                  lut_resolution_1d,
33                  aliases):
34     """
35     Creates colorspace covering the conversion from Sony spaces to ACES, with various 
36     transfer functions and encoding gamuts covered
37
38     Parameters
39     ----------
40     gamut : str
41         The name of the encoding gamut to use.
42     transfer_function : str
43         The name of the transfer function to use
44     lut_directory : str or unicode 
45         The directory to use when generating LUTs
46     lut_resolution_1d : int
47         The resolution of generated 1D LUTs
48     aliases : list of str
49         Aliases for this colorspace
50
51     Returns
52     -------
53     ColorSpace
54          A ColorSpace container class referencing the LUTs, matrices and identifying
55          information for the requested colorspace.
56     """
57
58     name = '%s - %s' % (transfer_function, gamut)
59     if transfer_function == '':
60         name = 'Linear - %s' % gamut
61     if gamut == '':
62         name = 'Curve - %s' % transfer_function
63
64     cs = ColorSpace(name)
65     cs.description = name
66     cs.aliases = aliases
67     cs.equality_group = ''
68     cs.family = 'Input/Sony'
69     cs.is_data = False
70
71     if gamut and transfer_function:
72         cs.aces_transform_id = 'IDT.Sony.%s_%s_10i.a1.v1' % (
73             transfer_function.replace('-', ''),
74             gamut.replace('-', '').replace(' ', '_'))
75
76     # A linear space needs allocation variables.
77     if transfer_function == '':
78         cs.allocation_type = ocio.Constants.ALLOCATION_LG2
79         cs.allocation_vars = [-8, 5, 0.00390625]
80
81     def s_log1_to_linear(s_log):
82         b = 64.
83         ab = 90.
84         w = 940.
85
86         if s_log >= ab:
87             linear = ((pow(10.,
88                            (((s_log - b) /
89                              (w - b) - 0.616596 - 0.03) / 0.432699)) -
90                        0.037584) * 0.9)
91         else:
92             linear = (((s_log - b) / (
93                 w - b) - 0.030001222851889303) / 5.) * 0.9
94         return linear
95
96     def s_log2_to_linear(s_log):
97         b = 64.
98         ab = 90.
99         w = 940.
100
101         if s_log >= ab:
102             linear = ((219. * (pow(10.,
103                                    (((s_log - b) /
104                                      (w - b) - 0.616596 - 0.03) / 0.432699)) -
105                                0.037584) / 155.) * 0.9)
106         else:
107             linear = (((s_log - b) / (
108                 w - b) - 0.030001222851889303) / 3.53881278538813) * 0.9
109         return linear
110
111     def s_log3_to_linear(code_value):
112         if code_value >= 171.2102946929:
113             linear = (pow(10, ((code_value - 420) / 261.5)) *
114                       (0.18 + 0.01) - 0.01)
115         else:
116             linear = (code_value - 95) * 0.01125000 / (171.2102946929 - 95)
117
118         return linear
119
120     cs.to_reference_transforms = []
121
122     if transfer_function == 'S-Log1':
123         data = array.array('f', '\0' * lut_resolution_1d * 4)
124         for c in range(lut_resolution_1d):
125             data[c] = s_log1_to_linear(1023 * c / (lut_resolution_1d - 1))
126
127         lut = '%s_to_linear.spi1d' % transfer_function
128         genlut.write_SPI_1d(
129             os.path.join(lut_directory, lut),
130             0,
131             1,
132             data,
133             lut_resolution_1d,
134             1)
135
136         cs.to_reference_transforms.append({
137             'type': 'lutFile',
138             'path': lut,
139             'interpolation': 'linear',
140             'direction': 'forward'})
141     elif transfer_function == 'S-Log2':
142         data = array.array('f', '\0' * lut_resolution_1d * 4)
143         for c in range(lut_resolution_1d):
144             data[c] = s_log2_to_linear(1023 * c / (lut_resolution_1d - 1))
145
146         lut = '%s_to_linear.spi1d' % transfer_function
147         genlut.write_SPI_1d(
148             os.path.join(lut_directory, lut),
149             0,
150             1,
151             data,
152             lut_resolution_1d,
153             1)
154
155         cs.to_reference_transforms.append({
156             'type': 'lutFile',
157             'path': lut,
158             'interpolation': 'linear',
159             'direction': 'forward'})
160     elif transfer_function == 'S-Log3':
161         data = array.array('f', '\0' * lut_resolution_1d * 4)
162         for c in range(lut_resolution_1d):
163             data[c] = s_log3_to_linear(1023 * c / (lut_resolution_1d - 1))
164
165         lut = '%s_to_linear.spi1d' % transfer_function
166         genlut.write_SPI_1d(
167             os.path.join(lut_directory, lut),
168             0,
169             1,
170             data,
171             lut_resolution_1d,
172             1)
173
174         cs.to_reference_transforms.append({
175             'type': 'lutFile',
176             'path': lut,
177             'interpolation': 'linear',
178             'direction': 'forward'})
179
180     if gamut == 'S-Gamut':
181         cs.to_reference_transforms.append({
182             'type': 'matrix',
183             'matrix': mat44_from_mat33(
184                 [0.754338638, 0.133697046, 0.111968437,
185                  0.021198141, 1.005410934, -0.026610548,
186                  -0.009756991, 0.004508563, 1.005253201]),
187             'direction': 'forward'})
188     elif gamut == 'S-Gamut Daylight':
189         cs.to_reference_transforms.append({
190             'type': 'matrix',
191             'matrix': mat44_from_mat33(
192                 [0.8764457030, 0.0145411681, 0.1090131290,
193                  0.0774075345, 0.9529571767, -0.0303647111,
194                  0.0573564351, -0.1151066335, 1.0577501984]),
195             'direction': 'forward'})
196     elif gamut == 'S-Gamut Tungsten':
197         cs.to_reference_transforms.append({
198             'type': 'matrix',
199             'matrix': mat44_from_mat33(
200                 [1.0110238740, -0.1362526051, 0.1252287310,
201                  0.1011994504, 0.9562196265, -0.0574190769,
202                  0.0600766530, -0.1010185315, 1.0409418785]),
203             'direction': 'forward'})
204     elif gamut == 'S-Gamut3.Cine':
205         cs.to_reference_transforms.append({
206             'type': 'matrix',
207             'matrix': mat44_from_mat33(
208                 [0.6387886672, 0.2723514337, 0.0888598992,
209                  -0.0039159061, 1.0880732308, -0.0841573249,
210                  -0.0299072021, -0.0264325799, 1.0563397820]),
211             'direction': 'forward'})
212     elif gamut == 'S-Gamut3':
213         cs.to_reference_transforms.append({
214             'type': 'matrix',
215             'matrix': mat44_from_mat33(
216                 [0.7529825954, 0.1433702162, 0.1036471884,
217                  0.0217076974, 1.0153188355, -0.0370265329,
218                  -0.0094160528, 0.0033704179, 1.0060456349]),
219             'direction': 'forward'})
220
221     cs.from_reference_transforms = []
222     return cs
223
224
225 def create_colorspaces(lut_directory, lut_resolution_1d):
226     """
227     Generates the colorspace conversions.
228
229     Parameters
230     ----------
231     lut_directory : str or unicode 
232         The directory to use when generating LUTs
233     lut_resolution_1d : int
234         The resolution of generated 1D LUTs
235
236     Returns
237     -------
238     list
239          A list of colorspaces for Sony cameras and encodings 
240     """
241
242     colorspaces = []
243
244     # *S-Log1*
245     s_log1_s_gamut = create_s_log(
246         'S-Gamut',
247         'S-Log1',
248         lut_directory,
249         lut_resolution_1d,
250         ['slog1_sgamut'])
251     colorspaces.append(s_log1_s_gamut)
252
253     # *S-Log2*
254     s_log2_s_gamut = create_s_log(
255         'S-Gamut',
256         'S-Log2',
257         lut_directory,
258         lut_resolution_1d,
259         ['slog2_sgamut'])
260     colorspaces.append(s_log2_s_gamut)
261
262     s_log2_s_gamut_daylight = create_s_log(
263         'S-Gamut Daylight',
264         'S-Log2',
265         lut_directory,
266         lut_resolution_1d,
267         ['slog2_sgamutday'])
268     colorspaces.append(s_log2_s_gamut_daylight)
269
270     s_log2_s_gamut_tungsten = create_s_log(
271         'S-Gamut Tungsten',
272         'S-Log2',
273         lut_directory,
274         lut_resolution_1d,
275         ['slog2_sgamuttung'])
276     colorspaces.append(s_log2_s_gamut_tungsten)
277
278     # *S-Log3*
279     s_log3_s_gamut3Cine = create_s_log(
280         'S-Gamut3.Cine',
281         'S-Log3',
282         lut_directory,
283         lut_resolution_1d,
284         ['slog3_sgamutcine'])
285     colorspaces.append(s_log3_s_gamut3Cine)
286
287     s_log3_s_gamut3 = create_s_log(
288         'S-Gamut3',
289         'S-Log3',
290         lut_directory,
291         lut_resolution_1d,
292         ['slog3_sgamut3'])
293     colorspaces.append(s_log3_s_gamut3)
294
295     # Linearization Only
296     s_log1 = create_s_log(
297         '',
298         'S-Log1',
299         lut_directory,
300         lut_resolution_1d,
301         ['crv_slog1'])
302     colorspaces.append(s_log1)
303
304     s_log2 = create_s_log(
305         '',
306         'S-Log2',
307         lut_directory,
308         lut_resolution_1d,
309         ['crv_slog2'])
310     colorspaces.append(s_log2)
311
312     s_log3 = create_s_log(
313         '',
314         'S-Log3',
315         lut_directory,
316         lut_resolution_1d,
317         ['crv_slog3'])
318     colorspaces.append(s_log3)
319
320     # Primaries Only
321     s_gamut = create_s_log(
322         'S-Gamut',
323         '',
324         lut_directory,
325         lut_resolution_1d,
326         ['lin_sgamut'])
327     colorspaces.append(s_gamut)
328
329     s_gamut_daylight = create_s_log(
330         'S-Gamut Daylight',
331         '',
332         lut_directory,
333         lut_resolution_1d,
334         ['lin_sgamutday'])
335     colorspaces.append(s_gamut_daylight)
336
337     s_gamut_tungsten = create_s_log(
338         'S-Gamut Tungsten',
339         '',
340         lut_directory,
341         lut_resolution_1d,
342         ['lin_sgamuttung'])
343     colorspaces.append(s_gamut_tungsten)
344
345     s_gamut3Cine = create_s_log(
346         'S-Gamut3.Cine',
347         '',
348         lut_directory,
349         lut_resolution_1d,
350         ['lin_sgamut3cine'])
351     colorspaces.append(s_gamut3Cine)
352
353     s_gamut3 = create_s_log(
354         'S-Gamut3',
355         '',
356         lut_directory,
357         lut_resolution_1d,
358         ['lin_sgamut3'])
359     colorspaces.append(s_gamut3)
360
361     return colorspaces