From 21c71e5bd09c9d110625c05941f720e008da86a3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 1 Dec 2025 19:33:08 +0100 Subject: [PATCH 1/2] feat: Make color interop IDs work with older OpenColorIO ACES configs Add a legacy alias for color interop IDs, matching aliases that exist in the OpenColorIO ACES configs back to version 1.0.0 (made for OpenColorIO 2.1). Signed-off-by: Brecht Van Lommel --- src/libOpenImageIO/color_ocio.cpp | 102 +++++++++--------- .../python-colorconfig/ref/out-ocio230.txt | 1 + .../python-colorconfig/ref/out-ocio230b.txt | 1 + .../python-colorconfig/ref/out-ocio232.txt | 1 + .../python-colorconfig/ref/out-ocio24.txt | 1 + .../python-colorconfig/ref/out-ocio25.txt | 1 + testsuite/python-colorconfig/ref/out.txt | 1 + .../src/test_colorconfig.py | 1 + 8 files changed, 61 insertions(+), 48 deletions(-) diff --git a/src/libOpenImageIO/color_ocio.cpp b/src/libOpenImageIO/color_ocio.cpp index a0935f06b4..c83ace96e0 100644 --- a/src/libOpenImageIO/color_ocio.cpp +++ b/src/libOpenImageIO/color_ocio.cpp @@ -2242,16 +2242,19 @@ enum class CICPRange : int { }; struct ColorInteropID { - constexpr ColorInteropID(const char* interop_id) + constexpr ColorInteropID(const char* interop_id, const char* legacy_alias) : interop_id(interop_id) + , legacy_alias(legacy_alias) , cicp({ 0, 0, 0, 0 }) , has_cicp(false) { } - constexpr ColorInteropID(const char* interop_id, CICPPrimaries primaries, - CICPTransfer transfer, CICPMatrix matrix) + constexpr ColorInteropID(const char* interop_id, const char* legacy_alias, + CICPPrimaries primaries, CICPTransfer transfer, + CICPMatrix matrix) : interop_id(interop_id) + , legacy_alias(legacy_alias) , cicp({ int(primaries), int(transfer), int(matrix), int(CICPRange::Full) }) , has_cicp(true) @@ -2259,67 +2262,68 @@ struct ColorInteropID { } const char* interop_id; + const char* legacy_alias; std::array cicp; bool has_cicp; }; // Mapping between color interop ID and CICP, based on Color Interop Forum -// recommendations. +// recommendations. The legacy aliases are for older ACES configs. constexpr ColorInteropID color_interop_ids[] = { // Scene referred interop IDs first so they are the default in automatic // conversion from CICP to interop ID. Some are not display color spaces // at all, but can be represented by CICP anyway. - { "lin_ap1_scene" }, - { "lin_ap0_scene" }, - { "lin_rec709_scene", CICPPrimaries::Rec709, CICPTransfer::Linear, - CICPMatrix::BT709 }, - { "lin_p3d65_scene", CICPPrimaries::P3D65, CICPTransfer::Linear, - CICPMatrix::BT709 }, - { "lin_rec2020_scene", CICPPrimaries::Rec2020, CICPTransfer::Linear, - CICPMatrix::Rec2020_CL }, - { "lin_adobergb_scene" }, - { "lin_ciexyzd65_scene", CICPPrimaries::XYZD65, CICPTransfer::Linear, - CICPMatrix::Unspecified }, - { "srgb_rec709_scene", CICPPrimaries::Rec709, CICPTransfer::sRGB, - CICPMatrix::BT709 }, - { "g22_rec709_scene", CICPPrimaries::Rec709, CICPTransfer::Gamma22, - CICPMatrix::BT709 }, - { "g18_rec709_scene" }, - { "srgb_ap1_scene" }, - { "g22_ap1_scene" }, - { "srgb_p3d65_scene", CICPPrimaries::P3D65, CICPTransfer::sRGB, - CICPMatrix::BT709 }, - { "g22_adobergb_scene" }, - { "data" }, - { "unknown" }, + { "lin_ap1_scene", "lin_ap1" }, + { "lin_ap0_scene", "lin_ap0" }, + { "lin_rec709_scene", "lin_rec709", CICPPrimaries::Rec709, + CICPTransfer::Linear, CICPMatrix::BT709 }, + { "lin_p3d65_scene", "lin_p3d65", CICPPrimaries::P3D65, + CICPTransfer::Linear, CICPMatrix::BT709 }, + { "lin_rec2020_scene", "lin_rec2020", CICPPrimaries::Rec2020, + CICPTransfer::Linear, CICPMatrix::Rec2020_CL }, + { "lin_adobergb_scene", "lin_adobergb" }, + { "lin_ciexyzd65_scene", "cie_xyz_d65", CICPPrimaries::XYZD65, + CICPTransfer::Linear, CICPMatrix::Unspecified }, + { "srgb_rec709_scene", "srgb_texture", CICPPrimaries::Rec709, + CICPTransfer::sRGB, CICPMatrix::BT709 }, + { "g22_rec709_scene", "g22_rec709", CICPPrimaries::Rec709, + CICPTransfer::Gamma22, CICPMatrix::BT709 }, + { "g18_rec709_scene", "g18_rec709" }, + { "srgb_ap1_scene", "srgb_ap1" }, + { "g22_ap1_scene", "g22_ap1" }, + { "srgb_p3d65_scene", "srgb_p3d65", CICPPrimaries::P3D65, + CICPTransfer::sRGB, CICPMatrix::BT709 }, + { "g22_adobergb_scene", nullptr }, + { "data", nullptr }, + { "unknown", nullptr }, // Display referred interop IDs. - { "srgb_rec709_display", CICPPrimaries::Rec709, CICPTransfer::sRGB, + { "srgb_rec709_display", "srgb_display", CICPPrimaries::Rec709, + CICPTransfer::sRGB, CICPMatrix::BT709 }, + { "g24_rec709_display", "rec1886_rec709_display", CICPPrimaries::Rec709, + CICPTransfer::BT709, CICPMatrix::BT709 }, + { "srgb_p3d65_display", "p3d65_display", CICPPrimaries::P3D65, + CICPTransfer::sRGB, CICPMatrix::BT709 }, + { "srgbe_p3d65_display", nullptr, CICPPrimaries::P3D65, CICPTransfer::sRGB, CICPMatrix::BT709 }, - { "g24_rec709_display", CICPPrimaries::Rec709, CICPTransfer::BT709, - CICPMatrix::BT709 }, - { "srgb_p3d65_display", CICPPrimaries::P3D65, CICPTransfer::sRGB, - CICPMatrix::BT709 }, - { "srgbe_p3d65_display", CICPPrimaries::P3D65, CICPTransfer::sRGB, - CICPMatrix::BT709 }, - { "pq_p3d65_display", CICPPrimaries::P3D65, CICPTransfer::PQ, - CICPMatrix::Rec2020_NCL }, - { "pq_rec2020_display", CICPPrimaries::Rec2020, CICPTransfer::PQ, - CICPMatrix::Rec2020_NCL }, - { "hlg_rec2020_display", CICPPrimaries::Rec2020, CICPTransfer::HLG, - CICPMatrix::Rec2020_NCL }, + { "pq_p3d65_display", "st2084_p3d65_display", CICPPrimaries::P3D65, + CICPTransfer::PQ, CICPMatrix::Rec2020_NCL }, + { "pq_rec2020_display", "rec2100_pq_display", CICPPrimaries::Rec2020, + CICPTransfer::PQ, CICPMatrix::Rec2020_NCL }, + { "hlg_rec2020_display", "rec2100_hlg_display", CICPPrimaries::Rec2020, + CICPTransfer::HLG, CICPMatrix::Rec2020_NCL }, // No CICP mapping to keep previous behavior unchanged, as Gamma 2.2 // display is more likely meant to be written as sRGB. On read the // scene referred interop ID will be used. - { "g22_rec709_display", + { "g22_rec709_display", nullptr /* CICPPrimaries::Rec709, CICPTransfer::Gamma22, CICPMatrix::BT709 */ }, // No CICP code for Adobe RGB primaries. - { "g22_adobergb_display" }, - { "g26_p3d65_display", CICPPrimaries::P3D65, CICPTransfer::Gamma26, - CICPMatrix::BT709 }, - { "g26_xyzd65_display", CICPPrimaries::XYZD65, CICPTransfer::Gamma26, - CICPMatrix::Unspecified }, - { "pq_xyzd65_display", CICPPrimaries::XYZD65, CICPTransfer::PQ, + { "g22_adobergb_display", nullptr }, + { "g26_p3d65_display", "p3_dci_display", CICPPrimaries::P3D65, + CICPTransfer::Gamma26, CICPMatrix::BT709 }, + { "g26_xyzd65_display", nullptr, CICPPrimaries::XYZD65, + CICPTransfer::Gamma26, CICPMatrix::Unspecified }, + { "pq_xyzd65_display", nullptr, CICPPrimaries::XYZD65, CICPTransfer::PQ, CICPMatrix::Unspecified }, }; } // namespace @@ -2346,7 +2350,9 @@ ColorConfig::get_color_interop_id(string_view colorspace) const } #endif for (const ColorInteropID& interop : color_interop_ids) { - if (equivalent(colorspace, interop.interop_id)) { + if (equivalent(colorspace, interop.interop_id) + || (interop.legacy_alias + && equivalent(colorspace, interop.legacy_alias))) { return interop.interop_id; } } diff --git a/testsuite/python-colorconfig/ref/out-ocio230.txt b/testsuite/python-colorconfig/ref/out-ocio230.txt index ca19551d3d..6e2ddd701f 100644 --- a/testsuite/python-colorconfig/ref/out-ocio230.txt +++ b/testsuite/python-colorconfig/ref/out-ocio230.txt @@ -28,6 +28,7 @@ equivalent('linear', 'lin_srgb'): False equivalent('scene_linear', 'lin_srgb'): False equivalent('ACEScg', 'scene_linear'): True equivalent('lnf', 'scene_linear'): False +get_color_interop_id('ACES2065-1') = lin_ap0_scene get_color_interop_id('ACEScg') = lin_ap1_scene get_color_interop_id('lin_srgb') = lin_rec709_scene get_color_interop_id([1, 13, 1, 1]) = srgb_rec709_scene diff --git a/testsuite/python-colorconfig/ref/out-ocio230b.txt b/testsuite/python-colorconfig/ref/out-ocio230b.txt index 542aa2a3bb..f6e10ac62e 100644 --- a/testsuite/python-colorconfig/ref/out-ocio230b.txt +++ b/testsuite/python-colorconfig/ref/out-ocio230b.txt @@ -28,6 +28,7 @@ equivalent('linear', 'lin_srgb'): False equivalent('scene_linear', 'lin_srgb'): False equivalent('ACEScg', 'scene_linear'): True equivalent('lnf', 'scene_linear'): False +get_color_interop_id('ACES2065-1') = lin_ap0_scene get_color_interop_id('ACEScg') = lin_ap1_scene get_color_interop_id('lin_srgb') = lin_rec709_scene get_color_interop_id([1, 13, 1, 1]) = srgb_rec709_scene diff --git a/testsuite/python-colorconfig/ref/out-ocio232.txt b/testsuite/python-colorconfig/ref/out-ocio232.txt index 9c063cdd9a..f7fd96cad3 100644 --- a/testsuite/python-colorconfig/ref/out-ocio232.txt +++ b/testsuite/python-colorconfig/ref/out-ocio232.txt @@ -28,6 +28,7 @@ equivalent('linear', 'lin_srgb'): False equivalent('scene_linear', 'lin_srgb'): False equivalent('ACEScg', 'scene_linear'): True equivalent('lnf', 'scene_linear'): False +get_color_interop_id('ACES2065-1') = lin_ap0_scene get_color_interop_id('ACEScg') = lin_ap1_scene get_color_interop_id('lin_srgb') = lin_rec709_scene get_color_interop_id([1, 13, 1, 1]) = srgb_rec709_scene diff --git a/testsuite/python-colorconfig/ref/out-ocio24.txt b/testsuite/python-colorconfig/ref/out-ocio24.txt index a8dab6c064..d166c6c372 100644 --- a/testsuite/python-colorconfig/ref/out-ocio24.txt +++ b/testsuite/python-colorconfig/ref/out-ocio24.txt @@ -28,6 +28,7 @@ equivalent('linear', 'lin_srgb'): False equivalent('scene_linear', 'lin_srgb'): False equivalent('ACEScg', 'scene_linear'): True equivalent('lnf', 'scene_linear'): False +get_color_interop_id('ACES2065-1') = lin_ap0_scene get_color_interop_id('ACEScg') = lin_ap1_scene get_color_interop_id('lin_srgb') = lin_rec709_scene get_color_interop_id([1, 13, 1, 1]) = srgb_rec709_scene diff --git a/testsuite/python-colorconfig/ref/out-ocio25.txt b/testsuite/python-colorconfig/ref/out-ocio25.txt index 83e831b137..4b705176f7 100644 --- a/testsuite/python-colorconfig/ref/out-ocio25.txt +++ b/testsuite/python-colorconfig/ref/out-ocio25.txt @@ -28,6 +28,7 @@ equivalent('linear', 'lin_srgb'): False equivalent('scene_linear', 'lin_srgb'): False equivalent('ACEScg', 'scene_linear'): True equivalent('lnf', 'scene_linear'): False +get_color_interop_id('ACES2065-1') = lin_ap0_scene get_color_interop_id('ACEScg') = lin_ap1_scene get_color_interop_id('lin_srgb') = lin_rec709_scene get_color_interop_id([1, 13, 1, 1]) = srgb_rec709_scene diff --git a/testsuite/python-colorconfig/ref/out.txt b/testsuite/python-colorconfig/ref/out.txt index 711f2d88e4..54166f2a3e 100644 --- a/testsuite/python-colorconfig/ref/out.txt +++ b/testsuite/python-colorconfig/ref/out.txt @@ -28,6 +28,7 @@ equivalent('linear', 'lin_srgb'): False equivalent('scene_linear', 'lin_srgb'): False equivalent('ACEScg', 'scene_linear'): True equivalent('lnf', 'scene_linear'): False +get_color_interop_id('ACES2065-1') = lin_ap0_scene get_color_interop_id('ACEScg') = lin_ap1_scene get_color_interop_id('lin_srgb') = lin_rec709_scene get_color_interop_id([1, 13, 1, 1]) = srgb_rec709_scene diff --git a/testsuite/python-colorconfig/src/test_colorconfig.py b/testsuite/python-colorconfig/src/test_colorconfig.py index cbbba63dc9..5dc618df6f 100755 --- a/testsuite/python-colorconfig/src/test_colorconfig.py +++ b/testsuite/python-colorconfig/src/test_colorconfig.py @@ -57,6 +57,7 @@ print ("equivalent('scene_linear', 'lin_srgb'):", config.equivalent("scene_linear", "lin_srgb")) print ("equivalent('ACEScg', 'scene_linear'):", config.equivalent("ACEScg", "scene_linear")) print ("equivalent('lnf', 'scene_linear'):", config.equivalent("lnf", "scene_linear")) + print ("get_color_interop_id('ACES2065-1') = ", config.get_color_interop_id("ACES2065-1")) print ("get_color_interop_id('ACEScg') = ", config.get_color_interop_id("ACEScg")) print ("get_color_interop_id('lin_srgb') = ", config.get_color_interop_id("lin_srgb")) print ("get_color_interop_id([1, 13, 1, 1]) = ", config.get_color_interop_id([1, 13, 1, 1])) From 8f923dcf15f23812a04d3905b02bdcd415d9d8d1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 14 Aug 2026 13:56:09 +0200 Subject: [PATCH 2/2] Fix wrong P3 legacy aliases Signed-off-by: Brecht Van Lommel --- src/libOpenImageIO/color_ocio.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libOpenImageIO/color_ocio.cpp b/src/libOpenImageIO/color_ocio.cpp index da7e299ca2..b37e00a2d7 100644 --- a/src/libOpenImageIO/color_ocio.cpp +++ b/src/libOpenImageIO/color_ocio.cpp @@ -2339,10 +2339,10 @@ constexpr ColorInteropID color_interop_ids[] = { // interpret it as BT.1886. { "g24_rec709_display", "rec1886_rec709_display", CICPPrimaries::Rec709, CICPTransfer::BT709, CICPMatrix::BT709 }, - { "srgb_p3d65_display", "p3d65_display", CICPPrimaries::P3D65, + { "srgb_p3d65_display", "displayp3_display", CICPPrimaries::P3D65, + CICPTransfer::sRGB, CICPMatrix::BT709 }, + { "srgbe_p3d65_display", "displayp3_hdr_display", CICPPrimaries::P3D65, CICPTransfer::sRGB, CICPMatrix::BT709 }, - { "srgbe_p3d65_display", nullptr, CICPPrimaries::P3D65, CICPTransfer::sRGB, - CICPMatrix::BT709 }, { "pq_p3d65_display", "st2084_p3d65_display", CICPPrimaries::P3D65, CICPTransfer::PQ, CICPMatrix::Rec2020_NCL }, { "pq_rec2020_display", "rec2100_pq_display", CICPPrimaries::Rec2020, @@ -2356,7 +2356,7 @@ constexpr ColorInteropID color_interop_ids[] = { /* CICPPrimaries::Rec709, CICPTransfer::Gamma22, CICPMatrix::BT709 */ }, // No CICP code for Adobe RGB primaries. { "g22_adobergb_display", nullptr }, - { "g26_p3d65_display", "p3_dci_display", CICPPrimaries::P3D65, + { "g26_p3d65_display", "p3d65_display", CICPPrimaries::P3D65, CICPTransfer::Gamma26, CICPMatrix::BT709 }, { "g26_xyzd65_display", nullptr, CICPPrimaries::XYZD65, CICPTransfer::Gamma26, CICPMatrix::Unspecified },