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