PageRenderTime 31ms CodeModel.GetById 14ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

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