Closed danburzo closed 6 years ago
It may be useful to specify in the section about lab() and lch() colors the specific values for the D50 white point as defined in the Profile Connection Space: [0.9642, 1.0000, 0.8249]
.
This document contains some matrices that may be useful.
Thanks for reporting the discrepancy!
neither ICC nor Lindbloom are authoritative for D50, which is defined by the CIE. I will check up and update the spec (and sample code) with the correct value.
I will also check in Wyszecki & Stiles when I get home.
Thanks!
So if I understand correctly, the intent of the spec is to:
In regards to 1, this sentence:
D50 is also the whitepoint used for the profile connection space in ICC color interconversion,
I think may benefit from clarifying the distinction between the ICC definition of D50 and the CIE definition of D50.
In regards to 2, I'm a bit concerned that I've seen many variations on the matrices used to get sRGB ↔️ XYZD65 ↔️ XYZD50, or direct sRGB ↔️ XYZD50 pairs, and I wonder whether some well-defined matrices in the spec won't lead to more consistent implementations, since the approximations and the floating-point errors have a compounding effect on the result.
P.S. This page another set of matrices, and this sentence which further confuses things:
and the values of D65 and D50 from CIE 15.2 (and the ICC specification for D50) D65 = [95.04; 100; 108.89]; D50 = [96.42; 100; 82.49];
Not having access to CIE 15.2, I'm having a hard time piecing things together...
I've seen many variations on the matrices used to get sRGB ↔️ XYZD65 ↔️ XYZD50, or direct sRGB ↔️ XYZD50 pairs
Firstly, you can't do any of those with just a matrix; the sRGB needs to be linearized first. But having done that step, the operations for lin_sRGB to XYZ_D65, and XYZ_D65 to LMS, and white adjustment, and LMS to XYZ_D50 are all 3x3 matrices so the overall matrix is obtained by matrix multiplication.
The slightly different value for the Z component of D50 in ICC is a mistake, not an intentional change, but one they are now unable to correct without requiring all deployed CMS to be updated.
I feel that it would be better to express the correct values in the spec, with enough significant digits to avoid roundoff error.
Also, in the Lab to LCH code, I think Math.atan2() should be normalized to the interval [0, 360)
.
Yes, indeed it should. Good catch. Although H is also defined to wrap, if someone enters a hue outside that range.
Ah yes, I had somehow misread that H is <number>
not <hue>
. Too much time in front of the screen :)
Some updates from my D50 saga: As I wrote in this thread, I was not able to find appropriate matrices for the conversion between sRGB and CIELab that did not introduce non-negligible errors. One particular doozy is that grayscale RGB colors will produce a Chroma of up to 0.0035 in the LCH equivalent.
One last thing is nagging me: is there a benefit to keeping the CIELab values relative to D50 rather than sRGB's D65? Since the standard D50 does not match the values from ICC / Profile Connection Space... Defining lab()
as relative to D65 would make computations simpler.
Yes, the value is that everyone else uses D50. If you use a spectrometer to measure color it will give you a readout in Lab with a D50 whitepoint.
Thank you for the clarification!
In Section 17. Sample code for color conversions of the CSS Color Module Level 4 spec, there's a discrepancy with the D50 white point values.
In the XYZ ↔ Lab conversion code, it's assumed to be
[0.9642, 1.0000, 0.8249]
(as specified by the ICC spec).However, the D50 ↔ D65 chromatic adaptation uses Bradford matrices from this page, which have been computed for D50 being
[0.96422, 1.00000, 0.82521]
.I think the correct approach is to use the ICC-defined D50 throughout, no?
(Also, I'm not clear on why the ICC value for the D50 white point differs from the generally accepted one. e.g. Matlab).