Re: [csswg-drafts] [css-color-4] Gamut mapping pseudocode was changed incorrectly (#9715)

Incorporating the changes from https://github.com/w3c/csswg-drafts/issues/9651#issuecomment-1858448087 and https://github.com/w3c/csswg-drafts/issues/9651#issuecomment-1861425392 too, we have

```html
<div algorithm="to CSS gamut map a color">
 To <dfn export>CSS gamut map</dfn> a color |origin|
 in color space |origin color space|
 to be in gamut of a destination color space |destination|:

<ol>
 <!-- check if we need gamut mapping at all -->
 <li>if |destination| has no gamut limits (XYZ-D65, XYZ-D50, Lab, LCH, Oklab, Oklch) convert |origin| to |destination| and return it as the gamut mapped color
 <!-- we do, so convert to Oklch -->
  <li>let |origin_Oklch| be |origin| converted
  from |origin color space| to the Oklch color space</li>
 <!-- constrain to SDR lightness range, which gamut maps to black or white -->
 <li>if the Lightness of |origin_Oklch| is greater than or equal to 100%,
  convert `oklab(1 0 0 / origin.alpha)` to |destination| and return it as the gamut mapped color</li>
 <li>if the Lightness of |origin_Oklch| is less than than or equal to 0%,
  convert `oklab(0 0 0 / origin.alpha)` to |destination| and return it as the gamut mapped color</li>
 <li>let inGamut(|color|) be a function which returns true if, when passed a color,
  that color is inside the gamut of |destination|.
  For HSL and HWB, it returns true if the color is inside the gamut of sRGB.
 </li>
 <!-- are we already in gamut? -->
 <li>if inGamut(|origin_Oklch|) is true, convert |origin_Oklch| to |destination| and return it as the gamut mapped color</li>
 <!-- now start to gamut map -->
 <li>otherwise, let delta(|one|, |two|) be a function which returns the deltaEOK of color |one| compared to color |two|</li>
 <li>let |JND| be 0.02</li>
 <li>let |epsilon| be 0.0001</li>
 <!-- we already excluded spaces with no gamut limits in the first step, so this is fine -->
 <li>let clip(|color|) be a function which converts |color| to |destination|,
  clamps each component to the bounds of the reference range for that component
  and returns the result</li>

 <!-- is clipped already indistinguishable from origin, and in gamut? -->
 <li>set |current| to |origin_Oklch|</li>
 <li>set |clipped| to clip(|current|)</li>
 <li>set |E| to delta(|clipped|, |current|)</li>
 <li>if |E| < |JND|
  <ol>
   <li>return |clipped| as the gamut mapped color</li>
  </ol>
 </li>

 <!-- reduce chroma -->
 <li>set |min| to zero</li>
 <li>set |max| to the Oklch chroma of |origin_Oklch|</li>
 <li> let |min_inGamut| be a boolean that represents when |min| is still in gamut, and set it to true
 <li>while (|max| - |min| is greater than |epsilon|) repeat the following steps
  <ol>
   <li>set |chroma| to (|min| + |max|) /2</li>
   <li>set the chroma component of |current| to |chroma|</li>
   <li>if |min_inGamut| is true and also if inGamut(|current|) is true, set |min| to |chroma| and continue to repeat these steps</li>
   <li>otherwise, if inGamut(|current|) is false carry out these steps:
    <ol>
     <li>set |clipped| to clip(|current|)</li>
     <li>set |E| to delta(|clipped|, |current|)</li>
     <li>if |E| < |JND|
     <ol>
      <li>if (|JND| - |E| < |epsilon|) return |clipped| as the gamut mapped color</li>
      <li>otherwise,
      <ol>
       <li>set |min_inGamut| to false</li>
       <li>set |min| to |chroma|</li>
      </ol>
      </li>
     </ol>
     </li>
     <li>otherwise, set |max| to |chroma| and continue to repeat these steps</li>
    </ol>
   </li>
  </ol>
 </li>
 <li>return |clipped| as the gamut mapped color</li>
</ol>
```

@jamesnw does that look correct?

-- 
GitHub Notification of comment by svgeesus
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/9715#issuecomment-1864923647 using your GitHub account


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

Received on Wednesday, 20 December 2023 18:15:49 UTC