diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index e747089f54..96caa09ebe 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -635,6 +635,43 @@ class OCIOEXPORT Config */ void setInactiveColorSpaces(const char * inactiveColorSpaces); const char * getInactiveColorSpaces() const; + + /** + * \brief Return true if the specified color space is linear. + * + * The determination of linearity is made with respect to one of the two reference spaces + * (i.e., either the scene-referred one or the display-referred one). If the reference space + * type of the color space is the opposite of the requested reference space type, false is + * returned immediately rather than trying to invoke the default view transform to convert + * between the reference spaces. + * + * Note: This function relies on heuristics that may sometimes give an incorrect result. + * For example, if the encoding attribute is not set appropriately or the sampled values fail + * to detect non-linearity. + * + * The algorithm proceeds as follows: + * -- If the color space isdata attribute is true, return false. + * -- If the reference space type of the color space differs from the requested reference + * space type, return false. + * -- If the color space's encoding attribute is present, return true if it matches the + * expected reference space type (i.e., "scene-linear" for REFERENCE_SPACE_SCENE or + * "display-linear" for REFERENCE_SPACE_DISPLAY) and false otherwise. + * -- If the color space has no to_reference or from_reference transform, return true. + * -- Evaluate several points through the color space's transform and check if the output only + * differs by a scale factor (which may be different per channel, e.g. allowing an arbitrary + * matrix transform, with no offset). + * + * Note that the encoding test happens before the sampled value test to give config authors + * ultimate control over the linearity determination. For example, they could set the encoding + * attribute to indicate linearity if they want to ignore some areas of non-linearity + * (e.g., at extreme values). Or they could set it to indicate that a color space should not + * be considered linear, even if it is, in a mathematical sense. + * + * \param colorSpace Color space to evaluate. + * \param referenceSpaceType Evaluate linearity with respect to the specified reference space + * (either scene-referred or display-referred). + */ + bool isColorSpaceLinear(const char * colorSpace, ReferenceSpaceType referenceSpaceType) const; // // Roles diff --git a/src/OpenColorIO/Config.cpp b/src/OpenColorIO/Config.cpp index ab94e3f11e..b58a8aa1f8 100644 --- a/src/OpenColorIO/Config.cpp +++ b/src/OpenColorIO/Config.cpp @@ -922,6 +922,22 @@ class Config::Impl m_cacheFlags = flags; m_processorCache.enable((m_cacheFlags & PROCESSOR_CACHE_ENABLED) == PROCESSOR_CACHE_ENABLED); } + + ConstProcessorRcPtr getProcessorWithoutCaching( + const Config & config, + const ConstTransformRcPtr & transform, + TransformDirection direction) const + { + if (!transform) + { + throw Exception("Config::GetProcessor failed. Transform is null."); + } + + ProcessorRcPtr processor = Processor::Create(); + processor->getImpl()->setProcessorCacheFlags(PROCESSOR_CACHE_OFF); + processor->getImpl()->setTransform(config, m_context, transform, direction); + return processor; + } int instantiateDisplay(const std::string & monitorName, const std::string & monitorDescription, @@ -2699,6 +2715,112 @@ void Config::clearColorSpaces() getImpl()->refreshActiveColorSpaces(); } +bool Config::isColorSpaceLinear(const char * colorSpace, ReferenceSpaceType referenceSpaceType) const +{ + auto cs = getColorSpace(colorSpace); + + if (cs->isData()) + { + return false; + } + + // Colorspace is not linear if the types are opposite. + if (cs->getReferenceSpaceType() != referenceSpaceType) + { + return false; + } + + std::string encoding = cs->getEncoding(); + if (!encoding.empty()) + { + // Check the encoding value if it is set. + if ((StringUtils::Compare(cs->getEncoding(), "scene-linear") && + referenceSpaceType == REFERENCE_SPACE_SCENE) || + (StringUtils::Compare(cs->getEncoding(), "display-linear") && + referenceSpaceType == REFERENCE_SPACE_DISPLAY)) + { + return true; + } + else + { + return false; + } + } + + // We want to assess linearity over at least a reasonable range of values, so use a very dark + // value and a very bright value. Test neutral, red, green, and blue points to detect situations + // where the neutral may be linear but there is non-linearity off the neutral axis. + auto evaluate = [](const Config & config, ConstTransformRcPtr &t) -> bool + { + std::vector img = + { + 0.0625f, 0.0625f, 0.0625f, 4.f, 4.f, 4.f, + 0.0625f, 0.f, 0.f, 4.f, 0.f, 0.f, + 0.f, 0.0625f, 0.f, 0.f, 4.f, 0.f, + 0.f, 0.f, 0.0625f, 0.f, 0.f, 4.f + }; + std::vector dst = + { + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f, 0.f + }; + + PackedImageDesc desc(&img[0], 8, 1, CHANNEL_ORDERING_RGB); + PackedImageDesc descDst(&dst[0], 8, 1, CHANNEL_ORDERING_RGB); + + auto procToReference = config.getImpl()->getProcessorWithoutCaching( + config, t, TRANSFORM_DIR_FORWARD + ); + auto optCPUProc = procToReference->getOptimizedCPUProcessor(OPTIMIZATION_LOSSLESS); + optCPUProc->apply(desc, descDst); + + + float absError = 1e-5f; + float multiplier = 64.f; + bool ret = true; + + // Test the first RGB pair. + ret &= EqualWithAbsError(dst[0]*multiplier, dst[3], absError); + ret &= EqualWithAbsError(dst[1]*multiplier, dst[4], absError); + ret &= EqualWithAbsError(dst[2]*multiplier, dst[5], absError); + + // Test the second RGB pair. + ret &= EqualWithAbsError(dst[6]*multiplier, dst[9], absError); + ret &= EqualWithAbsError(dst[7]*multiplier, dst[10], absError); + ret &= EqualWithAbsError(dst[8]*multiplier, dst[11], absError); + + // Test the third RGB pair. + ret &= EqualWithAbsError(dst[12]*multiplier, dst[15], absError); + ret &= EqualWithAbsError(dst[13]*multiplier, dst[16], absError); + ret &= EqualWithAbsError(dst[14]*multiplier, dst[17], absError); + + // Test the fourth RGB pair. + ret &= EqualWithAbsError(dst[18]*multiplier, dst[21], absError); + ret &= EqualWithAbsError(dst[19]*multiplier, dst[22], absError); + ret &= EqualWithAbsError(dst[20]*multiplier, dst[23], absError); + + return ret; + }; + + ConstTransformRcPtr transformToReference = cs->getTransform(COLORSPACE_DIR_TO_REFERENCE); + ConstTransformRcPtr transformFromReference = cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE); + if ((transformToReference && transformFromReference) || transformToReference) + { + // Color space has a transform for the to-reference direction, or both directions. + return evaluate(*this, transformToReference); + } + else if (transformFromReference) + { + // Color space only has a transform for the from-reference direction. + return evaluate(*this, transformFromReference); + } + + // Color space matches the desired reference space type, is not a data space, and has no + // transforms, so it is equivalent to the reference space and hence linear. + return true; +} /////////////////////////////////////////////////////////////////////////// diff --git a/src/bindings/python/PyConfig.cpp b/src/bindings/python/PyConfig.cpp index cfca6ea454..3cae83b602 100644 --- a/src/bindings/python/PyConfig.cpp +++ b/src/bindings/python/PyConfig.cpp @@ -318,6 +318,8 @@ void bindPyConfig(py::module & m) DOC(Config, addColorSpace)) .def("removeColorSpace", &Config::removeColorSpace, "name"_a, DOC(Config, removeColorSpace)) + .def("isColorSpaceLinear", &Config::isColorSpaceLinear, "colorSpace"_a, "referenceSpaceType"_a, + DOC(Config, isColorSpaceLinear)) .def("isColorSpaceUsed", &Config::isColorSpaceUsed, "name"_a, DOC(Config, isColorSpaceUsed)) .def("clearColorSpaces", &Config::clearColorSpaces, diff --git a/tests/cpu/ColorSpace_tests.cpp b/tests/cpu/ColorSpace_tests.cpp index 087a6c5f49..2e46fc58c8 100644 --- a/tests/cpu/ColorSpace_tests.cpp +++ b/tests/cpu/ColorSpace_tests.cpp @@ -6,7 +6,9 @@ #include "ColorSpace.cpp" +#include #include "testutils/UnitTest.h" +#include "UnitTestUtils.h" namespace OCIO = OCIO_NAMESPACE; @@ -716,3 +718,219 @@ active_views: [] OCIO_CHECK_EQUAL(std::string(cfg->getColorSpaceFromFilepath("test_aces_test")), "colorspace"); } + +OCIO_ADD_TEST(Config, is_colorspace_linear) +{ + + constexpr const char * TEST_CONFIG { R"(ocio_profile_version: 2 + +description: Test config for the isColorSpaceLinear method. + +environment: + {} +search_path: "non_existing_path" +roles: + aces_interchange: scene_linear-trans + cie_xyz_d65_interchange: display_linear-enc + color_timing: scene_linear-trans + compositing_log: scene_log-enc + default: display_data + scene_linear: scene_linear-trans + +displays: + generic display: + - ! {name: Raw, colorspace: scene_data} + +# Make a few of the color spaces inactive, this should not affect the result. +inactive_colorspaces: [display_linear-trans, scene_linear-trans] + +view_transforms: + - ! + name: view_transform + from_scene_reference: ! {} + +# Display-referred color spaces. + +display_colorspaces: + - ! + name: display_data + description: | + Data space. + Has a linear transform, which should never happen, but this will be ignored since + isdata is true. + isdata: true + encoding: data + from_display_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: display_linear-enc + description: | + Encoding set to display-linear. + Has a non-existent transform, but this should be ignored since the encoding takes precedence. + isdata: false + encoding: display-linear + from_display_reference: ! {src: does-not-exist.lut} + + - ! + name: display_wrong-linear-enc + description: | + Encoding set to scene-linear. This should never happen for a display space, but test it. + isdata: false + encoding: scene-linear + + - ! + name: display_video-enc + description: | + Encoding set to sdr-video. + Has a linear transform, but this should be ignored since the encoding takes precedence. + isdata: false + encoding: sdr-video + from_display_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: display_linear-trans + description: | + No encoding. Transform is linear. + isdata: false + from_display_reference: ! + children: + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + - ! {slope: [0.1, 2, 3], style: noclamp} + + - ! + name: display_video-trans + description: | + No encoding. Transform is non-linear. + isdata: false + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_sRGB} + +# Scene-referred color spaces. + +colorspaces: + - ! + name: scene_data + description: | + Data space. + Has a linear transform, which should never happen, but this will be ignored + since isdata is true. + isdata: true + encoding: data + from_scene_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: scene_linear-enc + description: | + Encoding set to scene-linear. + Has a non-linear transform, but this will be ignored since the encoding takes precedence. + isdata: false + encoding: scene-linear + from_scene_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_sRGB} + + - ! + name: scene_wrong-linear-enc + description: | + Encoding set to display-linear. This should never happen for a scene space, but test it. + isdata: false + encoding: display-linear + + - ! + name: scene_log-enc + description: | + Encoding set to log. + Has a linear transform, but this will be ignored since the encoding takes precedence. + isdata: false + encoding: log + from_scene_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: scene_linear-trans + aliases: [scene_linear-trans-alias] + description: | + No encoding. Transform is linear. + isdata: false + to_scene_reference: ! + children: + - ! {style: UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD} + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: scene_nonlin-trans + description: | + No encoding. Transform is non-linear because it clamps values outside [0,1]. + isdata: false + to_scene_reference: ! + children: + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + - ! {min_in_value: 0., min_out_value: 0., max_in_value: 1., max_out_value: 1.} + + - ! + name: scene_ref + description: | + No encoding. Considered linear since it is equivalent to the reference space. + isdata: false +)" }; + + // Load config. + std::istringstream is; + is.str(TEST_CONFIG); + OCIO::ConstConfigRcPtr config; + + OCIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); + OCIO_REQUIRE_ASSERT(config); + OCIO_CHECK_NO_THROW(config->validate()); + + auto testSceneReferred = [&config](const char * csName, bool bSceneExpected, int line) + { + auto cs = config->getColorSpace(csName); + OCIO_REQUIRE_ASSERT(cs); + + bool isLinearToSceneReference = config->isColorSpaceLinear(csName, OCIO::REFERENCE_SPACE_SCENE); + OCIO_CHECK_EQUAL_FROM(isLinearToSceneReference, bSceneExpected, line); + }; + + auto testDisplayReferred = [&config](const char * csName, bool bDisplayExpected, int line) + { + auto cs = config->getColorSpace(csName); + OCIO_REQUIRE_ASSERT(cs); + + bool isLinearToDisplayReference = config->isColorSpaceLinear(csName, OCIO::REFERENCE_SPACE_DISPLAY); + OCIO_CHECK_EQUAL_FROM(isLinearToDisplayReference, bDisplayExpected, line); + }; + + { + testSceneReferred("display_data", false, __LINE__); + testSceneReferred("display_linear-enc", false, __LINE__); + testSceneReferred("display_wrong-linear-enc", false, __LINE__); + testSceneReferred("display_video-enc", false, __LINE__); + testSceneReferred("display_linear-trans", false, __LINE__); + testSceneReferred("display_video-trans", false, __LINE__); + + testSceneReferred("scene_data", false, __LINE__); + testSceneReferred("scene_linear-enc", true, __LINE__); + testSceneReferred("scene_wrong-linear-enc", false, __LINE__); + testSceneReferred("scene_log-enc", false, __LINE__); + testSceneReferred("scene_linear-trans", true, __LINE__); + testSceneReferred("scene_nonlin-trans", false, __LINE__); + testSceneReferred("scene_linear-trans-alias", true, __LINE__); + testSceneReferred("scene_ref", true, __LINE__); + } + + { + testDisplayReferred("display_data", false, __LINE__); + testDisplayReferred("display_linear-enc", true, __LINE__); + testDisplayReferred("display_wrong-linear-enc", false, __LINE__); + testDisplayReferred("display_video-enc", false, __LINE__); + testDisplayReferred("display_linear-trans", true, __LINE__); + testDisplayReferred("display_video-trans", false, __LINE__); + + testDisplayReferred("scene_data", false, __LINE__); + testDisplayReferred("scene_linear-enc", false, __LINE__); + testDisplayReferred("scene_wrong-linear-enc", false, __LINE__); + testDisplayReferred("scene_log-enc", false, __LINE__); + testDisplayReferred("scene_linear-trans", false, __LINE__); + testDisplayReferred("scene_nonlin-trans", false, __LINE__); + testDisplayReferred("scene_linear-trans-alias", false, __LINE__); + testDisplayReferred("scene_ref", false, __LINE__); + } +} diff --git a/tests/python/ColorSpaceTest.py b/tests/python/ColorSpaceTest.py index 483e338d2a..57fafa544b 100644 --- a/tests/python/ColorSpaceTest.py +++ b/tests/python/ColorSpaceTest.py @@ -407,3 +407,208 @@ def test_aliases(self): cs.clearAliases() aliases = cs.getAliases() self.assertEqual(len(aliases), 0) + + def test_is_colorspace_linear(self): + """ + Test isColorSpaceLinear. + """ + SIMPLE_PROFILE = """ocio_profile_version: 2 + +description: Test config for the isColorSpaceLinear method. + +environment: + {} +search_path: "non_existing_path" +roles: + aces_interchange: scene_linear-trans + cie_xyz_d65_interchange: display_linear-enc + color_timing: scene_linear-trans + compositing_log: scene_log-enc + default: display_data + scene_linear: scene_linear-trans + +displays: + generic display: + - ! {name: Raw, colorspace: scene_data} + +# Make a few of the color spaces inactive, this should not affect the result. +inactive_colorspaces: [display_linear-trans, scene_linear-trans] + +view_transforms: + - ! + name: view_transform + from_scene_reference: ! {} + +# Display-referred color spaces. + +display_colorspaces: + - ! + name: display_data + description: | + Data space. + Has a linear transform, which should never happen, but this will be ignored since + isdata is true. + isdata: true + encoding: data + from_display_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: display_linear-enc + description: | + Encoding set to display-linear. + Has a non-existent transform, but this should be ignored since the encoding takes precedence. + isdata: false + encoding: display-linear + from_display_reference: ! {src: does-not-exist.lut} + + - ! + name: display_wrong-linear-enc + description: | + Encoding set to scene-linear. This should never happen for a display space, but test it. + isdata: false + encoding: scene-linear + + - ! + name: display_video-enc + description: | + Encoding set to sdr-video. + Has a linear transform, but this should be ignored since the encoding takes precedence. + isdata: false + encoding: sdr-video + from_display_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: display_linear-trans + description: | + No encoding. Transform is linear. + isdata: false + from_display_reference: ! + children: + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + - ! {slope: [0.1, 2, 3], style: noclamp} + + - ! + name: display_video-trans + description: | + No encoding. Transform is non-linear. + isdata: false + from_display_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_sRGB} + +# Scene-referred color spaces. + +colorspaces: + - ! + name: scene_data + description: | + Data space. + Has a linear transform, which should never happen, but this will be ignored + since isdata is true. + isdata: true + encoding: data + from_scene_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: scene_linear-enc + description: | + Encoding set to scene-linear. + Has a non-linear transform, but this will be ignored since the encoding takes precedence. + isdata: false + encoding: scene-linear + from_scene_reference: ! {style: DISPLAY - CIE-XYZ-D65_to_sRGB} + + - ! + name: scene_wrong-linear-enc + description: | + Encoding set to display-linear. This should never happen for a scene space, but test it. + isdata: false + encoding: display-linear + + - ! + name: scene_log-enc + description: | + Encoding set to log. + Has a linear transform, but this will be ignored since the encoding takes precedence. + isdata: false + encoding: log + from_scene_reference: ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: scene_linear-trans + aliases: [scene_linear-trans-alias] + description: | + No encoding. Transform is linear. + isdata: false + to_scene_reference: ! + children: + - ! {style: UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD} + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + + - ! + name: scene_nonlin-trans + description: | + No encoding. Transform is non-linear because it clamps values outside [0,1]. + isdata: false + to_scene_reference: ! + children: + - ! {matrix: [ 3.240969941905, -1.537383177570, -0.498610760293, 0, -0.969243636281, 1.875967501508, 0.041555057407, 0, 0.055630079697, -0.203976958889, 1.056971514243, 0, 0, 0, 0, 1 ]} + - ! {min_in_value: 0., min_out_value: 0., max_in_value: 1., max_out_value: 1.} + + - ! + name: scene_ref + description: | + No encoding. Considered linear since it is equivalent to the reference space. + isdata: false +""" + # Create a config. + cfg = OCIO.Config.CreateFromStream(SIMPLE_PROFILE) + + def test_scene_referred(self, cfg, cs_name, expected_value): + cs = cfg.getColorSpace(cs_name) + is_linear_to_scene_reference = cfg.isColorSpaceLinear( + cs_name, + OCIO.REFERENCE_SPACE_SCENE + ) + self.assertEqual(is_linear_to_scene_reference, expected_value) + + def test_display_referred(self, cfg, cs_name, expected_value): + cs = cfg.getColorSpace(cs_name) + is_linear_to_display_reference = cfg.isColorSpaceLinear( + cs_name, + OCIO.REFERENCE_SPACE_DISPLAY + ) + self.assertEqual(is_linear_to_display_reference, expected_value) + + # Test the scene referred color spaces. + test_scene_referred(self, cfg, "display_data", False) + test_scene_referred(self, cfg, "display_linear-enc", False) + test_scene_referred(self, cfg, "display_wrong-linear-enc", False) + test_scene_referred(self, cfg, "display_video-enc", False) + test_scene_referred(self, cfg, "display_linear-trans", False) + test_scene_referred(self, cfg, "display_video-trans", False) + + test_scene_referred(self, cfg, "scene_data", False) + test_scene_referred(self, cfg, "scene_linear-enc", True) + test_scene_referred(self, cfg, "scene_wrong-linear-enc", False) + test_scene_referred(self, cfg, "scene_log-enc", False) + test_scene_referred(self, cfg, "scene_linear-trans", True) + test_scene_referred(self, cfg, "scene_nonlin-trans", False) + test_scene_referred(self, cfg, "scene_linear-trans-alias", True) + test_scene_referred(self, cfg, "scene_ref", True) + + # Test the display referred color spaces. + test_display_referred(self, cfg, "display_data", False) + test_display_referred(self, cfg, "display_linear-enc", True) + test_display_referred(self, cfg, "display_wrong-linear-enc", False) + test_display_referred(self, cfg, "display_video-enc", False) + test_display_referred(self, cfg, "display_linear-trans", True) + test_display_referred(self, cfg, "display_video-trans", False) + + test_display_referred(self, cfg, "scene_data", False) + test_display_referred(self, cfg, "scene_linear-enc", False) + test_display_referred(self, cfg, "scene_wrong-linear-enc", False) + test_display_referred(self, cfg, "scene_log-enc", False) + test_display_referred(self, cfg, "scene_linear-trans", False) + test_display_referred(self, cfg, "scene_nonlin-trans", False) + test_display_referred(self, cfg, "scene_linear-trans-alias", False) + test_display_referred(self, cfg, "scene_ref", False)