OpenColorIO icon indicating copy to clipboard operation
OpenColorIO copied to clipboard

Add color space attribute for an "interop" ID

Open doug-walker opened this issue 8 months ago • 9 comments

The TSC has discussed many scenarios where applications need to create a correspondence between color spaces in a config and "known" external color spaces. Examples of this are:

  • Color space enums in external graphics APIs (macOS, iOS, Windows, Wayland, Android, Vulkan, etc.)
  • Color space IDs in asset file formats (MaterialX, OpenUSD, etc.)
  • Color spaces for common CICP values

It would be cumbersome for OCIO to try and maintain all of these mappings, there are dozens of them. Furthermore, they evolve over time and this would create challenges if we tried to store these values in the configs themselves.

Instead, OCIO should focus on a method for applications to identify the correspondence between a color space in a config and an unambiguous external definition.

The Color Interop Forum has already worked on producing an example of an unambiguous external definition: the Color Space Recommendations for Texture Assets and CG Rendering. The intent is for the Color Interop Forum to next take on the task of producing a similar recommendation for display color spaces that would include CICP values and enums for external graphics APIs.

The proposal is that OCIO add a new attribute for color spaces named "interop_id" that would hold a string that is used to establish this connection to an external reference. (This would be the "compact name" defined in the texture asset recommendation mentioned above, for example, "lin_rec709_scene".)

The intention is that this interop ID would be more stable over time than the user-facing color space names (which we've seen evolve, for example, in the ACES configs).

The interop ID should be a good choice for embedding in external asset formats such as OpenEXR, OpenUSD, and MaterialX.

It is intended that if a config author includes an interop ID from a Color Interop Forum recommendation, that they are using the exact transform specified in that recommendation. At some future point, it might be desirable to provide a function that would check that is true. In the meantime, it would be helpful to provide built-in transforms for all of the Color Interop Forum color spaces.

For color spaces that do not exist in Color Interop Forum recommendations, it is proposed that config authors should be allowed to populate their own interop ID string. Some sort of namespace mechanism could be used, if desired.

It will be up to applications to know how to handle the interop ID and manage their own mapping to external references. The Color Interop Forum recommendations will be helpful here. However, tracking the latest changes in all of these external formats and standards is a large task and it's not something that OCIO should try to manage. For example, we don't want to have to release a new OCIO library every time some external graphics API makes a change to their enum list.

The interop_id string would not automatically be considered an alias. If a config author wants the string to be considered an alias, they will need to add it to the aliases attribute as well.

Unlike color space names or aliases, it will be allowed for more than one color space to use a given interop ID.

doug-walker avatar Apr 29 '25 01:04 doug-walker

For color spaces that do not exist in Color Interop Forum recommendations, it is proposed that config authors should be allowed to populate their own interop ID string. Some sort of namespace mechanism could be used, if desired.

The IDs must be unique to unambiguously point to the same transformation: How does a user know he whether the id he picked is unique/already existing, e.g., lin_rec709_scene, without an authority / registrar to query from? Namespacing should be an absolute requirement even though it will not prevent a random user to define a framestore/framestore_wide_2 id. 🤔

KelSolaar avatar Jun 02 '25 20:06 KelSolaar

@KelSolaar , the way I was thinking about this is that the Color Interop Forum would be the registration authority and will be gradually adding new IDs over time and publishing the current list on its GitHub.

So for config authors coming up with interop IDs for their private color spaces, they will need to make their IDs unique somehow simply to ensure that the Color Interop Forum never decides to use that same string.

So what I meant by "namespacing" above was intended to be some informal convention used by individual config authors to choose a unique name. Are you saying that we should instead have a formal namespacing as part of the ID? That is, two separate tokens within the string? So for example the getter & setter for this attribute would take two separate strings? I'm not opposed to that, but it would help if you could give some examples of the benefits.

One thing that I would not want to see happen is people using the Color Interop Forum IDs with a different namespace, that could cause some confusion if the namespace gets separated.

If there is a separate namespace token, how would you envision it being handled when writing into the "color space" attribute of a file format?

I was anticipating that the interop IDs could be used as if they were color spaces. For example, extract the ID from the ocioColorSpace attribute of an EXR file and then look it up in a config as if it were a color space (assuming the config author has added it as an alias). I guess the namespace token in that scenario would be used to select the config to use?

doug-walker avatar Jun 02 '25 23:06 doug-walker

Yes, I was thinking an explicit, tokenizable, namespace that could be used to identify unambiguously the "vendor/creator". This would be in the vein of the ACEStransformID or CLFtransformID. lin_rec709_scene does not tell us any of that and does not allow programmatic partitioning/categorisation. With a namespace, we can start grouping the transformations and present them to users, e.g.,

  • color_interop_forum
    • lin_ap1_scene (color_interop_forum:lin_ap1_scene)
    • lin_ap0_scene (color_interop_forum:lin_ap0_scene)
    • lin_rec709_scene (color_interop_forum:lin_rec709_scene)
    • lin_p3d65_scene (color_interop_forum:lin_p3d65_scene)
    • lin_rec2020_scene (color_interop_forum:lin_rec2020_scene)
    • lin_adobergb_scene (color_interop_forum:lin_adobergb_scene)
    • lin_ciexyzd65_scene (color_interop_forum:lin_ciexyzd65_scene)
    • srgb_rec709_scene (color_interop_forum:srgb_rec709_scene)
    • g22_rec709_scene (color_interop_forum:g22_rec709_scene)
    • g18_rec709_scene (color_interop_forum:g18_rec709_scene)
    • srgb_ap1_scene (color_interop_forum:srgb_ap1_scene)
    • g22_ap1_scene (color_interop_forum:g22_ap1_scene)
    • srgb_p3d65_scene (color_interop_forum:srgb_p3d65_scene)
    • g22_adobergb_scene (color_interop_forum:g22_adobergb_scene)
  • framestore
    • framestorewide (framestore:framestorewide)
    • framestorewide2 (framestore:framestorewide2)

We can also see rapidly what is official or not, etc...

Edit: I'm not attached to : as a separator, / or . would work equally well.

KelSolaar avatar Jun 03 '25 01:06 KelSolaar

Hmmmm, I'm still not understanding the benefit of splitting it into two tokens with a formal namespace. I was not planning on the interop ID being a user-facing thing. It is not intended to supplant the canonical color space name. Yes, users may see these if they are inspecting the metadata in a file format, but they should not see them in typical color space menus.

I would argue that just because an ID starts with a "color_interop_forum" token, that does not mean it's official. It's only official if the second token is actually a Color Interop Forum ID (in other words, it needs to be compared with the official registry list).

doug-walker avatar Jun 03 '25 05:06 doug-walker

By user, I mean API users, developers.

I would argue that just because an ID starts with a "color_interop_forum" token, that does not mean it's official.

Most certainly! But then what is the mechanism for fetching this information? I'm trying to cater for the spawn of official "vendor" registry with their own ids, like it did happen with the IDTs and having a namespace in that situation is extremely useful for categorisation.

We for example spent a great deal of time ensuring that our CLFtransformIDs were properly namespaced:

Image

KelSolaar avatar Jun 03 '25 07:06 KelSolaar

So a reason for name spacing is to help avoid collisions within a distributed system (at the expense of potentially duplicated definitions), the alternate would be for the single registry to be easily and quickly updated. If we had such a singular mechanism the problem then turns into how to ensure the quality and support for the 'official list'.

Continuing with the examples, lets say that the Framestore wide space above represented some LED wall, then ILM come along and are asked to produce content on the same wall, so we both end up with our own name for the same gamut, etc, by the time the third studio is asked to work on the same wall we may want to identify that same set of settings by a common name, but it may not be something suitable for color_interop_forum, it is probably not something Material X will implement natively for example.

How could we detect and reduce this duplication, we'd have to have some way to back track to the originators to confirm the intent of the id?

How would somebody know which of the id's a given implementation is expected to support? What is an extension to the system etc.

We can choose to delegate these decisions to the registry, by some form of attributes, in the limit we can put all the human readable information into the registry, then the ID becomes just a number, but that is probably too cryptic for config authors and human readers of the file to work with.

I discussed in the meeting yesterday, that the other extreme putting all the attributes into the OCIO config file is also going to lead to problems of compatibility with config files and the API featuring different numbers of special attributes for each each type of information (CICP, ICC, GL buffer enums, etc).

One thing we didn't explicitly mention yesterday, but have mentioned previously, the mapping function between an OCIO Colorspace, (display, view etc) is not 1:1, we know of configs where there are two colorspaces with the same colorimetric definition but have other semantic differences e.g. "grade state", or you can have different CICP values you may want to embed in a .mov container for the same colour space for compatibility with specific players etc

To do this completely, there are probably cases where you need to know the display, view and any looks that have been applied in order to uniquely identify the correct set of values. So we may end up needing to consider the chain of Transforms, collecting up the IDs as we go, remembering that we would need to know the input and output ids of a given transform - it is quite common for us to get a cube style file that maps from Camera vendor colour space to ACEScct named to be an "LMT"

This suggests to me we need a data structure more suited to the problem than our current YAML can support cleanly.

For ICC profiles Just how many sRGB ICC profiles are there? we already mentioned the differences between the name and location on disk vs the embedded IDs during yesterday's meeting

So really I think we are looking for the suite spot of where to put the complexity, my take is to:

  1. Use a single ID attribute in the OCIO config and delegate everything else to a separately versioned "library"/repository.
  2. The id should be human readable, but be precise enough to avoid collisions.

I feel that we need something more than the binary choice of "official" and non-official, which could be achieved by having an official set of reserved names as this doesn't age well if we want to add a new reserved name we don't know if this will collide with other users configs etc. So a limited namespace type of distinction is needed.

This would separate the compatibility requirements of the main OCIO API/ABI from what could be quite a bit of churn as we add more and more to the metadata registry, whatever representation that is implemented using.

Speculation: I suspect we will end up with a mixture of a relational data structure storing sets of "facts", with some customisable rules engine that can take context from the end user, like the files rules but generalised to take information from external data systems like Shotgrid, ftrack, etc that resolves. This way it could be used for source files as well as outputs

KevinJW avatar Jun 03 '25 10:06 KevinJW

Hey y'all, thanks for the feedback. I still feel like we are over thinking and over complicating this, for the time being.

I have a few questions to clarify positions here:

  • [ ] Is a color space name + config file not a namespace in and of itself? This is what we are proposing going into OpenEXR. If not, why?
  • [ ] We are only proposing 3 fields - are there actual issues with these three that need to be solved now?
    • [ ] interop ID
    • [ ] icc file name (which can contain multiple names to account for as many as the config author would like.)
    • [ ] amf id (we need this - we currently put the amf ID in the color space description. having this would make config maintenance so much easier and we already use it.)

If we want to go further in the future and incorporate other fields, we could still go the direction of 1. using an external metadata library or 2. having a "general" key value pair item list or 3. continue adding bespoke items as needed.

I don't believe that adding these three now preclude us from doing other things in the future, especially as they are not required items. I do believe taking this small step now will enable us to test the ecosystem, foster adoption, etc. such that when we do more, we have set up a system in which to percolate these changes.

This is really what we need sign off on now. I know it is hard to not think way far in the future, and of course to a certain extent we need to. But also that can be prohibitive of change.

carolalynn avatar Jun 03 '25 15:06 carolalynn

We had a long discussion at the TSC meeting today and arrived at the following compromise:

  1. The interop ID will be a single string. This will avoid confusion about which tokens should be stored in file formats.
  2. The documentation will mandate that people who create their own inteop IDs must start their string with a prefix consisting of a "namespace" string and an official separator token. The proposed separator token is ":". For example: "weta:canon_r9_raw". The separator token may only appear once and will not be allowed for use elsewhere in the ID.
  3. An official registry of interop IDs will be maintained on the Color Interop Forum GitHub. The official IDs will not require a namespace (e.g. "srgb_rec709_scene").
  4. The ociocheck tool will be updated to check the interop IDs and issue a warning if it encounters an ID that is not in the list of CIF IDs that was current at the time the tool was compiled and yet does not have a namespace. It is acknowledged that this list may not be current since the CIF will introduce new IDs over time in a way that may not be synchronized with library releases (and there is no intent to have ociocheck, e.g., download a list from the CIF website when the tool is run).

doug-walker avatar Jun 09 '25 20:06 doug-walker

Long but good! :)

KelSolaar avatar Jun 09 '25 23:06 KelSolaar

I had a weird idea... what would you guys think about repurposing the equalitygroup attribute as a means for backporting (partial) interop ID support to earlier OCIO config versions?

E.g.:

  • ColorSpace.getInteropID():
    • Return interop_id value, IF present.
    • Else, return equalitygroup value, IFF matches known CIF token OR has one ":" in value.

"Equality Groups" are more of an intraop kinda thang; but, logically, I can't really think of a reason why they couldn't also serve interop_id purposes as well...?

zachlewis avatar Jul 02 '25 19:07 zachlewis

@zachlewis , thanks for the suggestion. I agree that it would be useful to somehow obtain this ID from pre-v2.5 configs.

Based on the discussion at the TSC meeting today, it sounds like people are using the equality group in v1 configs as a way of doing what the aliases mechanism provides in v2 configs. I don't think that would necessarily prevent using it for your intended purpose in v2 configs, but it sounds like the TSC would like to explore a more official mechanism.

We will take an action item to update PR #2165 to loosen the validation when writing the interop_id. In addition, we will test what happens when a v2.0-2.4 config with that attribute is read by a v2.0-2.4 library. (We're not going to go back to 1.0.)

And FYI, Issue #2170 mentions another way of getting support for interop IDs that are in the CIF list, which is to make them aliases (which they need to be anyway).

doug-walker avatar Jul 07 '25 20:07 doug-walker

We discussed this a little bit based on my unfortunately anonymous comments on the interopID google doc about name spacing. Reading through this again I have a different opinion. I don't think there should ever be a user-defined interop_id, so the namespace doesn't actually make sense in practice.

As described, it should be fairly black and white. If the colorspace "so solemnly swears" that it correctly implements one of the Color InterOp Forum color spaces, then it should add the interop_id and alias to its definition; otherwise it should do nothing.

I think this statement:

For color spaces that do not exist in Color Interop Forum recommendations, it is proposed that config authors should be allowed to populate their own interop ID string. Some sort of namespace mechanism could be used, if desired.

Is the source of error. In my (new) opinion if the interop_id is not backed by all the metadata and inter-system links that the Color InterOp Forum promises to provided, then it is meaningless and should not be there.

The challenge is, that it is annoying and slow/cumbersome to enforce that. So it's basically on the honor system for now. I would leave it at that.

My opinion about this not being a API construct but just a generic metadata field still stands, but that's not for here.

scoopxyz avatar Aug 04 '25 21:08 scoopxyz

Thanks for the feedback @scoopxyz. One of the problems we are trying to solve with OpenEXR is to provide a way of tagging any color space, not just the Color Interop Forum ones. One of the main problems affecting the reliability of color space metadata is that applications need to know what attributes should be cleared when the processing to the image modifies the color space. Therefore, we want one OpenEXR attribute that may be used for any color space, otherwise it becomes too complicated for apps to know what to invalidate. (There are already the acesImageContainer and Chromaticities attributes, so we're trying to avoid adding one attribute for CIF names and another for color spaces that are specific to a local config.)

doug-walker avatar Aug 04 '25 22:08 doug-walker

The semantics of this are really muddying the waters for me.

A colorInteropID is sometimes, but not always, a CIF ID. So you sometimes, but not always, need an OCIO config to know how to handle an EXR.

And a OCIO interopID field is sometimes, but not always, a CIF ID. It's also not guaranteed to be unique.

we're trying to avoid adding one attribute for CIF names and another for color spaces that are specific to a local config

So, if I want my EXR to be interoperable I need to surrender my local knowledge of its OCIO color space, and use a CIF ID. Potentially losing pipeline information.

scoopxyz avatar Aug 05 '25 23:08 scoopxyz

This clears up the intention more for me: https://youtu.be/ym1kfYmGz-M?si=p_q_tZXdEfFtZQSm&t=1202

scoopxyz avatar Aug 06 '25 17:08 scoopxyz

This is included in OCIO 2.5.

doug-walker avatar Oct 01 '25 19:10 doug-walker