Skip to content

Commit

Permalink
TRY: only set color space of unmarked exrs if it appears to be rgb
Browse files Browse the repository at this point in the history
Signed-off-by: Larry Gritz <lg@larrygritz.com>
  • Loading branch information
lgritz committed Oct 6, 2024
1 parent 6eea1da commit 3571387
Show file tree
Hide file tree
Showing 23 changed files with 61 additions and 81 deletions.
23 changes: 10 additions & 13 deletions src/openexr.imageio/exr_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,17 @@ static bool exrdebug = Strutil::stoi(Sysutil::getenv("OIIO_DEBUG_OPENEXR"))
#endif


namespace pvt {

// Split a full channel name into layer and suffix.
inline void
split_name(string_view fullname, string_view& layer, string_view& suffix)
{
size_t dot = fullname.find_last_of('.');
if (dot == string_view::npos) {
suffix = fullname;
layer = string_view();
} else {
layer = string_view(fullname.data(), dot + 1);
suffix = string_view(fullname.data() + dot + 1,
fullname.size() - dot - 1);
}
}
void
split_name(string_view fullname, string_view& layer, string_view& suffix);

// Do the channels appear to be R, G, B (or known common aliases)?
bool
channels_are_rgb(const ImageSpec& spec);

} // namespace pvt



Expand Down
45 changes: 42 additions & 3 deletions src/openexr.imageio/exrinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,40 @@ namespace pvt {
void
set_exr_threads();


// Split a full channel name into layer and suffix.
void
split_name(string_view fullname, string_view& layer, string_view& suffix)
{
size_t dot = fullname.find_last_of('.');
if (dot == string_view::npos) {
suffix = fullname;
layer = string_view();
} else {
layer = string_view(fullname.data(), dot + 1);
suffix = string_view(fullname.data() + dot + 1,
fullname.size() - dot - 1);
}
}


inline bool
str_equal_either(string_view str, string_view a, string_view b)
{
return Strutil::iequals(str, a) || Strutil::iequals(str, b);
}


// Do the channels appear to be R, G, B (or known common aliases)?
bool
channels_are_rgb(const ImageSpec& spec)
{
return spec.nchannels >= 3
&& str_equal_either(spec.channel_name(0), "R", "Red")
&& str_equal_either(spec.channel_name(1), "G", "Green")
&& str_equal_either(spec.channel_name(2), "B", "Blue");
}

} // namespace pvt


Expand Down Expand Up @@ -357,8 +391,13 @@ OpenEXRInput::PartInfo::parse_header(OpenEXRInput* in,

spec.deep = Strutil::istarts_with(header->type(), "deep");

// Unless otherwise specified, exr files are assumed to be linear Rec709.
spec.set_colorspace("lin_rec709");
// Unless otherwise specified, exr files are assumed to be linear Rec709
// if the channels appear to be R, G, B. I know this suspect, but I'm
// betting that this heuristic will guess the right thing that users want
// more often than if we pretending we have no idea what the color space
// is.
if (pvt::channels_are_rgb(spec))
spec.set_colorspace("lin_rec709");

if (levelmode != Imf::ONE_LEVEL)
spec.attribute("openexr:roundingmode", roundingmode);
Expand Down Expand Up @@ -666,7 +705,7 @@ struct ChanNameHolder {
, xSampling(exrchan.xSampling)
, ySampling(exrchan.ySampling)
{
split_name(fullname, layer, suffix);
pvt::split_name(fullname, layer, suffix);
}

// Compute canoninical channel list sort priority
Expand Down
11 changes: 8 additions & 3 deletions src/openexr.imageio/exrinput_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,13 @@ OpenEXRCoreInput::PartInfo::parse_header(OpenEXRCoreInput* in,
spec.deep = (storage == EXR_STORAGE_DEEP_TILED
|| storage == EXR_STORAGE_DEEP_SCANLINE);

// Unless otherwise specified, exr files are assumed to be linear Rec709.
spec.set_colorspace("lin_rec709");
// Unless otherwise specified, exr files are assumed to be linear Rec709
// if the channels appear to be R, G, B. I know this suspect, but I'm
// betting that this heuristic will guess the right thing that users want
// more often than if we pretending we have no idea what the color space
// is.
if (pvt::channels_are_rgb(spec))
spec.set_colorspace("lin_rec709");

if (levelmode != EXR_TILE_ONE_LEVEL)
spec.attribute("openexr:roundingmode", (int)roundingmode);
Expand Down Expand Up @@ -806,7 +811,7 @@ struct CChanNameHolder {
, xSampling(exrchan.x_sampling)
, ySampling(exrchan.y_sampling)
{
split_name(fullname, layer, suffix);
pvt::split_name(fullname, layer, suffix);
}

// Compute canoninical channel list sort priority
Expand Down
2 changes: 0 additions & 2 deletions testsuite/iinfo/ref/out-fmt6.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ src/tinydeep.exr : 4 x 4, 2 channel, deep float openexr
Software: "OpenImageIO 2.5.0.0spi : oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
version: 1
Exif:ImageHistory: "oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 4
Stats Min: 1.000000 10.000000 (float)
Expand Down Expand Up @@ -247,7 +246,6 @@ src/tinydeep.exr : 4 x 4, 2 channel, deep float openexr
Software: "OpenImageIO 2.5.0.0spi : oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
version: 1
Exif:ImageHistory: "oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 4
Pixel (0, 0): 0 samples
Expand Down
2 changes: 0 additions & 2 deletions testsuite/iinfo/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ src/tinydeep.exr : 4 x 4, 2 channel, deep float openexr
Software: "OpenImageIO 2.5.0.0spi : oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
version: 1
Exif:ImageHistory: "oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 4
Stats Min: 1.000000 10.000000 (float)
Expand Down Expand Up @@ -247,7 +246,6 @@ src/tinydeep.exr : 4 x 4, 2 channel, deep float openexr
Software: "OpenImageIO 2.5.0.0spi : oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
version: 1
Exif:ImageHistory: "oiiotool -pattern constant:color=1e38,0 4x4 2 --chnames Z,A --point:color=10.0,1.0 2,2 --deepen -o tinydeep.exr"
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 4
Pixel (0, 0): 0 samples
Expand Down
3 changes: 0 additions & 3 deletions testsuite/maketx/ref/out-macarm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,6 @@ bumpslope.exr : 64 x 64, 6 channel, half openexr
uvslopes_scale: 0
wrapmodes: "black,black"
oiio:AverageColor: "0.499779,-0.000457942,-4.17233e-05,0.00197116,0.00178894,3.45764e-05"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "49B533110A914CE89BE0B14753A6A4CC037C964F"
oiio:subimages: 1
openexr:roundingmode: 0
Expand All @@ -456,7 +455,6 @@ cdf.exr : 64 x 64, 1 channel, half openexr
textureformat: "Plain Texture"
wrapmodes: "black,black"
oiio:AverageColor: "0.499779"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "00DFB31D0260CC466CDCF9FE42446D4896E655FE"
oiio:subimages: 1
openexr:roundingmode: 0
Expand Down Expand Up @@ -488,7 +486,6 @@ bumpslope-cdf.exr : 64 x 64, 6 channel, half openexr
uvslopes_scale: 0
wrapmodes: "black,black"
oiio:AverageColor: "0.499779,-0.000457942,-4.17233e-05,0.00197116,0.00178894,3.45764e-05"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "49B533110A914CE89BE0B14753A6A4CC037C964F"
oiio:subimages: 1
openexr:roundingmode: 0
Expand Down
3 changes: 0 additions & 3 deletions testsuite/maketx/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,6 @@ bumpslope.exr : 64 x 64, 6 channel, half openexr
uvslopes_scale: 0
wrapmodes: "black,black"
oiio:AverageColor: "0.499779,-0.000457942,-4.17233e-05,0.00197116,0.00178894,3.45764e-05"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "49B533110A914CE89BE0B14753A6A4CC037C964F"
oiio:subimages: 1
openexr:roundingmode: 0
Expand All @@ -456,7 +455,6 @@ cdf.exr : 64 x 64, 1 channel, half openexr
textureformat: "Plain Texture"
wrapmodes: "black,black"
oiio:AverageColor: "0.499779"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "00DFB31D0260CC466CDCF9FE42446D4896E655FE"
oiio:subimages: 1
openexr:roundingmode: 0
Expand Down Expand Up @@ -488,7 +486,6 @@ bumpslope-cdf.exr : 64 x 64, 6 channel, half openexr
uvslopes_scale: 0
wrapmodes: "black,black"
oiio:AverageColor: "0.499779,-0.000457942,-4.17233e-05,0.00197116,0.00178894,3.45764e-05"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "49B533110A914CE89BE0B14753A6A4CC037C964F"
oiio:subimages: 1
openexr:roundingmode: 0
Expand Down
3 changes: 0 additions & 3 deletions testsuite/oiiotool-deep/ref/out-fmt6.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ allhalf.exr : 160 x 120, 2 channel, deep half openexr
version: 1
worldToCamera: 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 1.5, 0, 4, 1
worldToNDC: 2.41421, 0, 0, 0, 0, 3.21895, 0, 0, 0, 0, -1.00671, -1, 3.62132, 0, 3.92617, 4
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 6
Stats Min: 0.011902 3.031250 (float)
Expand Down Expand Up @@ -56,7 +55,6 @@ swaptypes.exr : 160 x 120, 2 channel, deep float/half openexr
version: 1
worldToCamera: 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 1.5, 0, 4, 1
worldToNDC: 2.41421, 0, 0, 0, 0, 3.21895, 0, 0, 0, 0, -1.00671, -1, 3.62132, 0, 3.92617, 4
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 6
Stats Min: 0.011902 3.031250 (float)
Expand Down Expand Up @@ -95,7 +93,6 @@ tinydeep.exr : 4 x 4, 2 channel, deep float openexr
screenWindowCenter: 0, 0
screenWindowWidth: 1
version: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 4
Pixel (0, 0): 0 samples
Expand Down
3 changes: 0 additions & 3 deletions testsuite/oiiotool-deep/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ allhalf.exr : 160 x 120, 2 channel, deep half openexr
version: 1
worldToCamera: 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 1.5, 0, 4, 1
worldToNDC: 2.41421, 0, 0, 0, 0, 3.21895, 0, 0, 0, 0, -1.00671, -1, 3.62132, 0, 3.92617, 4
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 6
Stats Min: 0.011902 3.031250 (float)
Expand Down Expand Up @@ -56,7 +55,6 @@ swaptypes.exr : 160 x 120, 2 channel, deep float/half openexr
version: 1
worldToCamera: 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 1.5, 0, 4, 1
worldToNDC: 2.41421, 0, 0, 0, 0, 3.21895, 0, 0, 0, 0, -1.00671, -1, 3.62132, 0, 3.92617, 4
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 6
Stats Min: 0.011902 3.031250 (float)
Expand Down Expand Up @@ -95,7 +93,6 @@ tinydeep.exr : 4 x 4, 2 channel, deep float openexr
screenWindowCenter: 0, 0
screenWindowWidth: 1
version: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
openexr:chunkCount: 4
Pixel (0, 0): 0 samples
Expand Down
1 change: 0 additions & 1 deletion testsuite/oiiotool-maketx/ref/out-rhel7.txt
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,6 @@ bumpslope-cdf.exr : 64 x 64, 6 channel, half openexr
uvslopes_scale: 0
wrapmodes: "black,black"
oiio:AverageColor: "0.499779,-0.000457942,-4.17233e-05,0.00197116,0.00178894,3.45764e-05"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "49B533110A914CE89BE0B14753A6A4CC037C964F"
oiio:subimages: 1
openexr:roundingmode: 0
1 change: 0 additions & 1 deletion testsuite/oiiotool-maketx/ref/out-win.txt
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,6 @@ bumpslope-cdf.exr : 64 x 64, 6 channel, half openexr
uvslopes_scale: 0
wrapmodes: "black,black"
oiio:AverageColor: "0.499779,-0.000457942,-4.17233e-05,0.00197116,0.00178894,3.45764e-05"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "49B533110A914CE89BE0B14753A6A4CC037C964F"
oiio:subimages: 1
openexr:roundingmode: 0
1 change: 0 additions & 1 deletion testsuite/oiiotool-maketx/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,6 @@ bumpslope-cdf.exr : 64 x 64, 6 channel, half openexr
uvslopes_scale: 0
wrapmodes: "black,black"
oiio:AverageColor: "0.499779,-0.000457942,-4.17233e-05,0.00197116,0.00178894,3.45764e-05"
oiio:ColorSpace: "lin_rec709"
oiio:SHA-1: "49B533110A914CE89BE0B14753A6A4CC037C964F"
oiio:subimages: 1
openexr:roundingmode: 0
1 change: 0 additions & 1 deletion testsuite/openexr-chroma/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ Reading ../openexr-images/LuminanceChroma/Garden.exr
PixelAspectRatio: 1
screenWindowCenter: 0, 0
screenWindowWidth: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
Comparing "../openexr-images/LuminanceChroma/Garden.exr" and "Garden.exr"
PASS
1 change: 0 additions & 1 deletion testsuite/openexr-multires/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ Reading ../openexr-images/MultiView/Fog.exr
screenWindowWidth: 1
XResolution: 100
YResolution: 100
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
Comparing "../openexr-images/MultiView/Fog.exr" and "Fog.exr"
PASS
Expand Down
3 changes: 0 additions & 3 deletions testsuite/openexr-suite/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ Reading ../openexr-images/TestImages/GrayRampsDiagonal.exr
PixelAspectRatio: 1
screenWindowCenter: 0, 0
screenWindowWidth: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
Comparing "../openexr-images/TestImages/GrayRampsDiagonal.exr" and "GrayRampsDiagonal.exr"
PASS
Expand All @@ -197,7 +196,6 @@ Reading ../openexr-images/TestImages/GrayRampsHorizontal.exr
PixelAspectRatio: 1
screenWindowCenter: 0, 0
screenWindowWidth: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
Comparing "../openexr-images/TestImages/GrayRampsHorizontal.exr" and "GrayRampsHorizontal.exr"
PASS
Expand Down Expand Up @@ -246,7 +244,6 @@ Reading ../openexr-images/TestImages/WideFloatRange.exr
PixelAspectRatio: 1
screenWindowCenter: 0, 0
screenWindowWidth: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimages: 1
Comparing "../openexr-images/TestImages/WideFloatRange.exr" and "WideFloatRange.exr"
PASS
Expand Down
10 changes: 0 additions & 10 deletions testsuite/openexr-v2/ref/out.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ Reading ../openexr-images/v2/Stereo/composited.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "left"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "depth.left"
oiio:subimages: 4
openexr:chunkCount: 1078
Expand Down Expand Up @@ -66,7 +65,6 @@ Reading ../openexr-images/v2/Stereo/composited.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "right"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "depth.right"
oiio:subimages: 4
openexr:chunkCount: 1078
Expand Down Expand Up @@ -231,7 +229,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "left"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "depth_left"
oiio:subimages: 10
openexr:chunkCount: 876
Expand All @@ -247,7 +244,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "left"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "forward_left"
oiio:subimages: 10
openexr:chunkCount: 876
Expand All @@ -263,7 +259,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "left"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "whitebarmask_left"
oiio:subimages: 10
openexr:chunkCount: 769
Expand Down Expand Up @@ -295,7 +290,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "right"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "depth_right"
oiio:subimages: 10
openexr:chunkCount: 876
Expand All @@ -311,7 +305,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "right"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "forward_right"
oiio:subimages: 10
openexr:chunkCount: 876
Expand All @@ -326,7 +319,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
PixelAspectRatio: 1
screenWindowCenter: 0, 0
screenWindowWidth: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "disparityL"
oiio:subimages: 10
openexr:chunkCount: 876
Expand All @@ -341,7 +333,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
PixelAspectRatio: 1
screenWindowCenter: 0, 0
screenWindowWidth: 1
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "disparityR"
oiio:subimages: 10
openexr:chunkCount: 876
Expand All @@ -357,7 +348,6 @@ Reading ../openexr-images/Beachball/multipart.0001.exr
screenWindowCenter: 0, 0
screenWindowWidth: 1
view: "right"
oiio:ColorSpace: "lin_rec709"
oiio:subimagename: "whitebarmask_right"
oiio:subimages: 10
openexr:chunkCount: 769
Expand Down
Loading

0 comments on commit 3571387

Please sign in to comment.