aboutsummaryrefslogtreecommitdiffstats
path: root/testing/opencolorio
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2018-03-22 11:18:24 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2018-03-22 11:58:10 +0000
commit92871bb01806718a347c41782b5e84d14367a88f (patch)
tree5e740801ea6db6813987fa02288848fb0a650940 /testing/opencolorio
parent012b37621b508cb41919959cd9b278f25aa53887 (diff)
downloadaports-92871bb01806718a347c41782b5e84d14367a88f.tar.bz2
aports-92871bb01806718a347c41782b5e84d14367a88f.tar.xz
testing/opencolorio: upgrade to 1.1.0
Diffstat (limited to 'testing/opencolorio')
-rw-r--r--testing/opencolorio/APKBUILD21
-rw-r--r--testing/opencolorio/temp-deref-with-yaml-0.5.0.patch112
-rw-r--r--testing/opencolorio/yaml-cpp-0.5-support.patch3815
3 files changed, 8 insertions, 3940 deletions
diff --git a/testing/opencolorio/APKBUILD b/testing/opencolorio/APKBUILD
index 09e1a2e717..66f2fb97a9 100644
--- a/testing/opencolorio/APKBUILD
+++ b/testing/opencolorio/APKBUILD
@@ -1,8 +1,8 @@
# Contributor: Mark Riedesel <mark@klowner.com>
# Maintainer: Mark Riedesel <mark@klowner.com>
pkgname=opencolorio
-pkgver=1.0.9
-pkgrel=5
+pkgver=1.1.0
+pkgrel=0
pkgdesc="A color management framework for visual effects and animation"
url="http://opencolorio.org"
arch="all"
@@ -12,8 +12,9 @@ makedepends="boost-dev cmake freeglut-dev glew-dev lcms2-dev python2-dev
python3-dev tinyxml-dev yaml-cpp-dev"
subpackages="py2-$pkgname:py2 py3-$pkgname:py3 $pkgname-dev $pkgname-tools"
source="$pkgname-$pkgver.tar.gz::http://github.com/imageworks/OpenColorIO/archive/v$pkgver.tar.gz
- yaml-cpp-0.5-support.patch
- temp-deref-with-yaml-0.5.0.patch"
+ OpenColorIO-gcc.patch
+ ocio-1.1.0-yamlcpp060.patch
+ "
builddir="$srcdir/OpenColorIO-$pkgver"
build() {
@@ -79,12 +80,6 @@ py3() {
_python 3 "$(python3 -c 'import site; print(site.getsitepackages()[0])')"
}
-md5sums="06d0efe9cc1b32d7b14134779c9d1251 opencolorio-1.0.9.tar.gz
-11bb6b587b2e5242f75aca281bab158c yaml-cpp-0.5-support.patch
-5f13bef26e14b2dd908e69a2bc8fb7a4 temp-deref-with-yaml-0.5.0.patch"
-sha256sums="27c81e691c15753cd2b560c2ca4bd5679a60c2350eedd43c99d44ca25d65ea7f opencolorio-1.0.9.tar.gz
-b381912a81342e242d1a6ef39cf1556f7b383407af9c1aefbde06e38186777ad yaml-cpp-0.5-support.patch
-6df29f0d3de06ab0fbc2fa06f6fc7537d0628c4185d7a9f6228b2d0be07917d7 temp-deref-with-yaml-0.5.0.patch"
-sha512sums="ac953ba9904aff44de37cc2ee60dbf524bd86d25f699c1eacaa61ca30fed8f077194d47d34a72c05b706da7e1a3974a988d67d60031d424d91b9240f8ab86ed3 opencolorio-1.0.9.tar.gz
-8b909e1aa688ca38ce7938a4855611cf19781a3c2dc9cc9bca3df3b8d21a2a7772e35917ba9f636c89ea2da8eec2aa7b7118bfa77e0787614110e7441b038de5 yaml-cpp-0.5-support.patch
-3793e39d74f3c585d7fc2fbcc7f131fba9f0fea130de80c31461101355954c3d3fa158028652f074fb129e7c0a7ee1e506dbfc187ca5fbfdce09303b371bf266 temp-deref-with-yaml-0.5.0.patch"
+sha512sums="909874a9f91a8d229622810fc70233680c6e75203bd8555179322de2873da00bf302432e19f189b787ffcda3157ddec1e4601c97f75a36e16f644fe7d42f6998 opencolorio-1.1.0.tar.gz
+befed734f240d26c7cbeb020b540ea91d84c9422fa61dcb0ab16f56389f7c5c90d10e015c6cdbed2033047b7e31ceb4fd1b2707c2bef1a8e0f33959601471d5f OpenColorIO-gcc.patch
+ef4b0e880c587fcd004865fd938e7f1fb1bbb933abf1ccf352260ebe3a50145664e27b9f1119b72ced99afe4d19b49b0b6c249dd95faaec9c1332ffc44bc9811 ocio-1.1.0-yamlcpp060.patch"
diff --git a/testing/opencolorio/temp-deref-with-yaml-0.5.0.patch b/testing/opencolorio/temp-deref-with-yaml-0.5.0.patch
deleted file mode 100644
index 23d971d5d6..0000000000
--- a/testing/opencolorio/temp-deref-with-yaml-0.5.0.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-commit 1384029df00525c479e2c7e52fdfa294413fceb6
-Author: Mark Boorer <mkj@dneg.com>
-Date: Wed Sep 3 22:41:28 2014 +0100
-
- OCIOYaml: Fixed dereference of temporary when yaml-cpp 0.5.x was used.
- CMakeLists.txt: Improved System yaml-cpp detection.
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 69eca4e..b539ea1 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -202,15 +202,44 @@ if(USE_EXTERNAL_YAML)
- # Set minimum yaml version for non-patched sources.
- set(YAML_VERSION_MIN "0.3.0")
- include(FindPkgConfig)
-- pkg_check_modules(YAML_CPP yaml-cpp)
-+ pkg_check_modules(PC_YAML_CPP REQUIRED QUIET yaml-cpp)
-+ find_path(YAML_CPP_INCLUDE_DIR yaml-cpp/yaml.h
-+ HINTS ${PC_YAML_CPP_INCLUDEDIR} ${PC_YAML_CPP_INCLUDE_DIRS} )
-+ find_library(YAML_CPP_LIBRARY LIBRARY_NAMES yaml-cpp libyaml-cpp
-+ HINTS ${PC_YAML_CPP_LIBRARY_DIRS} )
-+ set(YAML_CPP_LIBRARIES ${YAML_CPP_LIBRARY})
-+ set(YAML_CPP_INCLUDE_DIRS ${YAML_CPP_INCLUDE_DIR})
-+ set(YAML_CPP_VERSION ${PC_YAML_CPP_VERSION})
-+
-+ if(YAML_CPP_VERSION VERSION_LESS ${YAML_VERSION_MIN})
-+ message(FATAL_ERROR "ERROR: yaml-cpp ${YAML_VERSION_MIN} or greater is required.")
-+ endif()
-+
-+ find_package_handle_standard_args(yaml-cpp
-+ REQUIRED_VARS YAML_CPP_LIBRARIES YAML_CPP_INCLUDE_DIRS )
-+ set(YAML_CPP_FOUND ${YAML-CPP_FOUND})
-+ mark_as_advanced(YAML_CPP_INCLUDE_DIR YAML_CPP_LIBRARY YAML-CPP_FOUND)
-+
- if(YAML_CPP_FOUND)
-- if(YAML_CPP_VERSION VERSION_EQUAL ${YAML_VERSION_MIN} OR
-- YAML_CPP_VERSION VERSION_GREATER ${YAML_VERSION_MIN})
-- message(STATUS "System yaml-cpp library will be used.")
-- include_directories(BEFORE ${YAML_CPP_INCLUDE_DIRS})
-- else()
-- message(FATAL_ERROR "ERROR: yaml-cpp ${YAML_VERSION_MIN} or greater is required.")
-+ if(YAML_CPP_VERSION VERSION_GREATER "0.5.0")
-+ # Need to also get the boost headers here, as yaml-cpp 0.5.0+ requires them.
-+ # Don't bother doing this step if we are already including the boost headers for shared_ptr
-+ if(NOT OCIO_USE_BOOST_PTR)
-+ set(Boost_ADDITIONAL_VERSIONS "1.49" "1.45" "1.44" "1.43" "1.43.0" "1.42"
-+ "1.42.0" "1.41" "1.41.0" "1.40"
-+ "1.40.0" "1.39" "1.39.0" "1.38"
-+ "1.38.0" "1.37" "1.37.0" "1.34.1"
-+ "1_34_1")
-+ set(Boost_USE_MULTITHREADED ON)
-+ find_package(Boost 1.34)
-+ if(NOT Boost_FOUND)
-+ message(FATAL_ERROR "Error: Detected system yaml-cpp version ${YAML_CPP_VERSION} is greater than 0.5.0, and therefore requires boost, but a boost installation could not be found.")
-+ endif()
-+
-+ set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${Boost_INCLUDE_DIR})
-+ endif()
- endif()
-+ set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${YAML_CPP_INCLUDE_DIRS})
- else(YAML_CPP_FOUND)
- message(FATAL_ERROR "ERROR: System yaml-cpp library was not found. Make sure the library is installed and the pkg-config file exists.")
- endif(YAML_CPP_FOUND)
-diff --git a/src/core/OCIOYaml.cpp b/src/core/OCIOYaml.cpp
-index 5a95353..d9f1345 100644
---- a/src/core/OCIOYaml.cpp
-+++ b/src/core/OCIOYaml.cpp
-@@ -88,26 +88,36 @@ OCIO_NAMESPACE_ENTER
- #else
- typedef YAML::const_iterator Iterator;
- #endif
--
-+
- // Iterator access
--
-- inline const YAML::Node& get_first(const Iterator it)
-- {
-+ // Note: The ownership semantics have changed between yaml-cpp 0.3.x and 0.5.x .
-+ // Returning a const reference to a yaml node screws with the internal yaml-cpp smart ptr
-+ // implementation in the newer version. Luckily, the compiler does not care if we maintain
-+ // const YAML::Node & = get_first(iter) syntax at the call site even when returning an actual object
-+ // (instead of the reference as expected).
- #ifdef OLDYAML
-+ inline const YAML::Node& get_first(const Iterator &it)
-+ {
- return it.first();
-+ }
- #else
-+ inline YAML::Node get_first(const Iterator &it)
-+ {
- return it->first;
--#endif
- }
-+#endif
-
-- inline const YAML::Node& get_second(const Iterator it)
-- {
- #ifdef OLDYAML
-+ inline const YAML::Node& get_second(const Iterator &it)
-+ {
- return it.second();
-+ }
- #else
-+ inline YAML::Node get_second(const Iterator &it)
-+ {
- return it->second;
--#endif
- }
-+#endif
-
- // Basic types
-
diff --git a/testing/opencolorio/yaml-cpp-0.5-support.patch b/testing/opencolorio/yaml-cpp-0.5-support.patch
deleted file mode 100644
index e3b51c9362..0000000000
--- a/testing/opencolorio/yaml-cpp-0.5-support.patch
+++ /dev/null
@@ -1,3815 +0,0 @@
-commit 63c6bde2acac363c8c5e7fd3d744e17ea99e20ab
-Author: Malcolm Humphreys <malcolmhumphreys@gmail.com>
-Date: Thu Jan 30 12:42:21 2014 +0000
-
- * 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
-
-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 @@ OCIO_NAMESPACE_ENTER
- 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/ext/yaml-cpp-0.5.1.tar.gz b/ext/yaml-cpp-0.5.1.tar.gz
-new file mode 100644
-index 0000000..f087742
-Binary files /dev/null and b/ext/yaml-cpp-0.5.1.tar.gz differ
-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 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #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 @@ OCIO_NAMESPACE_ENTER
- 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 @@ OCIO_NAMESPACE_ENTER
-
- 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<View> ViewVec;
-- typedef std::map<std::string, ViewVec> 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<std::string>(stringval))
-- v.name = stringval;
-- }
-- else if(key == "colorspace")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- v.colorspace = stringval;
-- }
-- else if(key == "looks" || key == "look")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(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; i<vec.size(); ++i)
-- {
-- if(StrEqualsCaseIgnore(name, vec[i].name)) return i;
-- }
-- return -1;
-- }
--
-- void AddDisplay(DisplayMap & displays,
-- const std::string & display,
-- const std::string & view,
-- const std::string & colorspace,
-- const std::string & looks)
-- {
-- DisplayMap::iterator iter = find_display(displays, display);
-- if(iter == displays.end())
-- {
-- ViewVec views;
-- views.push_back( View(view, colorspace, looks) );
-- displays[display] = views;
-- }
-- else
-- {
-- ViewVec & views = iter->second;
-- 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 @@ OCIO_NAMESPACE_ENTER
- mutable StringMap cacheids_;
- mutable std::string cacheidnocontext_;
-
-+ OCIOYaml io_;
-+
- Impl() :
- context_(Context::Create()),
- strictParsing_(true),
-@@ -497,8 +322,6 @@ OCIO_NAMESPACE_ENTER
- 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 @@ OCIO_NAMESPACE_ENTER
- 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 @@ OCIO_NAMESPACE_ENTER
- }
-
- 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 @@ OCIO_NAMESPACE_ENTER
- 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 @@ OCIO_NAMESPACE_ENTER
- {
- 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 @@ OCIO_NAMESPACE_ENTER
- }
- }
-
-- 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<std::string>(stringval))
-- context_->setSearchPath(stringval.c_str());
-- }
-- else if(key == "strictparsing")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<bool>(boolval))
-- strictParsing_ = boolval;
-- }
-- else if(key == "description")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- description_ = stringval;
-- }
-- else if(key == "luma")
-- {
-- std::vector<float> 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 (- !<ColorSpace>) 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 (- !<Look>) 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 @@ OIIO_ADD_TEST(Config, SanityCheck)
- 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 @@ OIIO_ADD_TEST(Config, EnvCheck)
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
-- " - !<ColorSpace>\n"
-- " name: raw\n"
- "strictparsing: false\n"
- "roles:\n"
- " default: raw\n"
-@@ -2345,8 +1892,6 @@ OIIO_ADD_TEST(Config, EnvCheck)
- "colorspaces:\n"
- " - !<ColorSpace>\n"
- " name: raw\n"
-- " - !<ColorSpace>\n"
-- " name: raw\n"
- "strictparsing: false\n"
- "roles:\n"
- " default: raw\n"
-@@ -2370,7 +1915,6 @@ OIIO_ADD_TEST(Config, EnvCheck)
- "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 @@ OIIO_ADD_TEST(Config, EnvCheck)
- "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 <string>
-+
-+#include <OpenColorIO/OpenColorIO.h>
-+
-+#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; i<vec.size(); ++i)
-+ {
-+ if(StrEqualsCaseIgnore(name, vec[i].name)) return i;
-+ }
-+ return -1;
-+ }
-+
-+ void AddDisplay(DisplayMap & displays,
-+ const std::string & display,
-+ const std::string & view,
-+ const std::string & colorspace,
-+ const std::string & looks)
-+ {
-+ DisplayMap::iterator iter = find_display(displays, display);
-+ if(iter == displays.end())
-+ {
-+ ViewVec views;
-+ views.push_back( View(view, colorspace, looks) );
-+ displays[display] = views;
-+ }
-+ else
-+ {
-+ ViewVec & views = iter->second;
-+ 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 <OpenColorIO/OpenColorIO.h>
-+
-+#include <string>
-+#include <vector>
-+#include <map>
-+
-+#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<View> ViewVec;
-+ typedef std::map<std::string, ViewVec> 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 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- #include <OpenColorIO/OpenColorIO.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 <typename T> class TypedKeyNotFound;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::ColorSpace>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::Config>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::Exception>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::GpuShaderDesc>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::ImageDesc>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::Look>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::Processor>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::Transform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::AllocationTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::CDLTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::ColorSpaceTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::DisplayTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::ExponentTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::FileTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::GroupTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::LogTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::LookTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::MatrixTransform>;
-+ template <> class TypedKeyNotFound<OCIO_NAMESPACE::TruelightTransform>;
-+}
-+#pragma GCC visibility pop
-+
-+#endif
-+
-+#include <yaml-cpp/yaml.h>
-+
- #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 !<ColorSpace> 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<std::string>(stringval))
-- cs->setName(stringval.c_str());
-- }
-- else if(key == "description")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- cs->setDescription(stringval.c_str());
-- }
-- else if(key == "family")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- cs->setFamily(stringval.c_str());
-- }
-- else if(key == "equalitygroup")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- cs->setEqualityGroup(stringval.c_str());
-- }
-- else if(key == "bitdepth")
-- {
-- BitDepth ret;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<BitDepth>(ret))
-- cs->setBitDepth(ret);
-- }
-- else if(key == "isdata")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<bool>(boolval))
-- cs->setIsData(boolval);
-- }
-- else if(key == "allocation")
-- {
-- Allocation val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<Allocation>(val))
-- cs->setAllocation(val);
-- }
-- else if(key == "allocationvars")
-- {
-- std::vector<float> val;
-- if (iter.second().Type() != YAML::NodeType::Null)
-- {
-- iter.second() >> val;
-- if(!val.empty())
-- {
-- cs->setAllocationVars(static_cast<int>(val.size()), &val[0]);
-- }
-- }
-- }
-- else if(key == "to_reference")
-- {
-- TransformRcPtr val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformRcPtr>(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<TransformRcPtr>(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<float> 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<std::string>(stringval))
-- look->setName(stringval.c_str());
-- }
-- else if(key == "process_space")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- look->setProcessSpace(stringval.c_str());
-- }
-- else if(key == "transform")
-- {
-- TransformRcPtr val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformRcPtr>(val))
-- look->setTransform(val);
-- }
-- else if(key == "inverse_transform")
-- {
-- TransformRcPtr val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformRcPtr>(val))
-- look->setInverseTransform(val);
-- }
-- else
-- {
-- LogUnknownKeyWarning(node.Tag(), iter.first());
-- }
-+#ifdef OLDYAML
-+ node.Read<bool>(x);
-+#else
-+ x = node.as<bool>();
-+#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<int>(x);
-+#else
-+ x = node.as<int>();
-+#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<float>(x);
-+#else
-+ x = node.as<float>();
-+#endif
- }
-
-- out << YAML::EndMap;
-- out << YAML::Newline;
-+ inline void load(const YAML::Node& node, std::string& x)
-+ {
-+#ifdef OLDYAML
-+ node.Read<std::string>(x);
-+#else
-+ x = node.as<std::string>();
-+#endif
-+ }
-
-- return out;
-- }
--
--
--
-- ///////////////////////////////////////////////////////////////////////////
--
--
-- namespace
-- {
-- void EmitBaseTransformKeyValues(YAML::Emitter & out,
-- const ConstTransformRcPtr & t)
-+ inline void load(const YAML::Node& node, std::vector<std::string>& 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<std::vector<std::string> >();
-+#endif
- }
-- }
--
-- void operator >> (const YAML::Node& node, TransformRcPtr& t)
-- {
-- if(node.Type() != YAML::NodeType::Map)
-+
-+ inline void load(const YAML::Node& node, std::vector<float>& 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<std::vector<float> >();
-+#endif
- }
-
-- std::string type = node.Tag();
-+ // Enums
-
-- if(type == "AllocationTransform") {
-- AllocationTransformRcPtr temp;
-- node.Read<AllocationTransformRcPtr>(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<CDLTransformRcPtr>(temp);
-- t = temp;
-+
-+ inline void save(YAML::Emitter& out, BitDepth depth)
-+ {
-+ out << BitDepthToString(depth);
- }
-- else if(type == "ColorSpaceTransform") {
-- ColorSpaceTransformRcPtr temp;
-- node.Read<ColorSpaceTransformRcPtr>(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<ExponentTransformRcPtr>(temp);
-- t = temp;
-+
-+ inline void save(YAML::Emitter& out, Allocation alloc)
-+ {
-+ out << AllocationToString(alloc);
- }
-- else if(type == "FileTransform") {
-- FileTransformRcPtr temp;
-- node.Read<FileTransformRcPtr>(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<GroupTransformRcPtr>(temp);
-- t = temp;
-+
-+ inline void save(YAML::Emitter& out, ColorSpaceDirection dir)
-+ {
-+ out << ColorSpaceDirectionToString(dir);
- }
-- else if(type == "LogTransform") {
-- LogTransformRcPtr temp;
-- node.Read<LogTransformRcPtr>(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<LookTransformRcPtr>(temp);
-- t = temp;
-+
-+ inline void save(YAML::Emitter& out, TransformDirection dir)
-+ {
-+ out << TransformDirectionToString(dir);
- }
-- else if(type == "MatrixTransform") {
-- MatrixTransformRcPtr temp;
-- node.Read<MatrixTransformRcPtr>(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<TruelightTransformRcPtr>(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 !<tag> 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<const AllocationTransform>(t))
-- out << Allocation_tran;
-- else if(ConstCDLTransformRcPtr CDL_tran = \
-- DynamicPtrCast<const CDLTransform>(t))
-- out << CDL_tran;
-- else if(ConstColorSpaceTransformRcPtr ColorSpace_tran = \
-- DynamicPtrCast<const ColorSpaceTransform>(t))
-- out << ColorSpace_tran;
-- else if(ConstExponentTransformRcPtr Exponent_tran = \
-- DynamicPtrCast<const ExponentTransform>(t))
-- out << Exponent_tran;
-- else if(ConstFileTransformRcPtr File_tran = \
-- DynamicPtrCast<const FileTransform>(t))
-- out << File_tran;
-- else if(ConstGroupTransformRcPtr Group_tran = \
-- DynamicPtrCast<const GroupTransform>(t))
-- out << Group_tran;
-- else if(ConstLogTransformRcPtr Log_tran = \
-- DynamicPtrCast<const LogTransform>(t))
-- out << Log_tran;
-- else if(ConstLookTransformRcPtr Look_tran = \
-- DynamicPtrCast<const LookTransform>(t))
-- out << Look_tran;
-- else if(ConstMatrixTransformRcPtr Matrix_tran = \
-- DynamicPtrCast<const MatrixTransform>(t))
-- out << Matrix_tran;
-- else if(ConstTruelightTransformRcPtr Truelight_tran = \
-- DynamicPtrCast<const TruelightTransform>(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 <children.size(); ++i)
-+ 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")
- {
-- TransformRcPtr childTransform;
-- children[i].Read<TransformRcPtr>(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<TransformDirection>(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<std::string>(stringval))
-- t->setSrc(stringval.c_str());
-- }
-- else if(key == "cccid")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- t->setCCCId(stringval.c_str());
-- }
-- else if(key == "interpolation")
-- {
-- Interpolation val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<Interpolation>(val))
-- t->setInterpolation(val);
-- }
-- else if(key == "direction")
-- {
-- TransformDirection val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformDirection>(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<std::string>(stringval))
-- t->setSrc(stringval.c_str());
-- }
-- else if(key == "dst")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- t->setDst(stringval.c_str());
-- }
-- else if(key == "direction")
-- {
-- TransformDirection val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformDirection>(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<float> val;
-+ load(second, val);
-+ if(!val.empty())
-+ {
-+ t->setVars(static_cast<int>(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<std::string>(stringval))
-- t->setSrc(stringval.c_str());
-- }
-- else if(key == "dst")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- t->setDst(stringval.c_str());
-- }
-- else if(key == "looks")
-- {
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<std::string>(stringval))
-- t->setLooks(stringval.c_str());
-- }
-- else if(key == "direction")
-- {
-- TransformDirection val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformDirection>(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<float> 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<float> val;
-- if (iter.second().Type() != YAML::NodeType::Null)
-+ std::string key;
-+ std::vector<float> 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<TransformDirection>(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<float> 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<float>(val))
-- t->setBase(val);
-- }
-- else if(key == "direction")
-- {
-- TransformDirection val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformDirection>(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<float> 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<float> 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<float> 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<float> offset(3);
-+ t->getOffset(&offset[0]);
-+ if(!IsVecEqualToZero(&offset[0], 3))
- {
-- TransformDirection val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformDirection>(val))
-- t->setDirection(val);
-+ out << YAML::Key << "offset";
-+ out << YAML::Value << YAML::Flow << offset;
- }
-- else
-+
-+ std::vector<float> 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<float> 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<float> 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<float> 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<float> 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<float> 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<float>(val))
-- t->setSat(val);
-- }
-- else if(key == "direction")
-- {
-- TransformDirection val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformDirection>(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<float> 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<float> 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<float> 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<Allocation>(val))
-- t->setAllocation(val);
-- }
-- else if(key == "vars")
-- {
-- std::vector<float> 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<float> val;
-+ load(second, val);
-+ if(val.size() != 16)
- {
-- t->setVars(static_cast<int>(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<float> 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<float> matrix(16, 0.0);
-+ t->getMatrix(&matrix[0]);
-+ if(!IsM44Identity(&matrix[0]))
- {
-- TransformDirection val;
-- if (iter.second().Type() != YAML::NodeType::Null &&
-- iter.second().Read<TransformDirection>(val))
-- t->setDirection(val);
-+ out << YAML::Key << "matrix";
-+ out << YAML::Value << YAML::Flow << matrix;
- }
-- else
-+
-+ std::vector<float> 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<float> 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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<TransformDirection>(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 !<tag> 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<const AllocationTransform>(t))
-+ save(out, Allocation_tran);
-+ else if(ConstCDLTransformRcPtr CDL_tran = \
-+ DynamicPtrCast<const CDLTransform>(t))
-+ save(out, CDL_tran);
-+ else if(ConstColorSpaceTransformRcPtr ColorSpace_tran = \
-+ DynamicPtrCast<const ColorSpaceTransform>(t))
-+ save(out, ColorSpace_tran);
-+ else if(ConstExponentTransformRcPtr Exponent_tran = \
-+ DynamicPtrCast<const ExponentTransform>(t))
-+ save(out, Exponent_tran);
-+ else if(ConstFileTransformRcPtr File_tran = \
-+ DynamicPtrCast<const FileTransform>(t))
-+ save(out, File_tran);
-+ else if(ConstGroupTransformRcPtr Group_tran = \
-+ DynamicPtrCast<const GroupTransform>(t))
-+ save(out, Group_tran);
-+ else if(ConstLogTransformRcPtr Log_tran = \
-+ DynamicPtrCast<const LogTransform>(t))
-+ save(out, Log_tran);
-+ else if(ConstLookTransformRcPtr Look_tran = \
-+ DynamicPtrCast<const LookTransform>(t))
-+ save(out, Look_tran);
-+ else if(ConstMatrixTransformRcPtr Matrix_tran = \
-+ DynamicPtrCast<const MatrixTransform>(t))
-+ save(out, Matrix_tran);
-+ else if(ConstTruelightTransformRcPtr Truelight_tran = \
-+ DynamicPtrCast<const TruelightTransform>(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 !<ColorSpace> 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<float> val;
-+ load(second, val);
-+ if(!val.empty())
-+ cs->setAllocationVars(static_cast<int>(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<float> 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<float> 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<std::string> display;
-+ load(second, display);
-+ const char* displays = JoinStringEnvStyle(display).c_str();
-+ c->setActiveDisplays(displays);
-+ }
-+ else if(key == "active_views")
-+ {
-+ std::vector<std::string> 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 (- !<ColorSpace>) 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 (- !<Look>) 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<float> 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<std::string> 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<std::string> 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<std::string>(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<std::string>(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<std::string>(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<std::string>(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<std::string>(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 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- #include <OpenColorIO/OpenColorIO.h>
-
--#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 <typename T> class TypedKeyNotFound;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::ColorSpace>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::Config>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::Exception>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::GpuShaderDesc>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::ImageDesc>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::Look>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::Processor>;
--
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::Transform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::AllocationTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::CDLTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::ColorSpaceTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::DisplayTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::ExponentTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::FileTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::GroupTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::LogTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::LookTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::MatrixTransform>;
-- template <> class TypedKeyNotFound<OCIO_NAMESPACE::TruelightTransform>;
--}
--#pragma GCC visibility pop
--
--#endif
--
--#include <yaml-cpp/yaml.h>
--
- #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
-