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

Port from master to RB-2.0 - Adsk Contrib - Improve File Rules support for v1 configs (#1417) #1441

Closed
wants to merge 2 commits into from
Closed
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
16 changes: 8 additions & 8 deletions docs/guides/authoring/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -300,40 +300,40 @@ to use to control other types of tasks not listed below.

* ``color_picking`` - colors in a color-selection UI can be displayed
in this space, while selecting colors in a different working space
(e.g. ``scene_linear`` or ``texture_paint``)
(e.g. ``scene_linear`` or ``texture_paint``).

* ``color_timing`` - color space used for applying color corrections,
e.g. user-specified grade within an image viewer (if the application
uses the ``DisplayTransform::setDisplayCC`` API method)

* ``compositing_log`` - a log color space used for certain processing
operations (plate resizing, pulling keys, degrain, etc). Used by the
OCIOLogConvert Nuke node
OCIOLogConvert Nuke node.

* ``data`` - used when writing data outputs such as normals, depth
data, and other "non color" data. The color space in this role should
typically have ``data: true`` specified, so no color transforms are
applied
applied.

* ``default`` - when ``strictparsing: false``, this color space is used
as a fallback. If not defined, the ``scene_linear`` role is used
as a fallback.

* ``matte_paint`` - color space which matte-paintings are created in
(for more information, :ref:`see the guide on baking ICC profiles
for Photoshop <userguide-bakelut-photoshop>`, and
:ref:`config-spivfx`)
:ref:`config-spivfx`).

* ``reference`` - the color space against which the other color spaces
are defined
are defined.

.. note::
The reference role has sometimes been misinterpreted as being the
space in which "reference art" is stored in.

* ``scene_linear`` - the scene-referred linear-to-light color space,
often the same as the reference space (see:ref:`faq-terminology`)
often the same as the reference space (see:ref:`faq-terminology`).

* ``texture_paint`` - similar to ``matte_paint`` but for painting
textures for 3D objects (see the description of texture painting in
:ref:`SPI's pipeline <config-spipipeline-texture>`)
:ref:`SPI's pipeline <config-spipipeline-texture>`).

2 changes: 1 addition & 1 deletion docs/guides/authoring/rules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ determine the colorspace ``lnf`` (it being the right-most substring
containing a colorspace name)

However, if the colorspace cannot be determined and ``strictparsing:
true``, it will produce an error.
true``, it will return an empty string.

If the colorspace cannot be determined and ``strictparsing: false``,
the default role will be used. This allows unhandled images to operate
Expand Down
111 changes: 52 additions & 59 deletions include/OpenColorIO/OpenColorIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,8 @@ class OCIOEXPORT Config
*/
void setFileRules(ConstFileRulesRcPtr fileRules);

/// Get the color space of the first rule that matched filePath.
/// Get the color space of the first rule that matched filePath. (For v1 configs, this is
/// equivalent to calling parseColorSpaceFromString with strictparsing set to false.)
const char * getColorSpaceFromFilepath(const char * filePath) const;

/**
Expand Down Expand Up @@ -1149,64 +1150,56 @@ class OCIOEXPORT Config
extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Config&);



// TODO: Move to .rst
// FileRules
// *********
// The File Rules are a set of filepath to color space mappings that are evaluated
// from first to last. The first rule to match is what determines which color space is
// returned. There are four types of rules available. Each rule type has a name key that may
// be used by applications to refer to that rule. Name values must be unique i.e. using a
// case insensitive comparison. The other keys depend on the rule type:
//
// - Basic Rule: This is the basic rule type that uses Unix glob style pattern matching and
// is thus very easy to use. It contains the keys:
//
// * name: Name of the rule
//
// * colorspace: Color space name to be returned.
//
// * pattern: Glob pattern to be used for the main part of the name/path.
//
// * extension: Glob pattern to be used for the file extension. Note that if glob tokens
// are not used, the extension will be used in a non-case-sensitive way by default.
//
// - Regex Rule: This is similar to the basic rule but allows additional capabilities for
// power-users. It contains the keys:
//
// * name: Name of the rule
//
// * colorspace: Color space name to be returned.
//
// * regex: Regular expression to be evaluated.
//
// - OCIO v1 style Rule: This rule allows the use of the OCIO v1 style, where the string
// is searched for color space names from the config. This rule may occur 0 or 1 times
// in the list. The position in the list prioritizes it with respect to the other rules.
// StrictParsing is not used. If no color space is found in the path, the rule will not
// match and the next rule will be considered.
// \see FileRules::insertPathSearchRule.
// It has the key:
//
// * name: Must be "ColorSpaceNamePathSearch".
//
// - Default Rule: The file_rules must always end with this rule. If no prior rules match,
// this rule specifies the color space applications will use.
// \see FileRules::setDefaultRuleColorSpace.
// It has the keys:
//
// * name: must be "Default".
//
// * colorspace : Color space name to be returned.
//
// Custom string keys and associated string values may be used to convey app or
// workflow-specific information, e.g. whether the color space should be left as is
// or converted into a working space.
//
// Getters and setters are using the rule position, they will throw if the position is not
// valid. If the rule at the specified position does not implement the requested property
// getter will return NULL and setter will throw.
//
/**
* \brief
* The File Rules are a set of filepath to color space mappings that are evaluated
* from first to last. The first rule to match is what determines which color space is
* returned. There are four types of rules available. Each rule type has a name key that may
* be used by applications to refer to that rule. Name values must be unique i.e. using a
* case insensitive comparison. The other keys depend on the rule type:
*
* * *Basic Rule*: This is the basic rule type that uses Unix glob style pattern matching and
* is thus very easy to use. It contains the keys:
* * name: Name of the rule
* * colorspace: Color space name to be returned.
* * pattern: Glob pattern to be used for the main part of the name/path.
* * extension: Glob pattern to be used for the file extension. Note that if glob tokens
* are not used, the extension will be used in a non-case-sensitive way by default.
*
* * *Regex Rule*: This is similar to the basic rule but allows additional capabilities for
* power-users. It contains the keys:
* * name: Name of the rule
* * colorspace: Color space name to be returned.
* * regex: Regular expression to be evaluated.
*
* * *OCIO v1 style Rule*: This rule allows the use of the OCIO v1 style, where the string
* is searched for color space names from the config. This rule may occur 0 or 1 times
* in the list. The position in the list prioritizes it with respect to the other rules.
* StrictParsing is not used. If no color space is found in the path, the rule will not
* match and the next rule will be considered.
* see \ref insertPathSearchRule.
* It has the key:
* * name: Must be "ColorSpaceNamePathSearch".
*
* * *Default Rule*: The file_rules must always end with this rule. If no prior rules match,
* this rule specifies the color space applications will use.
* see \ref setDefaultRuleColorSpace.
* It has the keys:
* * name: must be "Default".
* * colorspace : Color space name to be returned.
*
* Custom string keys and associated string values may be used to convey app or
* workflow-specific information, e.g. whether the color space should be left as is
* or converted into a working space.
*
* Getters and setters are using the rule position, they will throw if the position is not
* valid. If the rule at the specified position does not implement the requested property
* getter will return NULL and setter will throw.
*
* When loading a v1 config, a set of FileRules are created with ColorSpaceNamePathSearch followed
* by the Default rule pointing to the default role. This allows getColorSpaceFromFilepath to emulate
* OCIO v1 code that used parseColorSpaceFromString with strictparsing set to false.
*/

class OCIOEXPORT FileRules
{
Expand Down
107 changes: 17 additions & 90 deletions src/OpenColorIO/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,24 +192,6 @@ void GetColorSpaceReferences(std::set<std::string> & colorSpaceNames,
}
}

static constexpr char AddedDefault[]{ "added_default_rule_colorspace" };

void FindAvailableName(const ColorSpaceSetRcPtr & colorspaces, std::string & csname)
{
int i = 0;
csname = AddedDefault;
while (true)
{
if (!colorspaces->hasColorSpace(csname.c_str()))
{
break;
}

csname = AddedDefault + std::to_string(i);
++i;
}
}

// Views are stored in two vectors of objects, using pointers to temporarily group them.
typedef std::vector<const View *> ViewPtrVec;

Expand Down Expand Up @@ -591,56 +573,6 @@ class Config::Impl

static ConstConfigRcPtr Read(std::istream & istream, const char * filename);

// Upgrade from v1 to v2.
void upgradeFromVersion1ToVersion2() noexcept
{
// V2 adds file_rules and these require a default rule. We try to initialize the default
// rule using the default role. If the default role doesn't exist, we look for a Raw
// ColorSpace with isdata true. If that is not found either, we add new ColorSpace
// named "added_default_rule_colorspace".

m_majorVersion = 2;
m_minorVersion = 0;

const char * rname = LookupRole(m_roles, ROLE_DEFAULT);
if (!hasColorSpace(rname))
{
std::string defaultCS;
bool addNewDefault = true;
// The default role doesn't exist so look for a color space named "raw"
// (not case-sensitive) with isdata true.
const int csindex = getColorSpaceIndex("raw");
if (-1 != csindex)
{
auto cs = m_allColorSpaces->getColorSpaceByIndex(csindex);
if (cs->isData())
{
// "Raw" color space can be used for default.
addNewDefault = false;
defaultCS = cs->getName();
}
}

if (addNewDefault)
{
FindAvailableName(m_allColorSpaces, defaultCS);
auto newCS = ColorSpace::Create();
newCS->setName(defaultCS.c_str());
newCS->setIsData(true);
m_allColorSpaces->addColorSpace(newCS);
// Put the added CS in the inactive list to avoid it showing up in user menus.
if (!m_inactiveColorSpaceNamesConf.empty())
{
m_inactiveColorSpaceNamesConf += ",";
}
m_inactiveColorSpaceNamesConf += defaultCS;
setInactiveColorSpaces(m_inactiveColorSpaceNamesConf.c_str());
}

m_fileRules->setColorSpace(m_fileRules->getNumEntries() - 1, defaultCS.c_str());
}
}

// Validate view object that can be a config defined shared view or a display-defined view.
void validateView(const std::string & display, const View & view, bool checkUseDisplayName) const
{
Expand Down Expand Up @@ -1269,15 +1201,19 @@ void Config::upgradeToLatestVersion() noexcept
{
if (wasVersion == 1)
{
m_impl->upgradeFromVersion1ToVersion2();
UpdateFileRulesFromV1ToV2(*this, m_impl->m_fileRules);

// The instance version is now 2.0
m_impl->m_majorVersion = 2;
m_impl->m_minorVersion = 0;
}

static_assert(LastSupportedMajorVersion == 2, "Config: Handle newer versions");
setMajorVersion(LastSupportedMajorVersion);
setMinorVersion(LastSupportedMinorVersion[LastSupportedMajorVersion - 1]);
}
}


ConfigRcPtr Config::createEditableCopy() const
{
ConfigRcPtr config = Config::Create();
Expand Down Expand Up @@ -1757,26 +1693,17 @@ void Config::validate() const

///// FileRules

// All Config objects have a fileRules object, regardless of version. This object is
// initialized to have a defaultRule with the color space set to "default" (i.e., the default
// role). The fileRules->validate call will validate that all color spaces used in rules
// exist, or if they are roles that they point to a color space that exists. Because this would
// cause validate to improperly fail on v1 configs (since they are not required to actually
// contain file rules), we don't do this check on v1 configs when there is only one rule.
if (getMajorVersion() >= 2 || getImpl()->m_fileRules->getNumEntries() != 1)
try
{
try
{
getImpl()->m_fileRules->getImpl()->validate(*this);
}
catch (const Exception & e)
{
std::ostringstream os;
os << "Config failed validation. File rules failed with: ";
os << e.what();
getImpl()->m_validationtext = os.str();
throw Exception(getImpl()->m_validationtext.c_str());
}
getImpl()->m_fileRules->getImpl()->validate(*this);
}
catch (const Exception & e)
{
std::ostringstream os;
os << "Config failed validation. File rules failed with: ";
os << e.what();
getImpl()->m_validationtext = os.str();
throw Exception(getImpl()->m_validationtext.c_str());
}

///// Resolve all file Transforms using context variables.
Expand Down Expand Up @@ -4718,7 +4645,7 @@ void Config::Impl::checkVersionConsistency() const

// Check for the file rules.

if (m_majorVersion < 2 && m_fileRules->getNumEntries() > 1)
if (m_majorVersion < 2 && m_fileRules->getNumEntries() > 2)
{
throw Exception("Only version 2 (or higher) can have file rules.");
}
Expand Down
Loading