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