diff --git a/CMakeLists.txt b/CMakeLists.txt index a8a7df98e..38dc17253 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,22 @@ endif() set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wshadow -Wconversion -Wcast-qual -Wformat=2") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Weffc++ -Winline ") +############################################################################### +### YAML ### + +include(ExternalProject) +ExternalProject_Add(YAML_CPP_LOCAL + DOWNLOAD_DIR ext/download + URL ${CMAKE_SOURCE_DIR}/ext/yaml-cpp-0.2.5.tar.gz + BINARY_DIR ext/build + PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/ext/yaml-cpp-0.2.5.patch + INSTALL_DIR ext/dist + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/ext/dist +) +set(YAML_CPP_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/ext/dist/include/yaml-cpp) +set(YAML_CPP_LIBRARY_DIRS ${PROJECT_BINARY_DIR}/ext/dist/lib) +set(YAML_CPP_STATIC_LIBRARIES ${PROJECT_BINARY_DIR}/ext/dist/lib/libyaml-cpp.a) + ############################################################################### ### BOOST ### diff --git a/LICENSE b/LICENSE index b539fc830..ea4e8d58b 100644 --- a/LICENSE +++ b/LICENSE @@ -6,6 +6,9 @@ http://code.google.com/p/pystring/ TinyXML http://sourceforge.net/projects/tinyxml/ +yaml-cpp +http://code.google.com/p/yaml-cpp/ + PTex (Mutex), courtesy of Brent Burley and Disney http://ptex.us/ @@ -100,6 +103,30 @@ distribution. --------------------------------------------------------------------- +yaml-cpp + +Copyright (c) 2008 Jesse Beder. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +--------------------------------------------------------------------- + PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. All rights reserved diff --git a/export/OpenColorIO/OpenColorIO.h b/export/OpenColorIO/OpenColorIO.h index 7ae55c928..ba1719dda 100644 --- a/export/OpenColorIO/OpenColorIO.h +++ b/export/OpenColorIO/OpenColorIO.h @@ -215,8 +215,7 @@ OCIO_NAMESPACE_ENTER const char * getDescription() const; void setDescription(const char * description); - void writeXML(std::ostream& os) const; - + void writeToStream(std::ostream& os) const; // COLORSPACES //////////////////////////////////////////////////////// diff --git a/ext/yaml-cpp-0.2.5.patch b/ext/yaml-cpp-0.2.5.patch new file mode 100644 index 000000000..6fde06fe3 --- /dev/null +++ b/ext/yaml-cpp-0.2.5.patch @@ -0,0 +1,12 @@ +diff -Naur YAML_CPP_LOCAL.orig/CMakeLists.txt YAML_CPP_LOCAL/CMakeLists.txt +--- YAML_CPP_LOCAL.orig/CMakeLists.txt 2010-10-18 10:11:19.000000000 +1100 ++++ YAML_CPP_LOCAL/CMakeLists.txt 2010-10-18 10:11:46.000000000 +1100 +@@ -2,7 +2,7 @@ + + project (YAML_CPP) + +-set(LIB_TYPE SHARED) ++set(LIB_TYPE STATIC) + + if(IPHONE) + set(CMAKE_OSX_SYSROOT iphoneos2.2.1) diff --git a/ext/yaml-cpp-0.2.5.tar.gz b/ext/yaml-cpp-0.2.5.tar.gz new file mode 100644 index 000000000..05f09b767 Binary files /dev/null and b/ext/yaml-cpp-0.2.5.tar.gz differ diff --git a/src/core/CDLTransform.cpp b/src/core/CDLTransform.cpp index 6ef5d55ed..64651359b 100644 --- a/src/core/CDLTransform.cpp +++ b/src/core/CDLTransform.cpp @@ -53,6 +53,29 @@ OCIO_NAMESPACE_ENTER " 1 " " " " "; + + // http://ticpp.googlecode.com/svn/docs/ticpp_8h-source.html#l01670 + + void SetText( TiXmlElement* element, const char * value) + { + if ( element->NoChildren() ) + { + element->LinkEndChild( new TiXmlText( value ) ); + } + else + { + if ( 0 == element->GetText() ) + { + element->InsertBeforeChild( element->FirstChild(), TiXmlText( value ) ); + } + else + { + // There already is text, so change it + element->FirstChild()->SetValue( value ); + } + } + } + } CDLTransformRcPtr CDLTransform::Create() diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ab9047b12..98e7ccaa1 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ + ${YAML_CPP_INCLUDE_DIRS} ) file(GLOB_RECURSE core_src_files "${CMAKE_SOURCE_DIR}/src/core/*.cpp") @@ -15,8 +16,17 @@ configure_file(${CMAKE_SOURCE_DIR}/export/OpenColorIO/OpenColorVersion.h.in ${CMAKE_BINARY_DIR}/export/OpenColorVersion.h @ONLY) list(APPEND core_export_headers ${CMAKE_BINARY_DIR}/export/OpenColorVersion.h) -add_library(OpenColorIO SHARED ${core_src_files}) -install(TARGETS OpenColorIO DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) +add_library(OpenColorIO SHARED + ${core_src_files}) + +add_dependencies(OpenColorIO + YAML_CPP_LOCAL) + +target_link_libraries(OpenColorIO + ${YAML_CPP_STATIC_LIBRARIES}) + +install(TARGETS OpenColorIO DESTINATION + ${CMAKE_INSTALL_PREFIX}/lib) # TODO: RegisterFileFormat() mechanism doesn't seem to work when static linked? #add_library(OpenColorIOStatic STATIC ${core_src_files}) diff --git a/src/core/CineonLogToLinTransform.cpp b/src/core/CineonLogToLinTransform.cpp index bb0df3647..6e3e6debd 100644 --- a/src/core/CineonLogToLinTransform.cpp +++ b/src/core/CineonLogToLinTransform.cpp @@ -275,7 +275,6 @@ namespace OCIO = OCIO_NAMESPACE; #include #include -#include "tinyxml/tinyxml.h" BOOST_AUTO_TEST_SUITE( CineonLogToLinTransform_Unit_Tests ) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index bbb417622..43e242a16 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -30,6 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include @@ -42,8 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ParseUtils.h" #include "Processor.h" #include "pystring/pystring.h" -#include "tinyxml/tinyxml.h" -#include "XmlIO.h" +#include "OCIOYaml.h" OCIO_NAMESPACE_ENTER { @@ -55,15 +55,25 @@ OCIO_NAMESPACE_ENTER const float DEFAULT_LUMA_COEFF_B = 0.0722f; const char * INTERNAL_RAW_PROFILE = - "" - " " - " " - " A raw color space. Conversions to and from this " - " space are no-ops." - " " - ""; + "ocs_profile_version: 1\n" + "resource_path:\n" + "strictparsing: false\n" + "luma: [ 0.2126, 0.7152, 0.0722 ]\n" + "roles:\n" + " default: ! {colorspace: raw}\n" + "displays:\n" + " - ! {device: sRGB, name: Raw, colorspace: raw}\n" + "colorspaces:\n" + " - !\n" + " name: raw\n" + " family: raw\n" + " bitdepth: 32f\n" + " isdata: true\n" + " gpuallocation: uniform\n" + " gpumin: 0\n" + " gpumax: 1\n" + " description: 'A raw color space. Conversions to and from this space are no-ops.'\n"; + } @@ -101,6 +111,33 @@ OCIO_NAMESPACE_ENTER typedef std::vector< std::pair > RoleVec; // (lowercase role name, colorspace) typedef std::vector DisplayKey; // (device, name, colorspace) + void operator >> (const YAML::Node& node, DisplayKey& k) + { + if(node.GetTag() != "Display") + return; // not a ! tag + if(node.FindValue("device") != NULL && + node.FindValue("name") != NULL && + node.FindValue("colorspace") != NULL) + { + k.push_back(node["device"].Read()); + k.push_back(node["name"].Read()); + k.push_back(node["colorspace"].Read()); + } + // else ignore node + } + + YAML::Emitter& operator << (YAML::Emitter& out, DisplayKey disp) { + if(disp.size() != 3) return out; // invalid DisplayKey + out << YAML::VerbatimTag("Display"); + out << YAML::Flow; // on one line + out << YAML::BeginMap; + out << YAML::Key << "device" << YAML::Value << disp[0]; + out << YAML::Key << "name" << YAML::Value << disp[1]; + out << YAML::Key << "colorspace" << YAML::Value << disp[2]; + out << YAML::EndMap; + return out; + } + std::string LookupRole(const RoleVec & roleVec, const std::string & rolename) { std::string s = pystring::lower(rolename); @@ -189,8 +226,7 @@ OCIO_NAMESPACE_ENTER return *this; } - void loadXmlElement(const TiXmlElement* rootElement, - const std::string & filename); + void load(std::istream & istream); }; @@ -208,71 +244,38 @@ OCIO_NAMESPACE_ENTER ConstConfigRcPtr Config::CreateFromEnv() { - char * file = std::getenv("OCIO"); - if(file) - { - return CreateFromFile(file); - } + char* file = std::getenv("OCIO"); + if(file) return CreateFromFile(file); std::ostringstream os; os << "Color management disabled. "; os << "(Specify the $OCIO environment variable to enable.)"; ReportInfo(os.str()); - ConfigRcPtr config = Config::Create(); - - TiXmlDocument doc; - doc.Parse(INTERNAL_RAW_PROFILE); - const TiXmlElement* rootElement = doc.RootElement(); - - config->m_impl->loadXmlElement(rootElement, - "INTERNAL_RAW_PROFILE"); - return config; + std::istringstream is; + is.str(INTERNAL_RAW_PROFILE); + return CreateFromStream(is); } - ConstConfigRcPtr Config::CreateFromFile(const char * filename) { - ConfigRcPtr config = Config::Create(); - - TiXmlDocument doc(filename); - - bool loadOkay = doc.LoadFile(); - if(!loadOkay) - { + std::ifstream file(filename); + if(file.fail()) { std::ostringstream os; - os << "Error parsing ocio configuration file, '" << filename; - os << "'. " << doc.ErrorDesc(); - if(doc.ErrorRow()) - { - os << " (line " << doc.ErrorRow(); - os << ", col " << doc.ErrorCol() << ")"; - } - throw Exception(os.str().c_str()); + os << "Error could not read '" << filename; + os << "' OCIO profile."; + throw Exception (os.str().c_str()); } - - const TiXmlElement* rootElement = doc.RootElement(); - config->m_impl->loadXmlElement(rootElement, filename); - return config; + return CreateFromStream(file); } ConstConfigRcPtr Config::CreateFromStream(std::istream & istream) { ConfigRcPtr config = Config::Create(); - - std::ostringstream oss; - oss << istream.rdbuf(); - - TiXmlDocument doc; - doc.Parse(oss.str().c_str()); - const TiXmlElement* rootElement = doc.RootElement(); - config->m_impl->loadXmlElement(rootElement, "ISTREAM_PROFILE"); - + config->m_impl->load(istream); return config; } - - /////////////////////////////////////////////////////////////////////////// @@ -739,260 +742,339 @@ OCIO_NAMESPACE_ENTER std::ostream& operator<< (std::ostream& os, const Config& config) { - config.writeXML(os); + config.writeToStream(os); return os; } - - - - - - - - //////////////////////////////////////////////////////////////////////////// - // - // - // - // + /////////////////////////////////////////////////////////////////////////// // Serialization - - void Config::writeXML(std::ostream& os) const + void Config::writeToStream(std::ostream& os) const { - TiXmlDocument doc; - - TiXmlElement * element = new TiXmlElement( "ocioconfig" ); - doc.LinkEndChild( element ); - try { - element->SetAttribute("version", "1"); - element->SetAttribute("resourcepath", m_impl->resourcePath_); - element->SetAttribute("strictparsing", BoolToString(m_impl->strictParsing_)); - - // Luma coefficients - element->SetDoubleAttribute("luma_r", m_impl->defaultLumaCoefs_[0]); - element->SetDoubleAttribute("luma_g", m_impl->defaultLumaCoefs_[1]); - element->SetDoubleAttribute("luma_b", m_impl->defaultLumaCoefs_[2]); - - // Description - if(!m_impl->description_.empty()) + // serialize the config + YAML::Emitter out; + out << YAML::Block; + out << YAML::BeginMap; + out << YAML::Key << "ocs_profile_version" << YAML::Value << 1; + if(m_impl->resourcePath_.empty()) + out << YAML::Key << "resource_path" << YAML::Value << m_impl->resourcePath_; + out << YAML::Key << "strictparsing" << YAML::Value << m_impl->strictParsing_; + // TODO: should we make defaultLumaCoefs_ a std::vector to make it easier + // to serialize? + out << YAML::Key << "luma" << YAML::Value; { - TiXmlElement * descElement = new TiXmlElement( "description" ); - element->LinkEndChild( descElement ); - TiXmlText * textElement = new TiXmlText( m_impl->description_ ); - descElement->LinkEndChild( textElement ); + out << YAML::Flow; + out << YAML::BeginSeq; + for(unsigned int i = 0; i < 3; ++i) + out << m_impl->defaultLumaCoefs_[i]; + out << YAML::EndSeq; } + if(m_impl->description_.empty()) + out << YAML::Key << "description" << YAML::Value << m_impl->description_; // Roles - for(unsigned int i=0; iroleVec_.size(); ++i) + if(m_impl->roleVec_.size() > 0) { - std::string roleKey = std::string("role_") + m_impl->roleVec_[i].first; - std::string roleValue = m_impl->roleVec_[i].second; - element->SetAttribute(roleKey, roleValue); + out << YAML::Key << "roles" << YAML::Value; + out << YAML::BeginMap; + for(unsigned int i=0; iroleVec_.size(); ++i) + { + out << YAML::Key << m_impl->roleVec_[i].first; + out << YAML::Value << m_impl->roleVec_[i].second; + } + out << YAML::EndMap; } - // Display Transforms - for(unsigned int i=0; idisplayDevices_.size(); ++i) + // Displays + if(m_impl->displayDevices_.size() > 0) { - if(m_impl->displayDevices_[i].size() != 3) continue; - - TiXmlElement * childElement = new TiXmlElement( "display" ); - childElement->SetAttribute("device", m_impl->displayDevices_[i][0]); - childElement->SetAttribute("name", m_impl->displayDevices_[i][1]); - childElement->SetAttribute("colorspace", m_impl->displayDevices_[i][2]); - element->LinkEndChild( childElement ); + out << YAML::Key << "displays" << YAML::Value; + out << YAML::BeginSeq; + for(unsigned int i=0; idisplayDevices_.size(); ++i) + out << m_impl->displayDevices_[i]; + out << YAML::EndSeq; } - // Colorspaces - for(unsigned int i=0; icolorspaces_.size(); ++i) + // ColorSpaces + if(m_impl->colorspaces_.size() > 0) { - TiXmlElement * childElement = GetColorSpaceElement(m_impl->colorspaces_[i]); - element->LinkEndChild( childElement ); + out << YAML::Key << "colorspaces"; + out << YAML::Value << m_impl->colorspaces_; // std::vector -> Seq } - TiXmlPrinter printer; - printer.SetIndent(" "); - doc.Accept( &printer ); - os << printer.Str(); + out << YAML::EndMap; + os << out.c_str(); + } catch( const std::exception & e) { std::ostringstream error; - error << "Error building xml: "; - error << e.what(); + error << "Error building YAML: " << e.what(); throw Exception(error.str().c_str()); } } - - - - - //////////////////////////////////////////////////////////////////////////// - - - void Config::Impl::loadXmlElement(const TiXmlElement* rootElement, - const std::string & filename) + void Config::Impl::load(std::istream & istream) { - if(!rootElement || std::string(rootElement->Value()) != "ocioconfig") - { - std::ostringstream os; - os << "Error loading '" << filename; - os << "'. Please confirm file is 'ocioconfig' format."; - throw Exception(os.str().c_str()); - } - - int version = -1; - - int lumaSet = 0; - float lumacoef[3] = { 0.0f, 0.0f, 0.0f }; - - // Read attributes + try { - const TiXmlAttribute* pAttrib=rootElement->FirstAttribute(); - while(pAttrib) + YAML::Parser parser(istream); + YAML::Node node; + parser.GetNextDocument(node); + + // check profile version + int profile_version; + if(node.FindValue("ocs_profile_version") == NULL) + { + std::ostringstream os; + os << "Error profile doesn't contain a ocs_profile_version field."; + throw Exception (os.str().c_str()); + } + node["ocs_profile_version"] >> profile_version; + if(profile_version != 1) + { + std::ostringstream os; + os << "Error profile version " << profile_version << " is not "; + os << "supported by OCIO v" << OCIO_VERSION "."; + throw Exception (os.str().c_str()); + } + + // cast YAML nodes to Impl members + if(node.FindValue("resource_path") != NULL) + node["resource_path"] >> resourcePath_; + if(node.FindValue("strictparsing") != NULL) + node["strictparsing"] >> strictParsing_; + if(node.FindValue("description") != NULL) + node["description"] >> description_; + + // Luma + if(node.FindValue("luma") != NULL) { - std::string attrName = pystring::lower(pAttrib->Name()); - if(attrName == "version") + if(node["luma"].GetType() != YAML::CT_SEQUENCE) { - if (pAttrib->QueryIntValue(&version)!=TIXML_SUCCESS) - { - std::ostringstream os; - os << "Error parsing ocio configuration file, '" << filename; - os << "'. Could not parse integer 'version' tag."; - throw Exception(os.str().c_str()); - } + std::ostringstream os; + os << "Error parsing ocio profile, "; + os << "'luma' field needs to be a (luma: [0, 0, 0]) list."; + throw Exception(os.str().c_str()); } - else if(attrName == "resourcepath") + std::vector value; + node["luma"] >> value; + if(value.size() != 3) { - resourcePath_ = pAttrib->Value(); + std::ostringstream os; + os << "Error parsing ocio profile, 'luma' field must be 3 "; + os << "floats. Found '" << value.size() << "'."; + throw Exception(os.str().c_str()); } - else if(attrName == "strictparsing") + defaultLumaCoefs_[0] = value[0]; + defaultLumaCoefs_[1] = value[1]; + defaultLumaCoefs_[2] = value[2]; + } + else throw Exception("Error parsing ocio profile, could not find required luma field."); + + // Roles + if(node.FindValue("roles") != NULL) { + if(node["roles"].GetType() != YAML::CT_MAP) { - strictParsing_ = BoolFromString(pAttrib->Value()); + std::ostringstream os; + os << "Error parsing ocio profile, "; + os << "'roles' field needs to be a (name: key) map."; + throw Exception(os.str().c_str()); } - else if(pystring::startswith(attrName, "role_")) + for (YAML::Iterator it = node["roles"].begin(); + it != node["roles"].end(); ++it) { - std::string role = pystring::slice(attrName, - (int)std::string("role_").size()); - roleVec_.push_back( std::make_pair(role.c_str(), - pAttrib->Value())); + const std::string key = it.first(); + const YAML::Node& value = it.second(); + if(value.GetTag() == "Role" && + value.FindValue("colorspace") != NULL) + { + roleVec_.push_back(std::make_pair(key, + value["colorspace"].Read())); + } + // ignore other tags + } + + } else { + // TODO: does it matter if there are no roles defined? + } + + // Displays + if(node.FindValue("displays") != NULL) { + if(node["displays"].GetType() != YAML::CT_SEQUENCE) + { + std::ostringstream os; + os << "Error parsing ocio profile, "; + os << "'displays' field needs to be a (- !) list."; + throw Exception(os.str().c_str()); } - else if(pystring::startswith(attrName, "luma_")) + for(unsigned i = 0; i < node["displays"].size(); ++i) { - std::string channel = pystring::slice(attrName, - (int)std::string("luma_").size()); - - int channelindex = -1; - if(channel == "r") channelindex = 0; - else if(channel == "g") channelindex = 1; - else if(channel == "b") channelindex = 2; - - if(channelindex<0) - { - std::ostringstream os; - os << "Error parsing ocio configuration file, '" << filename; - os << "'. Unknown luma channel '" << channel << "'."; - throw Exception(os.str().c_str()); - } - - double dval; - if(pAttrib->QueryDoubleValue(&dval) != TIXML_SUCCESS ) + if(node["displays"][i].GetTag() == "Display") { - std::ostringstream os; - os << "Error parsing ocio configuration file, '" << filename; - os << "'. Bad luma value in channel '" << channelindex << "'."; - throw Exception(os.str().c_str()); + DisplayKey tmp; + node["displays"][i] >> tmp; + displayDevices_.push_back(tmp); } - - lumacoef[channelindex] = static_cast(dval); - ++lumaSet; - } - else - { - // TODO: unknown root attr. + // ignore other tags + // TODO: print something or set some defaults in this case } - //if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval); - - pAttrib=pAttrib->Next(); - } - } - - if(version == -1) - { - std::ostringstream os; - os << "Config does not specify a version tag. "; - os << "Please confirm ocio file is of the expect format."; - throw Exception(os.str().c_str()); - } - if(version != 1) - { - std::ostringstream os; - os << "Config is format version '" << version << "',"; - os << " but this library only supports version 1."; - throw Exception(os.str().c_str()); - } - - // Traverse children - const TiXmlElement* pElem = rootElement->FirstChildElement(); - while(pElem) - { - std::string elementtype = pElem->Value(); - if(elementtype == "colorspace") - { - ColorSpaceRcPtr cs = CreateColorSpaceFromElement( pElem ); - colorspaces_.push_back( cs ); } - else if(elementtype == "description") + else { - description_ = pElem->GetText(); + // TODO: does it matter if there are no displays defined? } - else if(elementtype == "display") - { - const char * device = pElem->Attribute("device"); - const char * name = pElem->Attribute("name"); - const char * colorspace = pElem->Attribute("colorspace"); - if(!device || !name || !colorspace) + + // ColorSpaces + if(node.FindValue("colorspaces") != NULL) { + if(node["colorspaces"].GetType() != YAML::CT_SEQUENCE) { std::ostringstream os; - os << "Error parsing ocio configuration file, '" << filename; - os << "'. Invalid specification."; + os << "Error parsing ocio profile, "; + os << "'colorspaces' field needs to be a (- !) list."; throw Exception(os.str().c_str()); } - - DisplayKey displayKey; - displayKey.push_back(std::string(device)); - displayKey.push_back(std::string(name)); - displayKey.push_back(std::string(colorspace)); - displayDevices_.push_back(displayKey); + for(unsigned i = 0; i < node["colorspaces"].size(); ++i) + { + if(node["colorspaces"][i].GetTag() == "ColorSpace") + { + ColorSpaceRcPtr cs = ColorSpace::Create(); + node["colorspaces"][i] >> cs; + colorspaces_.push_back( cs ); + } + // ignore other tags + // TODO: print something in this case + } } else { - std::cerr << "[OCIO WARNING]: Parse error, "; - std::cerr << "unknown element type '" << elementtype << "'." << std::endl; + // TODO: does it matter if there are no colorspaces defined? } - pElem=pElem->NextSiblingElement(); - } - - originalFileDir_ = path::dirname(filename); - resolvedResourcePath_ = path::join(originalFileDir_, resourcePath_); - - if(lumaSet != 3) - { - std::ostringstream os; - os << "Error parsing ocio configuration file, '" << filename; - os << "'. Could not find required ocioconfig luma_{r,g,b} xml attributes."; - throw Exception(os.str().c_str()); + // TODO: what are these used for? + //originalFileDir_ = path::dirname(filename); + //resolvedResourcePath_ = path::join(originalFileDir_, resourcePath_); + } - else + catch( const std::exception & e) { - defaultLumaCoefs_[0] = lumacoef[0]; - defaultLumaCoefs_[1] = lumacoef[1]; - defaultLumaCoefs_[2] = lumacoef[2]; + std::ostringstream error; + error << "Error parsing YAML: " << e.what(); + throw Exception(error.str().c_str()); } + + return; } } OCIO_NAMESPACE_EXIT + +/////////////////////////////////////////////////////////////////////////////// + +#ifdef OCIO_UNIT_TEST + +namespace OCIO = OCIO_NAMESPACE; +#include + +BOOST_AUTO_TEST_SUITE( Config_Unit_Tests ) + +BOOST_AUTO_TEST_CASE ( test_INTERNAL_RAW_PROFILE ) +{ + std::istringstream is; + is.str(OCIO::INTERNAL_RAW_PROFILE); + BOOST_CHECK_NO_THROW(OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromStream(is)); +} + +BOOST_AUTO_TEST_CASE ( test_simpleConfig ) +{ + + std::string SIMPLE_PROFILE = + "ocs_profile_version: 1\n" + "strictparsing: false\n" + "luma: [0.2126, 0.7152, 0.0722]\n" + "roles:\n" + " compositing_log: lgh\n" + " default: raw\n" + " scene_linear: lnh\n" + "displays:\n" + " - ! {device: sRGB, name: Film1D, colorspace: vd8}\n" + " - ! {device: sRGB, name: Log, colorspace: lg10}\n" + " - ! {device: sRGB, name: Raw, colorspace: raw}\n" + "colorspaces:\n" + " - !\n" + " name: raw\n" + " family: raw\n" + " bitdepth: 32f\n" + " description: |\n" + " A raw color space. Conversions to and from this space are no-ops.\n" + " isdata: true\n" + " gpuallocation: uniform\n" + " gpumin: 0\n" + " gpumax: 1\n" + " - !\n" + " name: lnh\n" + " family: ln\n" + " bitdepth: 16f\n" + " description: |\n" + " The show reference space. This is a sensor referred linear\n" + " representation of the scene with primaries that correspond to\n" + " scanned film. 0.18 in this space corresponds to a properly\n" + " exposed 18% grey card.\n" + " isdata: false\n" + " gpuallocation: lg2\n" + " gpumin: -15\n" + " gpumax: 6\n" + " - !\n" + " name: loads_of_transforms\n" + " family: vd8\n" + " bitdepth: 8ui\n" + " description: 'how many transforms can we use?'\n" + " isdata: false\n" + " gpuallocation: uniform\n" + " gpumin: 0\n" + " gpumax: 1\n" + " to_reference:\n" + " - !\n" + " src: diffusemult.spimtx\n" + " interpolation: unknown\n" + " - !\n" + " src: vd8\n" + " dst: lnh\n" + " - !\n" + " value: [2.2, 2.2, 2.2, 1]\n" + " - !\n" + " max_aim_density: [2.046, 2.046, 2.046]\n" + " neg_gamma: [0.6, 0.6, 0.6]\n" + " neg_gray_reference: [0.435, 0.435, 0.435]\n" + " linear_gray_reference: [0.18, 0.18, 0.18]\n" + " - !\n" + " matrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]\n" + " offset: [0, 0, 0, 0]\n" + " - !\n" + " slope: [1, 1, 1]\n" + " offset: [0, 0, 0]\n" + " power: [1, 1, 1]\n" + " saturation: 1\n" + "\n"; + + std::istringstream is; + is.str(SIMPLE_PROFILE); + OCIO::ConstConfigRcPtr config; + BOOST_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); + //config = OCIO::Config::CreateFromStream(is); + + //OCIO::ConstColorSpaceRcPtr lnh = config->getColorSpace("lnh"); + //std::cerr << "getDescription: [" << lnh->getDescription() << "]\n"; + //OCIO::ConstGroupTransformRcPtr toref = lnh->getTransform(OCIO::COLORSPACE_DIR_TO_REFERENCE); + //std::cerr << "foo.to_ref.size: [" << toref->size() << "]\n"; + + //std::ostringstream os; + //config->writeToStream(os); + //std::cerr << os.str() << std::endl;; + +} + +BOOST_AUTO_TEST_SUITE_END() + +#endif // OCIO_UNIT_TEST diff --git a/src/core/OCIOYaml.cpp b/src/core/OCIOYaml.cpp new file mode 100644 index 000000000..86a2ec51e --- /dev/null +++ b/src/core/OCIOYaml.cpp @@ -0,0 +1,595 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include "OCIOYaml.h" + +OCIO_NAMESPACE_ENTER +{ + + /////////////////////////////////////////////////////////////////////////// + // Core + + void operator >> (const YAML::Node& node, ColorSpaceRcPtr& cs) + { + if(node.GetTag() != "ColorSpace") + return; // not a ! tag + if(node.FindValue("name") != NULL) + cs->setName(node["name"].Read().c_str()); + if(node.FindValue("description") != NULL) + cs->setDescription(node["description"].Read().c_str()); + if(node.FindValue("family") != NULL) + cs->setFamily(node["family"].Read().c_str()); + if(node.FindValue("bitdepth") != NULL) + cs->setBitDepth(node["bitdepth"].Read()); + if(node.FindValue("isdata") != NULL) + cs->setIsData(node["isdata"].Read()); + if(node.FindValue("gpuallocation") != NULL) + cs->setGpuAllocation(node["gpuallocation"].Read()); + if(node.FindValue("gpumin") != NULL) + cs->setGpuMin(node["gpumin"].Read()); + if(node.FindValue("gpumax") != NULL) + cs->setGpuMax(node["gpumax"].Read()); + if(node.FindValue("to_reference") != NULL) + cs->setTransform(node["to_reference"].Read(), + COLORSPACE_DIR_TO_REFERENCE); + if(node.FindValue("from_reference") != NULL) + cs->setTransform(node["from_reference"].Read(), + COLORSPACE_DIR_TO_REFERENCE); + } + + 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 << "bitdepth" << YAML::Value << cs->getBitDepth(); + if(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 << "gpuallocation" << YAML::Value << cs->getGpuAllocation(); + out << YAML::Key << "gpumin" << YAML::Value << cs->getGpuMin(); + out << YAML::Key << "gpumax" << YAML::Value << cs->getGpuMax(); + + ConstGroupTransformRcPtr toref = \ + cs->getTransform(COLORSPACE_DIR_TO_REFERENCE); + if(cs->isTransformSpecified(COLORSPACE_DIR_TO_REFERENCE) + && !toref->empty()) + out << YAML::Key << "to_reference" << YAML::Value << YAML::Indent(4) << toref; + + ConstGroupTransformRcPtr fromref = \ + cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE); + if(cs->isTransformSpecified(COLORSPACE_DIR_FROM_REFERENCE) + && !fromref->empty()) + out << YAML::Key << "from_reference" << YAML::Value << YAML::Indent(4) << fromref; + + out << YAML::EndMap; + + return out; + } + + void operator >> (const YAML::Node& node, GroupTransformRcPtr& t) + { + t = GroupTransform::Create(); + for(unsigned i = 0; i < node.size(); ++i) + t->push_back(node[i].Read()); + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstGroupTransformRcPtr t) + { + out << YAML::BeginSeq; + for(int i = 0; i < t->size(); ++i) + out << t->getTransform(i); + out << YAML::EndSeq; + return out; + } + + void operator >> (const YAML::Node& node, TransformRcPtr& t) + { + // TODO: when a Transform() types are registered, add logic here so that + // it calls the correct Transform()::Create() for the ! type + std::string type = node.GetTag(); + + // TODO: GroupTransform seems to be a mixed concept, maybe this could + // be made a little clearer so that it's diffrent than other Transform()s + // I would go from some like TransformChain() or TransformList() + //if(type == "GroupTransform") + // t = node.Read(); + + // TODO: add DisplayTransform + if(type == "FileTransform") + t = node.Read(); + else if(type == "MatrixTransform") + t = node.Read(); + else if(type == "ExponentTransform") + t = node.Read(); + else if(type == "ColorSpaceTransform") + t = node.Read(); + else if(type == "CineonLogToLinTransform") + t = node.Read(); + else if(type == "CDLTransform") + t = node.Read(); + else + { + // TODO: add a new empty (better name?) aka passthru Transform() + // which does nothing. This is so upsupported ! types don't + // throw an exception. Alternativly this could be caught in the + // GroupTransformRcPtr >> operator with some type of + // supported_tag() method + // t = EmptyTransformRcPtr(new EmptyTransform(), &deleter); + std::ostringstream os; + os << "Unsupported transform type !<" << type << "> in OCIO profile"; + throw Exception(os.str().c_str()); + } + + // + if(node.FindValue("direction") != NULL) + t->setDirection(node["direction"].Read()); + else + t->setDirection(TRANSFORM_DIR_FORWARD); + + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstTransformRcPtr t) + { + + // TODO: GroupTransform seems to be a mixed concept see comment above. + /* + if(ConstGroupTransformRcPtr Group_tran = \ + DynamicPtrCast(t)) + out << Group_tran; + */ + + /* + else if(ConstDisplayTransformRcPtr tran = \ + DynamicPtrCast(t)) + out << Display_tran; + else + */ + if(ConstCineonLogToLinTransformRcPtr CineonLogToLin_tran = \ + DynamicPtrCast(t)) + out << CineonLogToLin_tran; + else if(ConstColorSpaceTransformRcPtr ColorSpace_tran = \ + DynamicPtrCast(t)) + out << ColorSpace_tran; + else if(ConstExponentTransformRcPtr Exponent_tran = \ + DynamicPtrCast(t)) + out << Exponent_tran; + else if(ConstFileTransformRcPtr File_tran = \ + DynamicPtrCast(t)) + out << File_tran; + else if(ConstMatrixTransformRcPtr tran = \ + DynamicPtrCast(t)) + out << tran; + else if(ConstCDLTransformRcPtr CDL_tran = \ + DynamicPtrCast(t)) + out << CDL_tran; + else + throw Exception("Unsupported Transform() type for serialization."); + return out; + } + + /////////////////////////////////////////////////////////////////////////// + // Transforms + + void operator >> (const YAML::Node& node, FileTransformRcPtr& t) + { + t = FileTransform::Create(); + if(node.FindValue("src") != NULL) + t->setSrc(node["src"].Read().c_str()); + if(node.FindValue("interpolation") != NULL) + t->setInterpolation(node["interpolation"].Read()); + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstFileTransformRcPtr t) + { + out << YAML::VerbatimTag("FileTransform"); + out << YAML::BeginMap; + out << YAML::Key << "src" << YAML::Value << t->getSrc(); + out << YAML::Key << "interpolation"; + out << YAML::Value << t->getInterpolation(); + out << YAML::EndMap; + return out; + } + + void operator >> (const YAML::Node& node, ColorSpaceTransformRcPtr& t) + { + t = ColorSpaceTransform::Create(); + if(node.FindValue("src") != NULL) + t->setSrc(node["src"].Read().c_str()); + if(node.FindValue("dst") != NULL) + t->setDst(node["dst"].Read().c_str()); + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstColorSpaceTransformRcPtr t) + { + out << YAML::VerbatimTag("ColorSpaceTransform"); + out << YAML::BeginMap; + out << YAML::Key << "src" << YAML::Value << t->getSrc(); + out << YAML::Key << "dst" << YAML::Value << t->getDst(); + out << YAML::EndMap; + return out; + } + + void operator >> (const YAML::Node& node, ExponentTransformRcPtr& t) + { + t = ExponentTransform::Create(); + if(node.FindValue("value") != NULL) + { + std::vector value; + node["value"] >> value; + if(value.size() != 4) + { + std::ostringstream os; + os << "ExponentTransform parse error, value field must be 4 "; + os << "floats. Found '" << value.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setValue(&value[0]); + } + else throw Exception("ExponentTransform doesn't have a 'value:' specified."); + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstExponentTransformRcPtr t) + { + out << YAML::VerbatimTag("ExponentTransform"); + out << YAML::BeginMap; + std::vector value(4, 0.0); + t->getValue(&value[0]); + out << YAML::Key << "value"; + out << YAML::Value << YAML::Flow << value; + out << YAML::EndMap; + return out; + } + + void operator >> (const YAML::Node& node, CineonLogToLinTransformRcPtr& t) + { + t = CineonLogToLinTransform::Create(); + + // max_aim_density + if(node.FindValue("max_aim_density") != NULL) + { + std::vector value; + node["max_aim_density"] >> value; + if(value.size() != 3) + { + std::ostringstream os; + os << "CineonLogToLinTransform parse error, 'max_aim_density' "; + os << "field must be 3 floats. Found '" << value.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setMaxAimDensity(&value[0]); + } + else throw Exception("CineonLogToLinTransform doesn't have a 'max_aim_density:' specified."); + + // neg_gamma + if(node.FindValue("neg_gamma") != NULL) + { + std::vector value; + node["neg_gamma"] >> value; + if(value.size() != 3) + { + std::ostringstream os; + os << "CineonLogToLinTransform parse error, 'neg_gamma' "; + os << "field must be 3 floats. Found '" << value.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setNegGamma(&value[0]); + } + else throw Exception("CineonLogToLinTransform doesn't have a 'neg_gamma:' specified."); + + // neg_gray_reference + if(node.FindValue("neg_gray_reference") != NULL) + { + std::vector value; + node["neg_gray_reference"] >> value; + if(value.size() != 3) + { + std::ostringstream os; + os << "CineonLogToLinTransform parse error, 'neg_gray_reference' "; + os << "field must be 3 floats. Found '" << value.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setNegGrayReference(&value[0]); + } + else throw Exception("CineonLogToLinTransform doesn't have a 'neg_gray_reference:' specified."); + + // linear_gray_reference + if(node.FindValue("linear_gray_reference") != NULL) + { + std::vector value; + node["linear_gray_reference"] >> value; + if(value.size() != 3) + { + std::ostringstream os; + os << "CineonLogToLinTransform parse error, 'linear_gray_reference' "; + os << "field must be 3 floats. Found '" << value.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setLinearGrayReference(&value[0]); + } + else throw Exception("CineonLogToLinTransform doesn't have a 'linear_gray_reference:' specified."); + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstCineonLogToLinTransformRcPtr t) + { + + out << YAML::VerbatimTag("CineonLogToLinTransform"); + out << YAML::BeginMap; + + std::vector max_aim_density(3, 0.0); + t->getMaxAimDensity(&max_aim_density[0]); + out << YAML::Key << "max_aim_density"; + out << YAML::Value << YAML::Flow << max_aim_density; + + std::vector neg_gamma(3, 0.0); + t->getNegGamma(&neg_gamma[0]); + out << YAML::Key << "neg_gamma"; + out << YAML::Value << YAML::Flow << neg_gamma; + + std::vector neg_gray_reference(3, 0.0); + t->getNegGrayReference(&neg_gray_reference[0]); + out << YAML::Key << "neg_gray_reference"; + out << YAML::Value << YAML::Flow << neg_gray_reference; + + std::vector linear_gray_reference(3, 0.0); + t->getLinearGrayReference(&linear_gray_reference[0]); + out << YAML::Key << "linear_gray_reference"; + out << YAML::Value << YAML::Flow << linear_gray_reference; + + out << YAML::EndMap; + + return out; + } + + void operator >> (const YAML::Node& node, MatrixTransformRcPtr& t) + { + t = MatrixTransform::Create(); + + std::vector matrix; + std::vector offset; + + // matrix + if(node.FindValue("matrix") != NULL) + { + node["matrix"] >> matrix; + if(matrix.size() != 16) + { + std::ostringstream os; + os << "MatrixTransform parse error, 'matrix' field must be 16 "; + os << "floats. Found '" << matrix.size() << "'."; + throw Exception(os.str().c_str()); + } + } + else throw Exception("MatrixTransform doesn't have a 'matrix:' specified."); + + // offset + if(node.FindValue("offset") != NULL) + { + node["offset"] >> offset; + if(offset.size() != 4) + { + std::ostringstream os; + os << "MatrixTransform parse error, 'offset' field must be 4 "; + os << "floats. Found '" << offset.size() << "'."; + throw Exception(os.str().c_str()); + } + } + else throw Exception("MatrixTransform doesn't have a 'offset:' specified."); + + t->setValue(&matrix[0], &offset[0]); + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstMatrixTransformRcPtr t) + { + std::vector matrix(16, 0.0); + std::vector offset(4, 0.0); + t->getValue(&matrix[0], &offset[0]); + + out << YAML::VerbatimTag("MatrixTransform"); + out << YAML::BeginMap; + out << YAML::Key << "matrix"; + out << YAML::Value << YAML::Flow << matrix; + out << YAML::Key << "offset"; + out << YAML::Value << YAML::Flow << offset; + out << YAML::EndMap; + return out; + } + + void operator >> (const YAML::Node& node, CDLTransformRcPtr& t) + { + t = CDLTransform::Create(); + + if(node.FindValue("slope") != NULL) + { + std::vector slope; + node["slope"] >> slope; + if(slope.size() != 3) + { + std::ostringstream os; + os << "CDLTransform parse error, 'slope' field must be 3 "; + os << "floats. Found '" << slope.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setSlope(&slope[0]); + } + else throw Exception("CDLTransform doesn't have a 'slope:' specified."); + + if(node.FindValue("offset") != NULL) + { + std::vector offset; + node["offset"] >> offset; + if(offset.size() != 3) + { + std::ostringstream os; + os << "CDLTransform parse error, 'offset' field must be 3 "; + os << "floats. Found '" << offset.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setOffset(&offset[0]); + } + else throw Exception("CDLTransform doesn't have a 'offset:' specified."); + + if(node.FindValue("power") != NULL) + { + std::vector power; + node["power"] >> power; + if(power.size() != 3) + { + std::ostringstream os; + os << "CDLTransform parse error, 'power' field must be 3 "; + os << "floats. Found '" << power.size() << "'."; + throw Exception(os.str().c_str()); + } + t->setPower(&power[0]); + } + else throw Exception("CDLTransform doesn't have a 'power:' specified."); + + if(node.FindValue("saturation") != NULL) + t->setSat(node["saturation"].Read()); + else + throw Exception("CDLTransform doesn't have a 'saturation:' specified."); + + } + + YAML::Emitter& operator << (YAML::Emitter& out, ConstCDLTransformRcPtr t) + { + std::vector slope(3, 1.0); + t->getSlope(&slope[0]); + std::vector offset(3, 0.0); + t->getOffset(&offset[0]); + std::vector power(3, 1.0); + t->getPower(&power[0]); + + out << YAML::VerbatimTag("CDLTransform"); + out << YAML::BeginMap; + out << YAML::Key << "slope"; + out << YAML::Value << YAML::Flow << slope; + out << YAML::Key << "offset"; + out << YAML::Value << YAML::Flow << offset; + out << YAML::Key << "power"; + out << YAML::Value << YAML::Flow << power; + out << YAML::Key << "saturation" << YAML::Value << t->getSat(); + out << YAML::EndMap; + return out; + } + + /////////////////////////////////////////////////////////////////////////// + // Enums + + YAML::Emitter& operator << (YAML::Emitter& out, BitDepth depth) { + if(depth == BIT_DEPTH_UINT8) out << "8ui"; + else if(depth == BIT_DEPTH_UINT10) out << "10ui"; + else if(depth == BIT_DEPTH_UINT12) out << "12ui"; + else if(depth == BIT_DEPTH_UINT14) out << "14ui"; + else if(depth == BIT_DEPTH_UINT16) out << "16ui"; + else if(depth == BIT_DEPTH_UINT32) out << "32ui"; + else if(depth == BIT_DEPTH_F16) out << "16f"; + else if(depth == BIT_DEPTH_F32) out << "32f"; + else out << "unknown"; + return out; + } + + void operator >> (const YAML::Node& node, BitDepth& depth) { + std::string str = node.Read(); + if(str == "8ui") depth = BIT_DEPTH_UINT8; + else if(str == "10ui") depth = BIT_DEPTH_UINT10; + else if(str == "12ui") depth = BIT_DEPTH_UINT12; + else if(str == "14ui") depth = BIT_DEPTH_UINT14; + else if(str == "16ui") depth = BIT_DEPTH_UINT16; + else if(str == "32ui") depth = BIT_DEPTH_UINT32; + else if(str == "16f") depth = BIT_DEPTH_F16; + else if(str == "32f") depth = BIT_DEPTH_F32; + else depth = BIT_DEPTH_UNKNOWN; + } + + YAML::Emitter& operator << (YAML::Emitter& out, GpuAllocation alloc) { + if(alloc == GPU_ALLOCATION_UNIFORM) out << "uniform"; + else if(alloc == GPU_ALLOCATION_LG2) out << "lg2"; + else out << "unknown"; + return out; + } + + void operator >> (const YAML::Node& node, GpuAllocation& alloc) { + std::string str = node.Read(); + if(str == "uniform") alloc = GPU_ALLOCATION_UNIFORM; + else if(str == "lg2") alloc = GPU_ALLOCATION_LG2; + else alloc = GPU_ALLOCATION_UNKNOWN; + } + + YAML::Emitter& operator << (YAML::Emitter& out, ColorSpaceDirection dir) { + if(dir == COLORSPACE_DIR_TO_REFERENCE) out << "to_reference"; + else if(dir == COLORSPACE_DIR_FROM_REFERENCE) out << "from_reference"; + else out << "unknown"; + return out; + } + + void operator >> (const YAML::Node& node, ColorSpaceDirection& dir) { + std::string str = node.Read(); + if(str == "to_reference") dir = COLORSPACE_DIR_TO_REFERENCE; + else if(str == "from_reference") dir = COLORSPACE_DIR_FROM_REFERENCE; + else dir = COLORSPACE_DIR_UNKNOWN; + } + + YAML::Emitter& operator << (YAML::Emitter& out, TransformDirection dir) { + if(dir == TRANSFORM_DIR_FORWARD) out << "forward"; + else if(dir == TRANSFORM_DIR_INVERSE) out << "inverse"; + else out << "unknown"; + return out; + } + + void operator >> (const YAML::Node& node, TransformDirection& dir) { + std::string str = node.Read(); + if(str == "forward") dir = TRANSFORM_DIR_FORWARD; + else if(str == "inverse") dir = TRANSFORM_DIR_INVERSE; + else dir = TRANSFORM_DIR_UNKNOWN; + } + + YAML::Emitter& operator << (YAML::Emitter& out, Interpolation iterp) { + if(iterp == INTERP_NEAREST) out << "nearest"; + else if(iterp == INTERP_LINEAR) out << "linear"; + else out << "unknown"; + return out; + } + + void operator >> (const YAML::Node& node, Interpolation& iterp) { + std::string str = node.Read(); + if(str == "nearest") iterp = INTERP_NEAREST; + else if(str == "linear") iterp = INTERP_LINEAR; + else iterp = INTERP_UNKNOWN; + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/core/OCIOYaml.h b/src/core/OCIOYaml.h new file mode 100644 index 000000000..c1a450ba6 --- /dev/null +++ b/src/core/OCIOYaml.h @@ -0,0 +1,77 @@ +/* +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 + +// TODO: Add the OCIO_NAMESPACE to yaml-cpp +#include + +#ifndef INCLUDED_OCIO_YAML_H +#define INCLUDED_OCIO_YAML_H + +OCIO_NAMESPACE_ENTER +{ + + // Core + void operator >> (const YAML::Node& node, ColorSpaceRcPtr& cs); + YAML::Emitter& operator << (YAML::Emitter& out, ColorSpaceRcPtr cs); + void operator >> (const YAML::Node& node, GroupTransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstGroupTransformRcPtr t); + void operator >> (const YAML::Node& node, TransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstTransformRcPtr t); + + // Transforms + void operator >> (const YAML::Node& node, FileTransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstFileTransformRcPtr t); + void operator >> (const YAML::Node& node, ColorSpaceTransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstColorSpaceTransformRcPtr t); + void operator >> (const YAML::Node& node, ExponentTransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstExponentTransformRcPtr t); + void operator >> (const YAML::Node& node, CineonLogToLinTransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstCineonLogToLinTransformRcPtr t); + void operator >> (const YAML::Node& node, MatrixTransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstMatrixTransformRcPtr t); + void operator >> (const YAML::Node& node, CDLTransformRcPtr& t); + YAML::Emitter& operator << (YAML::Emitter& out, ConstCDLTransformRcPtr t); + + // Enums + YAML::Emitter& operator << (YAML::Emitter& out, BitDepth depth); + void operator >> (const YAML::Node& node, BitDepth& depth); + YAML::Emitter& operator << (YAML::Emitter& out, GpuAllocation alloc); + void operator >> (const YAML::Node& node, GpuAllocation& alloc); + YAML::Emitter& operator << (YAML::Emitter& out, ColorSpaceDirection dir); + void operator >> (const YAML::Node& node, ColorSpaceDirection& dir); + YAML::Emitter& operator << (YAML::Emitter& out, TransformDirection dir); + void operator >> (const YAML::Node& node, TransformDirection& dir); + YAML::Emitter& operator << (YAML::Emitter& out, Interpolation iterp); + void operator >> (const YAML::Node& node, Interpolation& iterp); + +} +OCIO_NAMESPACE_EXIT + +#endif // INCLUDED_OCIO_YAML_H diff --git a/src/core/ParseUtils.cpp b/src/core/ParseUtils.cpp index f18933992..3652c81fc 100644 --- a/src/core/ParseUtils.cpp +++ b/src/core/ParseUtils.cpp @@ -29,9 +29,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "pystring/pystring.h" -#include "tinyxml/tinyxml.h" #include +#include OCIO_NAMESPACE_ENTER { @@ -187,37 +187,6 @@ OCIO_NAMESPACE_ENTER const char * ROLE_COMPOSITING_LOG = "compositing_log"; const char * ROLE_COLOR_TIMING = "color_timing"; - - - ////////////////////////////////////////////////////////////////////////// - - - // http://ticpp.googlecode.com/svn/docs/ticpp_8h-source.html#l01670 - - void SetText( TiXmlElement* element, const char * value) - { - if ( element->NoChildren() ) - { - element->LinkEndChild( new TiXmlText( value ) ); - } - else - { - if ( 0 == element->GetText() ) - { - element->InsertBeforeChild( element->FirstChild(), TiXmlText( value ) ); - } - else - { - // There already is text, so change it - element->FirstChild()->SetValue( value ); - } - } - } - - - - ////////////////////////////////////////////////////////////////////////// - namespace { const int FLOAT_DECIMALS = 7; diff --git a/src/core/ParseUtils.h b/src/core/ParseUtils.h index a43374910..5bbc67fd9 100644 --- a/src/core/ParseUtils.h +++ b/src/core/ParseUtils.h @@ -37,9 +37,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OCIO_NAMESPACE_ENTER { - class TiXmlElement; - - void SetText( TiXmlElement* element, const char * value); std::string FloatToString(float fval); std::string FloatVecToString(const float * fval, unsigned int size); diff --git a/src/core/XmlIO.cpp b/src/core/XmlIO.cpp deleted file mode 100644 index 5949613df..000000000 --- a/src/core/XmlIO.cpp +++ /dev/null @@ -1,879 +0,0 @@ -/* -Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. -All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -* Neither the name of Sony Pictures Imageworks nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include - -#include "MathUtils.h" -#include "ParseUtils.h" -#include "pystring/pystring.h" -#include "tinyxml/tinyxml.h" -#include "XmlIO.h" - -OCIO_NAMESPACE_ENTER -{ - namespace - { - TiXmlElement * CreateTransformXML(const ConstTransformRcPtr& transform); - - TransformRcPtr CreateTransform(const TiXmlElement * element); - - - - - - - - - void WriteBaseTransformXML(TiXmlElement * element, const ConstTransformRcPtr & t) - { - if(!element) return; - - if(t->getDirection() != TRANSFORM_DIR_FORWARD) - { - const char * dir = TransformDirectionToString(t->getDirection()); - element->SetAttribute("direction", dir); - } - } - - void ReadBaseTransformXML(TransformRcPtr t, const TiXmlElement * element) - { - if(!element) return; - - const char * direction = element->Attribute("direction"); - if(direction) - { - t->setDirection( TransformDirectionFromString(direction) ); - } - else - { - t->setDirection( TRANSFORM_DIR_FORWARD ); - } - } - - - - - - - /////////////////////////////////////////////////////////////////////// - // - // CineonLogToLinTransform - - CineonLogToLinTransformRcPtr CreateCineonLogToLinTransform(const TiXmlElement * element) - { - if(!element) - throw Exception("CreateCineonLogToLin received null XmlElement."); - - if(std::string(element->Value()) != "cineonlogtolin") - { - std::ostringstream os; - os << "HandleElement passed incorrect element type '"; - os << element->Value() << "'. "; - os << "Expected 'cineonlogtolin'."; - throw Exception(os.str().c_str()); - } - - CineonLogToLinTransformRcPtr t = CineonLogToLinTransform::Create(); - ReadBaseTransformXML(t, element); - - const char * cstr = 0; - - cstr = element->Attribute("max_aim_density"); - if(cstr) - { - std::vector parts; - std::vector value; - pystring::split(pystring::strip(cstr), parts); - - if(!StringVecToFloatVec(value, parts) || value.size() != 3) - { - std::ostringstream os; - os << "cineonlogtolin parse error. "; - os << "max_aim_density attribute must be 3 floats."; - os << "Found, '" << cstr << "'. "; - throw Exception(os.str().c_str()); - } - - t->setMaxAimDensity(&value[0]); - } - - cstr = element->Attribute("neg_gamma"); - if(cstr) - { - std::vector parts; - std::vector value; - pystring::split(pystring::strip(cstr), parts); - - if(!StringVecToFloatVec(value, parts) || value.size() != 3) - { - std::ostringstream os; - os << "cineonlogtolin parse error. "; - os << "neg_gamma attribute must be 3 floats."; - os << "Found, '" << cstr << "'. "; - throw Exception(os.str().c_str()); - } - - t->setNegGamma(&value[0]); - } - - cstr = element->Attribute("neg_gray_reference"); - if(cstr) - { - std::vector parts; - std::vector value; - pystring::split(pystring::strip(cstr), parts); - - if(!StringVecToFloatVec(value, parts) || value.size() != 3) - { - std::ostringstream os; - os << "cineonlogtolin parse error. "; - os << "neg_gray_reference attribute must be 3 floats."; - os << "Found, '" << cstr << "'. "; - throw Exception(os.str().c_str()); - } - - t->setNegGrayReference(&value[0]); - } - - cstr = element->Attribute("linear_gray_reference"); - if(cstr) - { - std::vector parts; - std::vector value; - pystring::split(pystring::strip(cstr), parts); - - if(!StringVecToFloatVec(value, parts) || value.size() != 3) - { - std::ostringstream os; - os << "cineonlogtolin parse error. "; - os << "linear_gray_reference attribute must be 3 floats."; - os << "Found, '" << cstr << "'. "; - throw Exception(os.str().c_str()); - } - - t->setLinearGrayReference(&value[0]); - } - - return t; - } - - ConstCineonLogToLinTransformRcPtr GetDefaultCineonLogToLinTransform() - { - static ConstCineonLogToLinTransformRcPtr cineonlogtolintransform_ = \ - CineonLogToLinTransform::Create(); - return cineonlogtolintransform_; - } - - TiXmlElement * CreateCineonLogToLinTransformXML(const ConstCineonLogToLinTransformRcPtr & t) - { - ConstCineonLogToLinTransformRcPtr t_default = GetDefaultCineonLogToLinTransform(); - - TiXmlElement * element = new TiXmlElement( "cineonlogtolin" ); - WriteBaseTransformXML(element, t); - - float value[3] = { 0.0f, 0.0f, 0.0f }; - float value_default[3] = { 0.0f, 0.0f, 0.0f }; - - { - t->getMaxAimDensity(value); - t_default->getMaxAimDensity(value_default); - - std::string value_str = FloatVecToString(value, 3); - if(value_str != FloatVecToString(value_default, 3)) - element->SetAttribute("max_aim_density",value_str); - } - - { - t->getNegGamma(value); - t_default->getNegGamma(value_default); - - std::string value_str = FloatVecToString(value, 3); - if(value_str != FloatVecToString(value_default, 3)) - element->SetAttribute("neg_gamma",value_str); - } - - { - t->getNegGrayReference(value); - t_default->getNegGrayReference(value_default); - - std::string value_str = FloatVecToString(value, 3); - if(value_str != FloatVecToString(value_default, 3)) - element->SetAttribute("neg_gray_reference",value_str); - } - - { - t->getLinearGrayReference(value); - t_default->getLinearGrayReference(value_default); - - std::string value_str = FloatVecToString(value, 3); - if(value_str != FloatVecToString(value_default, 3)) - element->SetAttribute("linear_gray_reference",value_str); - } - - return element; - } - - - - - - - - - - /////////////////////////////////////////////////////////////////////// - // - // Exponent Transform - - ExponentTransformRcPtr CreateExponentTransform(const TiXmlElement * element) - { - if(!element) - throw Exception("CreateExponentTransform received null XmlElement."); - - if(std::string(element->Value()) != "exponent") - { - std::ostringstream os; - os << "HandleElement passed incorrect element type '"; - os << element->Value() << "'. "; - os << "Expected 'exponent'."; - throw Exception(os.str().c_str()); - } - - ExponentTransformRcPtr t = ExponentTransform::Create(); - ReadBaseTransformXML(t, element); - - const char * cstr = 0; - - cstr = element->Attribute("value"); - if(cstr) - { - std::vector parts; - std::vector value; - pystring::split(pystring::strip(cstr), parts); - - if(!StringVecToFloatVec(value, parts) || value.size() != 4) - { - std::ostringstream os; - os << "exponent parse error. "; - os << "value attribute must be 4 floats."; - os << "Found, '" << cstr << "'. "; - throw Exception(os.str().c_str()); - } - - t->setValue(&value[0]); - } - - return t; - } - - ConstExponentTransformRcPtr GetDefaultExponentTransform() - { - static ConstExponentTransformRcPtr exponenttransform_ = \ - ExponentTransform::Create(); - return exponenttransform_; - } - - TiXmlElement * CreateExponentTransformXML(const ConstExponentTransformRcPtr & t) - { - ConstExponentTransformRcPtr t_default = GetDefaultExponentTransform(); - - TiXmlElement * element = new TiXmlElement( "exponent" ); - WriteBaseTransformXML(element, t); - - float value[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - float value_default[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - { - t->getValue(value); - t_default->getValue(value_default); - - std::string value_str = FloatVecToString(value, 4); - if(value_str != FloatVecToString(value_default, 4)) - element->SetAttribute("value", value_str); - } - - return element; - } - - - - - /////////////////////////////////////////////////////////////////////// - // - // FileTransform - - FileTransformRcPtr CreateFileTransform(const TiXmlElement * element) - { - if(!element) - throw Exception("CreateFileTransform received null XmlElement."); - - if(std::string(element->Value()) != "file") - { - std::ostringstream os; - os << "HandleElement passed incorrect element type '"; - os << element->Value() << "'. "; - os << "Expected 'file'."; - throw Exception(os.str().c_str()); - } - - FileTransformRcPtr t = FileTransform::Create(); - ReadBaseTransformXML(t, element); - - const TiXmlAttribute* pAttrib = element->FirstAttribute(); - - while(pAttrib) - { - std::string attrName = pystring::lower(pAttrib->Name()); - - if(attrName == "src") - { - t->setSrc( pAttrib->Value() ); - } - else if(attrName == "interpolation") - { - t->setInterpolation( InterpolationFromString(pAttrib->Value()) ); - } - else - { - // TODO: unknown attr - } - pAttrib = pAttrib->Next(); - } - - return t; - } - - ConstFileTransformRcPtr GetDefaultFileTransform() - { - static ConstFileTransformRcPtr filetransform_ = FileTransform::Create(); - return filetransform_; - } - - TiXmlElement * CreateFileTransformXML(const ConstFileTransformRcPtr & t) - { - TiXmlElement * element = new TiXmlElement( "file" ); - WriteBaseTransformXML(element, t); - - element->SetAttribute("src", t->getSrc()); - - ConstFileTransformRcPtr def = GetDefaultFileTransform(); - - if(t->getInterpolation() != def->getInterpolation()) - { - const char * interp = InterpolationToString(t->getInterpolation()); - element->SetAttribute("interpolation", interp); - } - - return element; - } - - - - /////////////////////////////////////////////////////////////////////// - // - // MatrixTransform - - MatrixTransformRcPtr CreateMatrixTransform(const TiXmlElement * element) - { - if(!element) - throw Exception("CreateMatrixTransform received null XmlElement."); - - if(std::string(element->Value()) != "matrix") - { - std::ostringstream os; - os << "HandleElement passed incorrect element type '"; - os << element->Value() << "'. "; - os << "Expected 'matrix'."; - throw Exception(os.str().c_str()); - } - - MatrixTransformRcPtr t = MatrixTransform::Create(); - ReadBaseTransformXML(t, element); - - float matrix[16]; - float offset[4]; - t->getValue(matrix, offset); - - const TiXmlAttribute* pAttrib = element->FirstAttribute(); - - - while(pAttrib) - { - std::string attrName = pystring::lower(pAttrib->Name()); - - if(pystring::startswith(attrName, "m_")) - { - std::string strval = pystring::slice(attrName, - (int)std::string("m_").size()); - int mindex = 0; - if(!StringToInt(&mindex, strval.c_str()) || mindex > 15 || mindex < 0) - { - std::ostringstream os; - os << "Matrix has invalid index specified, '"; - os << attrName << "'. "; - os << "Expected m_{0-15}."; - throw Exception(os.str().c_str()); - } - - float value = 0.0; - if(!StringToFloat(&value, pAttrib->Value())) - { - std::ostringstream os; - os << "Matrix has invalid value specified, '"; - os << pAttrib->Value() << "'. "; - os << "Expected float."; - throw Exception(os.str().c_str()); - } - - matrix[mindex] = value; - } - - if(pystring::startswith(attrName, "b_")) - { - std::string strval = pystring::slice(attrName, - (int)std::string("b_").size()); - int bindex = 0; - if(!StringToInt(&bindex, strval.c_str()) || bindex > 3 || bindex < 0) - { - std::ostringstream os; - os << "Matrix offset has invalid index specified, '"; - os << attrName << "'. "; - os << "Expected b_{0-3}."; - throw Exception(os.str().c_str()); - } - - float value = 0.0; - if(!StringToFloat(&value, pAttrib->Value())) - { - std::ostringstream os; - os << "Matrix has invalid value specified, '"; - os << pAttrib->Value() << "'. "; - os << "Expected float."; - throw Exception(os.str().c_str()); - } - - offset[bindex] = value; - } - - pAttrib = pAttrib->Next(); - } - - t->setValue(matrix, offset); - - return t; - } - - TiXmlElement * CreateMatrixTransformXML(const ConstMatrixTransformRcPtr & t) - { - TiXmlElement * element = new TiXmlElement( "matrix" ); - WriteBaseTransformXML(element, t); - - float matrix[16]; - float offset[4]; - t->getValue(matrix, offset); - - // Get the defaults - MatrixTransformRcPtr dMtx = MatrixTransform::Create(); - float dmatrix[16]; - float doffset[4]; - dMtx->getValue(dmatrix, doffset); - - const float abserror = 1e-9f; - - for(unsigned int i=0; i<16; ++i) - { - if(equalWithAbsError(matrix[i], dmatrix[i], abserror)) - continue; - - std::ostringstream attrname; - attrname << "m_" << i; - element->SetDoubleAttribute(attrname.str(), matrix[i]); - } - - for(unsigned int i=0; i<4; ++i) - { - if(equalWithAbsError(offset[i], doffset[i], abserror)) - continue; - - std::ostringstream attrname; - attrname << "b_" << i; - element->SetDoubleAttribute(attrname.str(), offset[i]); - } - - return element; - } - - - - - - /////////////////////////////////////////////////////////////////////// - // - // ColorSpaceTransform - - ColorSpaceTransformRcPtr CreateColorSpaceTransform(const TiXmlElement * element) - { - if(!element) - throw Exception("ColorSpaceTransform received null XmlElement."); - - if(std::string(element->Value()) != "colorspacetransform") - { - std::ostringstream os; - os << "HandleElement passed incorrect element type '"; - os << element->Value() << "'. "; - os << "Expected 'colorspacetransform'."; - throw Exception(os.str().c_str()); - } - - ColorSpaceTransformRcPtr t = ColorSpaceTransform::Create(); - ReadBaseTransformXML(t, element); - - const char * src = element->Attribute("src"); - const char * dst = element->Attribute("dst"); - - if(!src || !dst) - { - std::ostringstream os; - os << "ColorSpaceTransform must specify both src and dst "; - os << "ColorSpaces."; - throw Exception(os.str().c_str()); - } - - t->setSrc(src); - t->setDst(dst); - - return t; - } - - - - TiXmlElement * CreateColorSpaceTransformXML(const ConstColorSpaceTransformRcPtr & t) - { - TiXmlElement * element = new TiXmlElement( "colorspacetransform" ); - WriteBaseTransformXML(element, t); - - element->SetAttribute("src", t->getSrc()); - element->SetAttribute("dst", t->getDst()); - - return element; - } - - - - - - /////////////////////////////////////////////////////////////////////// - // - // GroupTransform - - GroupTransformRcPtr CreateGroupTransform(const TiXmlElement * element) - { - if(!element) - throw Exception("CreateGroupTransform received null XmlElement."); - - if(std::string(element->Value()) != "group") - { - std::ostringstream os; - os << "HandleElement passed incorrect element type '"; - os << element->Value() << "'. "; - os << "Expected 'group'."; - throw Exception(os.str().c_str()); - } - - GroupTransformRcPtr t = GroupTransform::Create(); - ReadBaseTransformXML(t, element); - - // Traverse Children - const TiXmlElement* pElem = element->FirstChildElement(); - while(pElem) - { - t->push_back( CreateTransform(pElem) ); - pElem = pElem->NextSiblingElement(); - } - - return t; - } - - const ConstGroupTransformRcPtr & GetDefaultGroupTransform() - { - static ConstGroupTransformRcPtr gt = GroupTransform::Create(); - return gt; - } - - TiXmlElement * CreateGroupTransformXML(const ConstGroupTransformRcPtr& t) - { - TiXmlElement * element = new TiXmlElement( "group" ); - WriteBaseTransformXML(element, t); - - ConstGroupTransformRcPtr def = GetDefaultGroupTransform(); - - for(int i=0; isize(); ++i) - { - ConstTransformRcPtr child = t->getTransform(i); - TiXmlElement * childElement = CreateTransformXML(child); - element->LinkEndChild( childElement ); - } - - return element; - } - } - - namespace - { - TiXmlElement * CreateTransformXML(const ConstTransformRcPtr& transform) - { - /* - if(ConstCDLTransformRcPtr cdlTransform = \ - DynamicPtrCast(transform)) - { - //return CreateCDLTransformXML(cdlTransform); - } - */ - if(ConstCineonLogToLinTransformRcPtr cineonTransform = \ - DynamicPtrCast(transform)) - { - return CreateCineonLogToLinTransformXML(cineonTransform); - } - else if(ConstColorSpaceTransformRcPtr colorSpaceTransform = \ - DynamicPtrCast(transform)) - { - return CreateColorSpaceTransformXML(colorSpaceTransform); - } - /* - else if(ConstDisplayTransformRcPtr displayTransform = \ - DynamicPtrCast(transform)) - { - //return CreateDisplayTransformXML(displayTransform); - } - */ - - else if(ConstExponentTransformRcPtr exponentTransform = \ - DynamicPtrCast(transform)) - { - return CreateExponentTransformXML(exponentTransform); - } - else if(ConstFileTransformRcPtr fileTransform = \ - DynamicPtrCast(transform)) - { - return CreateFileTransformXML(fileTransform); - } - else if(ConstGroupTransformRcPtr groupTransform = \ - DynamicPtrCast(transform)) - { - return CreateGroupTransformXML(groupTransform); - } - else if(ConstMatrixTransformRcPtr matrixTransform = \ - DynamicPtrCast(transform)) - { - return CreateMatrixTransformXML(matrixTransform); - } - - std::ostringstream os; - os << "Unsupported transform type for xml serialization."; - throw Exception(os.str().c_str()); - } - - - TransformRcPtr CreateTransform(const TiXmlElement * element) - { - if(!element) - throw Exception("CreateTransform received null XmlElement."); - - std::string type = element->Value(); - - // cdltransform - if(type == "cineonlogtolin") - { - return CreateCineonLogToLinTransform(element); - } - else if(type == "colorspacetransform") - { - return CreateColorSpaceTransform(element); - } - // displaytransform - else if(type == "exponent") - { - return CreateExponentTransform(element); - } - else if(type == "file") - { - return CreateFileTransform(element); - } - else if(type == "group") - { - return CreateGroupTransform(element); - } - else if(type == "matrix") - { - return CreateMatrixTransform(element); - } - - - std::ostringstream os; - os << "Unsupported transform type for xml parsing, '"; - os << type << "'."; - throw Exception(os.str().c_str()); - } - } - - - - - /////////////////////////////////////////////////////////////////////// - // - // ColorSpace - - TiXmlElement * GetColorSpaceElement(const ConstColorSpaceRcPtr & cs) - { - TiXmlElement * element = new TiXmlElement( "colorspace" ); - element->SetAttribute("name", cs->getName()); - element->SetAttribute("family", cs->getFamily()); - element->SetAttribute("bitdepth", BitDepthToString(cs->getBitDepth())); - element->SetAttribute("isdata", BoolToString(cs->isData())); - element->SetAttribute("gpuallocation", GpuAllocationToString(cs->getGpuAllocation())); - element->SetDoubleAttribute("gpumin", cs->getGpuMin()); - element->SetDoubleAttribute("gpumax", cs->getGpuMax()); - - const char * description = cs->getDescription(); - if(strlen(description) > 0) - { - TiXmlElement * descElement = new TiXmlElement( "description" ); - element->LinkEndChild( descElement ); - - TiXmlText * textElement = new TiXmlText( description ); - descElement->LinkEndChild( textElement ); - } - - ColorSpaceDirection dirs[2] = { COLORSPACE_DIR_TO_REFERENCE, - COLORSPACE_DIR_FROM_REFERENCE }; - for(int i=0; i<2; ++i) - { - ConstGroupTransformRcPtr group = cs->getTransform(dirs[i]); - - if(cs->isTransformSpecified(dirs[i]) && !group->empty()) - { - std::string childType = ColorSpaceDirectionToString(dirs[i]); - - TiXmlElement * childElement = new TiXmlElement( childType ); - - // In the words of Jack Handey... - // "I believe in making the world safe for our children, but - // not our children's children, because I don't think - // children should be having sex." - - TiXmlElement * childsChild = CreateTransformXML( group ); - childElement->LinkEndChild( childsChild ); - - element->LinkEndChild( childElement ); - } - } - - return element; - } - - ColorSpaceRcPtr CreateColorSpaceFromElement(const TiXmlElement * element) - { - if(std::string(element->Value()) != "colorspace") - throw Exception("HandleElement GroupTransform passed incorrect element type."); - - ColorSpaceRcPtr cs = ColorSpace::Create(); - - // TODO: better error handling; Require Attrs Exist - - // Read attributes - { - const TiXmlAttribute* pAttrib = element->FirstAttribute(); - double dval = 0.0; - while(pAttrib) - { - std::string attrName = pystring::lower(pAttrib->Name()); - if(attrName == "name") cs->setName( pAttrib->Value() ); - else if(attrName == "family") cs->setFamily( pAttrib->Value() ); - else if(attrName == "bitdepth") cs->setBitDepth( BitDepthFromString(pAttrib->Value()) ); - else if(attrName == "isdata") cs->setIsData( BoolFromString(pAttrib->Value()) ); - else if(attrName == "gpuallocation") cs->setGpuAllocation( GpuAllocationFromString(pAttrib->Value()) ); - else if(attrName == "gpumin" && pAttrib->QueryDoubleValue(&dval) == TIXML_SUCCESS ) cs->setGpuMin( (float)dval ); - else if(attrName == "gpumax" && pAttrib->QueryDoubleValue(&dval) == TIXML_SUCCESS ) cs->setGpuMax( (float)dval ); - else - { - // TODO: unknown attr - } - pAttrib = pAttrib->Next(); - } - } - - // Traverse Children - const TiXmlElement* pElem = element->FirstChildElement(); - while(pElem) - { - std::string elementtype = pElem->Value(); - if(elementtype == "description") - { - const char * text = pElem->GetText(); - if(text) cs->setDescription(text); - } - else - { - ColorSpaceDirection dir = ColorSpaceDirectionFromString(elementtype.c_str()); - - if(dir != COLORSPACE_DIR_UNKNOWN) - { - const TiXmlElement* gchildElem = pElem->FirstChildElement(); - while(gchildElem) - { - std::string childelementtype = gchildElem->Value(); - if(childelementtype == "group") - { - cs->setTransform(CreateGroupTransform(gchildElem), dir); - break; - } - else - { - std::ostringstream os; - os << "CreateColorSpaceFromElement passed incorrect element type '"; - os << childelementtype << "'. 'group' expected."; - throw Exception(os.str().c_str()); - } - - gchildElem=gchildElem->NextSiblingElement(); - } - } - } - - pElem=pElem->NextSiblingElement(); - } - - return cs; - } - -} -OCIO_NAMESPACE_EXIT - - - - diff --git a/src/core/XmlIO.h b/src/core/XmlIO.h deleted file mode 100644 index 5102eedf9..000000000 --- a/src/core/XmlIO.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -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_XMLIO_H -#define INCLUDED_OCIO_XMLIO_H - -#include - -#include "tinyxml/tinyxml.h" - - -OCIO_NAMESPACE_ENTER -{ - ColorSpaceRcPtr CreateColorSpaceFromElement(const TiXmlElement * element); - - TiXmlElement * GetColorSpaceElement(const ConstColorSpaceRcPtr & cs); -} -OCIO_NAMESPACE_EXIT - -#endif diff --git a/src/core_tests/CMakeLists.txt b/src/core_tests/CMakeLists.txt index b37e7f11c..cbc38c316 100644 --- a/src/core_tests/CMakeLists.txt +++ b/src/core_tests/CMakeLists.txt @@ -7,23 +7,26 @@ if(Boost_FOUND) include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ + ${YAML_CPP_INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ) file( GLOB_RECURSE core_test_src_files "${CMAKE_SOURCE_DIR}/src/core/*.cpp" ) - link_directories( ${Boost_LIBRARY_DIRS} ) + link_directories( + ${Boost_LIBRARY_DIRS}) - add_executable( ocio_core_tests ${core_test_src_files} ) + add_executable(ocio_core_tests + ${core_test_src_files}) - target_link_libraries(ocio_core_tests + add_dependencies(ocio_core_tests + YAML_CPP_LOCAL) -# Linking to OpenColorIO is not appropriate, -# as we are going to recompile all the src files with OCIO_UNIT_TEST defined. -# OpenColorIO - - ${Boost_LIBRARIES} - ) + # Linking to OpenColorIO is not appropriate, + # as we are going to recompile all the src files with OCIO_UNIT_TEST defined. + target_link_libraries(ocio_core_tests + ${YAML_CPP_STATIC_LIBRARIES} + ${Boost_LIBRARIES}) install(TARGETS ocio_core_tests DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/src/pyglue/PyConfig.cpp b/src/pyglue/PyConfig.cpp index b64ff8abe..340062d8f 100644 --- a/src/pyglue/PyConfig.cpp +++ b/src/pyglue/PyConfig.cpp @@ -465,7 +465,7 @@ OCIO_NAMESPACE_ENTER std::ostringstream os; - config->writeXML(os); + config->writeToStream(os); return PyString_FromString( os.str().c_str() ); } diff --git a/src/testbed/main.cpp b/src/testbed/main.cpp index 93cc56aee..b97782a4f 100644 --- a/src/testbed/main.cpp +++ b/src/testbed/main.cpp @@ -156,7 +156,7 @@ void loadConfigFromEnv() std::string outputname = "/mcp/test.ocio"; std::cout << "Writing " << outputname << std::endl; std::ofstream outfile(outputname.c_str()); - config->writeXML(outfile); + config->writeToStream(outfile); outfile.close(); } } @@ -211,7 +211,7 @@ void createConfig() std::string outputname = "/mcp/test.ocio"; std::cout << "Writing " << outputname << std::endl; std::ofstream outfile(outputname.c_str()); - config->writeXML(outfile); + config->writeToStream(outfile); outfile.close(); //config.loadFromFile(outputname.c_str()); @@ -221,7 +221,7 @@ void createConfig() std::string outputname = "/mcp/test2.ocio"; std::cout << "Writing " << outputname << std::endl; std::ofstream outfile(outputname.c_str()); - config.writeXML(outfile); + config.writeToStream(outfile); outfile.close(); } */