Skip to content

Commit b5a442b

Browse files
committed
feat: Support display color space interop IDs in I/O
Previously only srgb_rec709_scene was recognized as sRGB for file metadata and display, now srgb_rec709_display and g22_rec709_display are treated as sRGB as well. The reason for g22_rec709_display behavior is that this type of display is often used to correct for the discrepancy where images are encoded as sRGB but usually decoded as gamma 2.2 by the physical display. By encoding it as gamma 2.2 and claiming it's sRGB the transfer functions cancel out exactly. g24_rec709_display is now recognized as having gamma 2.4, and g24_rec709_scene was replaced by ocio:g24_rec709_scene since the former is not an official interop ID. ocio:itu709_rec709_scene and ocio:lin_ciexyzd65_display to complete the list of interop IDs in OCIO configs that match a CICP. None of the other display color space interop IDs required changes. Signed-off-by: Brecht Van Lommel <brecht@blender.org>
1 parent 6e5712b commit b5a442b

File tree

5 files changed

+58
-9
lines changed

5 files changed

+58
-9
lines changed

src/libOpenImageIO/color_ocio.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,9 @@ constexpr ColorInteropID color_interop_ids[] = {
20872087
// Display referred interop IDs.
20882088
{ "srgb_rec709_display", CICPPrimaries::Rec709, CICPTransfer::sRGB,
20892089
CICPMatrix::BT709 },
2090+
// Not all software interprets this CICP the same, see the
2091+
// "QuickTime Gamma Shift" issue. We follow the CIF recommendation and
2092+
// interpret it as BT.1886.
20902093
{ "g24_rec709_display", CICPPrimaries::Rec709, CICPTransfer::BT709,
20912094
CICPMatrix::BT709 },
20922095
{ "srgb_p3d65_display", CICPPrimaries::P3D65, CICPTransfer::sRGB,
@@ -2099,11 +2102,13 @@ constexpr ColorInteropID color_interop_ids[] = {
20992102
CICPMatrix::Rec2020_NCL },
21002103
{ "hlg_rec2020_display", CICPPrimaries::Rec2020, CICPTransfer::HLG,
21012104
CICPMatrix::Rec2020_NCL },
2102-
// No CICP mapping to keep previous behavior unchanged, as Gamma 2.2
2103-
// display is more likely meant to be written as sRGB. On read the
2104-
// scene referred interop ID will be used.
2105-
{ "g22_rec709_display",
2106-
/* CICPPrimaries::Rec709, CICPTransfer::Gamma22, CICPMatrix::BT709 */ },
2105+
// Mapped to sRGB as a gamma 2.2 display is more likely meant to be written
2106+
// as sRGB. This type of display is often used to correct for the discrepancy
2107+
// where images are encoded as sRGB but usually decoded as gamma 2.2 by the
2108+
// physical display.
2109+
// For read and write, g22_rec709_scene. still maps to Gamma 2.2.
2110+
{ "g22_rec709_display", CICPPrimaries::Rec709, CICPTransfer::sRGB,
2111+
CICPMatrix::BT709 },
21072112
// No CICP code for Adobe RGB primaries.
21082113
{ "g22_adobergb_display" },
21092114
{ "g26_p3d65_display", CICPPrimaries::P3D65, CICPTransfer::Gamma26,
@@ -2112,6 +2117,15 @@ constexpr ColorInteropID color_interop_ids[] = {
21122117
CICPMatrix::Unspecified },
21132118
{ "pq_xyzd65_display", CICPPrimaries::XYZD65, CICPTransfer::PQ,
21142119
CICPMatrix::Unspecified },
2120+
2121+
// OpenColorIO interop IDs.
2122+
{ "ocio:g24_rec709_scene", CICPPrimaries::Rec709, CICPTransfer::BT709,
2123+
CICPMatrix::BT709 },
2124+
// Not mapped to any CICP, because we already interpret the potential CICP
2125+
// as g24_rec709_*, see explanation for g24_rec709_display above.
2126+
{ "ocio:itu709_rec709_scene" },
2127+
{ "ocio:lin_ciexyzd65_display", CICPPrimaries::XYZD65, CICPTransfer::Linear,
2128+
CICPMatrix::Unspecified }
21152129
};
21162130
} // namespace
21172131

@@ -2813,7 +2827,7 @@ ColorConfig::set_colorspace_rec709_gamma(ImageSpec& spec, float gamma) const
28132827
set_colorspace(spec, "g22_rec709_scene");
28142828
spec.attribute("oiio:Gamma", 2.2f);
28152829
} else if (fabsf(gamma - 2.4f) <= 0.01f) {
2816-
set_colorspace(spec, "g24_rec709_scene");
2830+
set_colorspace(spec, "ocio:g24_rec709_scene");
28172831
spec.attribute("oiio:Gamma", 2.4f);
28182832
} else {
28192833
set_colorspace(spec, Strutil::fmt::format("g{}_rec709_scene",
@@ -2849,7 +2863,11 @@ pvt::is_colorspace_srgb(const ImageSpec& spec, bool default_to_srgb)
28492863

28502864
const ColorConfig& colorconfig(ColorConfig::default_colorconfig());
28512865
string_view interop_id = colorconfig.get_color_interop_id(colorspace);
2852-
return interop_id == "srgb_rec709_scene";
2866+
2867+
// See the interop table above for why g22_rec709_display is treated as sRGB
2868+
return (interop_id == "srgb_rec709_scene"
2869+
|| interop_id == "srgb_rec709_display"
2870+
|| interop_id == "g22_rec709_display");
28532871
}
28542872

28552873
float
@@ -2864,11 +2882,13 @@ pvt::get_colorspace_rec709_gamma(const ImageSpec& spec)
28642882
|| colorconfig.equivalent(colorspace, "scene_linear")
28652883
|| interop_id == "lin_rec709_scene")
28662884
return 1.0f;
2885+
// See the interop table above for why g22_rec709_display is not treated as gamma
28672886
else if (interop_id == "g22_rec709_scene")
28682887
return 2.2f;
2869-
// Note g24_rec709_scene is not a standard interop ID
2870-
else if (colorconfig.equivalent(colorspace, "g24_rec709_scene"))
2888+
else if (interop_id == "ocio:g24_rec709_scene"
2889+
|| interop_id == "g24_rec709_display")
28712890
return 2.4f;
2891+
// Note g18_rec709_display is not an interop ID
28722892
else if (interop_id == "g18_rec709_scene")
28732893
return 1.8f;
28742894
// Back compatible, this is DEPRECATED(3.1)

src/raw.imageio/rawinput.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ RawInput::open_raw(bool unpack, bool process, const std::string& name,
577577
m_processor->imgdata.params.gamm[0] = 1.0;
578578
m_processor->imgdata.params.gamm[1] = 1.0;
579579
} else if (colorconfig.equivalent(cs, "srgb_rec709_scene")
580+
|| colorconfig.equivalent(cs, "srgb_rec709_display")
580581
|| Strutil::iequals(cs, "sRGB") /* Necessary? */) {
581582
// Request explicit sRGB, including usual sRGB response
582583
m_processor->imgdata.params.output_color = 1;

testsuite/png/ref/out-libpng15.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,16 @@ remove_cicp_via_set_colorspace:
102102
16 x 16, 4 channel, float png
103103
channel list: R, G, B, A
104104
oiio:ColorSpace: "g22_rec709_display"
105+
Reading g22_rec709_display.png
106+
g22_rec709_display.png : 64 x 64, 3 channel, uint8 png
107+
SHA-1: 7CB41FEA50720B48BE0C145E1473982B23E9AB77
108+
channel list: R, G, B
109+
oiio:ColorSpace: "g22_rec709_display"
110+
Reading g22_rec709_scene.png
111+
g22_rec709_scene.png : 64 x 64, 3 channel, uint8 png
112+
SHA-1: 7CB41FEA50720B48BE0C145E1473982B23E9AB77
113+
channel list: R, G, B
114+
oiio:ColorSpace: "g22_rec709_scene"
115+
oiio:Gamma: 2.2
105116
Comparing "test16.png" and "ref/test16.png"
106117
PASS

testsuite/png/ref/out.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,16 @@ remove_cicp_via_set_colorspace:
103103
16 x 16, 4 channel, float png
104104
channel list: R, G, B, A
105105
oiio:ColorSpace: "g22_rec709_display"
106+
Reading g22_rec709_display.png
107+
g22_rec709_display.png : 64 x 64, 3 channel, uint8 png
108+
SHA-1: 7CB41FEA50720B48BE0C145E1473982B23E9AB77
109+
channel list: R, G, B
110+
oiio:ColorSpace: "g22_rec709_display"
111+
Reading g22_rec709_scene.png
112+
g22_rec709_scene.png : 64 x 64, 3 channel, uint8 png
113+
SHA-1: 7CB41FEA50720B48BE0C145E1473982B23E9AB77
114+
channel list: R, G, B
115+
oiio:ColorSpace: "g22_rec709_scene"
116+
oiio:Gamma: 2.2
106117
Comparing "test16.png" and "ref/test16.png"
107118
PASS

testsuite/png/run.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,10 @@
4343
# Test that "set_colorspace" removes CICP metadata
4444
command += oiiotool ("-echo remove_cicp_via_set_colorspace: test16.png --eraseattrib Software --cicp 1,13 --iscolorspace g22_rec709_display --printinfo")
4545

46+
# Test g22_rec709_display being written as sRGB
47+
command += oiiotool ("--create 64x64 3 --iscolorspace g22_rec709_display -o g22_rec709_display.png")
48+
command += oiiotool ("--create 64x64 3 --iscolorspace g22_rec709_scene -o g22_rec709_scene.png")
49+
command += info_command ("g22_rec709_display.png", safematch=True)
50+
command += info_command ("g22_rec709_scene.png", safematch=True)
51+
4652
outputs = [ "test16.png", "out.txt" ]

0 commit comments

Comments
 (0)