/src/core/Config.cpp
C++ | 1957 lines | 1514 code | 336 blank | 107 comment | 189 complexity | 86cd1be9ee9af0728bff52be00b4832d MD5 | raw file
Possible License(s): BSD-3-Clause
- /*
- Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
- All Rights Reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Sony Pictures Imageworks nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <cstdlib>
- #include <cstring>
- #include <set>
- #include <sstream>
- #include <fstream>
- #include <utility>
- #include <vector>
- #include <OpenColorIO/OpenColorIO.h>
- #include "HashUtils.h"
- #include "Logging.h"
- #include "LookParse.h"
- #include "Display.h"
- #include "MathUtils.h"
- #include "Mutex.h"
- #include "OpBuilders.h"
- #include "PathUtils.h"
- #include "ParseUtils.h"
- #include "Processor.h"
- #include "PrivateTypes.h"
- #include "pystring/pystring.h"
- #include "OCIOYaml.h"
- OCIO_NAMESPACE_ENTER
- {
- namespace
- {
- const char * OCIO_CONFIG_ENVVAR = "OCIO";
- const char * OCIO_ACTIVE_DISPLAYS_ENVVAR = "OCIO_ACTIVE_DISPLAYS";
- const char * OCIO_ACTIVE_VIEWS_ENVVAR = "OCIO_ACTIVE_VIEWS";
-
- enum Sanity
- {
- SANITY_UNKNOWN = 0,
- SANITY_SANE,
- SANITY_INSANE
- };
-
- // These are the 709 primaries specified by the ASC.
- const float DEFAULT_LUMA_COEFF_R = 0.2126f;
- const float DEFAULT_LUMA_COEFF_G = 0.7152f;
- const float DEFAULT_LUMA_COEFF_B = 0.0722f;
-
- const char * INTERNAL_RAW_PROFILE =
- "ocio_profile_version: 1\n"
- "strictparsing: false\n"
- "roles:\n"
- " default: raw\n"
- "displays:\n"
- " sRGB:\n"
- " - !<View> {name: Raw, colorspace: raw}\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- " family: raw\n"
- " equalitygroup:\n"
- " bitdepth: 32f\n"
- " isdata: true\n"
- " allocation: uniform\n"
- " description: 'A raw color space. Conversions to and from this space are no-ops.'\n";
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
-
- const char * GetVersion()
- {
- return OCIO_VERSION;
- }
-
- int GetVersionHex()
- {
- return OCIO_VERSION_HEX;
- }
-
- namespace
- {
- ConstConfigRcPtr g_currentConfig;
- Mutex g_currentConfigLock;
- }
-
- ConstConfigRcPtr GetCurrentConfig()
- {
- AutoMutex lock(g_currentConfigLock);
-
- if(!g_currentConfig)
- {
- g_currentConfig = Config::CreateFromEnv();
- }
-
- return g_currentConfig;
- }
-
- void SetCurrentConfig(const ConstConfigRcPtr & config)
- {
- AutoMutex lock(g_currentConfigLock);
-
- g_currentConfig = config->createEditableCopy();
- }
-
- namespace
- {
-
- // Environment
- std::string LookupEnvironment(const StringMap & env, const std::string & name)
- {
- StringMap::const_iterator iter = env.find(name);
- if(iter == env.end()) return "";
- return iter->second;
- }
-
- // Roles
- // (lower case role name: colorspace name)
- std::string LookupRole(const StringMap & roles, const std::string & rolename)
- {
- StringMap::const_iterator iter = roles.find(pystring::lower(rolename));
- if(iter == roles.end()) return "";
- return iter->second;
- }
-
-
- void GetFileReferences(std::set<std::string> & files,
- const ConstTransformRcPtr & transform)
- {
- if(!transform) return;
-
- if(ConstGroupTransformRcPtr groupTransform = \
- DynamicPtrCast<const GroupTransform>(transform))
- {
- for(int i=0; i<groupTransform->size(); ++i)
- {
- GetFileReferences(files, groupTransform->getTransform(i));
- }
- }
- else if(ConstFileTransformRcPtr fileTransform = \
- DynamicPtrCast<const FileTransform>(transform))
- {
- files.insert(fileTransform->getSrc());
- }
- }
-
- void GetColorSpaceReferences(std::set<std::string> & colorSpaceNames,
- const ConstTransformRcPtr & transform)
- {
- if(!transform) return;
-
- if(ConstGroupTransformRcPtr groupTransform = \
- DynamicPtrCast<const GroupTransform>(transform))
- {
- for(int i=0; i<groupTransform->size(); ++i)
- {
- GetColorSpaceReferences(colorSpaceNames, groupTransform->getTransform(i));
- }
- }
- else if(ConstColorSpaceTransformRcPtr colorSpaceTransform = \
- DynamicPtrCast<const ColorSpaceTransform>(transform))
- {
- colorSpaceNames.insert(colorSpaceTransform->getSrc());
- colorSpaceNames.insert(colorSpaceTransform->getDst());
- }
- else if(ConstDisplayTransformRcPtr displayTransform = \
- DynamicPtrCast<const DisplayTransform>(transform))
- {
- colorSpaceNames.insert(displayTransform->getInputColorSpaceName());
- }
- else if(ConstLookTransformRcPtr lookTransform = \
- DynamicPtrCast<const LookTransform>(transform))
- {
- colorSpaceNames.insert(colorSpaceTransform->getSrc());
- colorSpaceNames.insert(colorSpaceTransform->getDst());
- }
- }
-
-
- bool FindColorSpaceIndex(int * index,
- const ColorSpaceVec & colorspaces,
- const std::string & csname)
- {
- if(csname.empty()) return false;
-
- std::string csnamelower = pystring::lower(csname);
- for(unsigned int i = 0; i < colorspaces.size(); ++i)
- {
- if(csnamelower == pystring::lower(colorspaces[i]->getName()))
- {
- if(index) *index = i;
- return true;
- }
- }
-
- return false;
- }
-
- } // namespace
-
- class Config::Impl
- {
- public:
- StringMap env_;
- ContextRcPtr context_;
- std::string description_;
- ColorSpaceVec colorspaces_;
- StringMap roles_;
- LookVec looksList_;
-
- DisplayMap displays_;
- StringVec activeDisplays_;
- StringVec activeDisplaysEnvOverride_;
- StringVec activeViews_;
- StringVec activeViewsEnvOverride_;
-
- mutable std::string activeDisplaysStr_;
- mutable std::string activeViewsStr_;
- mutable StringVec displayCache_;
-
- // Misc
- std::vector<float> defaultLumaCoefs_;
- bool strictParsing_;
-
- mutable Sanity sanity_;
- mutable std::string sanitytext_;
-
- mutable Mutex cacheidMutex_;
- mutable StringMap cacheids_;
- mutable std::string cacheidnocontext_;
-
- OCIOYaml io_;
-
- Impl() :
- context_(Context::Create()),
- strictParsing_(true),
- sanity_(SANITY_UNKNOWN)
- {
- char* activeDisplays = std::getenv(OCIO_ACTIVE_DISPLAYS_ENVVAR);
- SplitStringEnvStyle(activeDisplaysEnvOverride_, activeDisplays);
-
- char * activeViews = std::getenv(OCIO_ACTIVE_VIEWS_ENVVAR);
- SplitStringEnvStyle(activeViewsEnvOverride_, activeViews);
-
- defaultLumaCoefs_.resize(3);
- defaultLumaCoefs_[0] = DEFAULT_LUMA_COEFF_R;
- defaultLumaCoefs_[1] = DEFAULT_LUMA_COEFF_G;
- defaultLumaCoefs_[2] = DEFAULT_LUMA_COEFF_B;
- }
-
- ~Impl()
- {
-
- }
-
- Impl& operator= (const Impl & rhs)
- {
- env_ = rhs.env_;
- context_ = rhs.context_->createEditableCopy();
- description_ = rhs.description_;
-
- // Deep copy the colorspaces
- colorspaces_.clear();
- colorspaces_.reserve(rhs.colorspaces_.size());
- for(unsigned int i=0; i<rhs.colorspaces_.size(); ++i)
- {
- colorspaces_.push_back(rhs.colorspaces_[i]->createEditableCopy());
- }
-
- // Deep copy the looks
- looksList_.clear();
- looksList_.reserve(rhs.looksList_.size());
- for(unsigned int i=0; i<rhs.looksList_.size(); ++i)
- {
- looksList_.push_back(rhs.looksList_[i]->createEditableCopy());
- }
-
- // Assignment operator will suffice for these
- roles_ = rhs.roles_;
-
- displays_ = rhs.displays_;
- activeDisplays_ = rhs.activeDisplays_;
- activeViews_ = rhs.activeViews_;
- activeViewsEnvOverride_ = rhs.activeViewsEnvOverride_;
- activeDisplaysEnvOverride_ = rhs.activeDisplaysEnvOverride_;
- activeDisplaysStr_ = rhs.activeDisplaysStr_;
- displayCache_ = rhs.displayCache_;
-
- defaultLumaCoefs_ = rhs.defaultLumaCoefs_;
- strictParsing_ = rhs.strictParsing_;
-
- sanity_ = rhs.sanity_;
- sanitytext_ = rhs.sanitytext_;
-
- cacheids_ = rhs.cacheids_;
- cacheidnocontext_ = cacheidnocontext_;
- return *this;
- }
-
- // Any time you modify the state of the config, you must call this
- // to reset internal cache states. You also should do this in a
- // thread safe manner by acquiring the cacheidMutex_;
- void resetCacheIDs();
-
- // Get all internal transforms (to generate cacheIDs, validation, etc).
- // This currently crawls colorspaces + looks
- void getAllIntenalTransforms(ConstTransformVec & transformVec) const;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
-
- ConfigRcPtr Config::Create()
- {
- return ConfigRcPtr(new Config(), &deleter);
- }
-
- void Config::deleter(Config* c)
- {
- delete c;
- }
-
- ConstConfigRcPtr Config::CreateFromEnv()
- {
- char* file = std::getenv(OCIO_CONFIG_ENVVAR);
- if(file) return CreateFromFile(file);
-
- std::ostringstream os;
- os << "Color management disabled. ";
- os << "(Specify the $OCIO environment variable to enable.)";
- LogInfo(os.str());
-
- std::istringstream istream;
- istream.str(INTERNAL_RAW_PROFILE);
-
- ConfigRcPtr config = Config::Create();
- config->getImpl()->io_.open(istream, config);
- return config;
- }
-
- ConstConfigRcPtr Config::CreateFromFile(const char * filename)
- {
- std::ifstream istream(filename);
- if(istream.fail()) {
- std::ostringstream os;
- os << "Error could not read '" << filename;
- os << "' OCIO profile.";
- throw Exception (os.str().c_str());
- }
-
- ConfigRcPtr config = Config::Create();
- config->getImpl()->io_.open(istream, config, filename);
- return config;
- }
-
- ConstConfigRcPtr Config::CreateFromStream(std::istream & istream)
- {
- ConfigRcPtr config = Config::Create();
- config->getImpl()->io_.open(istream, config);
- return config;
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
-
-
- Config::Config()
- : m_impl(new Config::Impl)
- {
- }
-
- Config::~Config()
- {
- delete m_impl;
- m_impl = NULL;
- }
-
- ConfigRcPtr Config::createEditableCopy() const
- {
- ConfigRcPtr config = Config::Create();
- *config->m_impl = *m_impl;
- return config;
- }
-
- void Config::sanityCheck() const
- {
- if(getImpl()->sanity_ == SANITY_SANE) return;
- if(getImpl()->sanity_ == SANITY_INSANE)
- {
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- getImpl()->sanity_ = SANITY_INSANE;
- getImpl()->sanitytext_ = "";
-
-
- ///// COLORSPACES
- StringSet existingColorSpaces;
-
- // Confirm all ColorSpaces are valid
- for(unsigned int i=0; i<getImpl()->colorspaces_.size(); ++i)
- {
- if(!getImpl()->colorspaces_[i])
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The colorspace at index " << i << " is null.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- const char * name = getImpl()->colorspaces_[i]->getName();
- if(!name || strlen(name) == 0)
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The colorspace at index " << i << " is not named.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- std::string namelower = pystring::lower(name);
- StringSet::const_iterator it = existingColorSpaces.find(namelower);
- if(it != existingColorSpaces.end())
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "Two colorspaces are defined with the same name, '";
- os << namelower << "'.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- existingColorSpaces.insert(namelower);
- }
-
- // Confirm all roles are valid
- {
- for(StringMap::const_iterator iter = getImpl()->roles_.begin(),
- end = getImpl()->roles_.end(); iter!=end; ++iter)
- {
- int csindex = -1;
- if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, iter->second))
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The role '" << iter->first << "' ";
- os << "refers to a colorspace, '" << iter->second << "', ";
- os << "which is not defined.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- // Confirm no name conflicts between colorspaces and roles
- if(FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, iter->first))
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The role '" << iter->first << "' ";
- os << " is in conflict with a colorspace of the same name.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
- }
- }
-
- ///// DISPLAYS
-
- int numviews = 0;
-
- // Confirm all Displays transforms refer to colorspaces that exit
- for(DisplayMap::const_iterator iter = getImpl()->displays_.begin();
- iter != getImpl()->displays_.end();
- ++iter)
- {
- std::string display = iter->first;
- const ViewVec & views = iter->second;
- if(views.empty())
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The display '" << display << "' ";
- os << "does not define any views.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- for(unsigned int i=0; i<views.size(); ++i)
- {
- if(views[i].name.empty() || views[i].colorspace.empty())
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The display '" << display << "' ";
- os << "defines a view with an empty name and/or colorspace.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- int csindex = -1;
- if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, views[i].colorspace))
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The display '" << display << "' ";
- os << "refers to a colorspace, '" << views[i].colorspace << "', ";
- os << "which is not defined.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- // Confirm looks references exist
- LookParseResult looks;
- const LookParseResult::Options & options = looks.parse(views[i].looks);
-
- for(unsigned int optionindex=0;
- optionindex<options.size();
- ++optionindex)
- {
- for(unsigned int tokenindex=0;
- tokenindex<options[optionindex].size();
- ++tokenindex)
- {
- std::string look = options[optionindex][tokenindex].name;
-
- if(!look.empty() && !getLook(look.c_str()))
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The display '" << display << "' ";
- os << "refers to a look, '" << look << "', ";
- os << "which is not defined.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
- }
- }
-
- ++numviews;
- }
- }
-
- // Confirm at least one display entry exists.
- if(numviews == 0)
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "No displays are specified.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- // Confirm for all Transforms that reference internal colorspaces,
- // the named space exists
- {
- ConstTransformVec allTransforms;
- getImpl()->getAllIntenalTransforms(allTransforms);
-
- std::set<std::string> colorSpaceNames;
- for(unsigned int i=0; i<colorSpaceNames.size(); ++i)
- {
- GetColorSpaceReferences(colorSpaceNames, allTransforms[i]);
- }
-
- for(std::set<std::string>::iterator iter = colorSpaceNames.begin();
- iter != colorSpaceNames.end(); ++iter)
- {
- int csindex = -1;
- if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, *iter))
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "This config references a ColorSpace, '" << *iter << "', ";
- os << "which is not defined.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
- }
- }
-
- ///// LOOKS
-
- // For all looks, confirm the process space exists and the look is named
- for(unsigned int i=0; i<getImpl()->looksList_.size(); ++i)
- {
- std::string name = getImpl()->looksList_[i]->getName();
- if(name.empty())
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The look at index '" << i << "' ";
- os << "does not specify a name.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- std::string processSpace = getImpl()->looksList_[i]->getProcessSpace();
- if(processSpace.empty())
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The look '" << name << "' ";
- os << "does not specify a process space.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
-
- int csindex=0;
- if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, processSpace))
- {
- std::ostringstream os;
- os << "Config failed sanitycheck. ";
- os << "The look '" << name << "' ";
- os << "specifies a process color space, '";
- os << processSpace << "', which is not defined.";
- getImpl()->sanitytext_ = os.str();
- throw Exception(getImpl()->sanitytext_.c_str());
- }
- }
-
-
-
- // Everything is groovy.
- getImpl()->sanity_ = SANITY_SANE;
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- const char * Config::getDescription() const
- {
- return getImpl()->description_.c_str();
- }
-
- void Config::setDescription(const char * description)
- {
- getImpl()->description_ = description;
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
-
- // RESOURCES //////////////////////////////////////////////////////////////
-
- ConstContextRcPtr Config::getCurrentContext() const
- {
- return getImpl()->context_;
- }
-
- void Config::addEnvironmentVar(const char * name, const char * defaultValue)
- {
- if(defaultValue)
- {
- getImpl()->env_[std::string(name)] = std::string(defaultValue);
- getImpl()->context_->setStringVar(name, defaultValue);
- }
- else
- {
- StringMap::iterator iter = getImpl()->env_.find(std::string(name));
- if(iter != getImpl()->env_.end()) getImpl()->env_.erase(iter);
- }
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- int Config::getNumEnvironmentVars() const
- {
- return static_cast<int>(getImpl()->env_.size());
- }
-
- const char * Config::getEnvironmentVarNameByIndex(int index) const
- {
- if(index < 0 || index >= (int)getImpl()->env_.size()) return "";
- StringMap::const_iterator iter = getImpl()->env_.begin();
- for(int i = 0; i < index; ++i) ++iter;
- return iter->first.c_str();
- }
-
- const char * Config::getEnvironmentVarDefault(const char * name) const
- {
- return LookupEnvironment(getImpl()->env_, name).c_str();
- }
-
- void Config::clearEnvironmentVars()
- {
- getImpl()->env_.clear();
- getImpl()->context_->clearStringVars();
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- void Config::setEnvironmentMode(EnvironmentMode mode)
- {
- getImpl()->context_->setEnvironmentMode(mode);
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- EnvironmentMode Config::getEnvironmentMode() const
- {
- return getImpl()->context_->getEnvironmentMode();
- }
-
- void Config::loadEnvironment()
- {
- getImpl()->context_->loadEnvironment();
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- const char * Config::getSearchPath() const
- {
- return getImpl()->context_->getSearchPath();
- }
-
- void Config::setSearchPath(const char * path)
- {
- getImpl()->context_->setSearchPath(path);
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- const char * Config::getWorkingDir() const
- {
- return getImpl()->context_->getWorkingDir();
- }
-
- void Config::setWorkingDir(const char * dirname)
- {
- getImpl()->context_->setWorkingDir(dirname);
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
-
- int Config::getNumColorSpaces() const
- {
- return static_cast<int>(getImpl()->colorspaces_.size());
- }
-
- const char * Config::getColorSpaceNameByIndex(int index) const
- {
- if(index<0 || index >= (int)getImpl()->colorspaces_.size())
- {
- return "";
- }
-
- return getImpl()->colorspaces_[index]->getName();
- }
-
- ConstColorSpaceRcPtr Config::getColorSpace(const char * name) const
- {
- int index = getIndexForColorSpace(name);
- if(index<0 || index >= (int)getImpl()->colorspaces_.size())
- {
- return ColorSpaceRcPtr();
- }
-
- return getImpl()->colorspaces_[index];
- }
-
- int Config::getIndexForColorSpace(const char * name) const
- {
- int csindex = -1;
-
- // Check to see if the name is a color space
- if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, name) )
- {
- return csindex;
- }
-
- // Check to see if the name is a role
- std::string csname = LookupRole(getImpl()->roles_, name);
- if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, csname) )
- {
- return csindex;
- }
-
- // Is a default role defined?
- // (And, are we allowed to use it)
- if(!getImpl()->strictParsing_)
- {
- csname = LookupRole(getImpl()->roles_, ROLE_DEFAULT);
- if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, csname) )
- {
- return csindex;
- }
- }
-
- return -1;
- }
-
- void Config::addColorSpace(const ConstColorSpaceRcPtr & original)
- {
- ColorSpaceRcPtr cs = original->createEditableCopy();
-
- std::string name = cs->getName();
- if(name.empty())
- throw Exception("Cannot addColorSpace with an empty name.");
-
- // Check to see if the colorspace already exists
- int csindex = -1;
- if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, name) )
- {
- getImpl()->colorspaces_[csindex] = cs;
- }
- else
- {
- // Otherwise, add it
- getImpl()->colorspaces_.push_back( cs );
- }
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- void Config::clearColorSpaces()
- {
- getImpl()->colorspaces_.clear();
- }
-
-
-
-
-
-
- const char * Config::parseColorSpaceFromString(const char * str) const
- {
- if(!str) return "";
-
- // Search the entire filePath, including directory name (if provided)
- // convert the filename to lowercase.
- std::string fullstr = pystring::lower(std::string(str));
-
- // See if it matches a lut name.
- // This is the position of the RIGHT end of the colorspace substring, not the left
- int rightMostColorPos=-1;
- std::string rightMostColorspace = "";
- int rightMostColorSpaceIndex = -1;
-
- // Find the right-most occcurance within the string for each colorspace.
- for (unsigned int i=0; i<getImpl()->colorspaces_.size(); ++i)
- {
- std::string csname = pystring::lower(getImpl()->colorspaces_[i]->getName());
-
- // find right-most extension matched in filename
- int colorspacePos = pystring::rfind(fullstr, csname);
- if(colorspacePos < 0)
- continue;
-
- // If we have found a match, move the pointer over to the right end of the substring
- // This will allow us to find the longest name that matches the rightmost colorspace
- colorspacePos += (int)csname.size();
-
- if ( (colorspacePos > rightMostColorPos) ||
- ((colorspacePos == rightMostColorPos) && (csname.size() > rightMostColorspace.size()))
- )
- {
- rightMostColorPos = colorspacePos;
- rightMostColorspace = csname;
- rightMostColorSpaceIndex = i;
- }
- }
-
- if(rightMostColorSpaceIndex>=0)
- {
- return getImpl()->colorspaces_[rightMostColorSpaceIndex]->getName();
- }
-
- if(!getImpl()->strictParsing_)
- {
- // Is a default role defined?
- std::string csname = LookupRole(getImpl()->roles_, ROLE_DEFAULT);
- if(!csname.empty())
- {
- int csindex = -1;
- if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, csname) )
- {
- // This is necessary to not return a reference to
- // a local variable.
- return getImpl()->colorspaces_[csindex]->getName();
- }
- }
- }
-
- return "";
- }
-
- bool Config::isStrictParsingEnabled() const
- {
- return getImpl()->strictParsing_;
- }
-
- void Config::setStrictParsingEnabled(bool enabled)
- {
- getImpl()->strictParsing_ = enabled;
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- // Roles
- void Config::setRole(const char * role, const char * colorSpaceName)
- {
- // Set the role
- if(colorSpaceName)
- {
- getImpl()->roles_[pystring::lower(role)] = std::string(colorSpaceName);
- }
- // Unset the role
- else
- {
- StringMap::iterator iter = getImpl()->roles_.find(pystring::lower(role));
- if(iter != getImpl()->roles_.end())
- {
- getImpl()->roles_.erase(iter);
- }
- }
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- int Config::getNumRoles() const
- {
- return static_cast<int>(getImpl()->roles_.size());
- }
-
- bool Config::hasRole(const char * role) const
- {
- return LookupRole(getImpl()->roles_, role) == "" ? false : true;
- }
-
- const char * Config::getRoleName(int index) const
- {
- if(index < 0 || index >= (int)getImpl()->roles_.size()) return "";
- StringMap::const_iterator iter = getImpl()->roles_.begin();
- for(int i = 0; i < index; ++i) ++iter;
- return iter->first.c_str();
- }
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // Display/View Registration
-
-
- const char * Config::getDefaultDisplay() const
- {
- if(getImpl()->displayCache_.empty())
- {
- ComputeDisplays(getImpl()->displayCache_,
- getImpl()->displays_,
- getImpl()->activeDisplays_,
- getImpl()->activeDisplaysEnvOverride_);
- }
-
- int index = -1;
-
- if(!getImpl()->activeDisplaysEnvOverride_.empty())
- {
- StringVec orderedDisplays = IntersectStringVecsCaseIgnore(getImpl()->activeDisplaysEnvOverride_,
- getImpl()->displayCache_);
- if(!orderedDisplays.empty())
- {
- index = FindInStringVecCaseIgnore(getImpl()->displayCache_, orderedDisplays[0]);
- }
- }
- else if(!getImpl()->activeDisplays_.empty())
- {
- StringVec orderedDisplays = IntersectStringVecsCaseIgnore(getImpl()->activeDisplays_,
- getImpl()->displayCache_);
- if(!orderedDisplays.empty())
- {
- index = FindInStringVecCaseIgnore(getImpl()->displayCache_, orderedDisplays[0]);
- }
- }
-
- if(index >= 0)
- {
- return getImpl()->displayCache_[index].c_str();
- }
-
- if(!getImpl()->displayCache_.empty())
- {
- return getImpl()->displayCache_[0].c_str();
- }
-
- return "";
- }
- int Config::getNumDisplays() const
- {
- if(getImpl()->displayCache_.empty())
- {
- ComputeDisplays(getImpl()->displayCache_,
- getImpl()->displays_,
- getImpl()->activeDisplays_,
- getImpl()->activeDisplaysEnvOverride_);
- }
-
- return static_cast<int>(getImpl()->displayCache_.size());
- }
- const char * Config::getDisplay(int index) const
- {
- if(getImpl()->displayCache_.empty())
- {
- ComputeDisplays(getImpl()->displayCache_,
- getImpl()->displays_,
- getImpl()->activeDisplays_,
- getImpl()->activeDisplaysEnvOverride_);
- }
-
- if(index>=0 || index < static_cast<int>(getImpl()->displayCache_.size()))
- {
- return getImpl()->displayCache_[index].c_str();
- }
-
- return "";
- }
-
- const char * Config::getDefaultView(const char * display) const
- {
- if(getImpl()->displayCache_.empty())
- {
- ComputeDisplays(getImpl()->displayCache_,
- getImpl()->displays_,
- getImpl()->activeDisplays_,
- getImpl()->activeDisplaysEnvOverride_);
- }
-
- if(!display) return "";
-
- DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display);
- if(iter == getImpl()->displays_.end()) return "";
-
- const ViewVec & views = iter->second;
-
- StringVec masterViews;
- for(unsigned int i=0; i<views.size(); ++i)
- {
- masterViews.push_back(views[i].name);
- }
-
- int index = -1;
-
- if(!getImpl()->activeViewsEnvOverride_.empty())
- {
- StringVec orderedViews = IntersectStringVecsCaseIgnore(getImpl()->activeViewsEnvOverride_,
- masterViews);
- if(!orderedViews.empty())
- {
- index = FindInStringVecCaseIgnore(masterViews, orderedViews[0]);
- }
- }
- else if(!getImpl()->activeViews_.empty())
- {
- StringVec orderedViews = IntersectStringVecsCaseIgnore(getImpl()->activeViews_,
- masterViews);
- if(!orderedViews.empty())
- {
- index = FindInStringVecCaseIgnore(masterViews, orderedViews[0]);
- }
- }
-
- if(index >= 0)
- {
- return views[index].name.c_str();
- }
-
- if(!views.empty())
- {
- return views[0].name.c_str();
- }
-
- return "";
- }
- int Config::getNumViews(const char * display) const
- {
- if(getImpl()->displayCache_.empty())
- {
- ComputeDisplays(getImpl()->displayCache_,
- getImpl()->displays_,
- getImpl()->activeDisplays_,
- getImpl()->activeDisplaysEnvOverride_);
- }
-
- if(!display) return 0;
-
- DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display);
- if(iter == getImpl()->displays_.end()) return 0;
-
- const ViewVec & views = iter->second;
- return static_cast<int>(views.size());
- }
- const char * Config::getView(const char * display, int index) const
- {
- if(getImpl()->displayCache_.empty())
- {
- ComputeDisplays(getImpl()->displayCache_,
- getImpl()->displays_,
- getImpl()->activeDisplays_,
- getImpl()->activeDisplaysEnvOverride_);
- }
-
- if(!display) return "";
-
- DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display);
- if(iter == getImpl()->displays_.end()) return "";
-
- const ViewVec & views = iter->second;
- return views[index].name.c_str();
- }
- const char * Config::getDisplayColorSpaceName(const char * display, const char * view) const
- {
- if(!display || !view) return "";
-
- DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display);
- if(iter == getImpl()->displays_.end()) return "";
-
- const ViewVec & views = iter->second;
- int index = find_view(views, view);
- if(index<0) return "";
-
- return views[index].colorspace.c_str();
- }
-
- const char * Config::getDisplayLooks(const char * display, const char * view) const
- {
- if(!display || !view) return "";
-
- DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display);
- if(iter == getImpl()->displays_.end()) return "";
-
- const ViewVec & views = iter->second;
- int index = find_view(views, view);
- if(index<0) return "";
-
- return views[index].looks.c_str();
- }
-
- void Config::addDisplay(const char * display, const char * view,
- const char * colorSpaceName, const char * lookName)
- {
-
- if(!display || !view || !colorSpaceName || !lookName) return;
-
- AddDisplay(getImpl()->displays_,
- display, view, colorSpaceName, lookName);
- getImpl()->displayCache_.clear();
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- void Config::clearDisplays()
- {
- getImpl()->displays_.clear();
- getImpl()->displayCache_.clear();
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- void Config::setActiveDisplays(const char * displays)
- {
- getImpl()->activeDisplays_.clear();
- SplitStringEnvStyle(getImpl()->activeDisplays_, displays);
-
- getImpl()->displayCache_.clear();
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
- const char * Config::getActiveDisplays() const
- {
- getImpl()->activeDisplaysStr_ = JoinStringEnvStyle(getImpl()->activeDisplays_);
- return getImpl()->activeDisplaysStr_.c_str();
- }
-
- void Config::setActiveViews(const char * views)
- {
- getImpl()->activeViews_.clear();
- SplitStringEnvStyle(getImpl()->activeViews_, views);
-
- getImpl()->displayCache_.clear();
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
- const char * Config::getActiveViews() const
- {
- getImpl()->activeViewsStr_ = JoinStringEnvStyle(getImpl()->activeViews_);
- return getImpl()->activeViewsStr_.c_str();
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
-
- void Config::getDefaultLumaCoefs(float * c3) const
- {
- memcpy(c3, &getImpl()->defaultLumaCoefs_[0], 3*sizeof(float));
- }
-
- void Config::setDefaultLumaCoefs(const float * c3)
- {
- memcpy(&getImpl()->defaultLumaCoefs_[0], c3, 3*sizeof(float));
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
-
-
-
- ///////////////////////////////////////////////////////////////////////////
-
-
-
-
- ConstLookRcPtr Config::getLook(const char * name) const
- {
- std::string namelower = pystring::lower(name);
-
- for(unsigned int i=0; i<getImpl()->looksList_.size(); ++i)
- {
- if(pystring::lower(getImpl()->looksList_[i]->getName()) == namelower)
- {
- return getImpl()->looksList_[i];
- }
- }
-
- return ConstLookRcPtr();
- }
-
- int Config::getNumLooks() const
- {
- return static_cast<int>(getImpl()->looksList_.size());
- }
-
- const char * Config::getLookNameByIndex(int index) const
- {
- if(index<0 || index>=static_cast<int>(getImpl()->looksList_.size()))
- {
- return "";
- }
-
- return getImpl()->looksList_[index]->getName();
- }
-
- void Config::addLook(const ConstLookRcPtr & look)
- {
- std::string name = look->getName();
- if(name.empty())
- throw Exception("Cannot addLook with an empty name.");
-
- std::string namelower = pystring::lower(name);
-
- // If the look exists, replace it
- for(unsigned int i=0; i<getImpl()->looksList_.size(); ++i)
- {
- if(pystring::lower(getImpl()->looksList_[i]->getName()) == namelower)
- {
- getImpl()->looksList_[i] = look->createEditableCopy();
- return;
- }
- }
-
- // Otherwise, add it
- getImpl()->looksList_.push_back(look->createEditableCopy());
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- void Config::clearLooks()
- {
- getImpl()->looksList_.clear();
-
- AutoMutex lock(getImpl()->cacheidMutex_);
- getImpl()->resetCacheIDs();
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
-
-
- ConstProcessorRcPtr Config::getProcessor(const ConstColorSpaceRcPtr & src,
- const ConstColorSpaceRcPtr & dst) const
- {
- ConstContextRcPtr context = getCurrentContext();
- return getProcessor(context, src, dst);
- }
-
- ConstProcessorRcPtr Config::getProcessor(const ConstContextRcPtr & context,
- const ConstColorSpaceRcPtr & src,
- const ConstColorSpaceRcPtr & dst) const
- {
- if(!src)
- {
- throw Exception("Config::GetProcessor failed. Source colorspace is null.");
- }
- if(!dst)
- {
- throw Exception("Config::GetProcessor failed. Destination colorspace is null.");
- }
-
- ProcessorRcPtr processor = Processor::Create();
- processor->getImpl()->addColorSpaceConversion(*this, context, src, dst);
- processor->getImpl()->finalize();
- return processor;
- }
-
- ConstProcessorRcPtr Config::getProcessor(const char * srcName,
- const char * dstName) const
- {
- ConstContextRcPtr context = getCurrentContext();
- return getProcessor(context, srcName, dstName);
- }
-
- //! Names can be colorspace name or role name
- ConstProcessorRcPtr Config::getProcessor(const ConstContextRcPtr & context,
- const char * srcName,
- const char * dstName) const
- {
- ConstColorSpaceRcPtr src = getColorSpace(srcName);
- if(!src)
- {
- std::ostringstream os;
- os << "Could not find colorspace '" << srcName << "'.";
- throw Exception(os.str().c_str());
- }
-
- ConstColorSpaceRcPtr dst = getColorSpace(dstName);
- if(!dst)
- {
- std::ostringstream os;
- os << "Could not find colorspace '" << dstName << "'.";
- throw Exception(os.str().c_str());
- }
-
- return getProcessor(context, src, dst);
- }
-
-
- ConstProcessorRcPtr Config::getProcessor(const ConstTransformRcPtr& transform) const
- {
- return getProcessor(transform, TRANSFORM_DIR_FORWARD);
- }
-
-
- ConstProcessorRcPtr Config::getProcessor(const ConstTransformRcPtr& transform,
- TransformDirection direction) const
- {
- ConstContextRcPtr context = getCurrentContext();
- return getProcessor(context, transform, direction);
- }
-
- ConstProcessorRcPtr Config::getProcessor(const ConstContextRcPtr & context,
- const ConstTransformRcPtr& transform,
- TransformDirection direction) const
- {
- ProcessorRcPtr processor = Processor::Create();
- processor->getImpl()->addTransform(*this, context, transform, direction);
- processor->getImpl()->finalize();
- return processor;
- }
-
- std::ostream& operator<< (std::ostream& os, const Config& config)
- {
- config.serialize(os);
- return os;
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // CacheID
-
- const char * Config::getCacheID() const
- {
- return getCacheID(getCurrentContext());
- }
-
- const char * Config::getCacheID(const ConstContextRcPtr & context) const
- {
- AutoMutex lock(getImpl()->cacheidMutex_);
-
- // A null context will use the empty cacheid
- std::string contextcacheid = "";
- if(context) contextcacheid = context->getCacheID();
-
- StringMap::const_iterator cacheiditer = getImpl()->cacheids_.find(contextcacheid);
- if(cacheiditer != getImpl()->cacheids_.end())
- {
- return cacheiditer->second.c_str();
- }
-
- // Include the hash of the yaml config serialization
- if(getImpl()->cacheidnocontext_.empty())
- {
- std::stringstream cacheid;
- serialize(cacheid);
- std::string fullstr = cacheid.str();
- getImpl()->cacheidnocontext_ = CacheIDHash(fullstr.c_str(), (int)fullstr.size());
- }
-
- // Also include all file references, using the context (if specified)
- std::string fileReferencesFashHash = "";
- if(context)
- {
- std::ostringstream filehash;
-
- ConstTransformVec allTransforms;
- getImpl()->getAllIntenalTransforms(allTransforms);
-
- std::set<std::string> files;
- for(unsigned int i=0; i<allTransforms.size(); ++i)
- {
- GetFileReferences(files, allTransforms[i]);
- }
-
- for(std::set<std::string>::iterator iter = files.begin();
- iter != files.end(); ++iter)
- {
- if(iter->empty()) continue;
- filehash << *iter << "=";
-
- try
- {
- std::string resolvedLocation = context->resolveFileLocation(iter->c_str());
- filehash << GetFastFileHash(resolvedLocation) << " ";
- }
- catch(...)
- {
- filehash << "? ";
- continue;
- }
- }
-
- std::string fullstr = filehash.str();
- fileReferencesFashHash = CacheIDHash(fullstr.c_str(), (int)fullstr.size());
- }
-
- getImpl()->cacheids_[contextcacheid] = getImpl()->cacheidnocontext_ + ":" + fileReferencesFashHash;
- return getImpl()->cacheids_[contextcacheid].c_str();
- }
-
-
- ///////////////////////////////////////////////////////////////////////////
- // Serialization
-
- void Config::serialize(std::ostream& os) const
- {
- try
- {
- getImpl()->io_.write(os, this);
- }
- catch( const std::exception & e)
- {
- std::ostringstream error;
- error << "Error building YAML: " << e.what();
- throw Exception(error.str().c_str());
- }
- }
-
- void Config::Impl::resetCacheIDs()
- {
- cacheids_.clear();
- cacheidnocontext_ = "";
- sanity_ = SANITY_UNKNOWN;
- sanitytext_ = "";
- }
-
- void Config::Impl::getAllIntenalTransforms(ConstTransformVec & transformVec) const
- {
- // Grab all transforms from the ColorSpaces
- for(unsigned int i=0; i<colorspaces_.size(); ++i)
- {
- if(colorspaces_[i]->getTransform(COLORSPACE_DIR_TO_REFERENCE))
- transformVec.push_back(colorspaces_[i]->getTransform(COLORSPACE_DIR_TO_REFERENCE));
- if(colorspaces_[i]->getTransform(COLORSPACE_DIR_FROM_REFERENCE))
- transformVec.push_back(colorspaces_[i]->getTransform(COLORSPACE_DIR_FROM_REFERENCE));
- }
-
- // Grab all transforms from the Looks
- for(unsigned int i=0; i<looksList_.size(); ++i)
- {
- if(looksList_[i]->getTransform())
- transformVec.push_back(looksList_[i]->getTransform());
- if(looksList_[i]->getInverseTransform())
- transformVec.push_back(looksList_[i]->getInverseTransform());
- }
-
- }
- }
- OCIO_NAMESPACE_EXIT
- ///////////////////////////////////////////////////////////////////////////////
- #ifdef OCIO_UNIT_TEST
- namespace OCIO = OCIO_NAMESPACE;
- #include "UnitTest.h"
- #include <sys/stat.h>
- #include "pystring/pystring.h"
- #if 0
- OIIO_ADD_TEST(Config, test_searchpath_filesystem)
- {
-
- OCIO::EnvMap env = OCIO::GetEnvMap();
- std::string OCIO_TEST_AREA("$OCIO_TEST_AREA");
- EnvExpand(&OCIO_TEST_AREA, &env);
-
- OCIO::ConfigRcPtr config = OCIO::Config::Create();
-
- // basic get/set/expand
- config->setSearchPath("."
- ":$OCIO_TEST1"
- ":/$OCIO_JOB/${OCIO_SEQ}/$OCIO_SHOT/ocio");
-
- OIIO_CHECK_ASSERT(strcmp(config->getSearchPath(),
- ".:$OCIO_TEST1:/$OCIO_JOB/${OCIO_SEQ}/$OCIO_SHOT/ocio") == 0);
- OIIO_CHECK_ASSERT(strcmp(config->getSearchPath(true),
- ".:foobar:/meatballs/cheesecake/mb-cc-001/ocio") == 0);
-
- // find some files
- config->setSearchPath(".."
- ":$OCIO_TEST1"
- ":${OCIO_TEST_AREA}/test_search/one"
- ":$OCIO_TEST_AREA/test_search/two");
-
- // setup for search test
- std::string base_dir("$OCIO_TEST_AREA/test_search/");
- EnvExpand(&base_dir, &env);
- mkdir(base_dir.c_str(), 0777);
-
- std::string one_dir("$OCIO_TEST_AREA/test_search/one/");
- EnvExpand(&one_dir, &env);
- mkdir(one_dir.c_str(), 0777);
-
- std::string two_dir("$OCIO_TEST_AREA/test_search/two/");
- EnvExpand(&two_dir, &env);
- mkdir(two_dir.c_str(), 0777);
-
- std::string lut1(one_dir+"somelut1.lut");
- std::ofstream somelut1(lut1.c_str());
- somelut1.close();
-
- std::string lut2(two_dir+"somelut2.lut");
- std::ofstream somelut2(lut2.c_str());
- somelut2.close();
-
- std::string lut3(two_dir+"somelut3.lut");
- std::ofstream somelut3(lut3.c_str());
- somelut3.close();
-
- std::string lutdotdot(OCIO_TEST_AREA+"/lutdotdot.lut");
- std::ofstream somelutdotdot(lutdotdot.c_str());
- somelutdotdot.close();
-
- // basic search test
- OIIO_CHECK_ASSERT(strcmp(config->findFile("somelut1.lut"),
- lut1.c_str()) == 0);
- OIIO_CHECK_ASSERT(strcmp(config->findFile("somelut2.lut"),
- lut2.c_str()) == 0);
- OIIO_CHECK_ASSERT(strcmp(config->findFile("somelut3.lut"),
- lut3.c_str()) == 0);
- OIIO_CHECK_ASSERT(strcmp(config->findFile("lutdotdot.lut"),
- lutdotdot.c_str()) == 0);
-
- }
- #endif
- OIIO_ADD_TEST(Config, InternalRawProfile)
- {
- std::istringstream is;
- is.str(OCIO::INTERNAL_RAW_PROFILE);
- OIIO_CHECK_NO_THOW(OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromStream(is));
- }
- OIIO_ADD_TEST(Config, SimpleConfig)
- {
-
- std::string SIMPLE_PROFILE =
- "ocio_profile_version: 1\n"
- "resource_path: luts\n"
- "strictparsing: false\n"
- "luma: [0.2126, 0.7152, 0.0722]\n"
- "roles:\n"
- " compositing_log: lgh\n"
- " default: raw\n"
- " scene_linear: lnh\n"
- "displays:\n"
- " sRGB:\n"
- " - !<View> {name: Film1D, colorspace: vd8}\n"
- " - !<View> {name: Log, colorspace: lg10}\n"
- " - !<View> {name: Raw, colorspace: raw}\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- " family: raw\n"
- " equalitygroup: \n"
- " bitdepth: 32f\n"
- " description: |\n"
- " A raw color space. Conversions to and from this space are no-ops.\n"
- " isdata: true\n"
- " allocation: uniform\n"
- " - !<ColorSpace>\n"
- " name: lnh\n"
- " family: ln\n"
- " equalitygroup: \n"
- " bitdepth: 16f\n"
- " description: |\n"
- " The show reference space. This is a sensor referred linear\n"
- " representation of the scene with primaries that correspond to\n"
- " scanned film. 0.18 in this space corresponds to a properly\n"
- " exposed 18% grey card.\n"
- " isdata: false\n"
- " allocation: lg2\n"
- " - !<ColorSpace>\n"
- " name: loads_of_transforms\n"
- " family: vd8\n"
- " equalitygroup: \n"
- " bitdepth: 8ui\n"
- " description: 'how many transforms can we use?'\n"
- " isdata: false\n"
- " allocation: uniform\n"
- " to_reference: !<GroupTransform>\n"
- " direction: forward\n"
- " children:\n"
- " - !<FileTransform>\n"
- " src: diffusemult.spimtx\n"
- " interpolation: unknown\n"
- " - !<ColorSpaceTransform>\n"
- " src: vd8\n"
- " dst: lnh\n"
- " - !<ExponentTransform>\n"
- " value: [2.2, 2.2, 2.2, 1]\n"
- " - !<MatrixTransform>\n"
- " matrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]\n"
- " offset: [0, 0, 0, 0]\n"
- " - !<CDLTransform>\n"
- " slope: [1, 1, 1]\n"
- " offset: [0, 0, 0]\n"
- " power: [1, 1, 1]\n"
- " saturation: 1\n"
- "\n";
-
- std::istringstream is;
- is.str(SIMPLE_PROFILE);
- OCIO::ConstConfigRcPtr config;
- OIIO_CHECK_NO_THOW(config = OCIO::Config::CreateFromStream(is));
- }
- OIIO_ADD_TEST(Config, Roles)
- {
-
- std::string SIMPLE_PROFILE =
- "ocio_profile_version: 1\n"
- "strictparsing: false\n"
- "roles:\n"
- " compositing_log: lgh\n"
- " default: raw\n"
- " scene_linear: lnh\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- " - !<ColorSpace>\n"
- " name: lnh\n"
- " - !<ColorSpace>\n"
- " name: lgh\n"
- "\n";
-
- std::istringstream is;
- is.str(SIMPLE_PROFILE);
- OCIO::ConstConfigRcPtr config;
- OIIO_CHECK_NO_THOW(config = OCIO::Config::CreateFromStream(is));
-
- OIIO_CHECK_EQUAL(config->getNumRoles(), 3);
-
- OIIO_CHECK_ASSERT(config->hasRole("compositing_log") == true);
- OIIO_CHECK_ASSERT(config->hasRole("cheese") == false);
- OIIO_CHECK_ASSERT(config->hasRole("") == false);
-
- OIIO_CHECK_ASSERT(strcmp(config->getRoleName(2), "scene_linear") == 0);
- OIIO_CHECK_ASSERT(strcmp(config->getRoleName(0), "compositing_log") == 0);
- OIIO_CHECK_ASSERT(strcmp(config->getRoleName(1), "default") == 0);
- OIIO_CHECK_ASSERT(strcmp(config->getRoleName(10), "") == 0);
- OIIO_CHECK_ASSERT(strcmp(config->getRoleName(-4), "") == 0);
-
- }
- OIIO_ADD_TEST(Config, Serialize)
- {
-
- OCIO::ConfigRcPtr config = OCIO::Config::Create();
- {
- OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create();
- cs->setName("testing");
- cs->setFamily("test");
- OCIO::FileTransformRcPtr transform1 = \
- OCIO::FileTransform::Create();
- OCIO::GroupTransformRcPtr groupTransform = OCIO::GroupTransform::Create();
- groupTransform->push_back(transform1);
- cs->setTransform(groupTransform, OCIO::COLORSPACE_DIR_TO_REFERENCE);
- config->addColorSpace(cs);
- config->setRole( OCIO::ROLE_COMPOSITING_LOG, cs->getName() );
- }
- {
- OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create();
- cs->setName("testing2");
- cs->setFamily("test");
- OCIO::ExponentTransformRcPtr transform1 = \
- OCIO::ExponentTransform::Create();
- OCIO::GroupTransformRcPtr groupTransform = OCIO::GroupTransform::Create();
- groupTransform->push_back(transform1);
- cs->setTransform(groupTransform, OCIO::COLORSPACE_DIR_TO_REFERENCE);
- config->addColorSpace(cs);
- config->setRole( OCIO::ROLE_COMPOSITING_LOG, cs->getName() );
- }
-
- // for testing
- //std::ofstream outfile("/tmp/test.ocio");
- //config->serialize(outfile);
- //outfile.close();
-
- std::ostringstream os;
- config->serialize(os);
-
- std::string PROFILE_OUT =
- "ocio_profile_version: 1\n"
- "\n"
- "search_path: \"\"\n"
- "strictparsing: true\n"
- "luma: [0.2126, 0.7152, 0.0722]\n"
- "\n"
- "roles:\n"
- " compositing_log: testing2\n"
- "\n"
- "displays:\n"
- " {}\n"
- "\n"
- "active_displays: []\n"
- "active_views: []\n"
- "\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: testing\n"
- " family: test\n"
- " equalitygroup: \"\"\n"
- " bitdepth: unknown\n"
- " isdata: false\n"
- " allocation: uniform\n"
- " to_reference: !<GroupTransform>\n"
- " children:\n"
- " - !<FileTransform> {src: \"\", interpolation: unknown}\n"
- "\n"
- " - !<ColorSpace>\n"
- " name: testing2\n"
- " family: test\n"
- " equalitygroup: \"\"\n"
- " bitdepth: unknown\n"
- " isdata: false\n"
- " allocation: uniform\n"
- " to_reference: !<GroupTransform>\n"
- " children:\n"
- " - !<ExponentTransform> {value: [1, 1, 1, 1]}\n";
-
- std::vector<std::string> osvec;
- OCIO::pystring::splitlines(os.str(), osvec);
- std::vector<std::string> PROFILE_OUTvec;
- OCIO::pystring::splitlines(PROFILE_OUT, PROFILE_OUTvec);
-
- OIIO_CHECK_EQUAL(osvec.size(), PROFILE_OUTvec.size());
- for(unsigned int i = 0; i < PROFILE_OUTvec.size(); ++i)
- OIIO_CHECK_EQUAL(osvec[i], PROFILE_OUTvec[i]);
- }
- OIIO_ADD_TEST(Config, SanityCheck)
- {
- {
- std::string SIMPLE_PROFILE =
- "ocio_profile_version: 1\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- "strictparsing: false\n"
- "roles:\n"
- " default: raw\n"
- "displays:\n"
- " sRGB:\n"
- " - !<View> {name: Raw, colorspace: raw}\n"
- "\n";
-
- std::istringstream is;
- is.str(SIMPLE_PROFILE);
- OCIO::ConstConfigRcPtr config;
- OIIO_CHECK_THOW(config = OCIO::Config::CreateFromStream(is), OCIO::Exception);
- }
-
- {
- std::string SIMPLE_PROFILE =
- "ocio_profile_version: 1\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- "strictparsing: false\n"
- "roles:\n"
- " default: raw\n"
- "displays:\n"
- " sRGB:\n"
- " - !<View> {name: Raw, colorspace: raw}\n"
- "\n";
-
- std::istringstream is;
- is.str(SIMPLE_PROFILE);
- OCIO::ConstConfigRcPtr config;
- OIIO_CHECK_NO_THOW(config = OCIO::Config::CreateFromStream(is));
-
- OIIO_CHECK_NO_THOW(config->sanityCheck());
- }
- }
- OIIO_ADD_TEST(Config, EnvCheck)
- {
- {
- std::string SIMPLE_PROFILE =
- "ocio_profile_version: 1\n"
- "environment:\n"
- " SHOW: super\n"
- " SHOT: test\n"
- " SEQ: foo\n"
- " test: bar${cheese}\n"
- " cheese: chedder\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- "strictparsing: false\n"
- "roles:\n"
- " default: raw\n"
- "displays:\n"
- " sRGB:\n"
- " - !<View> {name: Raw, colorspace: raw}\n"
- "\n";
-
- std::string SIMPLE_PROFILE2 =
- "ocio_profile_version: 1\n"
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
- "strictparsing: false\n"
- "roles:\n"
- " default: raw\n"
- "displays:\n"
- " sRGB:\n"
- " - !<View> {name: Raw, colorspace: raw}\n"
- "\n";
-
-
- std::string test("SHOW=bar");
- putenv((char *)test.c_str());
- std::string test2("TASK=lighting");
- putenv((char *)test2.c_str());
-
- std::istringstream is;
- is.str(SIMPLE_PROFILE);
- OCIO::ConstConfigRcPtr config;
- OIIO_CHECK_NO_THOW(config = OCIO::Config::CreateFromStream(is));
- OIIO_CHECK_EQUAL(config->getNumEnvironmentVars(), 5);
- OIIO_CHECK_ASSERT(strcmp(config->getCurrentContext()->resolveStringVar("test${test}"),
- "testbarchedder") == 0);
- OIIO_CHECK_ASSERT(strcmp(config->getCurrentContext()->resolveStringVar("${SHOW}"),
- "bar") == 0);
- OIIO_CHECK_ASSERT(strcmp(config->getEnvironmentVarDefault("SHOW"), "super") == 0);
-
- OCIO::ConfigRcPtr edit = config->createEditableCopy();
- edit->clearEnvironmentVars();
- OIIO_CHECK_EQUAL(edit->getNumEnvironmentVars(), 0);
-
- edit->addEnvironmentVar("testing", "dupvar");
- edit->addEnvironmentVar("testing", "dupvar");
- edit->addEnvironmentVar("foobar", "testing");
- edit->addEnvironmentVar("blank", "");
- edit->addEnvironmentVar("dontadd", NULL);
- OIIO_CHECK_EQUAL(edit->getNumEnvironmentVars(), 3);
- edit->addEnvironmentVar("foobar", NULL); // remove
- OIIO_CHECK_EQUAL(edit->getNumEnvironmentVars(), 2);
- edit->clearEnvironmentVars();
-
- edit->addEnvironmentVar("SHOW", "super");
- edit->addEnvironmentVar("SHOT", "test");
- edit->addEnvironmentVar("SEQ", "foo");
- edit->addEnvironmentVar("test", "bar${cheese}");
- edit->addEnvironmentVar("cheese", "chedder");
-
- //Test
- OCIO::LoggingLevel loglevel = OCIO::GetLoggingLevel();
- OCIO::SetLoggingLevel(OCIO::LOGGING_LEVEL_DEBUG);
- is.str(SIMPLE_PROFILE2);
- OCIO::ConstConfigRcPtr noenv;
- OIIO_CHECK_NO_THOW(noenv = OCIO::Config::CreateFromStream(is));
- OIIO_CHECK_ASSERT(strcmp(noenv->getCurrentContext()->resolveStringVar("${TASK}"),
- "lighting") == 0);
- OCIO::SetLoggingLevel(loglevel);
-
- OIIO_CHECK_EQUAL(edit->getEnvironmentMode(), OCIO::ENV_ENVIRONMENT_LOAD_PREDEFINED);
- edit->setEnvironmentMode(OCIO::ENV_ENVIRONMENT_LOAD_ALL);
- OIIO_CHECK_EQUAL(edit->getEnvironmentMode(), OCIO::ENV_ENVIRONMENT_LOAD_ALL);
-
- }
- }
- #endif // OCIO_UNIT_TEST