https://bugs.kde.org/show_bug.cgi?id=528375
--- Comment #2 from Jozsef Tar <[email protected]> --- DESCRIPTION The sRGB inverse EOTF implementation in src/core/colorspace.cpp contains an incorrect operation in its linear segment. In `TransferFunction::sRGBinverseEOTF(double nits)`, the following code is used when the normalized input is below the threshold of 0.0031308: return std::max(normalized / 12.92, 0.0); However, the linear segment of the inverse sRGB transfer function should multiply the normalized linear-light input by 12.92, not divide it. The expected implementation is: return std::max(normalized * 12.92, 0.0); For example, with a normalized linear-light input of 0.001: - Current implementation: 0.001 / 12.92 ≈ 0.0000773994 - Expected implementation: 0.001 * 12.92 = 0.01292 The current implementation therefore produces an output approximately 167 times smaller than the expected value in this linear segment. Cross-validation against Weston Weston's independent inverse sRGB transfer function implementation (`sRGB_two_piece_inv()` in `tests/harness/color_util.c`) uses multiplication by 12.92 in the linear segment: Weston's threshold (0.04045 / 12.92 ≈ 0.00313080495) is equivalent, within rounding precision, to KWin's threshold of 0.0031308. Weston source code: https://fossies.org/linux/weston/tests/harness/color_util.c Gamma table comparison (measured test results) I performed tests comparing the generated gamma table values from Weston and Plasma. The following table shows selected measured results. The input indices are 8-bit values (0–255), while the corresponding gamma table output values are 16-bit values (0–65535). The most noticeable discrepancy occurs between indices 10 and 11: - At index 10, the Plasma output is 15, compared to the linear reference value of 2570. - At index 11, the Plasma output is already 2827, matching the reference value. These measured results show a significant discrepancy at low input values, consistent with the incorrect calculation in the linear segment of KWin's inverse sRGB transfer function. STEPS TO REPRODUCE 1. Use KWin 6.8.2 with the original sRGB inverse EOTF implementation. 2. Examine `TransferFunction::sRGBinverseEOTF()` in `src/core/colorspace.cpp`. 3. Evaluate the linear segment with a normalized input below 0.0031308, for example 0.001. 4. Compare the result with the expected inverse sRGB calculation or Weston's implementation. 5. Compare the generated gamma table values at low input indices. OBSERVED RESULT The function divides the normalized linear-light input by 12.92 in the linear segment, resulting in an incorrect sRGB conversion. For an input of 0.001, the function returns approximately 0.0000773994 instead of 0.01292. My gamma table tests also show a significant discrepancy at low input indices, as illustrated above. I reproduced the resulting issue on Fedora 44 running KDE Plasma Wayland. EXPECTED RESULT The linear segment of the inverse sRGB transfer function should multiply the normalized linear-light input by 12.92: ```cpp return std::max(normalized * 12.92, 0.0); ``` This is consistent with Weston's independent inverse sRGB implementation. SOFTWARE/OS VERSIONS Operating System: Fedora Linux 44 KDE Plasma Version: 6.8.2 KDE Frameworks Version: 6.31.0 Qt Version: 6.11.2 KWin Version: 6.8.2-3.fc44 (original Fedora package) Session type: Wayland ADDITIONAL INFORMATION I built a locally patched KWin 6.8.2 RPM package using the proposed one-line change. After installing the patched package, the issue I was investigating disappeared on my system. Original Fedora package: 6.8.2-3.fc44 Locally patched package: 6.8.2-3.fc44.1 -- You are receiving this mail because: You are watching all bug changes.
