From 63c6bde2acac363c8c5e7fd3d744e17ea99e20ab Mon Sep 17 00:00:00 2001 From: Malcolm Humphreys Date: Thu, 30 Jan 2014 12:42:21 +0000 Subject: [PATCH] * added support form yaml-cpp > 5.0.1 * when yaml-cpp < 5.0.0 define OLDYAML * added yaml-cpp 5.0.1 tarball in preparation for moving to the new api * added OCIOYaml class and moved all yaml-cpp code into OCIOYaml.cpp * moved Config serialize code into OCIOYaml.cpp * added Config::setEnvironmentMode(), Config::getEnvironmentMode(), Config::loadEnvironment() * moved Display code from Config.cpp into it's own files --- CMakeLists.txt | 6 +- export/OpenColorIO/OpenColorIO.h | 6 + ext/yaml-cpp-0.5.1.patch | 12 + ext/yaml-cpp-0.5.1.tar.gz | Bin 0 -> 118244 bytes src/core/Config.cpp | 518 +------- src/core/Display.cpp | 145 +++ src/core/Display.h | 85 ++ src/core/OCIOYaml.cpp | 2527 +++++++++++++++++++++++--------------- src/core/OCIOYaml.h | 90 +- 9 files changed, 1854 insertions(+), 1535 deletions(-) create mode 100644 ext/yaml-cpp-0.5.1.patch create mode 100644 ext/yaml-cpp-0.5.1.tar.gz create mode 100644 src/core/Display.cpp create mode 100644 src/core/Display.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 13e2d64..ea3fb8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,13 +225,15 @@ else(USE_EXTERNAL_YAML) endif() endif(USE_EXTERNAL_YAML) - +if(YAML_CPP_VERSION VERSION_LESS "0.5.0") + set(YAML_CPP_COMPILE_FLAGS "-DOLDYAML") +endif() ############################################################################### ### Externals ### set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${PROJECT_BINARY_DIR}/ext/dist/include) -set(EXTERNAL_COMPILE_FLAGS "-DTIXML_USE_STL") +set(EXTERNAL_COMPILE_FLAGS "-DTIXML_USE_STL ${YAML_CPP_COMPILE_FLAGS}") if(CMAKE_COMPILER_IS_GNUCXX) diff --git a/export/OpenColorIO/OpenColorIO.h b/export/OpenColorIO/OpenColorIO.h index 561ce50..00716fa 100644 --- a/export/OpenColorIO/OpenColorIO.h +++ b/export/OpenColorIO/OpenColorIO.h @@ -279,6 +279,12 @@ const char * getEnvironmentVarDefault(const char * name) const; //!cpp:function:: void clearEnvironmentVars(); + //!cpp:function:: + void setEnvironmentMode(EnvironmentMode mode); + //!cpp:function:: + EnvironmentMode getEnvironmentMode() const; + //!cpp:function:: + void loadEnvironment(); //!cpp:function:: const char * getSearchPath() const; diff --git a/ext/yaml-cpp-0.5.1.patch b/ext/yaml-cpp-0.5.1.patch new file mode 100644 index 0000000..23433cb --- /dev/null +++ b/ext/yaml-cpp-0.5.1.patch @@ -0,0 +1,12 @@ +diff -Naur yaml-cpp-0.5.1.orig/CMakeLists.txt yaml-cpp-0.5.1/CMakeLists.txt +--- yaml-cpp-0.5.1.orig/CMakeLists.txt 2014-01-30 09:45:54.000000000 +0000 ++++ yaml-cpp-0.5.1/CMakeLists.txt 2014-01-30 09:51:04.000000000 +0000 +@@ -140,7 +140,7 @@ + set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}") + endif() + # +- set(CMAKE_CXX_FLAGS "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}") ++ set(CMAKE_CXX_FLAGS "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long -fPIC -fvisibility-inlines-hidden -fvisibility=hidden ${CMAKE_CXX_FLAGS}") + # + add_custom_target(debuggable $(MAKE) clean + COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR} diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 00e1e70..82b5073 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -40,6 +40,7 @@ #include "HashUtils.h" #include "Logging.h" #include "LookParse.h" +#include "Display.h" #include "MathUtils.h" #include "Mutex.h" #include "OpBuilders.h" @@ -208,7 +209,6 @@ 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())) @@ -220,184 +220,7 @@ return false; } - - - // Displays - struct View - { - std::string name; - std::string colorspace; - std::string looks; - - View() { } - - View(const std::string & name_, - const std::string & colorspace_, - const std::string & looksList_) : - name(name_), - colorspace(colorspace_), - looks(looksList_) - { } - }; - - typedef std::vector ViewVec; - typedef std::map DisplayMap; // (display name : ViewVec) - - void operator >> (const YAML::Node& node, View& v) - { - if(node.Tag() != "View") - return; - - std::string key, stringval; - - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) - { - iter.first() >> key; - - if(key == "name") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - v.name = stringval; - } - else if(key == "colorspace") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - v.colorspace = stringval; - } - else if(key == "looks" || key == "look") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - v.looks = stringval; - } - else - { - LogUnknownKeyWarning(node.Tag(), iter.first()); - } - } - - if(v.name.empty()) - { - throw Exception("View does not specify 'name'."); - } - if(v.colorspace.empty()) - { - std::ostringstream os; - os << "View '" << v.name << "' "; - os << "does not specify colorspace."; - throw Exception(os.str().c_str()); - } - } - - YAML::Emitter& operator << (YAML::Emitter& out, View view) - { - out << YAML::VerbatimTag("View"); - out << YAML::Flow; - out << YAML::BeginMap; - out << YAML::Key << "name" << YAML::Value << view.name; - out << YAML::Key << "colorspace" << YAML::Value << view.colorspace; - if(!view.looks.empty()) out << YAML::Key << "looks" << YAML::Value << view.looks; - out << YAML::EndMap; - return out; - } - - DisplayMap::iterator find_display(DisplayMap & displays, const std::string & display) - { - for(DisplayMap::iterator iter = displays.begin(); - iter != displays.end(); - ++iter) - { - if(StrEqualsCaseIgnore(display, iter->first)) return iter; - } - return displays.end(); - } - - DisplayMap::const_iterator find_display_const(const DisplayMap & displays, const std::string & display) - { - for(DisplayMap::const_iterator iter = displays.begin(); - iter != displays.end(); - ++iter) - { - if(StrEqualsCaseIgnore(display, iter->first)) return iter; - } - return displays.end(); - } - - int find_view(const ViewVec & vec, const std::string & name) - { - for(unsigned int i=0; isecond; - int index = find_view(views, view); - if(index<0) - { - views.push_back( View(view, colorspace, looks) ); - } - else - { - views[index].colorspace = colorspace; - views[index].looks = looks; - } - } - } - - void ComputeDisplays(StringVec & displayCache, - const DisplayMap & displays, - const StringVec & activeDisplays, - const StringVec & activeDisplaysEnvOverride) - { - displayCache.clear(); - StringVec displayMasterList; - for(DisplayMap::const_iterator iter = displays.begin(); - iter != displays.end(); - ++iter) - { - displayMasterList.push_back(iter->first); - } - - // Apply the env override if it's not empty. - if(!activeDisplaysEnvOverride.empty()) - { - displayCache = IntersectStringVecsCaseIgnore(displayMasterList, activeDisplaysEnvOverride); - if(!displayCache.empty()) return; - } - // Otherwise, aApply the active displays if it's not empty. - else if(!activeDisplays.empty()) - { - displayCache = IntersectStringVecsCaseIgnore(displayMasterList, activeDisplays); - if(!displayCache.empty()) return; - } - - displayCache = displayMasterList; - } - - - } // namespace class Config::Impl @@ -431,6 +254,8 @@ mutable StringMap cacheids_; mutable std::string cacheidnocontext_; + OCIOYaml io_; + Impl() : context_(Context::Create()), strictParsing_(true), @@ -497,8 +322,6 @@ return *this; } - void load(std::istream & istream, const char * name); - // 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_; @@ -536,7 +359,7 @@ istream.str(INTERNAL_RAW_PROFILE); ConfigRcPtr config = Config::Create(); - config->getImpl()->load(istream, ""); + config->getImpl()->io_.open(istream, config); return config; } @@ -551,14 +374,14 @@ } ConfigRcPtr config = Config::Create(); - config->getImpl()->load(istream, filename); + config->getImpl()->io_.open(istream, config, filename); return config; } ConstConfigRcPtr Config::CreateFromStream(std::istream & istream) { ConfigRcPtr config = Config::Create(); - config->getImpl()->load(istream, ""); + config->getImpl()->io_.open(istream, config); return config; } @@ -893,6 +716,27 @@ 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(); @@ -1647,60 +1491,7 @@ { try { - YAML::Emitter out; - out << YAML::Block; - out << YAML::BeginMap; - out << YAML::Key << "ocio_profile_version" << YAML::Value << 1; - out << YAML::Newline; - if(getImpl()->env_.size() > 0) { - out << YAML::Key << "environment"; - out << YAML::Value << getImpl()->env_; - out << YAML::Newline; - } - out << YAML::Key << "search_path" << YAML::Value << getImpl()->context_->getSearchPath(); - out << YAML::Key << "strictparsing" << YAML::Value << getImpl()->strictParsing_; - out << YAML::Key << "luma" << YAML::Value << YAML::Flow << getImpl()->defaultLumaCoefs_; - - if(getImpl()->description_ != "") - { - out << YAML::Newline; - out << YAML::Key << "description"; - out << YAML::Value << getImpl()->description_; - } - - // Roles - out << YAML::Newline; - out << YAML::Key << "roles"; - out << YAML::Value << getImpl()->roles_; - - // Displays - out << YAML::Newline; - out << YAML::Key << "displays"; - out << YAML::Value << getImpl()->displays_; - out << YAML::Newline; - out << YAML::Key << "active_displays"; - out << YAML::Value << YAML::Flow << getImpl()->activeDisplays_; - out << YAML::Key << "active_views"; - out << YAML::Value << YAML::Flow << getImpl()->activeViews_; - - // Looks - if(!getImpl()->looksList_.empty()) - { - out << YAML::Newline; - out << YAML::Key << "looks"; - out << YAML::Value << getImpl()->looksList_; - } - - // ColorSpaces - { - out << YAML::Newline; - out << YAML::Key << "colorspaces"; - out << YAML::Value << getImpl()->colorspaces_; - } - - out << YAML::EndMap; - - os << out.c_str(); + getImpl()->io_.write(os, this); } catch( const std::exception & e) { @@ -1710,246 +1501,6 @@ } } - void Config::Impl::load(std::istream & istream, const char * filename) - { - try - { - YAML::Parser parser(istream); - YAML::Node node; - parser.GetNextDocument(node); - - // check profile version - int profile_version = 0; - if(node.FindValue("ocio_profile_version") == NULL) - { - std::ostringstream os; - os << "The specified file "; - os << "does not appear to be an OCIO configuration."; - throw Exception (os.str().c_str()); - } - - node["ocio_profile_version"] >> profile_version; - if(profile_version > 1) - { - std::ostringstream os; - os << "This .ocio config "; - if(filename && *filename) - { - os << " '" << filename << "' "; - } - os << "is version " << profile_version << ". "; - os << "This version of the OpenColorIO library (" << OCIO_VERSION ") "; - os << "is not known to be able to load this profile. "; - os << "An attempt will be made, but there are no guarantees that the "; - os << "results will be accurate. Continue at your own risk."; - LogWarning(os.str()); - } - - - std::string key, stringval; - bool boolval = false; - EnvironmentMode mode = ENV_ENVIRONMENT_LOAD_ALL; - - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) - { - iter.first() >> key; - - if(key == "ocio_profile_version") { } // Already handled above. - else if(key == "environment") - { - mode = ENV_ENVIRONMENT_LOAD_PREDEFINED; - const YAML::Node& environment = iter.second(); - if(environment.Type() != YAML::NodeType::Map) - { - std::ostringstream os; - os << "'environment' field needs to be a (name: key) map."; - throw Exception(os.str().c_str()); - } - for (YAML::Iterator it = environment.begin(); - it != environment.end(); ++it) - { - std::string k, v; - it.first() >> k; - it.second() >> v; - env_[k] = v; - context_->setStringVar(k.c_str(), v.c_str()); - } - } - else if(key == "search_path" || key == "resource_path") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - context_->setSearchPath(stringval.c_str()); - } - else if(key == "strictparsing") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(boolval)) - strictParsing_ = boolval; - } - else if(key == "description") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - description_ = stringval; - } - else if(key == "luma") - { - std::vector val; - if (iter.second().Type() != YAML::NodeType::Null) - { - iter.second() >> val; - if(val.size() != 3) - { - std::ostringstream os; - os << "'luma' field must be 3 "; - os << "floats. Found '" << val.size() << "'."; - throw Exception(os.str().c_str()); - } - defaultLumaCoefs_ = val; - } - } - else if(key == "roles") - { - const YAML::Node& roles = iter.second(); - if(roles.Type() != YAML::NodeType::Map) - { - std::ostringstream os; - os << "'roles' field needs to be a (name: key) map."; - throw Exception(os.str().c_str()); - } - for (YAML::Iterator it = roles.begin(); - it != roles.end(); ++it) - { - std::string k, v; - it.first() >> k; - it.second() >> v; - roles_[pystring::lower(k)] = v; - } - } - else if(key == "displays") - { - if (iter.second().Type() != YAML::NodeType::Null) - { - iter.second() >> displays_; - } - } - else if(key == "active_displays") - { - if (iter.second().Type() != YAML::NodeType::Null) - { - iter.second() >> activeDisplays_; - } - } - else if(key == "active_views") - { - if (iter.second().Type() != YAML::NodeType::Null) - { - iter.second() >> activeViews_; - } - } - else if(key == "colorspaces") - { - const YAML::Node& colorspaces = iter.second(); - - if(colorspaces.Type() != YAML::NodeType::Sequence) - { - std::ostringstream os; - os << "'colorspaces' field needs to be a (- !) list."; - throw Exception(os.str().c_str()); - } - - for(unsigned i = 0; i < colorspaces.size(); ++i) - { - if(colorspaces[i].Tag() == "ColorSpace") - { - ColorSpaceRcPtr cs = ColorSpace::Create(); - colorspaces[i] >> cs; - colorspaces_.push_back( cs ); - } - else - { - std::ostringstream os; - os << "Unknown element found in colorspaces:"; - os << colorspaces[i].Tag() << ". Only ColorSpace(s)"; - os << " currently handled."; - LogWarning(os.str()); - } - } - } - else if(key == "looks") - { - const YAML::Node& looks = iter.second(); - - if(looks.Type() != YAML::NodeType::Sequence) - { - std::ostringstream os; - os << "'looks' field needs to be a (- !) list."; - throw Exception(os.str().c_str()); - } - - for(unsigned i = 0; i < looks.size(); ++i) - { - if(looks[i].Tag() == "Look") - { - LookRcPtr look = Look::Create(); - looks[i] >> look; - looksList_.push_back( look ); - } - else - { - std::ostringstream os; - os << "Unknown element found in looks:"; - os << looks[i].Tag() << ". Only Look(s)"; - os << " currently handled."; - LogWarning(os.str()); - } - } - } - else - { - LogUnknownKeyWarning("profile", iter.first()); - } - } - - if(filename) - { - std::string realfilename = pystring::os::path::abspath(filename); - std::string configrootdir = pystring::os::path::dirname(realfilename); - context_->setWorkingDir(configrootdir.c_str()); - } - - context_->setEnvironmentMode(mode); - context_->loadEnvironment(); - - if(mode == ENV_ENVIRONMENT_LOAD_ALL) - { - std::ostringstream os; - os << "This .ocio config "; - if(filename && *filename) - { - os << " '" << filename << "' "; - } - os << "has no environment section defined. The default behaviour is to "; - os << "load all environment variables (" << context_->getNumStringVars() << ")"; - os << ", which reduces the efficiency of OCIO's caching. Considering "; - os << "predefining the environment variables used."; - LogDebug(os.str()); - } - - } - catch( const std::exception & e) - { - std::ostringstream os; - os << "Error: Loading the OCIO profile "; - if(filename) os << "'" << filename << "' "; - os << "failed. " << e.what(); - throw Exception(os.str().c_str()); - } - } - void Config::Impl::resetCacheIDs() { cacheids_.clear(); @@ -2287,9 +1838,7 @@ std::istringstream is; is.str(SIMPLE_PROFILE); OCIO::ConstConfigRcPtr config; - OIIO_CHECK_NO_THOW(config = OCIO::Config::CreateFromStream(is)); - - OIIO_CHECK_THOW(config->sanityCheck(), OCIO::Exception); + OIIO_CHECK_THOW(config = OCIO::Config::CreateFromStream(is), OCIO::Exception); } { @@ -2330,8 +1879,6 @@ "colorspaces:\n" " - !\n" " name: raw\n" - " - !\n" - " name: raw\n" "strictparsing: false\n" "roles:\n" " default: raw\n" @@ -2345,8 +1892,6 @@ "colorspaces:\n" " - !\n" " name: raw\n" - " - !\n" - " name: raw\n" "strictparsing: false\n" "roles:\n" " default: raw\n" @@ -2370,7 +1915,6 @@ "testbarchedder") == 0); OIIO_CHECK_ASSERT(strcmp(config->getCurrentContext()->resolveStringVar("${SHOW}"), "bar") == 0); - OIIO_CHECK_THOW(config->sanityCheck(), OCIO::Exception); OIIO_CHECK_ASSERT(strcmp(config->getEnvironmentVarDefault("SHOW"), "super") == 0); OCIO::ConfigRcPtr edit = config->createEditableCopy(); @@ -2403,6 +1947,10 @@ "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); + } } diff --git a/src/core/Display.cpp b/src/core/Display.cpp new file mode 100644 index 0000000..7c0a1ef --- /dev/null +++ b/src/core/Display.cpp @@ -0,0 +1,145 @@ +/* +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 + +#include + +#include "Display.h" +#include "ParseUtils.h" + +OCIO_NAMESPACE_ENTER +{ + + DisplayMap::iterator find_display(DisplayMap & displays, const std::string & display) + { + for(DisplayMap::iterator iter = displays.begin(); + iter != displays.end(); + ++iter) + { + if(StrEqualsCaseIgnore(display, iter->first)) return iter; + } + return displays.end(); + } + + DisplayMap::const_iterator find_display_const(const DisplayMap & displays, const std::string & display) + { + for(DisplayMap::const_iterator iter = displays.begin(); + iter != displays.end(); + ++iter) + { + if(StrEqualsCaseIgnore(display, iter->first)) return iter; + } + return displays.end(); + } + + int find_view(const ViewVec & vec, const std::string & name) + { + for(unsigned int i=0; isecond; + int index = find_view(views, view); + if(index<0) + { + views.push_back( View(view, colorspace, looks) ); + } + else + { + views[index].colorspace = colorspace; + views[index].looks = looks; + } + } + } + + void ComputeDisplays(StringVec & displayCache, + const DisplayMap & displays, + const StringVec & activeDisplays, + const StringVec & activeDisplaysEnvOverride) + { + displayCache.clear(); + + StringVec displayMasterList; + for(DisplayMap::const_iterator iter = displays.begin(); + iter != displays.end(); + ++iter) + { + displayMasterList.push_back(iter->first); + } + + // Apply the env override if it's not empty. + if(!activeDisplaysEnvOverride.empty()) + { + displayCache = IntersectStringVecsCaseIgnore(displayMasterList, activeDisplaysEnvOverride); + if(!displayCache.empty()) return; + } + // Otherwise, aApply the active displays if it's not empty. + else if(!activeDisplays.empty()) + { + displayCache = IntersectStringVecsCaseIgnore(displayMasterList, activeDisplays); + if(!displayCache.empty()) return; + } + + displayCache = displayMasterList; + } + +} +OCIO_NAMESPACE_EXIT + +/////////////////////////////////////////////////////////////////////////////// + +#ifdef OCIO_UNIT_TEST + +namespace OCIO = OCIO_NAMESPACE; +#include "UnitTest.h" + +OIIO_ADD_TEST(Display, Basic) +{ + +} + +#endif // OCIO_UNIT_TEST \ No newline at end of file diff --git a/src/core/Display.h b/src/core/Display.h new file mode 100644 index 0000000..6d63a43 --- /dev/null +++ b/src/core/Display.h @@ -0,0 +1,85 @@ +/* +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. +*/ + + +#ifndef INCLUDED_OCIO_DISPLAY_H +#define INCLUDED_OCIO_DISPLAY_H + +#include + +#include +#include +#include + +#include "PrivateTypes.h" + +OCIO_NAMESPACE_ENTER +{ + + // Displays + struct View + { + std::string name; + std::string colorspace; + std::string looks; + + View() { } + + View(const std::string & name_, + const std::string & colorspace_, + const std::string & looksList_) : + name(name_), + colorspace(colorspace_), + looks(looksList_) + { } + }; + + typedef std::vector ViewVec; + typedef std::map DisplayMap; // (display name : ViewVec) + + DisplayMap::iterator find_display(DisplayMap & displays, const std::string & display); + + DisplayMap::const_iterator find_display_const(const DisplayMap & displays, const std::string & display); + + int find_view(const ViewVec & vec, const std::string & name); + + void AddDisplay(DisplayMap & displays, + const std::string & display, + const std::string & view, + const std::string & colorspace, + const std::string & looks); + + void ComputeDisplays(StringVec & displayCache, + const DisplayMap & displays, + const StringVec & activeDisplays, + const StringVec & activeDisplaysEnvOverride); + +} +OCIO_NAMESPACE_EXIT + +#endif \ No newline at end of file diff --git a/src/core/OCIOYaml.cpp b/src/core/OCIOYaml.cpp index 7089318..fc2f5f8 100644 --- a/src/core/OCIOYaml.cpp +++ b/src/core/OCIOYaml.cpp @@ -30,1188 +30,1787 @@ #include +#ifndef WINDOWS + +// fwd declare yaml-cpp visibility +#pragma GCC visibility push(hidden) +namespace YAML { + class Exception; + class BadDereference; + class RepresentationException; + class EmitterException; + class ParserException; + class InvalidScalar; + class KeyNotFound; + template class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; + template <> class TypedKeyNotFound; +} +#pragma GCC visibility pop + +#endif + +#include + #include "Logging.h" #include "MathUtils.h" +#include "pystring/pystring.h" +#include "PathUtils.h" +#include "ParseUtils.h" +#include "Display.h" #include "OCIOYaml.h" OCIO_NAMESPACE_ENTER { - /////////////////////////////////////////////////////////////////////////// - // Core - void LogUnknownKeyWarning(const std::string & name, const YAML::Node& tag) + namespace { - std::string key; - tag >> key; - - std::ostringstream os; - os << "Unknown key in " << name << ": "; - os << "'" << key << "'. (line "; - os << (tag.GetMark().line+1) << ", column "; // (yaml line numbers start at 0) - os << tag.GetMark().column << ")"; - LogWarning(os.str()); - } - void operator >> (const YAML::Node& node, ColorSpaceRcPtr& cs) - { - if(node.Tag() != "ColorSpace") - return; // not a ! tag +#ifdef OLDYAML + typedef YAML::Iterator Iterator; +#else + typedef YAML::const_iterator Iterator; +#endif - std::string key, stringval; - bool boolval; + // Iterator access - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) - { - iter.first() >> key; - - if(key == "name") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - cs->setName(stringval.c_str()); - } - else if(key == "description") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - cs->setDescription(stringval.c_str()); - } - else if(key == "family") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - cs->setFamily(stringval.c_str()); - } - else if(key == "equalitygroup") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - cs->setEqualityGroup(stringval.c_str()); - } - else if(key == "bitdepth") - { - BitDepth ret; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(ret)) - cs->setBitDepth(ret); - } - else if(key == "isdata") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(boolval)) - cs->setIsData(boolval); - } - else if(key == "allocation") - { - Allocation val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - cs->setAllocation(val); - } - else if(key == "allocationvars") - { - std::vector val; - if (iter.second().Type() != YAML::NodeType::Null) - { - iter.second() >> val; - if(!val.empty()) - { - cs->setAllocationVars(static_cast(val.size()), &val[0]); - } - } - } - else if(key == "to_reference") - { - TransformRcPtr val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - cs->setTransform(val, COLORSPACE_DIR_TO_REFERENCE); - } - else if(key == "from_reference") - { - TransformRcPtr val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - cs->setTransform(val, COLORSPACE_DIR_FROM_REFERENCE); - } - else - { - LogUnknownKeyWarning(node.Tag(), iter.first()); - } - } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ColorSpaceRcPtr cs) - { - out << YAML::VerbatimTag("ColorSpace"); - out << YAML::BeginMap; - - out << YAML::Key << "name" << YAML::Value << cs->getName(); - out << YAML::Key << "family" << YAML::Value << cs->getFamily(); - out << YAML::Key << "equalitygroup" << YAML::Value << cs->getEqualityGroup(); - out << YAML::Key << "bitdepth" << YAML::Value << cs->getBitDepth(); - if(strlen(cs->getDescription()) > 0) + inline const YAML::Node& get_first(const Iterator it) { - out << YAML::Key << "description"; - out << YAML::Value << YAML::Literal << cs->getDescription(); +#ifdef OLDYAML + return it.first(); +#else + return it->first; +#endif } - out << YAML::Key << "isdata" << YAML::Value << cs->isData(); - out << YAML::Key << "allocation" << YAML::Value << cs->getAllocation(); - if(cs->getAllocationNumVars() > 0) + inline const YAML::Node& get_second(const Iterator it) { - std::vector allocationvars(cs->getAllocationNumVars()); - cs->getAllocationVars(&allocationvars[0]); - out << YAML::Key << "allocationvars"; - out << YAML::Flow << YAML::Value << allocationvars; +#ifdef OLDYAML + return it.second(); +#else + return it->second; +#endif } - ConstTransformRcPtr toref = \ - cs->getTransform(COLORSPACE_DIR_TO_REFERENCE); - if(toref) - out << YAML::Key << "to_reference" << YAML::Value << toref; - - ConstTransformRcPtr fromref = \ - cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE); - if(fromref) - out << YAML::Key << "from_reference" << YAML::Value << fromref; - - out << YAML::EndMap; - out << YAML::Newline; - - return out; - } - - - /////////////////////////////////////////////////////////////////////////// - - // Look. (not the transform, the top-level class) - - void operator >> (const YAML::Node& node, LookRcPtr& look) - { - if(node.Tag() != "Look") - return; - - std::string key, stringval; + // Basic types - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void load(const YAML::Node& node, bool& x) { - iter.first() >> key; - - if(key == "name") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - look->setName(stringval.c_str()); - } - else if(key == "process_space") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - look->setProcessSpace(stringval.c_str()); - } - else if(key == "transform") - { - TransformRcPtr val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - look->setTransform(val); - } - else if(key == "inverse_transform") - { - TransformRcPtr val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - look->setInverseTransform(val); - } - else - { - LogUnknownKeyWarning(node.Tag(), iter.first()); - } +#ifdef OLDYAML + node.Read(x); +#else + x = node.as(); +#endif } - } - - YAML::Emitter& operator << (YAML::Emitter& out, LookRcPtr look) - { - out << YAML::VerbatimTag("Look"); - out << YAML::BeginMap; - out << YAML::Key << "name" << YAML::Value << look->getName(); - out << YAML::Key << "process_space" << YAML::Value << look->getProcessSpace(); - if(look->getTransform()) + inline void load(const YAML::Node& node, int& x) { - out << YAML::Key << "transform"; - out << YAML::Value << look->getTransform(); +#ifdef OLDYAML + node.Read(x); +#else + x = node.as(); +#endif } - if(look->getInverseTransform()) + inline void load(const YAML::Node& node, float& x) { - out << YAML::Key << "inverse_transform"; - out << YAML::Value << look->getInverseTransform(); +#ifdef OLDYAML + node.Read(x); +#else + x = node.as(); +#endif } - out << YAML::EndMap; - out << YAML::Newline; + inline void load(const YAML::Node& node, std::string& x) + { +#ifdef OLDYAML + node.Read(x); +#else + x = node.as(); +#endif + } - return out; - } - - - - /////////////////////////////////////////////////////////////////////////// - - - namespace - { - void EmitBaseTransformKeyValues(YAML::Emitter & out, - const ConstTransformRcPtr & t) + inline void load(const YAML::Node& node, std::vector& x) { - if(t->getDirection() != TRANSFORM_DIR_FORWARD) - { - out << YAML::Key << "direction"; - out << YAML::Value << YAML::Flow << t->getDirection(); - } +#ifdef OLDYAML + node >> x; +#else + x = node.as >(); +#endif } - } - - void operator >> (const YAML::Node& node, TransformRcPtr& t) - { - if(node.Type() != YAML::NodeType::Map) + + inline void load(const YAML::Node& node, std::vector& x) { - std::ostringstream os; - os << "Unsupported Transform type encountered: (" << node.Type() << ") in OCIO profile. "; - os << "Only Mapping types supported. (line "; - os << (node.GetMark().line+1) << ", column "; // (yaml line numbers start at 0) - os << node.GetMark().column << ")"; - throw Exception(os.str().c_str()); +#ifdef OLDYAML + node >> x; +#else + x = node.as >(); +#endif } - std::string type = node.Tag(); + // Enums - if(type == "AllocationTransform") { - AllocationTransformRcPtr temp; - node.Read(temp); - t = temp; + inline void load(const YAML::Node& node, BitDepth& depth) + { + std::string str; + load(node, str); + depth = BitDepthFromString(str.c_str()); } - else if(type == "CDLTransform") { - CDLTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void save(YAML::Emitter& out, BitDepth depth) + { + out << BitDepthToString(depth); } - else if(type == "ColorSpaceTransform") { - ColorSpaceTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void load(const YAML::Node& node, Allocation& alloc) + { + std::string str; + load(node, str); + alloc = AllocationFromString(str.c_str()); } - // TODO: DisplayTransform - else if(type == "ExponentTransform") { - ExponentTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void save(YAML::Emitter& out, Allocation alloc) + { + out << AllocationToString(alloc); } - else if(type == "FileTransform") { - FileTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void load(const YAML::Node& node, ColorSpaceDirection& dir) + { + std::string str; + load(node, str); + dir = ColorSpaceDirectionFromString(str.c_str()); } - else if(type == "GroupTransform") { - GroupTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void save(YAML::Emitter& out, ColorSpaceDirection dir) + { + out << ColorSpaceDirectionToString(dir); } - else if(type == "LogTransform") { - LogTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void load(const YAML::Node& node, TransformDirection& dir) + { + std::string str; + load(node, str); + dir = TransformDirectionFromString(str.c_str()); } - else if(type == "LookTransform") { - LookTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void save(YAML::Emitter& out, TransformDirection dir) + { + out << TransformDirectionToString(dir); } - else if(type == "MatrixTransform") { - MatrixTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void load(const YAML::Node& node, Interpolation& interp) + { + std::string str; + load(node, str); + interp = InterpolationFromString(str.c_str()); } - else if(type == "TruelightTransform") { - TruelightTransformRcPtr temp; - node.Read(temp); - t = temp; + + inline void save(YAML::Emitter& out, Interpolation interp) + { + out << InterpolationToString(interp); } - else + + // + + inline void LogUnknownKeyWarning(const std::string & name, + const YAML::Node& tag) { - // TODO: add a new empty (better name?) aka passthru Transform() - // which does nothing. This is so upsupported ! types don't - // throw an exception. Alternativly this could be caught in the - // GroupTransformRcPtr >> operator with some type of - // supported_tag() method - - // TODO: consider the forwards-compatibility implication of - // throwing an exception. Should this be a warning, instead? - - // t = EmptyTransformRcPtr(new EmptyTransform(), &deleter); + std::string key; + load(tag, key); + std::ostringstream os; - os << "Unsupported transform type !<" << type << "> in OCIO profile. "; - os << " (line "; - os << (node.GetMark().line+1) << ", column "; // (yaml line numbers start at 0) - os << node.GetMark().column << ")"; - throw Exception(os.str().c_str()); + os << "Unknown key in " << name << ": '" << key << "'."; + LogWarning(os.str()); } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstTransformRcPtr t) - { - if(ConstAllocationTransformRcPtr Allocation_tran = \ - DynamicPtrCast(t)) - out << Allocation_tran; - else if(ConstCDLTransformRcPtr CDL_tran = \ - DynamicPtrCast(t)) - out << CDL_tran; - else if(ConstColorSpaceTransformRcPtr ColorSpace_tran = \ - DynamicPtrCast(t)) - out << ColorSpace_tran; - else if(ConstExponentTransformRcPtr Exponent_tran = \ - DynamicPtrCast(t)) - out << Exponent_tran; - else if(ConstFileTransformRcPtr File_tran = \ - DynamicPtrCast(t)) - out << File_tran; - else if(ConstGroupTransformRcPtr Group_tran = \ - DynamicPtrCast(t)) - out << Group_tran; - else if(ConstLogTransformRcPtr Log_tran = \ - DynamicPtrCast(t)) - out << Log_tran; - else if(ConstLookTransformRcPtr Look_tran = \ - DynamicPtrCast(t)) - out << Look_tran; - else if(ConstMatrixTransformRcPtr Matrix_tran = \ - DynamicPtrCast(t)) - out << Matrix_tran; - else if(ConstTruelightTransformRcPtr Truelight_tran = \ - DynamicPtrCast(t)) - out << Truelight_tran; - else - throw Exception("Unsupported Transform() type for serialization."); - - return out; - } - - - /////////////////////////////////////////////////////////////////////////// - // Transforms - - void operator >> (const YAML::Node& node, GroupTransformRcPtr& t) - { - t = GroupTransform::Create(); - std::string key; + // View - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void load(const YAML::Node& node, View& v) { - iter.first() >> key; + if(node.Tag() != "View") + return; - if(key == "children") - { - const YAML::Node & children = iter.second(); - for(unsigned i = 0; i (childTransform); - - // TODO: consider the forwards-compatibility implication of - // throwing an exception. Should this be a warning, instead? - if(!childTransform) - { - throw Exception("Child transform could not be parsed."); - } - - t->push_back(childTransform); + load(second, stringval); + v.name = stringval; + } + else if(key == "colorspace") + { + load(second, stringval); + v.colorspace = stringval; + } + else if(key == "looks" || key == "look") + { + load(second, stringval); + v.looks = stringval; + } + else + { + LogUnknownKeyWarning(node.Tag(), first); } } - else if(key == "direction") + + if(v.name.empty()) { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); + throw Exception("View does not specify 'name'."); } - else + if(v.colorspace.empty()) { - LogUnknownKeyWarning(node.Tag(), iter.first()); + std::ostringstream os; + os << "View '" << v.name << "' "; + os << "does not specify colorspace."; + throw Exception(os.str().c_str()); } } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstGroupTransformRcPtr t) - { - out << YAML::VerbatimTag("GroupTransform"); - out << YAML::BeginMap; - EmitBaseTransformKeyValues(out, t); - - out << YAML::Key << "children"; - out << YAML::Value; - out << YAML::BeginSeq; - for(int i = 0; i < t->size(); ++i) + inline void save(YAML::Emitter& out, View view) { - out << t->getTransform(i); + out << YAML::VerbatimTag("View"); + out << YAML::Flow; + out << YAML::BeginMap; + out << YAML::Key << "name" << YAML::Value << view.name; + out << YAML::Key << "colorspace" << YAML::Value << view.colorspace; + if(!view.looks.empty()) out << YAML::Key << "looks" << YAML::Value << view.looks; + out << YAML::EndMap; } - out << YAML::EndSeq; - - out << YAML::EndMap; - - return out; - } - - - - void operator >> (const YAML::Node& node, FileTransformRcPtr& t) - { - t = FileTransform::Create(); - std::string key, stringval; + // Common Transform - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void EmitBaseTransformKeyValues(YAML::Emitter & out, + const ConstTransformRcPtr & t) { - iter.first() >> key; - - if(key == "src") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setSrc(stringval.c_str()); - } - else if(key == "cccid") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setCCCId(stringval.c_str()); - } - else if(key == "interpolation") - { - Interpolation val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setInterpolation(val); - } - else if(key == "direction") - { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); - } - else + if(t->getDirection() != TRANSFORM_DIR_FORWARD) { - LogUnknownKeyWarning(node.Tag(), iter.first()); + out << YAML::Key << "direction"; + out << YAML::Value << YAML::Flow; + save(out, t->getDirection()); } } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstFileTransformRcPtr t) - { - out << YAML::VerbatimTag("FileTransform"); - out << YAML::Flow << YAML::BeginMap; - out << YAML::Key << "src" << YAML::Value << t->getSrc(); - const char * cccid = t->getCCCId(); - if(cccid && *cccid) - { - out << YAML::Key << "cccid" << YAML::Value << t->getCCCId(); - } - out << YAML::Key << "interpolation"; - out << YAML::Value << t->getInterpolation(); - - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, ColorSpaceTransformRcPtr& t) - { - t = ColorSpaceTransform::Create(); - std::string key, stringval; + // AllocationTransform - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void load(const YAML::Node& node, AllocationTransformRcPtr& t) { - iter.first() >> key; + t = AllocationTransform::Create(); - if(key == "src") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setSrc(stringval.c_str()); - } - else if(key == "dst") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setDst(stringval.c_str()); - } - else if(key == "direction") - { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); - } - else - { - LogUnknownKeyWarning(node.Tag(), iter.first()); + std::string key; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "allocation") + { + Allocation val; + load(second, val); + t->setAllocation(val); + } + else if(key == "vars") + { + std::vector val; + load(second, val); + if(!val.empty()) + { + t->setVars(static_cast(val.size()), &val[0]); + } + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } } } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstColorSpaceTransformRcPtr t) - { - out << YAML::VerbatimTag("ColorSpaceTransform"); - out << YAML::Flow << YAML::BeginMap; - out << YAML::Key << "src" << YAML::Value << t->getSrc(); - out << YAML::Key << "dst" << YAML::Value << t->getDst(); - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, LookTransformRcPtr& t) - { - t = LookTransform::Create(); - - std::string key, stringval; - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void save(YAML::Emitter& out, ConstAllocationTransformRcPtr t) { - iter.first() >> key; + out << YAML::VerbatimTag("AllocationTransform"); + out << YAML::Flow << YAML::BeginMap; - if(key == "src") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setSrc(stringval.c_str()); - } - else if(key == "dst") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setDst(stringval.c_str()); - } - else if(key == "looks") - { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setLooks(stringval.c_str()); - } - else if(key == "direction") - { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); - } - else + out << YAML::Key << "allocation"; + out << YAML::Value << YAML::Flow; + save(out, t->getAllocation()); + + if(t->getNumVars() > 0) { - LogUnknownKeyWarning(node.Tag(), iter.first()); + std::vector vars(t->getNumVars()); + t->getVars(&vars[0]); + out << YAML::Key << "vars"; + out << YAML::Flow << YAML::Value << vars; } + + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstLookTransformRcPtr t) - { - out << YAML::VerbatimTag("LookTransform"); - out << YAML::Flow << YAML::BeginMap; - out << YAML::Key << "src" << YAML::Value << t->getSrc(); - out << YAML::Key << "dst" << YAML::Value << t->getDst(); - out << YAML::Key << "looks" << YAML::Value << t->getLooks(); - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, ExponentTransformRcPtr& t) - { - t = ExponentTransform::Create(); - std::string key; + // CDLTransform - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void load(const YAML::Node& node, CDLTransformRcPtr& t) { - iter.first() >> key; + t = CDLTransform::Create(); - if(key == "value") - { - std::vector val; - if (iter.second().Type() != YAML::NodeType::Null) + std::string key; + std::vector floatvecval; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "slope") { - iter.second() >> val; - if(val.size() != 4) + load(second, floatvecval); + if(floatvecval.size() != 3) { std::ostringstream os; - os << "ExponentTransform parse error, value field must be 4 "; - os << "floats. Found '" << val.size() << "'."; + os << "CDLTransform parse error, 'slope' field must be 3 "; + os << "floats. Found '" << floatvecval.size() << "'."; throw Exception(os.str().c_str()); } - t->setValue(&val[0]); + t->setSlope(&floatvecval[0]); } - } - else if(key == "direction") - { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); - } - else - { - LogUnknownKeyWarning(node.Tag(), iter.first()); - } - } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstExponentTransformRcPtr t) - { - out << YAML::VerbatimTag("ExponentTransform"); - out << YAML::Flow << YAML::BeginMap; - - std::vector value(4, 0.0); - t->getValue(&value[0]); - out << YAML::Key << "value"; - out << YAML::Value << YAML::Flow << value; - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, LogTransformRcPtr& t) - { - t = LogTransform::Create(); - - std::string key; - - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) - { - iter.first() >> key; - - if(key == "base") - { - float val = 0.0f; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setBase(val); - } - else if(key == "direction") - { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); - } - else - { - LogUnknownKeyWarning(node.Tag(), iter.first()); - } - } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstLogTransformRcPtr t) - { - out << YAML::VerbatimTag("LogTransform"); - out << YAML::Flow << YAML::BeginMap; - out << YAML::Key << "base" << YAML::Value << t->getBase(); - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, MatrixTransformRcPtr& t) - { - t = MatrixTransform::Create(); - - std::string key; - - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) - { - iter.first() >> key; - - if(key == "matrix") - { - std::vector val; - if (iter.second().Type() != YAML::NodeType::Null) + else if(key == "offset") { - iter.second() >> val; - if(val.size() != 16) + load(second, floatvecval); + if(floatvecval.size() != 3) { std::ostringstream os; - os << "MatrixTransform parse error, matrix field must be 16 "; - os << "floats. Found '" << val.size() << "'."; + os << "CDLTransform parse error, 'offset' field must be 3 "; + os << "floats. Found '" << floatvecval.size() << "'."; throw Exception(os.str().c_str()); } - t->setMatrix(&val[0]); + t->setOffset(&floatvecval[0]); } - } - else if(key == "offset") - { - std::vector val; - if (iter.second().Type() != YAML::NodeType::Null) + else if(key == "power") { - iter.second() >> val; - if(val.size() != 4) + load(second, floatvecval); + if(floatvecval.size() != 3) { std::ostringstream os; - os << "MatrixTransform parse error, offset field must be 4 "; - os << "floats. Found '" << val.size() << "'."; + os << "CDLTransform parse error, 'power' field must be 3 "; + os << "floats. Found '" << floatvecval.size() << "'."; throw Exception(os.str().c_str()); } - t->setOffset(&val[0]); + t->setPower(&floatvecval[0]); + } + else if(key == "saturation" || key == "sat") + { + float val = 0.0f; + load(second, val); + t->setSat(val); } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } + } + } + + inline void save(YAML::Emitter& out, ConstCDLTransformRcPtr t) + { + out << YAML::VerbatimTag("CDLTransform"); + out << YAML::Flow << YAML::BeginMap; + + std::vector slope(3); + t->getSlope(&slope[0]); + if(!IsVecEqualToOne(&slope[0], 3)) + { + out << YAML::Key << "slope"; + out << YAML::Value << YAML::Flow << slope; } - else if(key == "direction") + + std::vector offset(3); + t->getOffset(&offset[0]); + if(!IsVecEqualToZero(&offset[0], 3)) { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); + out << YAML::Key << "offset"; + out << YAML::Value << YAML::Flow << offset; } - else + + std::vector power(3); + t->getPower(&power[0]); + if(!IsVecEqualToOne(&power[0], 3)) + { + out << YAML::Key << "power"; + out << YAML::Value << YAML::Flow << power; + } + + if(!IsScalarEqualToOne(t->getSat())) { - LogUnknownKeyWarning(node.Tag(), iter.first()); + out << YAML::Key << "sat" << YAML::Value << t->getSat(); } + + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstMatrixTransformRcPtr t) - { - out << YAML::VerbatimTag("MatrixTransform"); - out << YAML::Flow << YAML::BeginMap; - std::vector matrix(16, 0.0); - t->getMatrix(&matrix[0]); - if(!IsM44Identity(&matrix[0])) + // ColorSpaceTransform + + inline void load(const YAML::Node& node, ColorSpaceTransformRcPtr& t) { - out << YAML::Key << "matrix"; - out << YAML::Value << YAML::Flow << matrix; + t = ColorSpaceTransform::Create(); + + std::string key, stringval; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "src") + { + load(second, stringval); + t->setSrc(stringval.c_str()); + } + else if(key == "dst") + { + load(second, stringval); + t->setDst(stringval.c_str()); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } + } } - std::vector offset(4, 0.0); - t->getOffset(&offset[0]); - if(!IsVecEqualToZero(&offset[0],4)) + inline void save(YAML::Emitter& out, ConstColorSpaceTransformRcPtr t) { - out << YAML::Key << "offset"; - out << YAML::Value << YAML::Flow << offset; + out << YAML::VerbatimTag("ColorSpaceTransform"); + out << YAML::Flow << YAML::BeginMap; + out << YAML::Key << "src" << YAML::Value << t->getSrc(); + out << YAML::Key << "dst" << YAML::Value << t->getDst(); + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; } - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, CDLTransformRcPtr& t) - { - t = CDLTransform::Create(); + // ExponentTransform - std::string key; - std::vector floatvecval; - - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void load(const YAML::Node& node, ExponentTransformRcPtr& t) { - iter.first() >> key; + t = ExponentTransform::Create(); - if(key == "slope") - { - if (iter.second().Type() != YAML::NodeType::Null) + std::string key; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "value") { - iter.second() >> floatvecval; - if(floatvecval.size() != 3) + std::vector val; + load(second, val); + if(val.size() != 4) { std::ostringstream os; - os << "CDLTransform parse error, 'slope' field must be 3 "; - os << "floats. Found '" << floatvecval.size() << "'."; + os << "ExponentTransform parse error, value field must be 4 "; + os << "floats. Found '" << val.size() << "'."; throw Exception(os.str().c_str()); } - t->setSlope(&floatvecval[0]); + t->setValue(&val[0]); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); } } - else if(key == "offset") - { - if (iter.second().Type() != YAML::NodeType::Null) + } + + inline void save(YAML::Emitter& out, ConstExponentTransformRcPtr t) + { + out << YAML::VerbatimTag("ExponentTransform"); + out << YAML::Flow << YAML::BeginMap; + + std::vector value(4, 0.0); + t->getValue(&value[0]); + out << YAML::Key << "value"; + out << YAML::Value << YAML::Flow << value; + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; + } + + // FileTransform + + inline void load(const YAML::Node& node, FileTransformRcPtr& t) + { + t = FileTransform::Create(); + + std::string key, stringval; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "src") { - iter.second() >> floatvecval; - if(floatvecval.size() != 3) - { - std::ostringstream os; - os << "CDLTransform parse error, 'offset' field must be 3 "; - os << "floats. Found '" << floatvecval.size() << "'."; - throw Exception(os.str().c_str()); - } - t->setOffset(&floatvecval[0]); + load(second, stringval); + t->setSrc(stringval.c_str()); + } + else if(key == "cccid") + { + load(second, stringval); + t->setCCCId(stringval.c_str()); + } + else if(key == "interpolation") + { + Interpolation val; + load(second, val); + t->setInterpolation(val); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); } } - else if(key == "power") + } + + inline void save(YAML::Emitter& out, ConstFileTransformRcPtr t) + { + out << YAML::VerbatimTag("FileTransform"); + out << YAML::Flow << YAML::BeginMap; + out << YAML::Key << "src" << YAML::Value << t->getSrc(); + const char * cccid = t->getCCCId(); + if(cccid && *cccid) { - if (iter.second().Type() != YAML::NodeType::Null) + out << YAML::Key << "cccid" << YAML::Value << t->getCCCId(); + } + out << YAML::Key << "interpolation"; + out << YAML::Value; + save(out, t->getInterpolation()); + + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; + } + + // GroupTransform + + void load(const YAML::Node& node, TransformRcPtr& t); + void save(YAML::Emitter& out, ConstTransformRcPtr t); + + inline void load(const YAML::Node& node, GroupTransformRcPtr& t) + { + t = GroupTransform::Create(); + + std::string key; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "children") { - iter.second() >> floatvecval; - if(floatvecval.size() != 3) + for(unsigned i = 0; i < second.size(); ++i) { - std::ostringstream os; - os << "CDLTransform parse error, 'power' field must be 3 "; - os << "floats. Found '" << floatvecval.size() << "'."; - throw Exception(os.str().c_str()); + TransformRcPtr childTransform; + load(second[i], childTransform); + + // TODO: consider the forwards-compatibility implication of + // throwing an exception. Should this be a warning, instead? + if(!childTransform) + { + throw Exception("Child transform could not be parsed."); + } + + t->push_back(childTransform); } - t->setPower(&floatvecval[0]); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); } } - else if(key == "saturation" || key == "sat") - { - float val = 0.0f; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setSat(val); - } - else if(key == "direction") - { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); - } - else + } + + inline void save(YAML::Emitter& out, ConstGroupTransformRcPtr t) + { + out << YAML::VerbatimTag("GroupTransform"); + out << YAML::BeginMap; + EmitBaseTransformKeyValues(out, t); + + out << YAML::Key << "children"; + out << YAML::Value; + + out << YAML::BeginSeq; + for(int i = 0; i < t->size(); ++i) { - LogUnknownKeyWarning(node.Tag(), iter.first()); + save(out, t->getTransform(i)); } + out << YAML::EndSeq; + + out << YAML::EndMap; } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstCDLTransformRcPtr t) - { - out << YAML::VerbatimTag("CDLTransform"); - out << YAML::Flow << YAML::BeginMap; - std::vector slope(3); - t->getSlope(&slope[0]); - if(!IsVecEqualToOne(&slope[0], 3)) + // LogTransform + + inline void load(const YAML::Node& node, LogTransformRcPtr& t) { - out << YAML::Key << "slope"; - out << YAML::Value << YAML::Flow << slope; + t = LogTransform::Create(); + + std::string key; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "base") + { + float val = 0.0f; + load(second, val); + t->setBase(val); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } + } } - std::vector offset(3); - t->getOffset(&offset[0]); - if(!IsVecEqualToZero(&offset[0], 3)) + inline void save(YAML::Emitter& out, ConstLogTransformRcPtr t) { - out << YAML::Key << "offset"; - out << YAML::Value << YAML::Flow << offset; + out << YAML::VerbatimTag("LogTransform"); + out << YAML::Flow << YAML::BeginMap; + out << YAML::Key << "base" << YAML::Value << t->getBase(); + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; } - std::vector power(3); - t->getPower(&power[0]); - if(!IsVecEqualToOne(&power[0], 3)) + // LookTransform + + inline void load(const YAML::Node& node, LookTransformRcPtr& t) { - out << YAML::Key << "power"; - out << YAML::Value << YAML::Flow << power; + t = LookTransform::Create(); + + std::string key, stringval; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "src") + { + load(second, stringval); + t->setSrc(stringval.c_str()); + } + else if(key == "dst") + { + load(second, stringval); + t->setDst(stringval.c_str()); + } + else if(key == "looks") + { + load(second, stringval); + t->setLooks(stringval.c_str()); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } + } } - if(!IsScalarEqualToOne(t->getSat())) + inline void save(YAML::Emitter& out, ConstLookTransformRcPtr t) { - out << YAML::Key << "sat" << YAML::Value << t->getSat(); + out << YAML::VerbatimTag("LookTransform"); + out << YAML::Flow << YAML::BeginMap; + out << YAML::Key << "src" << YAML::Value << t->getSrc(); + out << YAML::Key << "dst" << YAML::Value << t->getDst(); + out << YAML::Key << "looks" << YAML::Value << t->getLooks(); + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; } - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, AllocationTransformRcPtr& t) - { - t = AllocationTransform::Create(); - - std::string key; + // MatrixTransform - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void load(const YAML::Node& node, MatrixTransformRcPtr& t) { - iter.first() >> key; + t = MatrixTransform::Create(); - if(key == "allocation") - { - Allocation val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setAllocation(val); - } - else if(key == "vars") - { - std::vector val; - if (iter.second().Type() != YAML::NodeType::Null) + std::string key; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "matrix") { - iter.second() >> val; - if(!val.empty()) + std::vector val; + load(second, val); + if(val.size() != 16) { - t->setVars(static_cast(val.size()), &val[0]); + std::ostringstream os; + os << "MatrixTransform parse error, matrix field must be 16 "; + os << "floats. Found '" << val.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setMatrix(&val[0]); + } + else if(key == "offset") + { + std::vector val; + load(second, val); + if(val.size() != 4) + { + std::ostringstream os; + os << "MatrixTransform parse error, offset field must be 4 "; + os << "floats. Found '" << val.size() << "'."; + throw Exception(os.str().c_str()); } + t->setOffset(&val[0]); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); } } - else if(key == "direction") + } + + inline void save(YAML::Emitter& out, ConstMatrixTransformRcPtr t) + { + out << YAML::VerbatimTag("MatrixTransform"); + out << YAML::Flow << YAML::BeginMap; + + std::vector matrix(16, 0.0); + t->getMatrix(&matrix[0]); + if(!IsM44Identity(&matrix[0])) { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); + out << YAML::Key << "matrix"; + out << YAML::Value << YAML::Flow << matrix; } - else + + std::vector offset(4, 0.0); + t->getOffset(&offset[0]); + if(!IsVecEqualToZero(&offset[0],4)) { - LogUnknownKeyWarning(node.Tag(), iter.first()); + out << YAML::Key << "offset"; + out << YAML::Value << YAML::Flow << offset; } + + EmitBaseTransformKeyValues(out, t); + out << YAML::EndMap; } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstAllocationTransformRcPtr t) - { - out << YAML::VerbatimTag("AllocationTransform"); - out << YAML::Flow << YAML::BeginMap; - out << YAML::Key << "allocation"; - out << YAML::Value << YAML::Flow << t->getAllocation(); + // TruelightTransform - if(t->getNumVars() > 0) + inline void load(const YAML::Node& node, TruelightTransformRcPtr& t) { - std::vector vars(t->getNumVars()); - t->getVars(&vars[0]); - out << YAML::Key << "vars"; - out << YAML::Flow << YAML::Value << vars; + t = TruelightTransform::Create(); + + std::string key, stringval; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "config_root") + { + load(second, stringval); + t->setConfigRoot(stringval.c_str()); + } + else if(key == "profile") + { + load(second, stringval); + t->setProfile(stringval.c_str()); + } + else if(key == "camera") + { + load(second, stringval); + t->setCamera(stringval.c_str()); + } + else if(key == "input_display") + { + load(second, stringval); + t->setInputDisplay(stringval.c_str()); + } + else if(key == "recorder") + { + load(second, stringval); + t->setRecorder(stringval.c_str()); + } + else if(key == "print") + { + load(second, stringval); + t->setPrint(stringval.c_str()); + } + else if(key == "lamp") + { + load(second, stringval); + t->setLamp(stringval.c_str()); + } + else if(key == "output_camera") + { + load(second, stringval); + t->setOutputCamera(stringval.c_str()); + } + else if(key == "display") + { + load(second, stringval); + t->setDisplay(stringval.c_str()); + } + else if(key == "cube_input") + { + load(second, stringval); + t->setCubeInput(stringval.c_str()); + } + else if(key == "direction") + { + TransformDirection val; + load(second, val); + t->setDirection(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } + } } - EmitBaseTransformKeyValues(out, t); - out << YAML::EndMap; - return out; - } - - void operator >> (const YAML::Node& node, TruelightTransformRcPtr& t) - { - t = TruelightTransform::Create(); - - std::string key, stringval; - - for (YAML::Iterator iter = node.begin(); - iter != node.end(); - ++iter) + inline void save(YAML::Emitter& out, ConstTruelightTransformRcPtr t) { - iter.first() >> key; - if(key == "config_root") + out << YAML::VerbatimTag("TruelightTransform"); + out << YAML::Flow << YAML::BeginMap; + if(strcmp(t->getConfigRoot(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setConfigRoot(stringval.c_str()); + out << YAML::Key << "config_root"; + out << YAML::Value << YAML::Flow << t->getConfigRoot(); } - else if(key == "profile") + if(strcmp(t->getProfile(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setProfile(stringval.c_str()); + out << YAML::Key << "profile"; + out << YAML::Value << YAML::Flow << t->getProfile(); } - else if(key == "camera") + if(strcmp(t->getCamera(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setCamera(stringval.c_str()); + out << YAML::Key << "camera"; + out << YAML::Value << YAML::Flow << t->getCamera(); } - else if(key == "input_display") + if(strcmp(t->getInputDisplay(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setInputDisplay(stringval.c_str()); + out << YAML::Key << "input_display"; + out << YAML::Value << YAML::Flow << t->getInputDisplay(); } - else if(key == "recorder") + if(strcmp(t->getRecorder(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setRecorder(stringval.c_str()); + out << YAML::Key << "recorder"; + out << YAML::Value << YAML::Flow << t->getRecorder(); } - else if(key == "print") + if(strcmp(t->getPrint(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setPrint(stringval.c_str()); + out << YAML::Key << "print"; + out << YAML::Value << YAML::Flow << t->getPrint(); } - else if(key == "lamp") + if(strcmp(t->getLamp(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setLamp(stringval.c_str()); + out << YAML::Key << "lamp"; + out << YAML::Value << YAML::Flow << t->getLamp(); } - else if(key == "output_camera") + if(strcmp(t->getOutputCamera(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setOutputCamera(stringval.c_str()); + out << YAML::Key << "output_camera"; + out << YAML::Value << YAML::Flow << t->getOutputCamera(); } - else if(key == "display") + if(strcmp(t->getDisplay(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setDisplay(stringval.c_str()); + out << YAML::Key << "display"; + out << YAML::Value << YAML::Flow << t->getDisplay(); } - else if(key == "cube_input") + if(strcmp(t->getCubeInput(), "") != 0) { - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(stringval)) - t->setCubeInput(stringval.c_str()); + out << YAML::Key << "cube_input"; + out << YAML::Value << YAML::Flow << t->getCubeInput(); } - else if(key == "direction") + + EmitBaseTransformKeyValues(out, t); + + out << YAML::EndMap; + } + + // Transform + + void load(const YAML::Node& node, TransformRcPtr& t) + { + if(node.Type() != YAML::NodeType::Map) { - TransformDirection val; - if (iter.second().Type() != YAML::NodeType::Null && - iter.second().Read(val)) - t->setDirection(val); + std::ostringstream os; + os << "Unsupported Transform type encountered: (" << node.Type() << ") in OCIO profile. "; + os << "Only Mapping types supported."; + throw Exception(os.str().c_str()); + } + + std::string type = node.Tag(); + + if(type == "AllocationTransform") { + AllocationTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "CDLTransform") { + CDLTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "ColorSpaceTransform") { + ColorSpaceTransformRcPtr temp; + load(node, temp); + t = temp; + } + // TODO: DisplayTransform + else if(type == "ExponentTransform") { + ExponentTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "FileTransform") { + FileTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "GroupTransform") { + GroupTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "LogTransform") { + LogTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "LookTransform") { + LookTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "MatrixTransform") { + MatrixTransformRcPtr temp; + load(node, temp); + t = temp; + } + else if(type == "TruelightTransform") { + TruelightTransformRcPtr temp; + load(node, temp); + t = temp; } else { - LogUnknownKeyWarning(node.Tag(), iter.first()); + // TODO: add a new empty (better name?) aka passthru Transform() + // which does nothing. This is so upsupported ! types don't + // throw an exception. Alternativly this could be caught in the + // GroupTransformRcPtr >> operator with some type of + // supported_tag() method + + // TODO: consider the forwards-compatibility implication of + // throwing an exception. Should this be a warning, instead? + + // t = EmptyTransformRcPtr(new EmptyTransform(), &deleter); + std::ostringstream os; + os << "Unsupported transform type !<" << type << "> in OCIO profile. "; + throw Exception(os.str().c_str()); } } - } - - YAML::Emitter& operator << (YAML::Emitter& out, ConstTruelightTransformRcPtr t) - { - out << YAML::VerbatimTag("TruelightTransform"); - out << YAML::Flow << YAML::BeginMap; - if(strcmp(t->getConfigRoot(), "") != 0) - { - out << YAML::Key << "config_root"; - out << YAML::Value << YAML::Flow << t->getConfigRoot(); - } - if(strcmp(t->getProfile(), "") != 0) + void save(YAML::Emitter& out, ConstTransformRcPtr t) { - out << YAML::Key << "profile"; - out << YAML::Value << YAML::Flow << t->getProfile(); - } - if(strcmp(t->getCamera(), "") != 0) - { - out << YAML::Key << "camera"; - out << YAML::Value << YAML::Flow << t->getCamera(); - } - if(strcmp(t->getInputDisplay(), "") != 0) - { - out << YAML::Key << "input_display"; - out << YAML::Value << YAML::Flow << t->getInputDisplay(); + if(ConstAllocationTransformRcPtr Allocation_tran = \ + DynamicPtrCast(t)) + save(out, Allocation_tran); + else if(ConstCDLTransformRcPtr CDL_tran = \ + DynamicPtrCast(t)) + save(out, CDL_tran); + else if(ConstColorSpaceTransformRcPtr ColorSpace_tran = \ + DynamicPtrCast(t)) + save(out, ColorSpace_tran); + else if(ConstExponentTransformRcPtr Exponent_tran = \ + DynamicPtrCast(t)) + save(out, Exponent_tran); + else if(ConstFileTransformRcPtr File_tran = \ + DynamicPtrCast(t)) + save(out, File_tran); + else if(ConstGroupTransformRcPtr Group_tran = \ + DynamicPtrCast(t)) + save(out, Group_tran); + else if(ConstLogTransformRcPtr Log_tran = \ + DynamicPtrCast(t)) + save(out, Log_tran); + else if(ConstLookTransformRcPtr Look_tran = \ + DynamicPtrCast(t)) + save(out, Look_tran); + else if(ConstMatrixTransformRcPtr Matrix_tran = \ + DynamicPtrCast(t)) + save(out, Matrix_tran); + else if(ConstTruelightTransformRcPtr Truelight_tran = \ + DynamicPtrCast(t)) + save(out, Truelight_tran); + else + throw Exception("Unsupported Transform() type for serialization."); } - if(strcmp(t->getRecorder(), "") != 0) + + // ColorSpace + + inline void load(const YAML::Node& node, ColorSpaceRcPtr& cs) { - out << YAML::Key << "recorder"; - out << YAML::Value << YAML::Flow << t->getRecorder(); + if(node.Tag() != "ColorSpace") + return; // not a ! tag + + std::string key, stringval; + bool boolval; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "name") + { + load(second, stringval); + cs->setName(stringval.c_str()); + } + else if(key == "description") + { + load(second, stringval); + cs->setDescription(stringval.c_str()); + } + else if(key == "family") + { + load(second, stringval); + cs->setFamily(stringval.c_str()); + } + else if(key == "equalitygroup") + { + load(second, stringval); + cs->setEqualityGroup(stringval.c_str()); + } + else if(key == "bitdepth") + { + BitDepth ret; + load(second, ret); + cs->setBitDepth(ret); + } + else if(key == "isdata") + { + load(second, boolval); + cs->setIsData(boolval); + } + else if(key == "allocation") + { + Allocation val; + load(second, val); + cs->setAllocation(val); + } + else if(key == "allocationvars") + { + std::vector val; + load(second, val); + if(!val.empty()) + cs->setAllocationVars(static_cast(val.size()), &val[0]); + } + else if(key == "to_reference") + { + TransformRcPtr val; + load(second, val); + cs->setTransform(val, COLORSPACE_DIR_TO_REFERENCE); + } + else if(key == "from_reference") + { + TransformRcPtr val; + load(second, val); + cs->setTransform(val, COLORSPACE_DIR_FROM_REFERENCE); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } + } } - if(strcmp(t->getPrint(), "") != 0) + + inline void save(YAML::Emitter& out, ConstColorSpaceRcPtr cs) { - out << YAML::Key << "print"; - out << YAML::Value << YAML::Flow << t->getPrint(); + out << YAML::VerbatimTag("ColorSpace"); + out << YAML::BeginMap; + + out << YAML::Key << "name" << YAML::Value << cs->getName(); + out << YAML::Key << "family" << YAML::Value << cs->getFamily(); + out << YAML::Key << "equalitygroup" << YAML::Value << cs->getEqualityGroup(); + out << YAML::Key << "bitdepth" << YAML::Value; + save(out, cs->getBitDepth()); + if(cs->getDescription() != NULL && strlen(cs->getDescription()) > 0) + { + out << YAML::Key << "description"; + out << YAML::Value << YAML::Literal << cs->getDescription(); + } + out << YAML::Key << "isdata" << YAML::Value << cs->isData(); + + out << YAML::Key << "allocation" << YAML::Value; + save(out, cs->getAllocation()); + if(cs->getAllocationNumVars() > 0) + { + std::vector allocationvars(cs->getAllocationNumVars()); + cs->getAllocationVars(&allocationvars[0]); + out << YAML::Key << "allocationvars"; + out << YAML::Flow << YAML::Value << allocationvars; + } + + ConstTransformRcPtr toref = \ + cs->getTransform(COLORSPACE_DIR_TO_REFERENCE); + if(toref) + { + out << YAML::Key << "to_reference" << YAML::Value; + save(out, toref); + } + + ConstTransformRcPtr fromref = \ + cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE); + if(fromref) + { + out << YAML::Key << "from_reference" << YAML::Value; + save(out, fromref); + } + + out << YAML::EndMap; + out << YAML::Newline; } - if(strcmp(t->getLamp(), "") != 0) + + // Look + + inline void load(const YAML::Node& node, LookRcPtr& look) { - out << YAML::Key << "lamp"; - out << YAML::Value << YAML::Flow << t->getLamp(); + if(node.Tag() != "Look") + return; + + std::string key, stringval; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "name") + { + load(second, stringval); + look->setName(stringval.c_str()); + } + else if(key == "process_space") + { + load(second, stringval); + look->setProcessSpace(stringval.c_str()); + } + else if(key == "transform") + { + TransformRcPtr val; + load(second, val); + look->setTransform(val); + } + else if(key == "inverse_transform") + { + TransformRcPtr val; + load(second, val); + look->setInverseTransform(val); + } + else + { + LogUnknownKeyWarning(node.Tag(), first); + } + } } - if(strcmp(t->getOutputCamera(), "") != 0) + + inline void save(YAML::Emitter& out, ConstLookRcPtr look) { - out << YAML::Key << "output_camera"; - out << YAML::Value << YAML::Flow << t->getOutputCamera(); + out << YAML::VerbatimTag("Look"); + out << YAML::BeginMap; + out << YAML::Key << "name" << YAML::Value << look->getName(); + out << YAML::Key << "process_space" << YAML::Value << look->getProcessSpace(); + + if(look->getTransform()) + { + out << YAML::Key << "transform"; + out << YAML::Value; + save(out, look->getTransform()); + } + + if(look->getInverseTransform()) + { + out << YAML::Key << "inverse_transform"; + out << YAML::Value; + save(out, look->getInverseTransform()); + } + + out << YAML::EndMap; + out << YAML::Newline; } - if(strcmp(t->getDisplay(), "") != 0) + + // Config + + inline void load(const YAML::Node& node, ConfigRcPtr& c, const char* filename) { - out << YAML::Key << "display"; - out << YAML::Value << YAML::Flow << t->getDisplay(); + + // check profile version + int profile_version = 0; +#ifdef OLDYAML + if(node.FindValue("ocio_profile_version") == NULL) +#else + if(node["ocio_profile_version"] == NULL) +#endif + { + std::ostringstream os; + os << "The specified file "; + os << "does not appear to be an OCIO configuration."; + throw Exception (os.str().c_str()); + } + + load(node["ocio_profile_version"], profile_version); + if(profile_version > 1) + { + std::ostringstream os; + os << "This .ocio config "; + if(filename && *filename) + { + os << " '" << filename << "' "; + } + os << "is version " << profile_version << ". "; + os << "This version of the OpenColorIO library (" << OCIO_VERSION ") "; + os << "is not known to be able to load this profile. "; + os << "An attempt will be made, but there are no guarantees that the "; + os << "results will be accurate. Continue at your own risk."; + LogWarning(os.str()); + } + + std::string key, stringval; + bool boolval = false; + EnvironmentMode mode = ENV_ENVIRONMENT_LOAD_ALL; + + for (Iterator iter = node.begin(); + iter != node.end(); + ++iter) + { + const YAML::Node& first = get_first(iter); + const YAML::Node& second = get_second(iter); + + load(first, key); + + if (second.Type() == YAML::NodeType::Null) continue; + + if(key == "ocio_profile_version") { } // Already handled above. + else if(key == "environment") + { + mode = ENV_ENVIRONMENT_LOAD_PREDEFINED; + if(second.Type() != YAML::NodeType::Map) + { + std::ostringstream os; + os << "'environment' field needs to be a (name: key) map."; + throw Exception(os.str().c_str()); + } + for (Iterator it = second.begin(); + it != second.end(); + ++it) + { + std::string k, v; + load(get_first(it), k); + load(get_second(it), v); + c->addEnvironmentVar(k.c_str(), v.c_str()); + } + } + else if(key == "search_path" || key == "resource_path") + { + load(second, stringval); + c->setSearchPath(stringval.c_str()); + } + else if(key == "strictparsing") + { + load(second, boolval); + c->setStrictParsingEnabled(boolval); + } + else if(key == "description") + { + load(second, stringval); + c->setDescription(stringval.c_str()); + } + else if(key == "luma") + { + std::vector val; + load(second, val); + if(val.size() != 3) + { + std::ostringstream os; + os << "'luma' field must be 3 "; + os << "floats. Found '" << val.size() << "'."; + throw Exception(os.str().c_str()); + } + c->setDefaultLumaCoefs(&val[0]); + } + else if(key == "roles") + { + if(second.Type() != YAML::NodeType::Map) + { + std::ostringstream os; + os << "'roles' field needs to be a (name: key) map."; + throw Exception(os.str().c_str()); + } + for (Iterator it = second.begin(); + it != second.end(); + ++it) + { + std::string k, v; + load(get_first(it), k); + load(get_second(it), v); + c->setRole(k.c_str(), v.c_str()); + } + } + else if(key == "displays") + { + if(second.Type() != YAML::NodeType::Map) + { + std::ostringstream os; + os << "'displays' field needs to be a (name: key) map."; + throw Exception(os.str().c_str()); + } + for (Iterator it = second.begin(); + it != second.end(); + ++it) + { + std::string display; + load(get_first(it), display); + const YAML::Node& dsecond = get_second(it); + for(unsigned i = 0; i < dsecond.size(); ++i) + { + View view; + load(dsecond[i], view); + c->addDisplay(display.c_str(), view.name.c_str(), + view.colorspace.c_str(), view.looks.c_str()); + } + } + } + else if(key == "active_displays") + { + std::vector display; + load(second, display); + const char* displays = JoinStringEnvStyle(display).c_str(); + c->setActiveDisplays(displays); + } + else if(key == "active_views") + { + std::vector view; + load(second, view); + const char* views = JoinStringEnvStyle(view).c_str(); + c->setActiveViews(views); + } + else if(key == "colorspaces") + { + if(second.Type() != YAML::NodeType::Sequence) + { + std::ostringstream os; + os << "'colorspaces' field needs to be a (- !) list."; + throw Exception(os.str().c_str()); + } + for(unsigned i = 0; i < second.size(); ++i) + { + if(second[i].Tag() == "ColorSpace") + { + ColorSpaceRcPtr cs = ColorSpace::Create(); + load(second[i], cs); + for(int ii = 0; ii < c->getNumColorSpaces(); ++ii) + { + if(strcmp(c->getColorSpaceNameByIndex(ii), cs->getName()) == 0) + { + std::ostringstream os; + os << "Colorspace with name '" << cs->getName() << "' already defined."; + throw Exception(os.str().c_str()); + } + } + c->addColorSpace(cs); + } + else + { + std::ostringstream os; + os << "Unknown element found in colorspaces:"; + os << second[i].Tag() << ". Only ColorSpace(s)"; + os << " currently handled."; + LogWarning(os.str()); + } + } + } + else if(key == "looks") + { + if(second.Type() != YAML::NodeType::Sequence) + { + std::ostringstream os; + os << "'looks' field needs to be a (- !) list."; + throw Exception(os.str().c_str()); + } + + for(unsigned i = 0; i < second.size(); ++i) + { + if(second[i].Tag() == "Look") + { + LookRcPtr look = Look::Create(); + load(second[i], look); + c->addLook(look); + } + else + { + std::ostringstream os; + os << "Unknown element found in looks:"; + os << second[i].Tag() << ". Only Look(s)"; + os << " currently handled."; + LogWarning(os.str()); + } + } + } + else + { + LogUnknownKeyWarning("profile", first); + } + } + + if(filename) + { + std::string realfilename = pystring::os::path::abspath(filename); + std::string configrootdir = pystring::os::path::dirname(realfilename); + c->setWorkingDir(configrootdir.c_str()); + } + + c->setEnvironmentMode(mode); + c->loadEnvironment(); + + if(mode == ENV_ENVIRONMENT_LOAD_ALL) + { + std::ostringstream os; + os << "This .ocio config "; + if(filename && *filename) + { + os << " '" << filename << "' "; + } + os << "has no environment section defined. The default behaviour is to "; + os << "load all environment variables (" << c->getNumEnvironmentVars() << ")"; + os << ", which reduces the efficiency of OCIO's caching. Considering "; + os << "predefining the environment variables used."; + LogDebug(os.str()); + } + } - if(strcmp(t->getCubeInput(), "") != 0) + + inline void save(YAML::Emitter& out, const Config* c) { - out << YAML::Key << "cube_input"; - out << YAML::Value << YAML::Flow << t->getCubeInput(); + out << YAML::Block; + out << YAML::BeginMap; + out << YAML::Key << "ocio_profile_version" << YAML::Value << 1; + out << YAML::Newline; +#ifndef OLDYAML + out << YAML::Newline; +#endif + + if(c->getNumEnvironmentVars() > 0) + { + out << YAML::Key << "environment"; + out << YAML::Value << YAML::BeginMap; + for(unsigned i = 0; i < c->getNumEnvironmentVars(); ++i) + { + const char* name = c->getEnvironmentVarNameByIndex(i); + out << YAML::Key << name; + out << YAML::Value << c->getEnvironmentVarDefault(name); + } + out << YAML::EndMap; + out << YAML::Newline; + } + out << YAML::Key << "search_path" << YAML::Value << c->getSearchPath(); + out << YAML::Key << "strictparsing" << YAML::Value << c->isStrictParsingEnabled(); + + std::vector luma(3, 0.f); + c->getDefaultLumaCoefs(&luma[0]); + out << YAML::Key << "luma" << YAML::Value << YAML::Flow << luma; + + if(c->getDescription() != NULL && strlen(c->getDescription()) > 0) + { + out << YAML::Newline; + out << YAML::Key << "description"; + out << YAML::Value << c->getDescription(); + out << YAML::Newline; + } + + // Roles + out << YAML::Newline; +#ifndef OLDYAML + out << YAML::Newline; +#endif + out << YAML::Key << "roles"; + out << YAML::Value << YAML::BeginMap; + for(unsigned i = 0; i < c->getNumRoles(); ++i) + { + const char* role = c->getRoleName(i); + out << YAML::Key << role; + out << YAML::Value << c->getColorSpace(role)->getName(); + } + out << YAML::EndMap; +#ifndef OLDYAML + out << YAML::Newline; +#endif + + // Displays + out << YAML::Newline; + out << YAML::Key << "displays"; + out << YAML::Value << YAML::BeginMap; + for(unsigned i = 0; i < c->getNumDisplays(); ++i) + { + const char* display = c->getDisplay(i); + out << YAML::Key << display; + out << YAML::Value << YAML::BeginSeq; + for(unsigned v = 0; v < c->getNumViews(display); ++v) + { + View dview; + dview.name = c->getView(display, v); + dview.colorspace = c->getDisplayColorSpaceName(display, dview.name.c_str()); + if(c->getDisplayLooks(display, dview.name.c_str()) != NULL) + dview.looks = c->getDisplayLooks(display, dview.name.c_str()); + save(out, dview); + + } + out << YAML::EndSeq; + } + out << YAML::EndMap; + +#ifndef OLDYAML + out << YAML::Newline; +#endif + out << YAML::Newline; + out << YAML::Key << "active_displays"; + std::vector active_displays; + if(c->getActiveDisplays() != NULL && strlen(c->getActiveDisplays()) > 0) + SplitStringEnvStyle(active_displays, c->getActiveDisplays()); + out << YAML::Value << YAML::Flow << active_displays; + out << YAML::Key << "active_views"; + std::vector active_views; + if(c->getActiveViews() != NULL && strlen(c->getActiveViews()) > 0) + SplitStringEnvStyle(active_views, c->getActiveViews()); + out << YAML::Value << YAML::Flow << active_views; +#ifndef OLDYAML + out << YAML::Newline; +#endif + + // Looks + if(c->getNumLooks() > 0) + { + out << YAML::Newline; + out << YAML::Key << "looks"; + out << YAML::Value << YAML::BeginSeq; + for(unsigned i = 0; i < c->getNumLooks(); ++i) + { + const char* name = c->getLookNameByIndex(i); + save(out, c->getLook(name)); + } + out << YAML::EndSeq; + out << YAML::Newline; + } + + // ColorSpaces + { + out << YAML::Newline; + out << YAML::Key << "colorspaces"; + out << YAML::Value << YAML::BeginSeq; + for(unsigned i = 0; i < c->getNumColorSpaces(); ++i) + { + const char* name = c->getColorSpaceNameByIndex(i); + save(out, c->getColorSpace(name)); + } + out << YAML::EndSeq; + } + + out << YAML::EndMap; } - EmitBaseTransformKeyValues(out, t); - - out << YAML::EndMap; - return out; } /////////////////////////////////////////////////////////////////////////// - // Enums - - YAML::Emitter& operator << (YAML::Emitter& out, BitDepth depth) { - out << BitDepthToString(depth); - return out; - } - - void operator >> (const YAML::Node& node, BitDepth& depth) { - std::string str; - node.Read(str); - depth = BitDepthFromString(str.c_str()); - } - - YAML::Emitter& operator << (YAML::Emitter& out, Allocation alloc) { - out << AllocationToString(alloc); - return out; - } - - void operator >> (const YAML::Node& node, Allocation& alloc) { - std::string str; - node.Read(str); - alloc = AllocationFromString(str.c_str()); - } - - YAML::Emitter& operator << (YAML::Emitter& out, ColorSpaceDirection dir) { - out << ColorSpaceDirectionToString(dir); - return out; - } - void operator >> (const YAML::Node& node, ColorSpaceDirection& dir) { - std::string str; - node.Read(str); - dir = ColorSpaceDirectionFromString(str.c_str()); - } - - YAML::Emitter& operator << (YAML::Emitter& out, TransformDirection dir) { - out << TransformDirectionToString(dir); - return out; - } - - void operator >> (const YAML::Node& node, TransformDirection& dir) { - std::string str; - node.Read(str); - dir = TransformDirectionFromString(str.c_str()); - } - - YAML::Emitter& operator << (YAML::Emitter& out, Interpolation interp) { - out << InterpolationToString(interp); - return out; + void OCIOYaml::open(std::istream& istream, ConfigRcPtr& c, const char* filename) const + { + try + { +#ifdef OLDYAML + YAML::Parser parser(istream); + YAML::Node node; + parser.GetNextDocument(node); +#else + YAML::Node node = YAML::Load(istream); +#endif + load(node, c, filename); + } + catch(const std::exception & e) + { + std::ostringstream os; + os << "Error: Loading the OCIO profile "; + if(filename) os << "'" << filename << "' "; + os << "failed. " << e.what(); + throw Exception(os.str().c_str()); + } } - void operator >> (const YAML::Node& node, Interpolation& interp) { - std::string str; - node.Read(str); - interp = InterpolationFromString(str.c_str()); + void OCIOYaml::write(std::ostream& ostream, const Config* c) const + { + YAML::Emitter out; + save(out, c); + ostream << out.c_str(); } } diff --git a/src/core/OCIOYaml.h b/src/core/OCIOYaml.h index 7104123..364a262 100644 --- a/src/core/OCIOYaml.h +++ b/src/core/OCIOYaml.h @@ -28,97 +28,19 @@ #include -#include "Platform.h" - -#ifndef WINDOWS - -// fwd declare yaml-cpp visibility -#pragma GCC visibility push(hidden) -namespace YAML { - class Exception; - class BadDereference; - class RepresentationException; - class EmitterException; - class ParserException; - class InvalidScalar; - class KeyNotFound; - template class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; - template <> class TypedKeyNotFound; -} -#pragma GCC visibility pop - -#endif - -#include - #ifndef INCLUDED_OCIO_YAML_H #define INCLUDED_OCIO_YAML_H OCIO_NAMESPACE_ENTER { - // Core - OCIOHIDDEN void operator >> (const YAML::Node& node, ColorSpaceRcPtr& cs); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ColorSpaceRcPtr cs); - OCIOHIDDEN void operator >> (const YAML::Node& node, GroupTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstGroupTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, TransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, LookRcPtr& cs); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, LookRcPtr cs); - - // Transforms - OCIOHIDDEN void operator >> (const YAML::Node& node, AllocationTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstAllocationTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, CDLTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstCDLTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, ColorSpaceTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstColorSpaceTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, ExponentTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstExponentTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, FileTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstFileTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, LogTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstLogTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, LookTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstLookTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, MatrixTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstMatrixTransformRcPtr t); - OCIOHIDDEN void operator >> (const YAML::Node& node, TruelightTransformRcPtr& t); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ConstTruelightTransformRcPtr t); - - // Enums - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, BitDepth depth); - OCIOHIDDEN void operator >> (const YAML::Node& node, BitDepth& depth); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, Allocation alloc); - OCIOHIDDEN void operator >> (const YAML::Node& node, Allocation& alloc); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, ColorSpaceDirection dir); - OCIOHIDDEN void operator >> (const YAML::Node& node, ColorSpaceDirection& dir); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, TransformDirection dir); - OCIOHIDDEN void operator >> (const YAML::Node& node, TransformDirection& dir); - OCIOHIDDEN YAML::Emitter& operator << (YAML::Emitter& out, Interpolation iterp); - OCIOHIDDEN void operator >> (const YAML::Node& node, Interpolation& iterp); + class OCIOYaml + { + public: + void open(std::istream& istream, ConfigRcPtr& c, const char* filename = NULL) const; + void write(std::ostream& ostream, const Config* c) const; + }; - void LogUnknownKeyWarning(const std::string & name, const YAML::Node& tag); } OCIO_NAMESPACE_EXIT -- 1.8.5.1