1 /*
2 Copyright (c) 2003-2010 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 
29 #include <vector>
30 #include <iostream>
31 
32 #include <OpenColorIO/OpenColorIO.h>
33 
34 #include "FileTransform.h"
35 #include "MathUtils.h"
36 #include "pystring/pystring.h"
37 
38 OCIO_NAMESPACE_ENTER
39 {
40 
41     BakerRcPtr Baker::Create()
42     {
43         return BakerRcPtr(new Baker(), &deleter);
44     }
45 
46     void Baker::deleter(Baker* c)
47     {
48         delete c;
49     }
50 
51     class Baker::Impl
52     {
53     public:
54 
55         ConfigRcPtr config_;
56         std::string formatName_;
57         std::string type_;
58         std::string metadata_;
59         std::string inputSpace_;
60         std::string shaperSpace_;
61         std::string looks_;
62         std::string targetSpace_;
63         int shapersize_;
64         int cubesize_;
65 
66         Impl() :
67             shapersize_(-1),
68             cubesize_(-1)
69         {
70         }
71 
72         ~Impl()
73         {
74         }
75 
76         Impl& operator= (const Impl & rhs)
77         {
78             config_      = rhs.config_;
79             formatName_  = rhs.formatName_;
80             inputSpace_  = rhs.inputSpace_;
81             shaperSpace_ = rhs.shaperSpace_;
82             looks_        = rhs.looks_;
83             targetSpace_ = rhs.targetSpace_;
84             shapersize_  = rhs.shapersize_;
85             cubesize_    = rhs.cubesize_;
86             return *this;
87         }
88     };
89 
90     Baker::Baker()
91     : m_impl(new Baker::Impl)
92     {
93     }
94 
95     Baker::~Baker()
96     {
97         delete m_impl;
98         m_impl = NULL;
99     }
100 
101     BakerRcPtr Baker::createEditableCopy() const
102     {
103         BakerRcPtr oven = Baker::Create();
104         *oven->m_impl = *m_impl;
105         return oven;
106     }
107 
108     void Baker::setConfig(const ConstConfigRcPtr & config)
109     {
110         getImpl()->config_ = config->createEditableCopy();
111     }
112 
113     ConstConfigRcPtr Baker::getConfig() const
114     {
115         return getImpl()->config_;
116     }
117 
118     int Baker::getNumFormats()
119     {
120         return FormatRegistry::GetInstance().getNumFormats(FORMAT_CAPABILITY_WRITE);
121     }
122 
123     const char * Baker::getFormatNameByIndex(int index)
124     {
125         return FormatRegistry::GetInstance().getFormatNameByIndex(FORMAT_CAPABILITY_WRITE, index);
126     }
127 
128     const char * Baker::getFormatExtensionByIndex(int index)
129     {
130         return FormatRegistry::GetInstance().getFormatExtensionByIndex(FORMAT_CAPABILITY_WRITE, index);
131     }
132 
133     void Baker::setFormat(const char * formatName)
134     {
135         getImpl()->formatName_ = formatName;
136     }
137 
138     const char * Baker::getFormat() const
139     {
140         return getImpl()->formatName_.c_str();
141     }
142 
143     void Baker::setType(const char * type)
144     {
145         getImpl()->type_ = type;
146     }
147 
148     const char * Baker::getType() const
149     {
150         return getImpl()->type_.c_str();
151     }
152 
153     void Baker::setMetadata(const char * metadata)
154     {
155         getImpl()->metadata_ = metadata;
156     }
157 
158     const char * Baker::getMetadata() const
159     {
160         return getImpl()->metadata_.c_str();
161     }
162 
163     void Baker::setInputSpace(const char * inputSpace)
164     {
165         getImpl()->inputSpace_ = inputSpace;
166     }
167 
168     const char * Baker::getInputSpace() const
169     {
170         return getImpl()->inputSpace_.c_str();
171     }
172 
173     void Baker::setShaperSpace(const char * shaperSpace)
174     {
175         getImpl()->shaperSpace_ = shaperSpace;
176     }
177 
178     const char * Baker::getShaperSpace() const
179     {
180         return getImpl()->shaperSpace_.c_str();
181     }
182 
183     void Baker::setLooks(const char * looks)
184     {
185         getImpl()->looks_ = looks;
186     }
187 
188     const char * Baker::getLooks() const
189     {
190         return getImpl()->looks_.c_str();
191     }
192 
193     void Baker::setTargetSpace(const char * targetSpace)
194     {
195         getImpl()->targetSpace_ = targetSpace;
196     }
197 
198     const char * Baker::getTargetSpace() const
199     {
200         return getImpl()->targetSpace_.c_str();
201     }
202 
203     void Baker::setShaperSize(int shapersize)
204     {
205         getImpl()->shapersize_ = shapersize;
206     }
207 
208     int Baker::getShaperSize() const
209     {
210         return getImpl()->shapersize_;
211     }
212 
213     void Baker::setCubeSize(int cubesize)
214     {
215         getImpl()->cubesize_ = cubesize;
216     }
217 
218     int Baker::getCubeSize() const
219     {
220         return getImpl()->cubesize_;
221     }
222 
223     void Baker::bake(std::ostream & os) const
224     {
225         FileFormat* fmt = FormatRegistry::GetInstance().getFileFormatByName(getImpl()->formatName_);
226 
227         if(!fmt)
228         {
229             std::ostringstream err;
230             err << "The format named '" << getImpl()->formatName_;
231             err << "' could not be found. ";
232             throw Exception(err.str().c_str());
233         }
234 
235         try
236         {
237             fmt->Write(*this, getImpl()->formatName_, os);
238         }
239         catch(std::exception & e)
240         {
241             std::ostringstream err;
242             err << "Error baking " << getImpl()->formatName_ << ":";
243             err << e.what();
244             throw Exception(err.str().c_str());
245         }
246 
247         //
248         // TODO:
249         //
250         // - throw exception when we don't have inputSpace and targetSpace
251         //   at least set
252         // - check limits of shaper and target, throw exception if we can't
253         //   write that much data in x format
254         // - check that the shaper is 1D transform only, throw excpetion
255         // - check the file format supports shapers, 1D and 3D
256         // - add some checks to make sure we are monotonic
257         // - deal with the case of writing out non cube formats (1D only)
258         // - do a compare between ocio transform and output lut transform
259         //   throw error if we going beyond tolerance
260         //
261     }
262 
263 }
264 OCIO_NAMESPACE_EXIT
265 
266 ///////////////////////////////////////////////////////////////////////////////
267 
268 #ifdef OCIO_UNIT_TEST
269 
270 namespace OCIO = OCIO_NAMESPACE;
271 #include "UnitTest.h"
272 
273 /*
274 OIIO_ADD_TEST(Baker_Unit_Tests, test_listlutwriters)
275 {
276 
277     std::vector<std::string> current_writers;
278     current_writers.push_back("cinespace");
279     current_writers.push_back("houdini");
280 
281     OCIO::BakerRcPtr baker = OCIO::Baker::Create();
282 
283     OIIO_CHECK_EQUAL(baker->getNumFormats(), (int)current_writers.size());
284 
285     std::vector<std::string> test;
286     for(int i = 0; i < baker->getNumFormats(); ++i)
287         test.push_back(baker->getFormatNameByIndex(i));
288 
289     for(unsigned int i = 0; i < current_writers.size(); ++i)
290         OIIO_CHECK_EQUAL(current_writers[i], test[i]);
291 
292 }
293 */
294 
295 #endif // OCIO_BUILD_TESTS
296 
297 
298