1 /*
2 Copyright (c) 2003-2017 Sony Pictures Imageworks Inc., et al.
3 All Rights Reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of Sony Pictures Imageworks nor the names of its
14 contributors may be used to endorse or promote products derived from
15 this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 #include "OpenColorIO_PS_Context.h"
29
30 int
FindSpace(const SpaceVec & spaceVec,const std::string & space)31 FindSpace(const SpaceVec &spaceVec, const std::string &space)
32 {
33 for(int i=0; i < spaceVec.size(); i++)
34 {
35 const std::string &s = spaceVec[i];
36
37 if(s == space)
38 return i;
39 }
40
41 return -1;
42 }
43
OpenColorIO_PS_Context(const std::string & path)44 OpenColorIO_PS_Context::OpenColorIO_PS_Context(const std::string &path) :
45 _path(path)
46 {
47 const std::string extension = _path.substr( path.find_last_of('.') + 1 );
48
49 if(extension == "ocio")
50 {
51 _config = OCIO::Config::CreateFromFile( _path.c_str() );
52
53 _config->sanityCheck();
54
55 _isLUT = false;
56
57 for(int i=0; i < _config->getNumColorSpaces(); ++i)
58 {
59 const std::string colorSpaceName = _config->getColorSpaceNameByIndex(i);
60
61 OCIO::ConstColorSpaceRcPtr colorSpace = _config->getColorSpace( colorSpaceName.c_str() );
62
63 const std::string colorSpaceFamily = colorSpace->getFamily();
64
65 const std::string colorSpacePath = (colorSpaceFamily.empty() ? colorSpaceName :
66 (colorSpaceFamily + "/" + colorSpaceName));
67
68 _colorSpaces.push_back(colorSpaceName);
69
70 _colorSpacesFullPaths.push_back(colorSpacePath);
71 }
72
73 OCIO::ConstColorSpaceRcPtr defaultInput = _config->getColorSpace(OCIO::ROLE_SCENE_LINEAR);
74
75 _defaultColorSpace = (defaultInput ? defaultInput->getName() : OCIO::ROLE_SCENE_LINEAR);
76
77
78 for(int i=0; i < _config->getNumDisplays(); ++i)
79 {
80 const std::string deviceName = _config->getDisplay(i);
81
82 _devices.push_back(deviceName);
83 }
84
85 _defaultDevice = _config->getDefaultDisplay();
86 }
87 else
88 {
89 _config = OCIO::Config::Create();
90
91
92 OCIO::FileTransformRcPtr forwardTransform = OCIO::FileTransform::Create();
93
94 forwardTransform->setSrc( _path.c_str() );
95 forwardTransform->setInterpolation(OCIO::INTERP_LINEAR);
96 forwardTransform->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
97
98 OCIO::ConstProcessorRcPtr forwardProcessor = _config->getProcessor(forwardTransform);
99
100 _isLUT = true;
101
102 _canInvertLUT = true;
103
104 try
105 {
106 OCIO::FileTransformRcPtr inverseTransform = OCIO::FileTransform::Create();
107
108 inverseTransform->setSrc( _path.c_str() );
109 inverseTransform->setInterpolation(OCIO::INTERP_LINEAR);
110 inverseTransform->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
111
112 OCIO::ConstProcessorRcPtr inverseProcessor = _config->getProcessor(inverseTransform);
113 }
114 catch(...)
115 {
116 _canInvertLUT = false;
117 }
118 }
119 }
120
121 OCIO::ConstProcessorRcPtr
getConvertProcessor(const std::string & inputSpace,const std::string & outputSpace) const122 OpenColorIO_PS_Context::getConvertProcessor(const std::string &inputSpace, const std::string &outputSpace) const
123 {
124 assert( !isLUT() );
125
126 OCIO::ColorSpaceTransformRcPtr transform = OCIO::ColorSpaceTransform::Create();
127
128 transform->setSrc( inputSpace.c_str() );
129 transform->setDst( outputSpace.c_str() );
130 transform->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
131
132 OCIO::ConstProcessorRcPtr processor = _config->getProcessor(transform);
133
134 return processor;
135 }
136
137
138 OCIO::ConstProcessorRcPtr
getDisplayProcessor(const std::string & inputSpace,const std::string & device,const std::string & transform) const139 OpenColorIO_PS_Context::getDisplayProcessor(const std::string &inputSpace, const std::string &device, const std::string &transform) const
140 {
141 assert( !isLUT() );
142
143 OCIO::DisplayTransformRcPtr ocio_transform = OCIO::DisplayTransform::Create();
144
145 ocio_transform->setInputColorSpaceName( inputSpace.c_str() );
146 ocio_transform->setDisplay( device.c_str() );
147 ocio_transform->setView( transform.c_str() );
148
149 OCIO::ConstProcessorRcPtr processor = _config->getProcessor(ocio_transform);
150
151 return processor;
152 }
153
154
155 OCIO::ConstProcessorRcPtr
getLUTProcessor(OCIO::Interpolation interpolation,OCIO::TransformDirection direction) const156 OpenColorIO_PS_Context::getLUTProcessor(OCIO::Interpolation interpolation, OCIO::TransformDirection direction) const
157 {
158 assert( isLUT() );
159
160 OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create();
161
162 transform->setSrc( _path.c_str() );
163 transform->setInterpolation(interpolation);
164 transform->setDirection(direction);
165
166 OCIO::ConstProcessorRcPtr processor = _config->getProcessor(transform);
167
168 return processor;
169 }
170
171
172 OCIO::BakerRcPtr
getConvertBaker(const std::string & inputSpace,const std::string & outputSpace) const173 OpenColorIO_PS_Context::getConvertBaker(const std::string &inputSpace, const std::string &outputSpace) const
174 {
175 assert( !isLUT() );
176
177 OCIO::BakerRcPtr baker = OCIO::Baker::Create();
178
179 baker->setConfig(_config);
180 baker->setInputSpace( inputSpace.c_str() );
181 baker->setTargetSpace( outputSpace.c_str() );
182
183 return baker;
184 }
185
186
187 OCIO::BakerRcPtr
getDisplayBaker(const std::string & inputSpace,const std::string & device,const std::string & transform) const188 OpenColorIO_PS_Context::getDisplayBaker(const std::string &inputSpace, const std::string &device, const std::string &transform) const
189 {
190 assert( !isLUT() );
191
192 OCIO::ConfigRcPtr editableConfig = _config->createEditableCopy();
193
194 OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create();
195 const std::string input_space = "RawInput";
196 inputColorSpace->setName( input_space.c_str() );
197 editableConfig->addColorSpace(inputColorSpace);
198
199
200 OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create();
201 const std::string output_space = "ProcessedOutput";
202 outputColorSpace->setName( output_space.c_str() );
203
204 OCIO::DisplayTransformRcPtr transformPtr = OCIO::DisplayTransform::Create();
205
206 transformPtr->setInputColorSpaceName( inputSpace.c_str() );
207 transformPtr->setDisplay( device.c_str() );
208 transformPtr->setView( transform.c_str() );
209
210 outputColorSpace->setTransform(transformPtr, OCIO::COLORSPACE_DIR_FROM_REFERENCE);
211
212 editableConfig->addColorSpace(outputColorSpace);
213
214
215 OCIO::BakerRcPtr baker = OCIO::Baker::Create();
216
217 baker->setConfig(editableConfig);
218 baker->setInputSpace( input_space.c_str() );
219 baker->setTargetSpace( output_space.c_str() );
220
221 return baker;
222 }
223
224
225 OCIO::BakerRcPtr
getLUTBaker(OCIO::Interpolation interpolation,OCIO::TransformDirection direction) const226 OpenColorIO_PS_Context::getLUTBaker(OCIO::Interpolation interpolation, OCIO::TransformDirection direction) const
227 {
228 assert( isLUT() );
229
230 OCIO::ConfigRcPtr editableConfig = OCIO::Config::Create();
231
232 OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create();
233 std::string inputspace = "RawInput";
234 inputColorSpace->setName(inputspace.c_str());
235 editableConfig->addColorSpace(inputColorSpace);
236
237
238 OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create();
239 std::string outputspace = "ProcessedOutput";
240 outputColorSpace->setName(outputspace.c_str());
241
242 OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create();
243
244 transform = OCIO::FileTransform::Create();
245 transform->setSrc(_path.c_str());
246 transform->setInterpolation(interpolation);
247 transform->setDirection(direction);
248
249 outputColorSpace->setTransform(transform, OCIO::COLORSPACE_DIR_FROM_REFERENCE);
250
251 editableConfig->addColorSpace(outputColorSpace);
252
253
254 OCIO::BakerRcPtr baker = OCIO::Baker::Create();
255
256 baker->setConfig(editableConfig);
257 baker->setInputSpace(inputspace.c_str());
258 baker->setTargetSpace(outputspace.c_str());
259
260 return baker;
261 }
262
263
264 SpaceVec
getTransforms(const std::string & device) const265 OpenColorIO_PS_Context::getTransforms(const std::string &device) const
266 {
267 SpaceVec transforms;
268
269 for(int i=0; i < _config->getNumViews( device.c_str() ); ++i)
270 {
271 const std::string transformName = _config->getView(device.c_str(), i);
272
273 transforms.push_back(transformName);
274 }
275
276 return transforms;
277 }
278
279
280 std::string
getDefaultTransform(const std::string & device) const281 OpenColorIO_PS_Context::getDefaultTransform(const std::string &device) const
282 {
283 return _config->getDefaultView( device.c_str() );
284 }
285
286