core/colorspace: ensure that we don't create elevated blacks with black point compensation

There are cases where the minimum luminance can be lower than the transfer function's minimum; in those
cases, the transfer function's minimum would get mapped to a value greater than black in the target
transfer function. To avoid that, this just takes the max. of the metadata and transfer function minimum

BUG: 494854
(cherry picked from commit cef6656ff5)
wilder/Plasma/6.2
Xaver Hugl 1 year ago
parent cef793da62
commit f702ad9c4c
  1. 2
      autotests/test_colorspaces.cpp
  2. 7
      src/core/colorspace.cpp

@ -225,7 +225,7 @@ void TestColorspaces::testOpenglShader_data()
QTest::addColumn<double>("maxError"); QTest::addColumn<double>("maxError");
// the allowed error here needs to be this high because of llvmpipe. With real GPU drivers it's lower // the allowed error here needs to be this high because of llvmpipe. With real GPU drivers it's lower
QTest::addRow("Perceptual") << RenderingIntent::Perceptual << 6.5; QTest::addRow("Perceptual") << RenderingIntent::Perceptual << 7.0;
QTest::addRow("RelativeColorimetric") << RenderingIntent::RelativeColorimetric << 1.5; QTest::addRow("RelativeColorimetric") << RenderingIntent::RelativeColorimetric << 1.5;
QTest::addRow("AbsoluteColorimetric") << RenderingIntent::AbsoluteColorimetric << 1.5; QTest::addRow("AbsoluteColorimetric") << RenderingIntent::AbsoluteColorimetric << 1.5;
QTest::addRow("RelativeColorimetricWithBPC") << RenderingIntent::RelativeColorimetricWithBPC << 1.5; QTest::addRow("RelativeColorimetricWithBPC") << RenderingIntent::RelativeColorimetricWithBPC << 1.5;

@ -461,11 +461,14 @@ QMatrix4x4 ColorDescription::toOther(const ColorDescription &other, RenderingInt
// add black point compensation: black and reference white from the source color space // add black point compensation: black and reference white from the source color space
// should both be mapped to black and reference white in the destination color space // should both be mapped to black and reference white in the destination color space
const double effectiveMin = std::max(minLuminance(), m_transferFunction.minLuminance);
const double otherEffectiveMin = std::max(other.minLuminance(), other.m_transferFunction.minLuminance);
// before color conversions, map [src min, src ref] to [0, 1] // before color conversions, map [src min, src ref] to [0, 1]
luminanceBefore.scale(1.0 / (reference - minLuminance())); luminanceBefore.scale(1.0 / (reference - minLuminance()));
luminanceBefore.translate(-minLuminance(), -minLuminance(), -minLuminance()); luminanceBefore.translate(-effectiveMin, -effectiveMin, -effectiveMin);
// afterwards, map [0, 1] again to [dst min, dst ref] // afterwards, map [0, 1] again to [dst min, dst ref]
luminanceAfter.translate(other.minLuminance(), other.minLuminance(), other.minLuminance()); luminanceAfter.translate(otherEffectiveMin, otherEffectiveMin, otherEffectiveMin);
luminanceAfter.scale(other.referenceLuminance() - other.minLuminance()); luminanceAfter.scale(other.referenceLuminance() - other.minLuminance());
} else { } else {
// map only the reference luminance // map only the reference luminance

Loading…
Cancel
Save