[BUG] EXR files are always assumed to be "Linear" without checking a previously existing value for oiio:ColorSpace
When reading an .exr file, the oiio:ColorSpace is always set to "Linear". If the read file already contained this metadata but set to another value (ACEScg for example), it is overwritten. I expected the original value to be retained.
The following piece of C++ code shows how to reproduce the bug:
const OIIO::ParamValue* p;
// Read input JPEG image
OIIO::ImageBuf imgBuf("path/to/my/file.jpg");
// Check oiio:ColorSpace value in the input image
p = imgBuf.spec().find_attribute("oiio:ColorSpace");
std::cout << "oiio:ColorSpace = " << ( p ? p->get_string() : "Undefined") << std::endl;
// Color Space conversion from sRGB to ACEScg
OIIO::ColorConfig colorConfig("path/to/my/config.ocio");
OIIO::ImageBuf colorspaceBuf;
OIIO::ImageBufAlgo::colorconvert(colorspaceBuf, imgBuf, "sRGB", "ACEScg", true, "", "", &colorConfig);
// Check oiio:ColorSpace value after conversion
p = colorspaceBuf.spec().find_attribute("oiio:ColorSpace");
std::cout << "oiio:ColorSpace = " << (p ? p->get_string() : "Undefined") << std::endl;
// Save converted image on disk as an .exr file
colorspaceBuf.write("path/to/my/convertedFile.exr");
// Read the stored .exr file
OIIO::ImageBuf imgBufNew("path/to/my/convertedFile.exr");
// Check oiio:ColorSpace value after reading the exr file
p = imgBufNew.spec().find_attribute("oiio:ColorSpace");
std::cout << "oiio:ColorSpace = " << (p ? p->get_string() : "Undefined") << std::endl;
This code produces the following output on the console:
oiio:ColorSpace = sRGB
oiio:ColorSpace = ACEScg
oiio:ColorSpace = Linear
I would expect that the last line to be:
oiio:ColorSpace = ACEScg
Platform information:
- OIIO picked and compiled through vcpkg package manager.
- OS: Windows 10
- C++ compiler: Visual Studio 2022 / platform x64
Hmmm, I'm suspecting that what's happening is that in your config, ACEScg is the color space tagged with the "scene_linear" role, and so they are actually synonyms, but it's getting confused about when it should report which name.
I'll look into it a bit. Maybe the logic is a little confused.
No, that's not it at all. I should have looked more closely before writing.
I'm working on a different theory.
Hi @lgritz , Any news? Not being able to read/write EXR without loosing colorspace information is a very critical issue.
Here's my understanding at this point (in no particular order):
The "oiio:ColorSpace" attribute is something we pass around internally (mostly to identify what we think an image is when we read it, IF there's a solid clue or if it's strongly dictated by the file format itself, such as how all JPEG files are assumed to be sRGB).
But we don't write its value to any file... unless, again, the file format itself has specific field or widely supported convention for labeling its color information.
OpenEXR currently has no such thing -- no attribute name that is designated to hold the color space information, and also no agreed convention for what information it would hold. (Is it the name of an OpenColorIO color space? But those are arbitrarily named and tied to a particular OCIO config.) So, in short, we don't write the color space info to the openexr file itself, because there is no accepted convention for doing so.
I've brought these issues up with both the OpenEXR and OpenColorIO advisory councils, and we're planning to discuss it in an upcoming meeting and see if the projects can, between them, come up with any guidance or a path forward. (We're aiming for the next OpenEXR TSC meeting, it's open and you should feel free to come.)
We could modify OIIO's openexr writer to save the color space in the file, with some attribute name we choose... but if the Exr/OCIO councils decide on a future path and choose a different name or a different concept, OIIO's doing this prematurely could even make matters worse by having yet another convention, and one that is only valid for a certain narrow range of OIIO releases.
So I'm not sure what we should do next, before those councils at least have the chance to hash out the matter.
And even if they do decide on a particular metadata attribute name, and decide that what that attribute should hold is the name of an OCIO color space (sweeping under the rug that such a name would be tied to an OCIO config that may or may not be available when the file is later read -- or even could be read in the presence of an OCIO config that has the same name, but it means a different color space!), there's still the matter of how all sorts of image operations (both in OIIO and the outside world) would need to be correctly aware of what this attribute means, as well as when it should be changed or erased depending on what happens to the pixels. In other words, there are so many ways for the color space attribute to turn out to not match the pixels and be misleadingly wrong. Many people are inclined to never trust it even if present.
For what it's worth, the way we and many other people solve this in production is to enforce with an iron fist a facility-wide very strict naming convention for all image files, which incorporates the color space name into the filename (such as "foobar_acescg.1001.exr"), and all the apps in the building rely on being able to decode the color space name from the filename itself.
Hi Larry, Thanks for your precise feedback. I believed that "oiio:colorspace" was written to the exr files, but you're right, that's not the case. Productions are using the same name for different show-specific colorspaces that cannot be standardized. But yes, to convert between fully-defined colorspaces, it would be great to have a standardized convention in ocio & openexr.