bbb5c8af27d52b0dfc8ba6b9e5376c0a15aac0a4
[OpenColorIO-Configs.git] / aces_1.0.0 / python / aces_ocio / colorspaces / canon.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 Implements support for *Canon* 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
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_c_log',
26            'create_colorspaces']
27
28
29 def create_c_log(gamut,
30                  transfer_function,
31                  lut_directory,
32                  lut_resolution_1d,
33                  aliases):
34     """
35     Creates colorspace covering the conversion from CLog to ACES, with various transfer 
36     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 - Canon %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/Canon'
69     cs.is_data = False
70
71     # A linear space needs allocation variables.
72     if transfer_function == '':
73         cs.allocation_type = ocio.Constants.ALLOCATION_LG2
74         cs.allocation_vars = [-8, 5, 0.00390625]
75
76     def legal_to_full(code_value):
77         return (code_value - 64) / (940 - 64)
78
79     def c_log_to_linear(code_value):
80         # log = fullToLegal(c1 * log10(c2*linear + 1) + c3)
81         # linear = (pow(10, (legalToFul(log) - c3)/c1) - 1)/c2
82         c1 = 0.529136
83         c2 = 10.1596
84         c3 = 0.0730597
85
86         linear = (pow(10, (legal_to_full(code_value) - c3) / c1) - 1) / c2
87         linear *= 0.9
88
89         return linear
90
91     cs.to_reference_transforms = []
92
93     if transfer_function == 'Canon-Log':
94         data = array.array('f', '\0' * lut_resolution_1d * 4)
95         for c in range(lut_resolution_1d):
96             data[c] = c_log_to_linear(1023 * c / (lut_resolution_1d - 1))
97
98         lut = '%s_to_linear.spi1d' % transfer_function
99         genlut.write_SPI_1d(
100             os.path.join(lut_directory, lut),
101             0,
102             1,
103             data,
104             lut_resolution_1d,
105             1)
106
107         cs.to_reference_transforms.append({
108             'type': 'lutFile',
109             'path': lut,
110             'interpolation': 'linear',
111             'direction': 'forward'})
112
113     if gamut == 'Rec. 709 Daylight':
114         cs.to_reference_transforms.append({
115             'type': 'matrix',
116             'matrix': [0.561538969, 0.402060105, 0.036400926, 0,
117                        0.092739623, 0.924121198, -0.016860821, 0,
118                        0.084812961, 0.006373835, 0.908813204, 0,
119                        0, 0, 0, 1],
120             'direction': 'forward'})
121     elif gamut == 'Rec. 709 Tungsten':
122         cs.to_reference_transforms.append({
123             'type': 'matrix',
124             'matrix': [0.566996399, 0.365079418, 0.067924183, 0,
125                        0.070901044, 0.880331008, 0.048767948, 0,
126                        0.073013542, -0.066540862, 0.99352732, 0,
127                        0, 0, 0, 1],
128             'direction': 'forward'})
129     elif gamut == 'DCI-P3 Daylight':
130         cs.to_reference_transforms.append({
131             'type': 'matrix',
132             'matrix': [0.607160575, 0.299507286, 0.093332140, 0,
133                        0.004968120, 1.050982224, -0.055950343, 0,
134                        -0.007839939, 0.000809127, 1.007030813, 0,
135                        0, 0, 0, 1],
136             'direction': 'forward'})
137     elif gamut == 'DCI-P3 Tungsten':
138         cs.to_reference_transforms.append({
139             'type': 'matrix',
140             'matrix': [0.650279125, 0.253880169, 0.095840706, 0,
141                        -0.026137986, 1.017900530, 0.008237456, 0,
142                        0.007757558, -0.063081669, 1.055324110, 0,
143                        0, 0, 0, 1],
144             'direction': 'forward'})
145     elif gamut == 'Cinema Gamut Daylight':
146         cs.to_reference_transforms.append({
147             'type': 'matrix',
148             'matrix': [0.763064455, 0.149021161, 0.087914384, 0,
149                        0.003657457, 1.10696038, -0.110617837, 0,
150                        -0.009407794, -0.218383305, 1.227791099, 0,
151                        0, 0, 0, 1],
152             'direction': 'forward'})
153     elif gamut == 'Cinema Gamut Tungsten':
154         cs.to_reference_transforms.append({
155             'type': 'matrix',
156             'matrix': [0.817416293, 0.090755698, 0.091828009, 0,
157                        -0.035361374, 1.065690585, -0.030329211, 0,
158                        0.010390366, -0.299271107, 1.288880741, 0,
159                        0, 0, 0, 1],
160             'direction': 'forward'})
161
162     cs.from_reference_transforms = []
163     return cs
164
165
166 def create_colorspaces(lut_directory, lut_resolution_1d):
167     """
168     Generates the colorspace conversions.
169
170     Parameters
171     ----------
172     lut_directory : str or unicode 
173         The directory to use when generating LUTs
174     lut_resolution_1d : int
175         The resolution of generated 1D LUTs
176
177     Returns
178     -------
179     list
180          A list of colorspaces for Canon cameras and encodings 
181     """
182
183     colorspaces = []
184
185     # Full conversion
186     c_log_1 = create_c_log(
187         'Rec. 709 Daylight',
188         'Canon-Log',
189         lut_directory,
190         lut_resolution_1d,
191         ['canonlog_rec709day'])
192     colorspaces.append(c_log_1)
193
194     c_log_2 = create_c_log(
195         'Rec. 709 Tungsten',
196         'Canon-Log',
197         lut_directory,
198         lut_resolution_1d,
199         ['canonlog_rec709tung'])
200     colorspaces.append(c_log_2)
201
202     c_log_3 = create_c_log(
203         'DCI-P3 Daylight',
204         'Canon-Log',
205         lut_directory,
206         lut_resolution_1d,
207         ['canonlog_dcip3day'])
208     colorspaces.append(c_log_3)
209
210     c_log_4 = create_c_log(
211         'DCI-P3 Tungsten',
212         'Canon-Log',
213         lut_directory,
214         lut_resolution_1d,
215         ['canonlog_dcip3tung'])
216     colorspaces.append(c_log_4)
217
218     c_log_5 = create_c_log(
219         'Cinema Gamut Daylight',
220         'Canon-Log',
221         lut_directory,
222         lut_resolution_1d,
223         ['canonlog_cgamutday'])
224     colorspaces.append(c_log_5)
225
226     c_log_6 = create_c_log(
227         'Cinema Gamut Tungsten',
228         'Canon-Log',
229         lut_directory,
230         lut_resolution_1d,
231         ['canonlog_cgamuttung'])
232     colorspaces.append(c_log_6)
233
234     # Linearization Only
235     c_log_7 = create_c_log(
236         '',
237         'Canon-Log',
238         lut_directory,
239         lut_resolution_1d,
240         ['crv_canonlog'])
241     colorspaces.append(c_log_7)
242
243     # Primaries Only
244     c_log_8 = create_c_log(
245         'Rec. 709 Daylight',
246         '',
247         lut_directory,
248         lut_resolution_1d,
249         ['lin_canonrec709day'])
250     colorspaces.append(c_log_8)
251
252     c_log_9 = create_c_log(
253         'Rec. 709 Tungsten',
254         '',
255         lut_directory,
256         lut_resolution_1d,
257         ['lin_canonrec709tung'])
258     colorspaces.append(c_log_9)
259
260     c_log_10 = create_c_log(
261         'DCI-P3 Daylight',
262         '',
263         lut_directory,
264         lut_resolution_1d,
265         ['lin_canondcip3day'])
266     colorspaces.append(c_log_10)
267
268     c_log_11 = create_c_log(
269         'DCI-P3 Tungsten',
270         '',
271         lut_directory,
272         lut_resolution_1d,
273         ['lin_canondcip3tung'])
274     colorspaces.append(c_log_11)
275
276     c_log_12 = create_c_log(
277         'Cinema Gamut Daylight',
278         '',
279         lut_directory,
280         lut_resolution_1d,
281         ['lin_canoncgamutday'])
282     colorspaces.append(c_log_12)
283
284     c_log_13 = create_c_log(
285         'Cinema Gamut Tungsten',
286         '',
287         lut_directory,
288         lut_resolution_1d,
289         ['lin_canoncgamuttung'])
290     colorspaces.append(c_log_13)
291
292     return colorspaces