diff options
author | Mark Riedesel <mark@klowner.com> | 2016-08-15 08:43:10 -0500 |
---|---|---|
committer | Jakub Jirutka <jakub@jirutka.cz> | 2016-08-15 18:26:26 +0200 |
commit | a696503b386fcb8b9f521af3693f85752f0e9b4a (patch) | |
tree | 2a05b91330dd555470a45da4465d072eb7a70cc0 /testing/opencolorio | |
parent | 53539e117ead530fd909bff21b1d985335a3ac4e (diff) | |
download | aports-a696503b386fcb8b9f521af3693f85752f0e9b4a.tar.bz2 aports-a696503b386fcb8b9f521af3693f85752f0e9b4a.tar.xz |
testing/opencolorio: new aport
http://opencolorio.org
A color management framework for visual effects and animation
Diffstat (limited to 'testing/opencolorio')
-rw-r--r-- | testing/opencolorio/APKBUILD | 83 | ||||
-rw-r--r-- | testing/opencolorio/temp-deref-with-yaml-0.5.0.patch | 112 | ||||
-rw-r--r-- | testing/opencolorio/yaml-cpp-0.5-support.patch | 3815 |
3 files changed, 4010 insertions, 0 deletions
diff --git a/testing/opencolorio/APKBUILD b/testing/opencolorio/APKBUILD new file mode 100644 index 0000000000..fa2187a59f --- /dev/null +++ b/testing/opencolorio/APKBUILD @@ -0,0 +1,83 @@ +# Contributor: Mark Riedesel <mark@klowner.com> +# Maintainer: Mark Riedesel <mark@klowner.com> +pkgname=opencolorio +pkgver=1.0.9 +pkgrel=0 +pkgdesc="A color management framework for visual effects and animation" +url="http://opencolorio.org" +arch="all" +license="BSD" +depends="" +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" +builddir="$srcdir/OpenColorIO-$pkgver" + +build() { + cd "$builddir" + + # Just to be sure we're using alpine dev packages + rm -f ext/lcms* ext/tinyxml* ext/yaml* + + local pyver + for pyver in python3 python2; do + mkdir build-$pyver && cd build-$pyver + + cmake .. \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DOCIO_BUILD_TRUELIGHT=OFF \ + -DOCIO_BUILD_NUKE=OFF \ + -DOCIO_BUILD_SHARED=ON \ + -DOCIO_BUILD_STATIC=OFF \ + -DPYTHON=/usr/bin/$pyver \ + -DUSE_EXTERNAL_YAML=TRUE \ + -DUSE_EXTERNAL_TINYXML=TRUE \ + -DUSE_EXTERNAL_LCMS=TRUE \ + || return 1 + make || return 1 + cd .. + done +} + +package() { + local pyver + for pyver in python3 python2; do + cd "$builddir"/build-$pyver + make DESTDIR="$pkgdir" install || return 1 + done +} + +tools() { + pkgdesc="OpenColorIO color management framework tools" + + mkdir -p "$subpkgdir"/usr/ + mv "$pkgdir"/usr/bin "$subpkgdir"/usr +} + +_python() { + pkgdesc="Python $1 bindings for OpenColorIO color management framework" + depends="python$1" + + mv "$pkgdir"$2 "$subpkgdir" +} + +py2() { + _python 2 "$(python2 -c 'import site; print(site.getsitepackages()[0])')" +} + +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" diff --git a/testing/opencolorio/temp-deref-with-yaml-0.5.0.patch b/testing/opencolorio/temp-deref-with-yaml-0.5.0.patch new file mode 100644 index 0000000000..23d971d5d6 --- /dev/null +++ b/testing/opencolorio/temp-deref-with-yaml-0.5.0.patch @@ -0,0 +1,112 @@ +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 new file mode 100644 index 0000000000..e3b51c9362 --- /dev/null +++ b/testing/opencolorio/yaml-cpp-0.5-support.patch @@ -0,0 +1,3815 @@ +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 + |