Hey Graeme, I’m really pleased you found your way into this thread.
Let me start with a few caveats before I get into your comments.
- I’ve been writing color management software for roughly 2% as long as you have
- I’ve never actually read the sRGB spec
- I unequivacally have zero knowledge of the inner workings of the ratification process for said spec
- I don’t necessarily expect you or anyone else to change their long-working implementations based on my math. After all, we disagree by a max value of 3/65536 in our primaries.
All that said, I’ll debate with you anyway
I don’t necessarily believe they’re more accurate, just that they’re more compliant with the spec.
That’s correct, and I believe that is the correct interpretation. The x,y values were the starting point for the sRGB primaries, but the spec deviated from those ever so slightly in order to make the math cleaner. That deviation was small enough that the value of the primaries is preserved to the level of precision given in both the sRGB and the Rec. 709 standards. In other words, using the XYZ values at the given precision maintains compatibility with the starting x,y values at their starting precision level. Using the x,y values does not maintain compatibility with the given XYZ values at their starting precision level. And that’s true no matter how much precision you keep in the intermediate processing.
This, I believe, is incorrect. The fact that the original matrices didn’t invert to each other would have justified publishing more decimal places. Instead of adding precision to the document/spec, they actually adjusted the numbers so they worked out at the lower precision. This is reinforced in the fact that not only were the matrix values adjusted, but the rounded XYZ value of D65 given is rounded in the wrong direction.
I can’t speak to lost accuracy within the CMS itself, but as soon as an ICC profile enters the mix, precision is lost anyway. The s15Fixed16Number format only has accuracy to log(2^16) =~ 4.8 decimal places, which really means 4 with the 5th being mostly right. Any precision you start with by trying to improve on the XYZ values given in the spec is lost when you save them to or read them from a profile.
Going back to the example I used in my post, this is the value of the D65 R’G’B’-XYZ matrix calculated with as much accuracy as I could preserve, starting from the x,y primaries. This was the matrix that produced the profile values that match the ones from ArgyllCMS (after adaptation, of course).
0.4123907992659590 0.3575843393838780 0.1804807884018340
0.2126390058715100 0.7151686787677560 0.0721923153607337
0.0193308187155918 0.1191947797946260 0.9505321522496610
If you round-trip those though s15Fixed16Number format, they only maintain 4 dp of accuracy.
0.4123840332031250 0.3575897216796880 0.1804809570312500
0.2126464843750000 0.7151641845703130 0.0721893310546875
0.0193328857421875 0.1192016601562500 0.9505310058593750
And taking that round-tripped matrix and inverting it, you get this.
3.2411015823888700 -1.5374742408225600 -0.4986348425717410
-0.9693232691940230 1.8760231681184500 0.0415720618303295
0.0556374237335379 -0.2039925695286720 1.0569719298571300
Which only matches the correct inverse matrix (below) to 3 dp.
3.2409699419045200 -1.5373831775700900 -0.4986107602930030
-0.9692436362808800 1.8759675015077200 0.0415550574071756
0.0556300796969936 -0.2039769588889760 1.0569715142428800
By contrast, the XYZ values used in the sRGB spec, with their intentional imprecision, maintain 4 dp of agreement on that round trip.