eefe9ef3c15d2ca25a0eadb5b7c9dff311758b03
[OpenColorIO-Configs.git] / aces_1.0.0 / python / aces_ocio / colorspaces / red.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 Implements support for *RED* 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_red_log_film',
26            'create_colorspaces']
27
28
29 def create_red_log_film(gamut,
30                         transfer_function,
31                         lut_directory,
32                         lut_resolution_1d,
33                         aliases=None):
34     """
35     Creates colorspace covering the conversion from RED 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     if aliases is None:
59         aliases = []
60
61     name = '%s - %s' % (transfer_function, gamut)
62     if transfer_function == '':
63         name = 'Linear - %s' % gamut
64     if gamut == '':
65         name = 'Curve - %s' % transfer_function
66
67     cs = ColorSpace(name)
68     cs.description = name
69     cs.aliases = aliases
70     cs.equality_group = ''
71     cs.family = 'Input/RED'
72     cs.is_data = False
73
74     # A linear space needs allocation variables
75     if transfer_function == '':
76         cs.allocation_type = ocio.Constants.ALLOCATION_LG2
77         cs.allocation_vars = [-8, 5, 0.00390625]
78
79     def cineon_to_linear(code_value):
80         n_gamma = 0.6
81         black_point = 95
82         white_point = 685
83         code_value_to_density = 0.002
84
85         black_linear = pow(10, (black_point - white_point) * (
86             code_value_to_density / n_gamma))
87         code_linear = pow(10, (code_value - white_point) * (
88             code_value_to_density / n_gamma))
89
90         return (code_linear - black_linear) / (1 - black_linear)
91
92     cs.to_reference_transforms = []
93
94     if transfer_function == 'REDlogFilm':
95         data = array.array('f', '\0' * lut_resolution_1d * 4)
96         for c in range(lut_resolution_1d):
97             data[c] = cineon_to_linear(1023 * c / (lut_resolution_1d - 1))
98
99         lut = 'CineonLog_to_linear.spi1d'
100         genlut.write_SPI_1d(
101             os.path.join(lut_directory, lut),
102             0,
103             1,
104             data,
105             lut_resolution_1d,
106             1)
107
108         cs.to_reference_transforms.append({
109             'type': 'lutFile',
110             'path': lut,
111             'interpolation': 'linear',
112             'direction': 'forward'})
113
114     if gamut == 'DRAGONcolor':
115         cs.to_reference_transforms.append({
116             'type': 'matrix',
117             'matrix': mat44_from_mat33([0.532279, 0.376648, 0.091073,
118                                         0.046344, 0.974513, -0.020860,
119                                         -0.053976, -0.000320, 1.054267]),
120             'direction': 'forward'})
121     elif gamut == 'DRAGONcolor2':
122         cs.to_reference_transforms.append({
123             'type': 'matrix',
124             'matrix': mat44_from_mat33([0.468452, 0.331484, 0.200064,
125                                         0.040787, 0.857658, 0.101553,
126                                         -0.047504, -0.000282, 1.047756]),
127             'direction': 'forward'})
128     elif gamut == 'REDcolor':
129         cs.to_reference_transforms.append({
130             'type': 'matrix',
131             'matrix': mat44_from_mat33([0.451464, 0.388498, 0.160038,
132                                         0.062716, 0.866790, 0.070491,
133                                         -0.017541, 0.086921, 0.930590]),
134             'direction': 'forward'})
135     elif gamut == 'REDcolor2':
136         cs.to_reference_transforms.append({
137             'type': 'matrix',
138             'matrix': mat44_from_mat33([0.480997, 0.402289, 0.116714,
139                                         -0.004938, 1.000154, 0.004781,
140                                         -0.105257, 0.025320, 1.079907]),
141             'direction': 'forward'})
142     elif gamut == 'REDcolor3':
143         cs.to_reference_transforms.append({
144             'type': 'matrix',
145             'matrix': mat44_from_mat33([0.512136, 0.360370, 0.127494,
146                                         0.070377, 0.903884, 0.025737,
147                                         -0.020824, 0.017671, 1.003123]),
148             'direction': 'forward'})
149     elif gamut == 'REDcolor4':
150         cs.to_reference_transforms.append({
151             'type': 'matrix',
152             'matrix': mat44_from_mat33([0.474202, 0.333677, 0.192121,
153                                         0.065164, 0.836932, 0.097901,
154                                         -0.019281, 0.016362, 1.002889]),
155             'direction': 'forward'})
156
157     cs.from_reference_transforms = []
158     return cs
159
160
161 def create_colorspaces(lut_directory, lut_resolution_1d):
162     """
163     Generates the colorspace conversions.
164
165     Parameters
166     ----------
167     lut_directory : str or unicode 
168         The directory to use when generating LUTs
169     lut_resolution_1d : int
170         The resolution of generated 1D LUTs
171
172     Returns
173     -------
174     list
175          A list of colorspaces for RED cameras and encodings 
176     """
177
178     colorspaces = []
179
180     # Full conversion
181     red_log_film_dragon = create_red_log_film(
182         'DRAGONcolor',
183         'REDlogFilm',
184         lut_directory,
185         lut_resolution_1d,
186         ['rlf_dgn'])
187     colorspaces.append(red_log_film_dragon)
188
189     red_log_film_dragon2 = create_red_log_film(
190         'DRAGONcolor2',
191         'REDlogFilm',
192         lut_directory,
193         lut_resolution_1d,
194         ['rlf_dgn2'])
195     colorspaces.append(red_log_film_dragon2)
196
197     red_log_film_color = create_red_log_film(
198         'REDcolor',
199         'REDlogFilm',
200         lut_directory,
201         lut_resolution_1d,
202         ['rlf_rc'])
203     colorspaces.append(red_log_film_color)
204
205     red_log_film_color2 = create_red_log_film(
206         'REDcolor2',
207         'REDlogFilm',
208         lut_directory,
209         lut_resolution_1d,
210         ['rlf_rc2'])
211     colorspaces.append(red_log_film_color2)
212
213     red_log_film_color3 = create_red_log_film(
214         'REDcolor3',
215         'REDlogFilm',
216         lut_directory,
217         lut_resolution_1d,
218         ['rlf_rc3'])
219     colorspaces.append(red_log_film_color3)
220
221     red_log_film_color4 = create_red_log_film(
222         'REDcolor4',
223         'REDlogFilm',
224         lut_directory,
225         lut_resolution_1d,
226         ['rlf_rc4'])
227     colorspaces.append(red_log_film_color4)
228
229     # Linearization only
230     red_log_film = create_red_log_film(
231         '',
232         'REDlogFilm',
233         lut_directory,
234         lut_resolution_1d,
235         ['crv_rlf'])
236     colorspaces.append(red_log_film)
237
238     # Primaries only
239     red_dragon = create_red_log_film(
240         'DRAGONcolor',
241         '',
242         lut_directory,
243         lut_resolution_1d,
244         ['lin_dgn'])
245     colorspaces.append(red_dragon)
246
247     red_dragon2 = create_red_log_film(
248         'DRAGONcolor2',
249         '',
250         lut_directory,
251         lut_resolution_1d,
252         ['lin_dgn2'])
253     colorspaces.append(red_dragon2)
254
255     red_color = create_red_log_film(
256         'REDcolor',
257         '',
258         lut_directory,
259         lut_resolution_1d,
260         ['lin_rc'])
261     colorspaces.append(red_color)
262
263     red_color2 = create_red_log_film(
264         'REDcolor2',
265         '',
266         lut_directory,
267         lut_resolution_1d,
268         ['lin_rc2'])
269     colorspaces.append(red_color2)
270
271     red_color3 = create_red_log_film(
272         'REDcolor3',
273         '',
274         lut_directory,
275         lut_resolution_1d,
276         ['lin_rc3'])
277     colorspaces.append(red_color3)
278
279     red_color4 = create_red_log_film(
280         'REDcolor4',
281         '',
282         lut_directory,
283         lut_resolution_1d,
284         ['lin_rc4'])
285     colorspaces.append(red_color4)
286
287     return colorspaces