Skip to content

[css-color-4] CSS gamut mapping algorithm clarifications #7653

@ccameron-chromium

Description

@ccameron-chromium

This is with respect to the definition of the CSS gamut mapping algorithm in CSS Gamut Mapping to an RGB Destination.

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):

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

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 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions