canvas icon indicating copy to clipboard operation
canvas copied to clipboard

Colour should match colour-science

Open 197g opened this issue 6 months ago • 2 comments

The python colour-science package is a defacto standard for open-source accurate color computation and a good reference for rigorous definitions, mostly, including possible tuning knobs that aren't strictly defined and listings of standardized parameter sets (primaries, whitepoints, transfer functions, stimulus curves, etc.)

We should do our best to match our own computation to values from this crate, investigating any deviation as a bug.

197g avatar Jun 21 '25 09:06 197g

Correct:

  • [x] Converting sRGB to Oklab is fine albeit newer versions round differently.

Known issues:

  • [x] ~~Converting between sRGB and ITU.BT2020 is inaccurate.~~
    // theirs: [255, 255, 0], array([ 243.96840205,  252.09511243,   26.61725637])
    // ours: ([255, 255, 0], [249, 254, 76])
    
    This was a problem at user level, conversion requires us setting apply_cctf_decoding as we pass everything in encoded form but their default is assuming linear primary space.
  • [x] ~~sRGB to Luma does not correspond to xyY.Y value as evaluated.~~ Same as above

Test coverage, Transfers:

  • [x] BT709 (#74)
  • [ ] Bt470-M
  • [x] Bt470 (pure gamma 2.8) (#74)
    • [x] Implement this first (#74)
  • [x] Bt601 (aka BT709) (#74)
  • [x] Smpte240 (#74)
  • [ ] Linear
  • [x] Srgb (#74)
  • [ ] Bt2020_10bit quantized (not in colour-science)
  • [ ] Bt2020_12bit quantized (not in colour-science)
  • [x] Bt2020 unquantized (#76)
  • [x] Smpte2084 (#76)
    • [ ] https://github.com/image-rs/canvas/pull/76#discussion_r2160426000
  • [ ] Bt2100Pq
  • [ ] Bt2100Hlg
  • [ ] Bt2100Scene

197g avatar Jun 21 '25 09:06 197g

So far so good. The biggest issue found after fixing coefficient bugs in transfer functions is that the conversion to XYZ and back is using multiplication in 32-bit floats and since this is a matrix multiplication it is a dot product. This has the potential of ugly inaccuracies from different cancellation between bit widths. We should switch to a more exact matrix-vector form, given we know the matrix sizes that can be done very precisely without too much overhead (particular on x86 AVX with DPPS though I'd recheck rounding modes).

197g avatar Jun 28 '25 23:06 197g