[graphics/krita] plugins/color/lcms2engine/colorprofiles: LCMS: fix value range detection of YCbCr profiles

L. E. Segovia null at kde.org
Tue Jun 28 18:04:36 BST 2022


Git commit 84197452989aa58ad6a507fa51d9185d1bbbd3d4 by L. E. Segovia.
Committed on 28/06/2022 at 16:01.
Pushed by lsegovia into branch 'master'.

LCMS: fix value range detection of YCbCr profiles

Wolthera's right, YCbCr (when used full-range, ICC doesn't allow
otherwise) is a reinterpretation of RGB. However, my profiles implement
roundtrip transformation through the AtoB0 and BtoA0 (plus the FP
alternatives) so returning early breaks the purpose of having them.

This commit moves the clause to the correct location and lets the
roundtrip check execute first.

CCMAIL: kimageshop at kde.org

M  +10   -14   plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp

https://invent.kde.org/graphics/krita/commit/84197452989aa58ad6a507fa51d9185d1bbbd3d4

diff --git a/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp b/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp
index 8aede2dbb5..6fb8aa2408 100644
--- a/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp
+++ b/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp
@@ -442,19 +442,6 @@ void IccColorProfile::calculateFloatUIMinMax(void)
     Q_ASSERT(num_channels >= 1 && num_channels <= 4); // num_channels==1 is for grayscale, we need to handle it
     Q_ASSERT(color_space_mask);
 
-    if (color_space_sig == cmsSigYCbCrData) {
-        // tricky, because the fundamental problem is that YCbCr profiles
-        // are LUT based, but this seems to be the case with the profiles
-        // that can be tested. Given this space is a reinterpretation of
-        // RGB spaces, this might be the appropriate value, though.
-        ret.resize(num_channels);
-        for (unsigned int i = 0; i < num_channels; ++i) {
-            ret[i].minVal = 0;
-            ret[i].maxVal = 1;
-        }
-        return;
-    }
-
     // to try to find the max range of float/doubles for this profile,
     // pass in min/max int and make the profile convert that
     // this is far from perfect, we need a better way, if possible to get the "bounds" of a profile
@@ -493,7 +480,16 @@ void IccColorProfile::calculateFloatUIMinMax(void)
 
     ret.resize(num_channels);
     for (unsigned int i = 0; i < num_channels; ++i) {
-        if (out_min_pixel[i] < out_max_pixel[i]) {
+        if (color_space_sig == cmsSigYCbCrData) {
+            // Although YCbCr profiles are essentially LUT-based
+            // (due to the inability of ICC to represent multiple successive
+            // matrix transforms except with BtoD0 tags in V4),
+            // YCbCr is intended to be a roundtrip transform to the
+            // corresponding RGB transform (BT.601, BT.709).
+            // Force enable the full range of values.
+            ret[i].minVal = 0;
+            ret[i].maxVal = 1;
+        } else if (out_min_pixel[i] < out_max_pixel[i]) {
             ret[i].minVal = out_min_pixel[i];
             ret[i].maxVal = out_max_pixel[i];
         } else {



More information about the kimageshop mailing list