/src/core/FileFormatCCC.cpp

http://github.com/imageworks/OpenColorIO · C++ · 229 lines · 146 code · 34 blank · 49 comment · 12 complexity · 6d34dce1955f13129972a680f9f0838e MD5 · raw file

  1. /*
  2. Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
  3. All Rights Reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are
  6. met:
  7. * Redistributions of source code must retain the above copyright
  8. notice, this list of conditions and the following disclaimer.
  9. * Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. * Neither the name of Sony Pictures Imageworks nor the names of its
  13. contributors may be used to endorse or promote products derived from
  14. this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  18. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  19. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  20. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  21. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include <map>
  28. #include <tinyxml.h>
  29. #include <OpenColorIO/OpenColorIO.h>
  30. #include "CDLTransform.h"
  31. #include "FileTransform.h"
  32. #include "OpBuilders.h"
  33. #include "ParseUtils.h"
  34. #include "pystring/pystring.h"
  35. OCIO_NAMESPACE_ENTER
  36. {
  37. ////////////////////////////////////////////////////////////////
  38. namespace
  39. {
  40. class LocalCachedFile : public CachedFile
  41. {
  42. public:
  43. LocalCachedFile () {};
  44. ~LocalCachedFile() {};
  45. CDLTransformMap transformMap;
  46. CDLTransformVec transformVec;
  47. };
  48. typedef OCIO_SHARED_PTR<LocalCachedFile> LocalCachedFileRcPtr;
  49. typedef OCIO_SHARED_PTR<TiXmlDocument> TiXmlDocumentRcPtr;
  50. class LocalFileFormat : public FileFormat
  51. {
  52. public:
  53. ~LocalFileFormat() {};
  54. virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const;
  55. virtual CachedFileRcPtr Read(std::istream & istream) const;
  56. virtual void BuildFileOps(OpRcPtrVec & ops,
  57. const Config& config,
  58. const ConstContextRcPtr & context,
  59. CachedFileRcPtr untypedCachedFile,
  60. const FileTransform& fileTransform,
  61. TransformDirection dir) const;
  62. };
  63. void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const
  64. {
  65. FormatInfo info;
  66. info.name = "ColorCorrectionCollection";
  67. info.extension = "ccc";
  68. info.capabilities = FORMAT_CAPABILITY_READ;
  69. formatInfoVec.push_back(info);
  70. }
  71. // Try and load the format
  72. // Raise an exception if it can't be loaded.
  73. CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const
  74. {
  75. std::ostringstream rawdata;
  76. rawdata << istream.rdbuf();
  77. LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile());
  78. TiXmlDocumentRcPtr doc = TiXmlDocumentRcPtr(new TiXmlDocument());
  79. doc->Parse(rawdata.str().c_str());
  80. if(doc->Error())
  81. {
  82. std::ostringstream os;
  83. os << "XML Parse Error. ";
  84. os << doc->ErrorDesc() << " (line ";
  85. os << doc->ErrorRow() << ", character ";
  86. os << doc->ErrorCol() << ")";
  87. throw Exception(os.str().c_str());
  88. }
  89. TiXmlElement* rootElement = doc->RootElement();
  90. GetCDLTransforms(cachedFile->transformMap,
  91. cachedFile->transformVec,
  92. rootElement);
  93. return cachedFile;
  94. }
  95. void
  96. LocalFileFormat::BuildFileOps(OpRcPtrVec & ops,
  97. const Config& config,
  98. const ConstContextRcPtr & context,
  99. CachedFileRcPtr untypedCachedFile,
  100. const FileTransform& fileTransform,
  101. TransformDirection dir) const
  102. {
  103. LocalCachedFileRcPtr cachedFile = DynamicPtrCast<LocalCachedFile>(untypedCachedFile);
  104. // This should never happen.
  105. if(!cachedFile)
  106. {
  107. std::ostringstream os;
  108. os << "Cannot build .ccc Op. Invalid cache type.";
  109. throw Exception(os.str().c_str());
  110. }
  111. TransformDirection newDir = CombineTransformDirections(dir,
  112. fileTransform.getDirection());
  113. if(newDir == TRANSFORM_DIR_UNKNOWN)
  114. {
  115. std::ostringstream os;
  116. os << "Cannot build ASC FileTransform,";
  117. os << " unspecified transform direction.";
  118. throw Exception(os.str().c_str());
  119. }
  120. // Below this point, we should throw ExceptionMissingFile on
  121. // errors rather than Exception
  122. // This is because we've verified that the ccc file is valid,
  123. // at now we're only querying whether the specified cccid can
  124. // be found.
  125. //
  126. // Using ExceptionMissingFile enables the missing looks fallback
  127. // mechanism to function properly.
  128. // At the time ExceptionMissingFile was named, we errently assumed
  129. // a 1:1 relationship between files and color corrections, which is
  130. // not true for .ccc files.
  131. //
  132. // In a future OCIO release, it may be more appropriate to
  133. // rename ExceptionMissingFile -> ExceptionMissingCorrection.
  134. // But either way, it's what we should throw below.
  135. std::string cccid = fileTransform.getCCCId();
  136. cccid = context->resolveStringVar(cccid.c_str());
  137. if(cccid.empty())
  138. {
  139. std::ostringstream os;
  140. os << "You must specify which cccid to load from the ccc file";
  141. os << " (either by name or index).";
  142. throw ExceptionMissingFile(os.str().c_str());
  143. }
  144. bool success=false;
  145. // Try to parse the cccid as a string id
  146. CDLTransformMap::const_iterator iter = cachedFile->transformMap.find(cccid);
  147. if(iter != cachedFile->transformMap.end())
  148. {
  149. success = true;
  150. BuildCDLOps(ops,
  151. config,
  152. *(iter->second),
  153. newDir);
  154. }
  155. // Try to parse the cccid as an integer index
  156. // We want to be strict, so fail if leftover chars in the parse.
  157. if(!success)
  158. {
  159. int cccindex=0;
  160. if(StringToInt(&cccindex, cccid.c_str(), true))
  161. {
  162. int maxindex = ((int)cachedFile->transformVec.size())-1;
  163. if(cccindex<0 || cccindex>maxindex)
  164. {
  165. std::ostringstream os;
  166. os << "The specified cccindex " << cccindex;
  167. os << " is outside the valid range for this file [0,";
  168. os << maxindex << "]";
  169. throw ExceptionMissingFile(os.str().c_str());
  170. }
  171. success = true;
  172. BuildCDLOps(ops,
  173. config,
  174. *cachedFile->transformVec[cccindex],
  175. newDir);
  176. }
  177. }
  178. if(!success)
  179. {
  180. std::ostringstream os;
  181. os << "You must specify a valid cccid to load from the ccc file";
  182. os << " (either by name or index). id='" << cccid << "' ";
  183. os << "is not found in the file, and is not parsable as an ";
  184. os << "integer index.";
  185. throw ExceptionMissingFile(os.str().c_str());
  186. }
  187. }
  188. }
  189. FileFormat * CreateFileFormatCCC()
  190. {
  191. return new LocalFileFormat();
  192. }
  193. }
  194. OCIO_NAMESPACE_EXIT