Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
42 changes: 41 additions & 1 deletion docs/api/python/frozen/pyopencolorio_colorspace.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

2. __init__(self: PyOpenColorIO.ColorSpace, referenceSpace: PyOpenColorIO.ReferenceSpaceType) -> None

3. __init__(self: PyOpenColorIO.ColorSpace, referenceSpace: PyOpenColorIO.ReferenceSpaceType = <ReferenceSpaceType.REFERENCE_SPACE_SCENE: 0>, name: str = '', aliases: List[str] = [], family: str = '', encoding: str = '', equalityGroup: str = '', description: str = '', bitDepth: PyOpenColorIO.BitDepth = <BitDepth.BIT_DEPTH_UNKNOWN: 0>, isData: bool = False, allocation: PyOpenColorIO.Allocation = <Allocation.ALLOCATION_UNIFORM: 1>, allocationVars: List[float] = [], toReference: PyOpenColorIO.Transform = None, fromReference: PyOpenColorIO.Transform = None, categories: List[str] = []) -> None
3. __init__(self: PyOpenColorIO.ColorSpace, referenceSpace: PyOpenColorIO.ReferenceSpaceType = <ReferenceSpaceType.REFERENCE_SPACE_SCENE: 0>, name: str = '', aliases: List[str] = [], family: str = '', encoding: str = '', equalityGroup: str = '', description: str = '', bitDepth: PyOpenColorIO.BitDepth = <BitDepth.BIT_DEPTH_UNKNOWN: 0>, isData: bool = False, allocation: PyOpenColorIO.Allocation = <Allocation.ALLOCATION_UNIFORM: 1>, allocationVars: List[float] = [], toReference: PyOpenColorIO.Transform = None, fromReference: PyOpenColorIO.Transform = None, categories: List[str] = [], interopID: str = '', amfTransformIDs: str = '', iccProfileName: str = '') -> None


.. py:method:: ColorSpace.addAlias(self: PyOpenColorIO.ColorSpace, alias: str) -> None
Expand Down Expand Up @@ -48,6 +48,14 @@
Clear all the categories.


.. py:method:: ColorSpace.getAMFTransformIDs(self: PyOpenColorIO.ColorSpace) -> str
:module: PyOpenColorIO

Get/Set the AMF transform IDs for the color space.

The AMF transform IDs are used to identify specific transforms in the ACES Metadata File. Multiple transform IDs can be specified in a newline-separated string.


.. py:method:: ColorSpace.getAliases(self: PyOpenColorIO.ColorSpace) -> PyOpenColorIO.ColorSpace.ColorSpaceAliasIterator
:module: PyOpenColorIO

Expand Down Expand Up @@ -104,6 +112,21 @@
Get the family, for use in user interfaces (optional) The family string could use a '/' separator to indicate levels to be used by hierarchical menus.


.. py:method:: ColorSpace.getICCProfileName(self: PyOpenColorIO.ColorSpace) -> str
:module: PyOpenColorIO

Get/Set the ICC profile name for the color space.

The ICC profile name identifies the ICC color profile associated with this color space. This can be used to link OCIO color spaces with corresponding ICC profiles for applications that need to work with both color management systems.


.. py:method:: ColorSpace.getInteropID(self: PyOpenColorIO.ColorSpace) -> str
:module: PyOpenColorIO

Get/Set the interop ID for the color space.

The interop ID is a standardized identifier to uniquely identify commonly used color spaces. These IDs are defined by the Academy Software Foundation's Color Interop Forum project. If you create your own ID, you must prefix it with unique characters that will ensure it won't conflict with future Color Interop Forum IDs.

.. py:method:: ColorSpace.getName(self: PyOpenColorIO.ColorSpace) -> str
:module: PyOpenColorIO

Expand All @@ -122,6 +145,11 @@
If a transform in the specified direction has been specified, return it. Otherwise return a null ConstTransformRcPtr


.. py:method:: ColorSpace.hasAlias(self: PyOpenColorIO.ColorSpace, alias: str) -> bool
:module: PyOpenColorIO

Return true if alias exists.

.. py:method:: ColorSpace.hasCategory(self: PyOpenColorIO.ColorSpace, category: str) -> bool
:module: PyOpenColorIO

Expand Down Expand Up @@ -168,6 +196,10 @@
Will do nothing if the category is missing.


.. py:method:: ColorSpace.setAMFTransformIDs(self: PyOpenColorIO.ColorSpace, amfTransformIDs: str) -> None
:module: PyOpenColorIO


.. py:method:: ColorSpace.setAllocation(self: PyOpenColorIO.ColorSpace, allocation: PyOpenColorIO.Allocation) -> None
:module: PyOpenColorIO

Expand Down Expand Up @@ -198,6 +230,14 @@
Set the family, for use in user interfaces (optional)


.. py:method:: ColorSpace.setICCProfileName(self: PyOpenColorIO.ColorSpace, iccProfileName: str) -> None
:module: PyOpenColorIO


.. py:method:: ColorSpace.setInteropID(self: PyOpenColorIO.ColorSpace, interopID: str) -> None
:module: PyOpenColorIO


.. py:method:: ColorSpace.setIsData(self: PyOpenColorIO.ColorSpace, isData: bool) -> None
:module: PyOpenColorIO

Expand Down
31 changes: 31 additions & 0 deletions include/OpenColorIO/OpenColorIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -1915,6 +1915,37 @@ class OCIOEXPORT ColorSpace
const char * getDescription() const noexcept;
void setDescription(const char * description);

/**
* Get/Set the interop ID for the color space.
*
* The interop ID is a standardized identifier to uniquely identify commonly
* used color spaces. These IDs are defined by the Academy Software
* Foundation's Color Interop Forum project. If you create your own ID, you
* must prefix it with unique characters that will ensure it won't conflict
* with future Color Interop Forum IDs.
*/
const char * getInteropID() const noexcept;
void setInteropID(const char * interopID);

/**
* Get/Set the AMF transform IDs for the color space.
*
* The AMF transform IDs are used to identify specific transforms in the ACES Metadata File.
* Multiple transform IDs can be specified in a newline-separated string.
*/
const char * getAMFTransformIDs() const noexcept;
void setAMFTransformIDs(const char * amfTransformIDs);

/**
* Get/Set the ICC profile name for the color space.
*
* The ICC profile name identifies the ICC color profile associated with this color space.
* This can be used to link OCIO color spaces with corresponding ICC profiles for
* applications that need to work with both color management systems.
*/
const char * getICCProfileName() const noexcept;
void setICCProfileName(const char * iccProfileName);

BitDepth getBitDepth() const noexcept;
void setBitDepth(BitDepth bitDepth);

Expand Down
12 changes: 6 additions & 6 deletions src/OpenColorIO/Baker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void Baker::setFormat(const char * formatName)
{
if (formatInfoVec[i].capabilities & FORMAT_CAPABILITY_BAKE)
{
getImpl()->m_formatName = formatName;
getImpl()->m_formatName = formatName ? formatName : "";
return;
}
}
Expand Down Expand Up @@ -155,7 +155,7 @@ FormatMetadata & Baker::getFormatMetadata()

void Baker::setInputSpace(const char * inputSpace)
{
getImpl()->m_inputSpace = inputSpace;
getImpl()->m_inputSpace = inputSpace ? inputSpace : "";
}

const char * Baker::getInputSpace() const
Expand All @@ -165,7 +165,7 @@ const char * Baker::getInputSpace() const

void Baker::setShaperSpace(const char * shaperSpace)
{
getImpl()->m_shaperSpace = shaperSpace;
getImpl()->m_shaperSpace = shaperSpace ? shaperSpace : "";
}

const char * Baker::getShaperSpace() const
Expand All @@ -175,7 +175,7 @@ const char * Baker::getShaperSpace() const

void Baker::setLooks(const char * looks)
{
getImpl()->m_looks = looks;
getImpl()->m_looks = looks ? looks : "";
}

const char * Baker::getLooks() const
Expand All @@ -185,7 +185,7 @@ const char * Baker::getLooks() const

void Baker::setTargetSpace(const char * targetSpace)
{
getImpl()->m_targetSpace = targetSpace;
getImpl()->m_targetSpace = targetSpace ? targetSpace : "";
}

const char * Baker::getTargetSpace() const
Expand All @@ -205,7 +205,7 @@ const char * Baker::getView() const

void Baker::setDisplayView(const char * display, const char * view)
{
if (!display ^ !view)
if (!display || !view)
{
throw Exception("Both display and view must be set.");
}
Expand Down
64 changes: 59 additions & 5 deletions src/OpenColorIO/ColorSpace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class ColorSpace::Impl
std::string m_equalityGroup;
std::string m_description;
std::string m_encoding;
std::string m_interopID;
std::string m_AMFTransformIDs;
std::string m_ICCProfileName;
StringUtils::StringVec m_aliases;

BitDepth m_bitDepth{ BIT_DEPTH_UNKNOWN };
Expand Down Expand Up @@ -62,6 +65,9 @@ class ColorSpace::Impl
m_equalityGroup = rhs.m_equalityGroup;
m_description = rhs.m_description;
m_encoding = rhs.m_encoding;
m_interopID = rhs.m_interopID;
m_AMFTransformIDs = rhs.m_AMFTransformIDs;
m_ICCProfileName = rhs.m_ICCProfileName;
m_bitDepth = rhs.m_bitDepth;
m_isData = rhs.m_isData;
m_referenceSpaceType = rhs.m_referenceSpaceType;
Expand Down Expand Up @@ -195,7 +201,7 @@ const char * ColorSpace::getFamily() const noexcept

void ColorSpace::setFamily(const char * family)
{
getImpl()->m_family = family;
getImpl()->m_family = family ? family : "";
}

const char * ColorSpace::getEqualityGroup() const noexcept
Expand All @@ -205,7 +211,7 @@ const char * ColorSpace::getEqualityGroup() const noexcept

void ColorSpace::setEqualityGroup(const char * equalityGroup)
{
getImpl()->m_equalityGroup = equalityGroup;
getImpl()->m_equalityGroup = equalityGroup ? equalityGroup : "";
}

const char * ColorSpace::getDescription() const noexcept
Expand All @@ -215,7 +221,37 @@ const char * ColorSpace::getDescription() const noexcept

void ColorSpace::setDescription(const char * description)
{
getImpl()->m_description = description;
getImpl()->m_description = description ? description : "";
}

const char * ColorSpace::getInteropID() const noexcept
{
return getImpl()->m_interopID.c_str();
}

void ColorSpace::setInteropID(const char * interopID)
{
getImpl()->m_interopID = interopID ? interopID : "";
}

const char * ColorSpace::getAMFTransformIDs() const noexcept
{
return getImpl()->m_AMFTransformIDs.c_str();
}

void ColorSpace::setAMFTransformIDs(const char * amfTransformIDs)
{
getImpl()->m_AMFTransformIDs = amfTransformIDs ? amfTransformIDs : "";
}

const char * ColorSpace::getICCProfileName() const noexcept
{
return getImpl()->m_ICCProfileName.c_str();
}

void ColorSpace::setICCProfileName(const char * iccProfileName)
{
getImpl()->m_ICCProfileName = iccProfileName ? iccProfileName : "";
}

BitDepth ColorSpace::getBitDepth() const noexcept
Expand Down Expand Up @@ -265,7 +301,7 @@ const char * ColorSpace::getEncoding() const noexcept

void ColorSpace::setEncoding(const char * encoding)
{
getImpl()->m_encoding = encoding;
getImpl()->m_encoding = encoding ? encoding : "";
}

bool ColorSpace::isData() const noexcept
Expand Down Expand Up @@ -371,7 +407,6 @@ std::ostream & operator<< (std::ostream & os, const ColorSpace & cs)
break;
}
os << "name=" << cs.getName() << ", ";
std::string str{ cs.getFamily() };
const auto numAliases = cs.getNumAliases();
if (numAliases == 1)
{
Expand All @@ -386,6 +421,15 @@ std::ostream & operator<< (std::ostream & os, const ColorSpace & cs)
}
os << "], ";
}

std::string str;

str = cs.getInteropID();
if (!str.empty())
{
os << "interop_id=" << str << ", ";
}
str = cs.getFamily();
if (!str.empty())
{
os << "family=" << str << ", ";
Expand Down Expand Up @@ -429,6 +473,16 @@ std::ostream & operator<< (std::ostream & os, const ColorSpace & cs)
{
os << ", description=" << str;
}
str = cs.getAMFTransformIDs();
if (!str.empty())
{
os << ", amf_transform_ids=" << str;
Copy link
Owner Author

@cozdas cozdas Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we're not parsing the string value that AMFTransformIDs field holds. Since the formatting stayed the same, that is multiple entities are separated with the newline character, this may create EOLs in the ostream.

Is this OK? Or should we try to create a list from each entity here (that requires tokenizing the string with /n/r separators).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description has the same problem. Maybe for both we should just add something like "=(non-empty)" rather than trying to include the whole string? Or a hash value?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave those as-is for now, we can decide/change if a real need arises.

}
str = cs.getICCProfileName();
if (!str.empty())
{
os << ", icc_profile_name=" << str;
}
if(cs.getTransform(COLORSPACE_DIR_TO_REFERENCE))
{
os << ",\n " << cs.getName() << " --> Reference";
Expand Down
46 changes: 37 additions & 9 deletions src/OpenColorIO/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ static constexpr unsigned LastSupportedMajorVersion = OCIO_VERSION_MAJOR;

// For each major version keep the most recent minor.
static const unsigned int LastSupportedMinorVersion[] = {0, // Version 1
4 // Version 2
5 // Version 2
};

} // namespace
Expand Down Expand Up @@ -1185,7 +1185,7 @@ ConstConfigRcPtr Config::CreateFromFile(const char * filename)
// Check if it is an OCIOZ archive.
if (magicNumber[0] == 'P' && magicNumber[1] == 'K')
{
// Closing ifstream even though it should be close by ifstream deconstructor (RAII).
// Closing ifstream even though it should be closed by ifstream destructor (RAII).
ifstream.close();

// The file should be an OCIOZ archive file.
Expand Down Expand Up @@ -1499,7 +1499,8 @@ void Config::validate() const


// Check for interchange roles requirements - scene-referred and display-referred.
if (getMajorVersion() >= 2 && getMinorVersion() >= 2)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would work only until v3.0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. But you could use GetVersionHex() rather than making your own.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that but that's a global function returning the library's version, not the config's current version.
I can add a function to Config class but that may break ABI.

unsigned int versionHex = (getMajorVersion() << 24) | (getMinorVersion() << 16);
if (versionHex >= 0x02020000u) // v2.2 or higher
{
bool hasRoleSceneLinear = false;
bool hasRoleCompositingLog = false;
Expand Down Expand Up @@ -5426,6 +5427,8 @@ void Config::Impl::checkVersionConsistency(ConstTransformRcPtr & transform) cons

void Config::Impl::checkVersionConsistency() const
{
unsigned int hexVersion = (m_majorVersion << 24) | (m_minorVersion << 16);

// Check for the Transforms.

ConstTransformVec transforms;
Expand Down Expand Up @@ -5495,18 +5498,43 @@ void Config::Impl::checkVersionConsistency() const
}
}

// Check for the DisplayColorSpaces.
// Check for the ColorSpaces.

if (m_majorVersion < 2)
const int nbCS = m_allColorSpaces->getNumColorSpaces();
for (int i = 0; i < nbCS; ++i)
{
const int nbCS = m_allColorSpaces->getNumColorSpaces();
for (int i = 0; i < nbCS; ++i)
const auto & cs = m_allColorSpaces->getColorSpaceByIndex(i);
if (m_majorVersion < 2)
{
const auto & cs = m_allColorSpaces->getColorSpaceByIndex(i);
if (MatchReferenceType(SEARCH_REFERENCE_SPACE_DISPLAY, cs->getReferenceSpaceType()))
if (MatchReferenceType(SEARCH_REFERENCE_SPACE_DISPLAY, cs->getReferenceSpaceType()))
{
throw Exception("Only version 2 (or higher) can have DisplayColorSpaces.");
}
}

if (hexVersion < 0x02050000) // Version 2.5
{
if (*cs->getInteropID())
{
std::ostringstream os;
os << "Config failed validation. The color space '" << cs->getName() << "' ";
os << "has non-empty InteropID and config version is less than 2.5.";
throw Exception(os.str().c_str());
}
if (*cs->getAMFTransformIDs())
{
std::ostringstream os;
os << "Config failed validation. The color space '" << cs->getName() << "' ";
os << "has non-empty AMFTransformIDs and config version is less than 2.5.";
throw Exception(os.str().c_str());
}
if (*cs->getICCProfileName())
{
std::ostringstream os;
os << "Config failed validation. The color space '" << cs->getName() << "' ";
os << "has non-empty ICCProfileName and config version is less than 2.5.";
throw Exception(os.str().c_str());
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/OpenColorIO/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void Context::setWorkingDir(const char * dirname)
{
AutoMutex lock(getImpl()->m_resultsCacheMutex);

getImpl()->m_workingDir = dirname;
getImpl()->m_workingDir = dirname ? dirname : "";
getImpl()->clearCaches();
}

Expand Down
Loading
Loading