Skip to content

Commit 27447f5

Browse files
Adsk contrib - Built-in configurations (#1659)
* First version of built-in configs feature Signed-off-by: Cedrik Fuoco <[email protected]> * Generating configs header into generated_include folder Signed-off-by: Cedrik Fuoco <[email protected]> * Added comments, move some code, added a test for public interface, changed how CG.h get generated and other minors fixes Signed-off-by: Cedrik Fuoco <[email protected]> * Adding support for ocio://default and a unit test for it Signed-off-by: Cedrik Fuoco <[email protected]> * Renamed methods to get align with BuiltinConfig class name and to remove confusion with Config class. Signed-off-by: Cedrik Fuoco <[email protected]> * Refactor the test suite for Built-in config and comments/descriptions changes Signed-off-by: Cedrik Fuoco <[email protected]> * Adding guard for setenv, added two tests and other minor changes Signed-off-by: Cedrik Fuoco <[email protected]> * Added readme file to help add a new config, minors fixes, changed some built-in config unit tests and created a generic guard for set/unset env. Signed-off-by: Cedrik Fuoco <[email protected]> * Fix some coding styles and remove try catch that was not really needed. Signed-off-by: Cedrik Fuoco <[email protected]> * Updating setenv/unset to the guard pattern in config_tests module. Signed-off-by: Cedrik Fuoco <[email protected]> * Python bindings Signed-off-by: Cedrik Fuoco <[email protected]> * Fixing styling issues and minor modifications in python unit tests Signed-off-by: Cedrik Fuoco <[email protected]> * Fixing problem with test_create_builtin_config Signed-off-by: Cedrik Fuoco <[email protected]> * Remove the check for the number of colorspaces in the python tests for now - only checking the name, removed readme and fix issue around config begin null in test by adding a OCIO_REQUIRE_ASSERT. Signed-off-by: Cedrik Fuoco <[email protected]> * Fixing styling and comments issues and adding back the tests for the number of colorspaces using len(). Signed-off-by: Cedrik Fuoco <[email protected]> * missing spaces in comments. Signed-off-by: Cedrik Fuoco <[email protected]> * Adding display name and getBuiltinConfigUIName. Signed-off-by: Cedrik Fuoco <[email protected]> * Fix a few issues with the builds - Replacing get_filename_component/NAME_WLE by a regex, replacing assetRaisesRegex with a combination of assertRaises/assertEqual and fixing the link issue with Doxygen in OpenColorIO.h Signed-off-by: Cedrik Fuoco <[email protected]> * Adding missing comment and changing "displayName" to "uiName" to remove confusion within ocio Signed-off-by: Cedrik Fuoco <[email protected]> * Fixing build issue on Linux and Mac : config string was not null terminated Signed-off-by: Cedrik Fuoco <[email protected]> * minor fixes Signed-off-by: Cedrik Fuoco <[email protected]> * A more Pythonic interface Signed-off-by: Cedrik Fuoco <[email protected]> * Adding more information into the tuple and modified corresponding tests. Signed-off-by: Cedrik Fuoco <[email protected]> * returning reference instead of smart pointer as it is not needed. Signed-off-by: Cedrik Fuoco <[email protected]> * Removed getNumBuiltinConfig from python binding since we have iterator and modified __contains__ magic method to not throw exception. Signed-off-by: Cedrik Fuoco <[email protected]> * Fix wrong type in for loop. (linux and mac issue) Signed-off-by: Cedrik Fuoco <[email protected]> Co-authored-by: Doug Walker <[email protected]>
1 parent 06601f0 commit 27447f5

23 files changed

+1662
-89
lines changed

include/OpenColorIO/OpenColorIO.h

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,15 +257,40 @@ class OCIOEXPORT Config
257257
/**
258258
* \brief Create a configuration using the OCIO environment variable.
259259
*
260+
* Also support OCIO URI format. See CreateFromFile.
261+
*
260262
* If the variable is missing or empty, returns the same result as
261263
* \ref Config::CreateRaw .
262264
*/
263265
static ConstConfigRcPtr CreateFromEnv();
264-
/// Create a configuration using a specific config file.
266+
/**
267+
* \brief Create a configuration using a specific config file.
268+
*
269+
* Also support the following OCIO URI format :
270+
* "ocio://default" - Default Built-in config.
271+
* "ocio://configName" - Built-in config named configName
272+
*
273+
*/
265274
static ConstConfigRcPtr CreateFromFile(const char * filename);
266275
/// Create a configuration using a stream.
267276
static ConstConfigRcPtr CreateFromStream(std::istream & istream);
268277

278+
/**
279+
* \brief Create a configuration using an OCIO built-in config.
280+
*
281+
* \param configName Built-in config name
282+
*
283+
* The available configNames are:
284+
* "cg-config-v0.1.0_aces-v1.3_ocio-v2.1.1" -- ACES CG config, basic color spaces for computer
285+
* graphics apps. More information is available at:
286+
* %https://github.com/AcademySoftwareFoundation/OpenColorIO-Config-ACES
287+
*
288+
* \throw Exception If the configName is not recognized.
289+
*
290+
* \return one of the configs built into OCIO library
291+
*/
292+
static ConstConfigRcPtr CreateFromBuiltinConfig(const char * configName);
293+
269294
ConfigRcPtr createEditableCopy() const;
270295

271296
/// Get the configuration major version.
@@ -3294,6 +3319,76 @@ class OCIOEXPORT BuiltinTransformRegistry
32943319
virtual ~BuiltinTransformRegistry() = default;
32953320
};
32963321

3322+
///////////////////////////////////////////////////////////////////////////
3323+
// BuiltinConfigRegistry
3324+
3325+
/**
3326+
* The built-in configs registry contains information about all the existing built-in configs.
3327+
*/
3328+
class OCIOEXPORT BuiltinConfigRegistry
3329+
{
3330+
public:
3331+
BuiltinConfigRegistry(const BuiltinConfigRegistry &) = delete;
3332+
BuiltinConfigRegistry & operator= (const BuiltinConfigRegistry &) = delete;
3333+
3334+
/// Get the current built-in configs registry.
3335+
static const BuiltinConfigRegistry & Get() noexcept;
3336+
3337+
/// Get the number of built-in configs available.
3338+
virtual size_t getNumBuiltinConfigs() const noexcept = 0;
3339+
3340+
/// Get the name of the config at the specified (zero-based) index.
3341+
/// Throws for illegal index.
3342+
virtual const char * getBuiltinConfigName(size_t configIndex) const = 0;
3343+
3344+
// Get a user-friendly name for a built-in config, appropriate for displaying in a user interface.
3345+
/// Throws for illegal index.
3346+
virtual const char * getBuiltinConfigUIName(size_t configIndex) const = 0;
3347+
3348+
/// Get Yaml text of the built-in config at the specified index.
3349+
/// Throws for illegal index.
3350+
virtual const char * getBuiltinConfig(size_t configIndex) const = 0;
3351+
3352+
/// Get the Yaml text of the built-in config with the specified name.
3353+
/// Throws if the name is not found.
3354+
virtual const char * getBuiltinConfigByName(const char * configName) const = 0;
3355+
3356+
/**
3357+
* @brief Check if a specific built-in config is recommended.
3358+
*
3359+
* For backwards compatibility reasons, configs will remain in the registry even if they have
3360+
* been superseded. If an app is presenting a list of configs to users, it should not include
3361+
* configs that are no longer recommended.
3362+
*
3363+
* Throws if the name is not found.
3364+
*
3365+
* @param configIndex Index of built-in config.
3366+
* @return true if the config is recommended.
3367+
*/
3368+
virtual bool isBuiltinConfigRecommended(size_t configIndex) const = 0;
3369+
3370+
/**
3371+
* @brief Get the default recommended built-in config.
3372+
*
3373+
* Get the name of the built-in config that is currently recommended as the default config
3374+
* to use for applications looking for basic color management.
3375+
*
3376+
* As the built-in config collection evolves, the default config name will change in future
3377+
* releases.
3378+
*
3379+
* For backwards compatibility, the name provided here will always work as an argument
3380+
* to other methods so that any previous default config may be recovered.
3381+
*
3382+
* Throws if the name is not found.
3383+
*
3384+
* @return Default's built-in config name.
3385+
*/
3386+
virtual const char * getDefaultBuiltinConfigName() const = 0;
3387+
protected:
3388+
BuiltinConfigRegistry() = default;
3389+
virtual ~BuiltinConfigRegistry() = default;
3390+
};
3391+
32973392

32983393
///////////////////////////////////////////////////////////////////////////
32993394
// SystemMonitors

src/OpenColorIO/CMakeLists.txt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ set(SOURCES
1010
Baker.cpp
1111
BakingUtils.cpp
1212
BitDepthUtils.cpp
13+
builtinconfigs/BuiltinConfigRegistry.cpp
14+
builtinconfigs/CGConfig.cpp
1315
Caching.cpp
1416
ColorSpace.cpp
1517
ColorSpaceSet.cpp
@@ -209,6 +211,46 @@ set(ABI_HEADER_LOCATION "${CMAKE_BINARY_DIR}/include/OpenColorIO")
209211
list(APPEND INSTALL_HEADERS ${ABI_HEADER_LOCATION}/OpenColorABI.h)
210212
configure_file("${HEADER_LOCATION}/OpenColorABI.h.in" "${ABI_HEADER_LOCATION}/OpenColorABI.h" @ONLY)
211213

214+
# Built-in configs
215+
set(CONFIGS_HEADER_LOCATION "${CMAKE_BINARY_DIR}/generated_include")
216+
file(GLOB CONFIGS_PATHS "builtinconfigs/configs/*.ocio")
217+
# Loop through the .ocio config files.
218+
foreach(C ${CONFIGS_PATHS})
219+
get_filename_component(CONFIG_FULLNAME "${C}" NAME)
220+
string(REGEX MATCH "^(.*)\\.ocio$" tempvar ${CONFIG_FULLNAME})
221+
set(CONFIG_NAME ${CMAKE_MATCH_1})
222+
list(APPEND CONFIGS_ALL ${CONFIG_NAME})
223+
224+
file(READ builtinconfigs/configs/${CONFIG_FULLNAME} HEX_CONTENTS HEX)
225+
# Separate into individual bytes.
226+
string(REGEX MATCHALL "([A-Za-z0-9][A-Za-z0-9])" SEPARATED_HEX "${HEX_CONTENTS}")
227+
228+
# Prepend the "0x" to each byte.
229+
list(JOIN SEPARATED_HEX ",0x" FORMATTED_HEX)
230+
231+
# Prepend "0x" to the first byte.
232+
string(PREPEND FORMATTED_HEX "0x")
233+
234+
# Append 0x00 to null-terminated the string.
235+
string(APPEND FORMATTED_HEX ",0x00")
236+
237+
# Set the dynamically named variable "${CONFIG_NAME}" to the config in HEX.
238+
set(${CONFIG_NAME} ${FORMATTED_HEX})
239+
endforeach()
240+
241+
file(GLOB TEMPLATE_HEADER_CONFIG_FILES "builtinconfigs/*.cpp.in")
242+
foreach(C ${TEMPLATE_HEADER_CONFIG_FILES})
243+
get_filename_component(TEMPLATE_HEADER_FULLNAME "${C}" NAME)
244+
245+
string(LENGTH ${TEMPLATE_HEADER_FULLNAME} TEMPLATE_HEADER_LENGTH)
246+
MATH(EXPR TEMPLATE_HEADER_LENGTH "${TEMPLATE_HEADER_LENGTH}-3")
247+
# Get TEMPLATE_HEADER_FULLNAME without .in extension.
248+
string(SUBSTRING ${TEMPLATE_HEADER_FULLNAME} 0 ${TEMPLATE_HEADER_LENGTH} TEMPLATE_HEADER_FULLNAME_H)
249+
250+
configure_file(builtinconfigs/${TEMPLATE_HEADER_FULLNAME} ${CONFIGS_HEADER_LOCATION}/${TEMPLATE_HEADER_FULLNAME_H} @ONLY)
251+
endforeach()
252+
253+
212254
set(BUILD_INCLUDES
213255
${HEADER_LOCATION}/..
214256
${HEADER_LOCATION}
@@ -220,6 +262,8 @@ target_include_directories(OpenColorIO
220262
PUBLIC
221263
"$<BUILD_INTERFACE:${BUILD_INCLUDES}>"
222264
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
265+
PRIVATE
266+
"${CONFIGS_HEADER_LOCATION}"
223267
)
224268

225269
target_link_libraries(OpenColorIO

src/OpenColorIO/Config.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <fstream>
1010
#include <utility>
1111
#include <vector>
12+
#include <regex>
1213

1314
#include <OpenColorIO/OpenColorIO.h>
1415

@@ -33,6 +34,8 @@
3334
#include "ViewingRules.h"
3435
#include "SystemMonitor.h"
3536

37+
#include "builtinconfigs/BuiltinConfigRegistry.h"
38+
3639

3740
namespace OCIO_NAMESPACE
3841
{
@@ -1100,6 +1103,8 @@ ConstConfigRcPtr Config::CreateFromEnv()
11001103
{
11011104
std::string file;
11021105
Platform::Getenv(OCIO_CONFIG_ENVVAR, file);
1106+
1107+
// File can be a filename/path or an URI to a default configuration (ocio://<config name>).
11031108
if(!file.empty()) return CreateFromFile(file.c_str());
11041109

11051110
static const char err[] =
@@ -1117,6 +1122,21 @@ ConstConfigRcPtr Config::CreateFromFile(const char * filename)
11171122
throw ExceptionMissingFile ("The config filepath is missing.");
11181123
}
11191124

1125+
// Check for URI Pattern: ocio://<config name>
1126+
static const std::regex uriPattern(R"(ocio:\/\/([^\s]+))");
1127+
std::smatch match;
1128+
const std::string uri = filename;
1129+
if (std::regex_search(uri, match, uriPattern))
1130+
{
1131+
if (Platform::Strcasecmp(match.str(1).c_str(), "default") == 0)
1132+
{
1133+
// Processing ocio://default
1134+
const BuiltinConfigRegistry & reg = BuiltinConfigRegistry::Get();
1135+
return CreateFromBuiltinConfig(reg.getDefaultBuiltinConfigName());
1136+
}
1137+
return CreateFromBuiltinConfig(match.str(1).c_str());
1138+
}
1139+
11201140
std::ifstream istream = Platform::CreateInputFileStream(filename, std::ios_base::in);
11211141
if (istream.fail())
11221142
{
@@ -1134,6 +1154,20 @@ ConstConfigRcPtr Config::CreateFromStream(std::istream & istream)
11341154
return Config::Impl::Read(istream, nullptr);
11351155
}
11361156

1157+
ConstConfigRcPtr Config::CreateFromBuiltinConfig(const char * configName)
1158+
{
1159+
ConstConfigRcPtr builtinConfig;
1160+
const BuiltinConfigRegistry & reg = BuiltinConfigRegistry::Get();
1161+
1162+
// getBuiltinConfigByName will throw if config name not found.
1163+
const char * builtinConfigStr = reg.getBuiltinConfigByName(configName);
1164+
std::istringstream iss;
1165+
iss.str(builtinConfigStr);
1166+
builtinConfig = Config::CreateFromStream(iss);
1167+
1168+
return builtinConfig;
1169+
}
1170+
11371171
///////////////////////////////////////////////////////////////////////////
11381172

11391173
Config::Config()

0 commit comments

Comments
 (0)