Repository navigation
Reference an OCIO Import or Export Transform using a single string syntax #2316
Description
Activity
- addedFeature RequestNew addition to OCIO functionality.New addition to OCIO functionality.Needs DiscussionNeeds discussion before implmentation, which could result in changes, or a decision not to proceed.Needs discussion before implmentation, which could result in changes, or a decision not to proceed.
on May 23, 2026 Doug, when you write
"<colorSpaceName>", it ends up rendering as "". (Look at the raw source of this comment to see what I mean.) Some of what you wrote above is probably not correctly visible when rendered.FWIW, I've long wished for a single-string way to express both the color space and any display/view applied, etc. as a single label for what comes of any OCIO-mediated transform.
Thanks Larry, I edited the text above to avoid
<colorSpaceName>being dropped.Thanks Larry, I edited the text above to avoid
<colorSpaceName>being dropped.I think there's at least one more, in the very next sentence, which renders as: DisplayViewTransform arguments could be " ()",
Argh, sorry Larry, I fixed that one too now. Looks like that was the last one.
I only recognized what was happening because I did exactly the same thing earlier in the week!
Reacted by Doug WalkerFor the record - repeating my comment from the last meeting ...
Rather than keep implementing lots of new mini parsers, I think something like JSON should be used for the more complex cases at least. It can be quite compact vs XML or even YAML, and there are support libraries that can validate using schemas etc. Should fit well into OTIO etc.
I think whats nice about this is that you can assume you have a single ocio-colorspace field that has a somewhat human readable value, if you go down the road of stuffing XML, YML or JSON into a text string, you then need to add an interpreter to the UI to make it human readable. It does feel like what Doug is proposing satisfies most cases, its only when you start getting into multiple context variables will things get a bit more out of control.
Having said that, the only part I dont get is specifying the working space. That feels like you are asking for trouble, like if you are using this string in a file, and the file you are importing it into has a working space, does this override that working space for everything?
We discussed this some more at the OCIO working group meeting today. Just capturing a few comments from that discussion:
Mark Boorer:
- Worried about the potential complexity of trying to do this, especially if supporting context vars.
- Could we not ask OTIO to have multiple strings for the different OCIO transform arguments?
- Would this impose limitations on characters usable in color space names?
- We already have other structured string representations (built-in configs, Interop IDs, YAML, CTF), perhaps build on one of those rather than adding a new thing?
- Do we really want to add a JSON parser dependency?
Sean Cooper:
- In OTIO, is this supposed to be a description of the color space of the source clip, or a recipe for the transform to apply? Doug: it's the latter.
Zach Lewis:
- Would like the metadata do be descriptive of the source, useful for downstream processing.
- Do we need a "tag only" option?
A single-string transform reference sounds useful, but the grammar and round-trip rules are the key design surface. It would help to specify how file paths, named transforms, looks, color spaces, and direction are escaped, and whether the string can be losslessly converted back to the structured form. A few examples with spaces and separators in names would make review much easier.
Just want to point out, there will need to be some bracket parsing since you could have a display/view combination like:
Rec.2100-PQ - Display (ACES 2.0 - HDR 1000 nits (Rec. 2020))Could be a bit unpleasant if we also have colorspace names like "ARRI LogC3 (EI800) - Wide Gamut", hopefully somebody doesnt rename it as "ARRI LogC3 - Wide Gamut (EI800)" Or do we match inside the brackets to a view first and then the rest to a display?
Just noticed you are saying:
DisplayViewTransform: "ociodisplayview: {}"
and
DisplayViewTransform: This uses parentheses to separate the tokens " ()".Especially since you are calling it "Display" - "View" transform, shouldnt it be " ()"
and similarly for ociodisplayview: ()"
switching the "{}" for "()"....@richardssam, for the Simple Syntax, yes, the parser would need to match up the display and view to components in the referenced config file, so I don't think there is too much of an issue around parens being misinterpreted.
Regarding the Flexible Syntax, as I mentioned at the CIF meeting, I'd like to make a new proposal, which will avoid all the syntax complications. The new proposal is to leverage the existing Yaml syntax from the config files. Specifically, the string would be allowed to contain anything you could put in a GroupTransform as part of a ColorSpace object. The most frequently used syntax would likely be a single ColorSpaceTransform or DisplayViewTransform, but it would be allowed to stack multiple items, as in a GroupTransform. Here's a simple example:
<DisplayViewTransform> {src: ACEScg, display: sRGB - Display, view: ACES 2.0 - SDR 100 nits (Rec.709), direction: inverse}Here's a longer example:
<LogCameraTransform> {log_side_slope: 0.0647, log_side_offset: -0.295, lin_side_slope: 2231.8, lin_side_offset: 64, lin_side_break: -0.018, direction: inverse} <MatrixTransform> {matrix: [0.7509, 0.1444, 0.1046, 0, 0.0008218, 1.007, -0.008219, 0, -0.0004999, -0.0008541, 1.001, 0, 0, 0, 0, 1]}Note that the second example is self-contained and would not require referencing a config file. This could potentially open up interop workflows with software that doesn't use OCIO, but is able to represent a similar operator set.
In both examples, the working space is either called out explicitly (as a named color space), or implicitly as part of the assumption underlying the transform contents. This implies that if the working space were changed, the string would need to be updated. But, keep in mind that if the working space changes significantly (e.g., the image state changes), the transform needs to be revisited anyway.
It's worth calling out that this proposal makes the direction explicit since the config Yaml syntax has an explicit transform
directionattribute.In addition to the transform, it's desirable for the syntax to specify the resulting color space. This happens implicitly for transform types such as ColorSpaceTransform, but not for FileTransform or the other "building block" transforms. In that case, I propose that we add a TaggingTransform that could be inserted at the end to label the color space of the result. This would allow easier validation if the working space needs to be modified.
The original proposal above mentioned the possibility of using NamedTransforms too. These are not usable in a ColorSpace GroupTransform currently. However, I don't believe it's essential to include them anymore since the components in a NamedTransform's GroupTransform are supported. So the solution would be to simply call the desired NamedTransforms' transform components directly.
The new proposal does not include support for context variables, though we could discuss how to add them, if people feel they are essential.
In the last meeting you mentioned for file inputs that we might need to specify the working colorspace as part of the specification.
e.g.
Could I use just "ARRI LogC3 (EI800)" or would I need to specify "ARRI LogC3 (EI800) | workingSpace=ACEScg"Would it be up to the developer to append the working space?
Based on the proposal from yesterday for the flexible syntax, the string would be:
<ColorSpaceTransform> {src: ARRI LogC3 (EI800), dst: ACEScg}I don't think the flexible syntax should be exposed directly to end-users, there should be a UI that sits on top of it. So, yes there would be work required of the developer.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNext
Problem Statement
There are three primary means for applications to use OCIO to transform colors to or from a working color space: ColorSpaceTransform, DIsplayViewTransform, and FileTransform.
Sometimes it's convenient to be able to specify the arguments for doing that as a single string. Many applications do this already to support the ColorSpaceTransfom case. That string is simple, it's just the color space of the incoming media.
In fact some applications or frameworks are setup so that they would like to always have just a single string to hold this information (particularly applications that were designed in the OCIO v1 era). This came up recently during the OpenTimelineIO color management discussions. It would be nice to have a single string that could be associated with a piece of media that would describe to OCIO how to convert it to a working color space.
In the case of OTIO, the use-case was primarily around converting into a working space on import. But there are other use-cases where this would be helpful to convert from a working space on export. It would be helpful if the syntax could support both directions. Though typically, it will be clear from the context which direction is involved, so it might not need to be explicitly stated.
One complication for such a syntax is that OCIO is very flexible in terms of how it allows color spaces to be named. The only characters that are disallowed are the ones used to define context variables. What characters should be used to break the string into tokens? Another complication are context variables themselves, should the syntax allow specifying an arbitrary set of string/value context variable pairs?
It might be nice if the syntax was essentially invisible for the simple cases. In other words, if it is just a color space name, then that's the complete string "
<colorSpaceName>". Similarly, the DisplayViewTransform arguments could be "<view> (<display>)", which is already a common way of combining the display and view into a single string. And as long as the FileTranform has an extension, the LUT file name could typically be disambiguated from the other cases without any additional syntax.Of course, while that is nice and simple, there are potential ways it could fail. For example, a color space could use parentheses so that it looks like a "view (display)" combination. It is unlikely that both of those possibilities would exist in a single config, however, there is probably a need for a more verbose but flexible syntax that could be used in cases where the intent might not be clear, even within the context of a given config. And it might be helpful to allow specifying other information.
Proposal
Here is a proposal for a single-string syntax that applications could use to with OCIO to import to a working color space or export from a working color space. There is a both a "simple syntax" and a "flexible syntax".
Simple Syntax
ColorSpaceTransform: This is simply the color space name.
DisplayViewTransform: This uses parentheses to separate the tokens "
<view> (<display>)".FileTransform: The string is simply the name of the LUT file. If a relative path is provided, the config search_path could be used, along with whatever other information the application might have, to resolve the path.
Flexible Syntax
ColorSpaceTransform: "
ociocolorspace: <colorSpaceName>"DisplayViewTranform: "
ociodisplayview: <viewName> {<displayName>}"FileTransform: "
ociofile: <filePath>"NamedTransform: "
ocionamedtransform: <transformName>"In the DisplayView case, if either the display or view name use the "{" or "}" characters, they would need to be escaped with a backslash.
Any of these could then be followed with context variable tokens as follows: "
| <cvName1>=<cvValue1> | <cvName2>=<cvValue2> |"For the FileTransform case, additional parameters such as CCCId, CDLStyle, and Interpolation could be specified similarly to context variables. For example: "
| Interpolation=tetrahedral |".The working color space for the transform may be added similarly: "
| workingSpace=<colorSpaceName> |". This would be helpful to invalidate the string if the working space later has changed.The inverse direction would be added as: "
| direction=inverse |". Note that this could be relevant for DisplayViewTransform as well as obviously FileTransform and NamedTransform.The parser will strip extra white space such as spaces and newlines, if that is helpful to keep the flexible syntax human readable.
API
We would add a function to the API as a method of the Config class that would accept a working color space name, a direction (forward/inverse), and the string (either simple or flexible syntax) and return an OCIO Processor object of the necessary type. It would throw if the string could not be interpreted. (If we don't want to support context variables, it could return a Transform object rather than a Processor, which would be more useful in some cases.)
We would add the inverse function that would take an enum to choose between Simple or Flexible syntax, a ColorSpaceTransform, DisplayViewTransform, or FileTransform, working color space, and a Context object (which could be null) and return the string. If Simple syntax is requested but not supported, it would throw. We would add a similar function that takes a NamedTransform (since it is not a Transform).
Limitations & Assumptions
One assumption is that a config file would need to be provided along with the string, it's not intended to be meaningful on its own (except in the case of a FileTransform).
Another assumption is that the direction (to or from working space) will be clear from the context.
Another assumption is that when this string is generated, the desired working space that the transform converts to (or from) is known. Furthermore, if the working space is later changed, any existing strings would potentially be invalidated. Certainly that would be true for FileTransform, but it could be true in other cases too, for example, if the the image state of the working space changes from scene-referred to display-referred, or vice versa.
Conclusion
That's a rough strawman to start the conversation. Let's start the discussion around what functionality is desired first, before getting into details of the syntax, which I'm sure could be improved later.
For reference, here is a related request in the ColorInterop issues.