[csswg-drafts] [css-color-4] CSS gamut mapping algorithm clarifications (#7653)

ccameron-chromium has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-color-4] CSS gamut mapping algorithm clarifications ==
This is with respect to the definition of the CSS gamut mapping algorithm in [CSS Gamut Mapping to an RGB Destination](https://www.w3.org/TR/css-color-4/#css-gamut-mapping).

In particular, the following text:

> For the analytical implementation, having found the exact intersection, project outwards (towards higher chroma) along the line of constant lightness until the deltaEOK between the projected point and a clipped version of that point exceeds one JND. Then returned the clipped version of the color as the mapped result.

In effect there are two steps: We start at the original point. We pull chroma in until we hit the border of the gamut, then we push chroma back out until clipping introduces only a certain level of error. 

**First question:** Should we limit the amount we push chroma out in the second phase to never push beyond the original point?

I suspect so, but it might be worth adding text to the spec regarding this. The difference between these two implementations is visible in these images (created using [this page](https://ccameron-chromium.github.io/gamut-map/gamut-map/ok-clip-lch-explorer.html)):

- [Walking out just to the original point](https://raw.githubusercontent.com/ccameron-chromium/gamut-map/main/gamut-map/chroma-walk-out-spec.png)
- [Walking out possibly beyond the original point](https://raw.githubusercontent.com/ccameron-chromium/gamut-map/main/gamut-map/chroma-walk-out-no-limit.png)

Notice the artifacts that are visible in the blue area on the left.

**Second question:** Should we reconsider the trade-off of the "push chrome back out" step?

While the "push chroma back out" is motivated in the subsections titled "Excessive Chroma Reduction" and "Chroma Reduction with Local Clipping", the results when visualizing constant luminance suggest that there there is some degradation of results.

The difference can be seen in these two images
- [Walking out just to the original point](https://raw.githubusercontent.com/ccameron-chromium/gamut-map/main/gamut-map/chroma-walk-out-spec.png)
- [No walking out, staying on the gamut border](https://raw.githubusercontent.com/ccameron-chromium/gamut-map/main/gamut-map/chroma-walk-out-none.png)

Notice the artifacts that are visible around the sRGB gamut when the walkout is applied versus when it isn't.

Also note that the "binary search implementation" is "allowed to" return points that are on the border, if the path of the binary search iteration happens to land there. These points (unpredictably located), would suffer the aforementioned chroma reduction that the "chroma walk out" part of the analytic algorithm is added to prevent.

**Third question:** Should we replace "binary search implementation" with something more precise and efficient?

The spec discusses two implementations, "binary search implementation" and "analytical implementation". I haven't found a code listing for the "analytical implementation", and I generally shy away from analytic solutions for nontrivial problems.

There do exist fast algorithms for computing the intersection of chroma with the border. For instance, [this algorithm](https://colab.research.google.com/drive/1GogK3_KPULEiproupphWtTlSlQZVtqZk#scrollTo=GkGcMJdInJHU&line=1&uniqifier=1) uses Newton's method to find the gamut boundary (up to floating-point precision), and requires just a few iterations (5 is a lot), and does nothing but adds and multiplies (and one divide) per iteration.

This might be a better algorithm to include in the code listing. I haven't looked into an efficient way to do the "chroma walk out" part of the algorithm, but perhaps we can remove it, depending on the resolution of the second question.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7653 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Monday, 29 August 2022 11:48:21 UTC