[csswg-drafts] [css-color-4] CSS gamut mapping algorithm pseudocode can result in infinite looping for some inputs (#6999)

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

== [css-color-4] CSS gamut mapping algorithm pseudocode can result in infinite looping for some inputs ==
The CSS gamut mapping algorithm [pseudocode](https://drafts.csswg.org/css-color/#binsearch) can result in infinite looping for some inputs. As an example, gamut mapping the color `oklch(104.4% 0 336)` to `display-p3` loops indefinitely due to the following steps:

```
gamut map oklch(104.4% 0 336) to display-p3:

origin_OKLCH -> oklch(104.4% 0 336)
inGamut<display-p3>(origin_OKLCH) -> false

min -> 0
max -> 0

start bisection loop:
    chroma -> 0
    current -> oklch(104.4% 0 336)

    inGamut<display-p3>(current) -> false
    current as display-p3 -> color(display-p3 1.058 1.058 1.058)

    clipped -> (display-p3 1 1 1)
    E -> delta(clipped, current)
          -> clipped as oklab(100% 0 5.96E-8)
          -> current as oklab(104.4% 0 0)
          -> sqrt(((100 / 100) - (104.4 / 100))^2 + (0 - 0)^2 + (5.96E-8 - 0)^2)
          -> 0.04

    0.04 is not less than JND of 0.02, so we loop forever
```

I added a condition to step 9.4.3 to also check if chroma was 0, making it something like:

```
        3. if E < JND or chroma is 0 convert clipped to destination and return it as the gamut mapped color
```

(though, it isn't really necessary to say "convert clipped to destination" since clipped is already in the destination color space by the definition of clip() in step 6.)


I haven't thought too deeply about whether there are any other cases that could infinite loop.

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


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

Received on Monday, 31 January 2022 00:43:29 UTC