-
Notifications
You must be signed in to change notification settings - Fork 715
[css-color-4] Sample color conversion code leads to NaN values #9477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
XYZ was designed (by the use of super-saturated, not physically realizable primaries) to use positive numbers only. However, negative numbers do crop up as a result of chromatic adaptation and this is the case here: Lab uses D50 and Oklab uses D65.
In general we want to avoid clamping intermediate results.
That seems a reasonable way to handle it (and is what is done for the extended transfer functions for RGB color spaces). |
I've verified that sign-matched cube root round-trips correctly, at least in this case. Edit: Actually, I just realized that JavaScript's |
Good that JavaScript does a sign-matched cube root in practice, although the ECMAScript standard is curiously silent on the matter and has some weasel words about implementation approximated. However, it is at least worth a comment, to aid those implementing in other languages. |
It's not.
Sure, because that's what's expected for an odd root. Even roots have no real solution for negative numbers, so See https://en.wikipedia.org/wiki/Nth_root#Definition_and_notation
I guess you were using something like |
I added a porting hint in the sample code |
The sample code for converting from XYZ to OKLab involves taking the cube root of the result of multiplying the XYZ color by the
XYZtoLMS
matrix. This is undefined for negative numbers, and returnsNaN
, despite the fact that the XYZ color space is notionally unbounded and thus could very easily produce negative numbers.This comes up even with fairly reasonable in-bounds colors. For example,
lab(0.01% 35 1)
is equivalent toxyz(0.008679770007260038 0.000011070564598794538 -0.0005206593067627204)
, which converts to LMS as[0.006751691618866409, 0.000022646971037596888, -0.00003832537822546193]
.Should the LMS logic clamp channels so that they're 0 at minimum? Should it take the cube root of the absolute value and then match the sign afterwards?
The text was updated successfully, but these errors were encountered: