Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adsk Contrib - Adding support for ocio://cg-config-latest and ocio://studio-config-latest #1773

Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions docs/tutorials/baking_luts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,7 @@ this to a Flame compatible 3dl file, simply run::
Reversing a 1D LUT
++++++++++++++++++

You can apply a LUT in reverse, and write this to a new LUT (this does
not work for 3D LUT's, but will for 1D LUT's)::
You can apply a LUT in reverse, and write this to a new LUT::

bash$ ociobakelut --format flame --invlut logtosrgb.3dl srgbtolog.3dl

Expand Down
58 changes: 35 additions & 23 deletions include/OpenColorIO/OpenColorIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,28 @@ extern OCIOEXPORT ConstConfigRcPtr GetCurrentConfig();
/// Set the current configuration. This will then store a copy of the specified config.
extern OCIOEXPORT void SetCurrentConfig(const ConstConfigRcPtr & config);

/**
* \brief Make a config path forward-compatible by replacing special built-in config names
* with the current name.
*
* Application developers should call this function on any config path they intend to persist
* (e.g., to include in a file saved from a DCC).
*
* As the built-in config collection evolves, special names such as "ocio://default" and
* "ocio://studio-config-latest" will point to newer versions of those configs. Therefore, it is
* recommended that application developers not save those strings and instead save the string that
* refers to the current version of that config. That way, it's guaranteed that there will be no
* change of behavior in the future. For example, as of OCIO 2.2, "ocio://default" should be saved
* as "ocio://cg-config-v1.0.0_aces-v1.3_ocio-v2.1".
*
* Note that there is no validation done on the path. That is left to the application since
* typically the application will load the config before attempting to save its path
* and therefore catch, for example, a badly formed URI such as "ocio:default".
*
* \return Resolved path if possible. Otherwise, the original path is returned unmodified.
*/
extern OCIOEXPORT const char * ResolveConfigPath(const char * originalPath) noexcept;

/**
* \brief Extract an OCIO Config archive.
*
Expand Down Expand Up @@ -298,13 +320,11 @@ class OCIOEXPORT Config
/**
* \brief Create a configuration using a specific config file.
*
* Also supports the following OCIO URI format for Built-in configs:
* "ocio://default" - Default Built-in config.
* "ocio://<CONFIG NAME>" - A specific Built-in config. For the list of available
* <CONFIG NAME> strings, see \ref Config::CreateFromBuiltinConfig.
*
* Also supports archived configs (.ocioz files).
* Supports the OCIO URI format for Built-in configs.
* See \ref Config::CreateFromBuiltinConfig.
*
* Supports archived configs (.ocioz files).
*
* \throw Exception If the file may not be read or does not parse.
* \return The Config object.
*/
Expand Down Expand Up @@ -342,7 +362,13 @@ class OCIOEXPORT Config
/**
* \brief Create a configuration using an OCIO built-in config.
*
* \param configName Built-in config name.
* \param configName Built-in config name (with or without the "ocio://" URI prefix).
*
* Also supports the following OCIO URI format for Built-in configs:
* "ocio://default" - Default Built-in config.
* "ocio://cg-config-latest" - Latest Built-in CG config.
* "ocio://studio-config-latest" - Latest Built-in Studio config.
* "ocio://<CONFIG NAME>" - A specific Built-in config.
*
* The available configNames are:
*
Expand Down Expand Up @@ -3624,22 +3650,8 @@ class OCIOEXPORT BuiltinConfigRegistry
*/
virtual bool isBuiltinConfigRecommended(size_t configIndex) const = 0;

/**
* @brief Get the default recommended built-in config.
*
* Get the name of the built-in config that is currently recommended as the default config
* to use for applications looking for basic color management.
*
* As the built-in config collection evolves, the default config name will change in future
* releases.
*
* For backwards compatibility, the name provided here will always work as an argument
* to other methods so that any previous default config may be recovered.
*
* Throws if the name is not found.
*
* @return Default's built-in config name.
*/
// Return the full forward-compatible name of the default built-in config.
// Please use ResolveConfigPath(\"ocio://default\"). This method will be deprecated in OCIO 2.3.
virtual const char * getDefaultBuiltinConfigName() const = 0;
protected:
BuiltinConfigRegistry() = default;
Expand Down
4 changes: 4 additions & 0 deletions include/OpenColorIO/OpenColorTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,10 @@ extern OCIOEXPORT const char * OCIO_CONFIG_DEFAULT_NAME;
extern OCIOEXPORT const char * OCIO_CONFIG_DEFAULT_FILE_EXT;
extern OCIOEXPORT const char * OCIO_CONFIG_ARCHIVE_FILE_EXT;

// Built-in config feature
// URI Prefix
extern OCIOEXPORT const char * OCIO_BUILTIN_URI_PREFIX;

} // namespace OCIO_NAMESPACE

#endif
37 changes: 27 additions & 10 deletions src/OpenColorIO/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ const char * OCIO_CONFIG_ARCHIVE_FILE_EXT = ".ocioz";
// has the same name as the display the shared view is used by.
const char * OCIO_VIEW_USE_DISPLAY_NAME = "<USE_DISPLAY_NAME>";

const char * OCIO_BUILTIN_URI_PREFIX = "ocio://";

namespace
{

Expand Down Expand Up @@ -1378,8 +1380,9 @@ class Config::Impl
const char * builtinColorSpaceName,
TransformDirection direction) const
{
// Use the Default config as the Built-in config to interpret the known color space name.
ConstConfigRcPtr builtinConfig = Config::CreateFromFile("ocio://default");
// Use the Default config as the Built-in config to interpret the known color space name.
std::string defaultBuiltin = std::string(OCIO_BUILTIN_URI_PREFIX) + std::string("default");
ConstConfigRcPtr builtinConfig = Config::CreateFromFile(defaultBuiltin.c_str());

// Define the set of candidate reference linear color spaces (aka, reference primaries) that
// will be used when searching through the source config. If the source config scene-referred
Expand Down Expand Up @@ -1562,13 +1565,7 @@ ConstConfigRcPtr Config::CreateFromFile(const char * filename)
const std::string uri = filename;
if (std::regex_search(uri, match, uriPattern))
{
if (Platform::Strcasecmp(match.str(1).c_str(), "default") == 0)
{
// Processing ocio://default
const BuiltinConfigRegistry & reg = BuiltinConfigRegistry::Get();
return CreateFromBuiltinConfig(reg.getDefaultBuiltinConfigName());
}
return CreateFromBuiltinConfig(match.str(1).c_str());
return CreateFromBuiltinConfig(uri.c_str());
}

std::ifstream ifstream = Platform::CreateInputFileStream(
Expand Down Expand Up @@ -1636,11 +1633,31 @@ ConstConfigRcPtr Config::CreateFromConfigIOProxy(ConfigIOProxyRcPtr ciop)

ConstConfigRcPtr Config::CreateFromBuiltinConfig(const char * configName)
{
std::string builtinConfigName = configName;

// Normalize the input to the URI format.
if (!StringUtils::StartsWith(builtinConfigName, OCIO_BUILTIN_URI_PREFIX))
{
builtinConfigName = std::string(OCIO_BUILTIN_URI_PREFIX) + builtinConfigName;
}

// Resolve the URI if needed.
const std::string uri = ResolveConfigPath(builtinConfigName.c_str());

// Check if the config path starts with ocio://
static const std::regex uriPattern(R"(ocio:\/\/([^\s]+))");
std::smatch match;
if (std::regex_search(uri, match, uriPattern))
{
// Store config path without the "ocio://" prefix, if present.
builtinConfigName = match.str(1).c_str();
}

ConstConfigRcPtr builtinConfig;
const BuiltinConfigRegistry & reg = BuiltinConfigRegistry::Get();

// getBuiltinConfigByName will throw if config name not found.
const char * builtinConfigStr = reg.getBuiltinConfigByName(configName);
const char * builtinConfigStr = reg.getBuiltinConfigByName(builtinConfigName.c_str());
std::istringstream iss;
iss.str(builtinConfigStr);
builtinConfig = Config::CreateFromStream(iss);
Expand Down
68 changes: 43 additions & 25 deletions src/OpenColorIO/builtinconfigs/BuiltinConfigRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <memory>
#include <algorithm>
#include <sstream>
#include <regex>

// OpenColorIO must be first - order is important.
#include <OpenColorIO/OpenColorIO.h>
Expand All @@ -15,11 +16,51 @@
#include "builtinconfigs/CGConfig.h"
#include "builtinconfigs/StudioConfig.h"

#define OUT_OF_RANGE_EXCEPTION_TEXT "Config index is out of range."
static constexpr char OUT_OF_RANGE_EXCEPTION_TEXT[] = "Config index is out of range.";

// TODO: Remove once getDefaultBuiltinConfigName is removed.
static constexpr char DEFAULT_BUILTIN_CONFIG[] = "cg-config-v1.0.0_aces-v1.3_ocio-v2.1";

// These are used for ResolveConfigPath function and we need to return a variable that still exists
// once the function finishes since we are returning a const char *.
static constexpr char DEFAULT_BUILTIN_CONFIG_URI[] = "ocio://cg-config-v1.0.0_aces-v1.3_ocio-v2.1";
static constexpr char LATEST_CG_BUILTIN_CONFIG_URI[] = "ocio://cg-config-v1.0.0_aces-v1.3_ocio-v2.1";
static constexpr char LATEST_STUDIO_BUILTIN_CONFIG_URI[] = "ocio://studio-config-v1.0.0_aces-v1.3_ocio-v2.1";

static constexpr char BUILTIN_DEFAULT_NAME[] = "default";
static constexpr char BUILTIN_LATEST_CG_NAME[] = "cg-config-latest";
static constexpr char BUILTIN_LATEST_STUDIO_NAME[] = "studio-config-latest";

namespace OCIO_NAMESPACE
{

// Note that this function does not require initializing the built-in config registry.
const char * ResolveConfigPath(const char * originalPath) noexcept
{
static const std::regex uriPattern(R"(ocio:\/\/([^\s]+))");
std::smatch match;
const std::string uri = originalPath;
// Check if original path starts with "ocio://".
if (std::regex_search(uri, match, uriPattern))
{
if (Platform::Strcasecmp(match.str(1).c_str(), BUILTIN_DEFAULT_NAME) == 0)
{
return DEFAULT_BUILTIN_CONFIG_URI;
}
else if (Platform::Strcasecmp(match.str(1).c_str(), BUILTIN_LATEST_CG_NAME) == 0)
{
return LATEST_CG_BUILTIN_CONFIG_URI;
}
else if (Platform::Strcasecmp(match.str(1).c_str(), BUILTIN_LATEST_STUDIO_NAME) == 0)
{
return LATEST_STUDIO_BUILTIN_CONFIG_URI;
}
}

// Return originalPath if no special path was used.
return originalPath;
}

const BuiltinConfigRegistry & BuiltinConfigRegistry::Get() noexcept
{
// Meyer's Singleton pattern.
Expand All @@ -46,8 +87,6 @@ void BuiltinConfigRegistryImpl::init() noexcept

CGCONFIG::Register(*this);
STUDIOCONFIG::Register(*this);

this->setDefaultBuiltinConfig("cg-config-v1.0.0_aces-v1.3_ocio-v2.1");
}
}

Expand Down Expand Up @@ -131,28 +170,7 @@ bool BuiltinConfigRegistryImpl::isBuiltinConfigRecommended(size_t configIndex) c

const char * BuiltinConfigRegistryImpl::getDefaultBuiltinConfigName() const
{
if (m_defaultBuiltinConfigName.empty())
{
// Make sure that at least one default built-ins config is present.
throw Exception("Internal error - The default built-in config name has not been set yet.");
}

return m_defaultBuiltinConfigName.c_str();
}

void BuiltinConfigRegistryImpl::setDefaultBuiltinConfig(const char * configName)
{
// Search for config name.
for (auto & builtin : m_builtinConfigs)
{
if (Platform::Strcasecmp(configName, builtin.m_name.c_str()) == 0)
{
m_defaultBuiltinConfigName = configName;
return;
}
}

throw Exception("Internal error - Config name does not exist.");
return DEFAULT_BUILTIN_CONFIG;
}

} // namespace OCIO_NAMESPACE
5 changes: 0 additions & 5 deletions src/OpenColorIO/builtinconfigs/BuiltinConfigRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,9 @@ using BuiltinConfigs = std::vector<BuiltinConfigData>;
bool isBuiltinConfigRecommended(size_t configIndex) const override;

/// Get the default recommended built-in config.
/// Throws for illegal index.
const char * getDefaultBuiltinConfigName() const override;

/// Set the default built-in config.
void setDefaultBuiltinConfig(const char * configName);
private:
BuiltinConfigs m_builtinConfigs;
std::string m_defaultBuiltinConfigName;
};

} // namespace OCIO_NAMESPACE
Expand Down
2 changes: 1 addition & 1 deletion src/OpenColorIO/builtinconfigs/CG.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

// It is included in the following places:
// - CGConfig.cpp for the Built-in config feature.
// - BuiltinConfigRegistry_tests.cpp for the unit tests
// - BuiltinConfig_tests.cpp for the unit tests

constexpr char CG_CONFIG_V100_ACES_V13_OCIO_V21[] = { @cg-config-v1.0.0_aces-v1.3_ocio-v2.1@ };
3 changes: 3 additions & 0 deletions src/OpenColorIO/builtinconfigs/CGConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace CGCONFIG
{
void Register(BuiltinConfigRegistryImpl & registry) noexcept
{
// If a new built-in config is added, do not forget to update the latestCGBuiltinConfigURI
// variable (in BuiltinConfigRegistry.h).

registry.addBuiltin(
"cg-config-v1.0.0_aces-v1.3_ocio-v2.1",
"Academy Color Encoding System - CG Config [COLORSPACES v1.0.0] [ACES v1.3] [OCIO v2.1]",
Expand Down
3 changes: 3 additions & 0 deletions src/OpenColorIO/builtinconfigs/StudioConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace STUDIOCONFIG
{
void Register(BuiltinConfigRegistryImpl & registry) noexcept
{
// If a new built-in config is added, do not forget to update the latestStudioBuiltinConfigURI
// variable (in BuiltinConfigRegistry.h).

registry.addBuiltin(
"studio-config-v1.0.0_aces-v1.3_ocio-v2.1",
"Academy Color Encoding System - Studio Config [COLORSPACES v1.0.0] [ACES v1.3] [OCIO v2.1]",
Expand Down
3 changes: 3 additions & 0 deletions src/bindings/python/PyConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,9 @@ void bindPyConfig(py::module & m)

m.def("ExtractOCIOZArchive", &ExtractOCIOZArchive,
DOC(PyOpenColorIO, ExtractOCIOZArchive));

m.def("ResolveConfigPath", &ResolveConfigPath,
DOC(PyOpenColorIO, ResolveConfigPath));
}

} // namespace OCIO_NAMESPACE
6 changes: 6 additions & 0 deletions src/bindings/python/PyTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,12 @@ void bindPyTypes(py::module & m)
m.attr("OCIO_DISABLE_ALL_CACHES") = OCIO_DISABLE_ALL_CACHES;
m.attr("OCIO_DISABLE_PROCESSOR_CACHES") = OCIO_DISABLE_PROCESSOR_CACHES;
m.attr("OCIO_DISABLE_CACHE_FALLBACK") = OCIO_DISABLE_CACHE_FALLBACK;

m.attr("OCIO_CONFIG_DEFAULT_NAME") = OCIO_CONFIG_DEFAULT_NAME;
m.attr("OCIO_CONFIG_DEFAULT_FILE_EXT") = OCIO_CONFIG_DEFAULT_FILE_EXT;
m.attr("OCIO_CONFIG_ARCHIVE_FILE_EXT") = OCIO_CONFIG_ARCHIVE_FILE_EXT;

m.attr("OCIO_BUILTIN_URI_PREFIX") = OCIO_BUILTIN_URI_PREFIX;
}

} // namespace OCIO_NAMESPACE
2 changes: 1 addition & 1 deletion tests/cpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ set(TESTS
apphelpers/MixingHelpers_tests.cpp
Baker_tests.cpp
BitDepthUtils_tests.cpp
builtinconfigs/BuiltinConfigRegistry_tests.cpp
builtinconfigs/BuiltinConfig_tests.cpp
Caching_tests.cpp
ColorSpace_tests.cpp
ColorSpaceSet_tests.cpp
Expand Down
Loading