tests: generate cLUT profiles
This adds new test cases that build a cLUT-based output ICC profile and test it through Weston. The aim is to ensure that the color-lcms/GL-renderer 3D LUT paths remain tested after color-lcms and GL-renderer gain support for matrix-based color transformations. The old test cases use a matrix-shaper type ICC profiles, so they should migrate to the matrix-based code paths in the future.
The new test cases are originally @vitalyp's work from !820 (closed). I took those and re-wrote how the ICC profile is built in order to simplify the code. An intermediate, messy version of my rewrites is in !864 (closed). This MR here is the cleaned up version.
Compared to !820 (closed), this MR:
- Simplifies how 3D LUT entries are computed: instead of constructing a LittleCMS pipeline to compute the values, we compute them by hand, using the already existing curve functions.
- Numerical normalization and de-normalization are removed, because I thought they should be unnecessary. They indeed are unnecessary, but only under certain conditions.
- Those conditions are met by dropping the BT.2020 RGB to XYZ conversion matrix and the related test case. This conversion would not have kept values inside [0.0, 1.0] range in XYZ. As any LUT input is clamped to [0.0, 1.0] range, testing the roundtrip conversion by adding the backward conversion didn't work. (The numerical normalization in !820 (closed) worked around this limitation.)
- As numerical normalization is no longer necessary, collecting min and max values from the matrix color conversion is also unnecessary and dropped.
- The choice of non-linear vs. optical input and output spaces for the 3D LUT element is dropped, hardcoding the element to work in optical-to-optical space. This was seen to produce the least error, because encoding a non-linear curve in the small number of taps per dimension that a 3D LUT has produces significant error, especially for pure power function curves like inverse AdobeRGB EOTF.
- ICC profile roundtrip verification is added. ICC profiles contain pipelines in both device-to-PCS and PCS-to-device directions. The roundtrip device-to-PCS-to-device should not alter any values (in these profiles).
- Curves (EOTF and inverse EOTF) are created as segmented curves (piece-wise analytically defined and parametrized) instead of tabulated curves (LUT) to improve their precision (near zero). They are also crafted in ICC multiProcessingElements compatible way to allow storing them in the ICC profiles.
- The reference images from the old test cases are re-used instead of adding new images.
- Memory leaks are fixed.
- LittleCMS error reporting function is installed, to ease debugging should LittleCMS refuse.
- The code is reorganized to be easier to read. Also some code motion is undone to reduce patch sizes.
- A lot of the helpers have been created or moved into
color_util.c
. - A new helper library
lcms_util.c
is introduced because it depends on LittleCMS whichcolor_util.c
does not. -
SetTextTags()
is re-copied from LittleCMS intolcms_util.c
, properly recording it's exact origins. - Consolidation of
dep_lcms2
in Meson files.
Compared to !864 (closed), the significant changes are:
- Segmented curves.
-
lcms_util.c
and its own tests. - Dropped
apply_tone_curve_ext()
which extended EOTF curves and their inverses to cover also negative and greater than 1.0 inputs. - Hardcoded optical→optical in 3D LUT, removed other options.
- Replacing
struct sampling_pipeline
with juststruct lcmsMAT3
, since 3D LUT operates with optical→optical now.