Ogeon / palette

A Rust library for linear color calculations and conversion
Apache License 2.0
748 stars 60 forks source link

Implement CAM16 #342

Closed Ogeon closed 4 months ago

Ogeon commented 1 year ago

Implements support for CIE CAM 16 and surrounding parts. This is a work in progress that is put up for early review, in case anyone has feedback or want to play Find The Typo. Based on https://observablehq.com/@jrus/cam16.

Closed Issues

Ogeon commented 1 year ago

The precision seem strangely low on my computer (3-4 digits are the same before it diverges). I can't find what causes it, but it's probably in xyz_to_cam16, since the output of prepare_parameters was identical to the reference.

Ogeon commented 1 year ago

The accuracy difference may be some trigonometry function that's different. Converting back to RGB yields near perfect results, so the round trip seem to be working as it should.

github-actions[bot] commented 1 year ago

Benchmark for 899f822

Click to view benchmark | Test | Base | PR | % | |------|--------------|------------------|---| | Cie family/lab to lch | 3.1±0.01µs | 3.1±0.01µs | 0.00% | | Cie family/lab to xyz | **773.2±0.54ns** | 774.4±0.39ns | **+0.16%** | | Cie family/lch to lab | 1149.1±47.74ns | **1143.3±0.83ns** | **-0.50%** | | Cie family/linsrgb to xyz | 299.8±6.66ns | **284.5±0.11ns** | **-5.10%** | | Cie family/linsrgb to xyz - wide::f32x8 | 312.6±0.36ns | **311.2±0.45ns** | **-0.45%** | | Cie family/xyz to lab | 8.4±0.02µs | **8.3±0.01µs** | **-1.19%** | | Cie family/xyz to yxy | **667.4±0.92ns** | 668.4±0.65ns | **+0.15%** | | Cie family/yxy to xyz | 611.5±0.30ns | **605.1±4.39ns** | **-1.05%** | | Matrix functions/matrix_inverse | **14.5±0.02ns** | 14.8±0.02ns | **+2.07%** | | Matrix functions/multiply_3x3 | 10.4±0.01ns | 10.4±0.00ns | 0.00% | | Matrix functions/multiply_rgb_to_xyz | 10.0±0.00ns | 10.0±0.00ns | 0.00% | | Matrix functions/multiply_xyz | 6.4±0.00ns | 6.4±0.00ns | 0.00% | | Matrix functions/multiply_xyz_to_rgb | 6.4±0.00ns | 6.4±0.00ns | 0.00% | | Matrix functions/rgb_to_xyz_matrix | 29.6±0.04ns | **29.2±0.03ns** | **-1.35%** | | Rgb family/hsl to hsv | **685.1±0.28ns** | 692.9±0.35ns | **+1.14%** | | Rgb family/hsl to linear hsl | 7.5±0.00µs | 7.5±0.01µs | 0.00% | | Rgb family/hsl to rgb | 2.1±0.01µs | 2.1±0.00µs | 0.00% | | Rgb family/hsv to hsl | **954.7±0.34ns** | 956.1±0.49ns | **+0.15%** | | Rgb family/hsv to hwb | **224.0±0.13ns** | 224.2±0.12ns | **+0.09%** | | Rgb family/hsv to linear hsv | 7.1±0.00µs | **7.0±0.00µs** | **-1.41%** | | Rgb family/hsv to rgb | 2.0±0.00µs | 2.0±0.00µs | 0.00% | | Rgb family/hwb to hsv | 555.3±0.40ns | 555.5±0.22ns | +0.04% | | Rgb family/hwb to linear hwb | **8.1±0.01µs** | 8.2±0.01µs | **+1.23%** | | Rgb family/linear hsl to hsl | 7.6±0.01µs | 7.6±0.00µs | 0.00% | | Rgb family/linear hsv to hsv | 7.1±0.00µs | 7.1±0.00µs | 0.00% | | Rgb family/linear hwb to hwb | 8.2±0.01µs | 8.2±0.01µs | 0.00% | | Rgb family/linsrgb to rgb | 3.8±0.00µs | 3.8±0.00µs | 0.00% | | Rgb family/linsrgb to rgb - wide::f32x8 | 5.5±0.00µs | 5.5±0.00µs | 0.00% | | Rgb family/linsrgb_f32 to rgb_u8 | **1310.8±0.58ns** | 1311.4±1.02ns | **+0.05%** | | Rgb family/linsrgb_f64 to rgb_u8 | 1367.2±0.65ns | 1366.8±0.94ns | -0.03% | | Rgb family/rgb to hsl | 661.1±0.27ns | **658.4±0.30ns** | **-0.41%** | | Rgb family/rgb to hsl - wide::f32x8 | **490.5±0.26ns** | 491.0±0.29ns | **+0.10%** | | Rgb family/rgb to hsv | 483.7±0.27ns | **479.3±0.31ns** | **-0.91%** | | Rgb family/rgb to hsv - wide::f32x8 | **429.7±0.94ns** | 430.3±0.54ns | **+0.14%** | | Rgb family/rgb to linsrgb | 3.8±0.00µs | 3.8±0.00µs | 0.00% | | Rgb family/rgb to linsrgb - wide::f32x8 | 3.6±0.01µs | 3.6±0.00µs | 0.00% | | Rgb family/rgb_u8 to linsrgb_f32 | **328.2±0.12ns** | 334.2±0.11ns | **+1.83%** | | Rgb family/rgb_u8 to linsrgb_f64 | **331.5±0.20ns** | 340.4±0.70ns | **+2.68%** | | Rgb family/xyz to linsrgb | 342.3±5.00ns | **328.2±0.19ns** | **-4.12%** | | Rgb family/xyz to linsrgb - wide::f32x8 | 306.4±0.19ns | 306.3±0.23ns | -0.03% |
github-actions[bot] commented 1 year ago

Benchmark for 76ea61d

Click to view benchmark | Test | Base | PR | % | |------|--------------|------------------|---| | Cie family/lab to lch | **3.3±0.00µs** | 3.4±0.01µs | **+3.03%** | | Cie family/lab to xyz | **771.4±1.18ns** | 773.2±0.31ns | **+0.23%** | | Cie family/lch to lab | **1212.4±47.59ns** | 1349.2±1.40ns | **+11.28%** | | Cie family/linsrgb to xyz | 311.1±0.18ns | **305.2±0.17ns** | **-1.90%** | | Cie family/linsrgb to xyz - wide::f32x8 | **250.9±0.41ns** | 251.4±0.23ns | **+0.20%** | | Cie family/xyz to lab | 8.6±0.01µs | 8.6±0.01µs | 0.00% | | Cie family/xyz to yxy | **652.4±0.40ns** | 686.5±0.91ns | **+5.23%** | | Cie family/yxy to xyz | **605.7±0.29ns** | 619.4±0.40ns | **+2.26%** | | Matrix functions/matrix_inverse | 14.1±0.01ns | **13.9±0.01ns** | **-1.42%** | | Matrix functions/multiply_3x3 | **9.6±0.03ns** | 9.8±0.03ns | **+2.08%** | | Matrix functions/multiply_rgb_to_xyz | 8.4±0.01ns | 8.4±0.02ns | 0.00% | | Matrix functions/multiply_xyz | 6.0±0.04ns | 6.0±0.04ns | 0.00% | | Matrix functions/multiply_xyz_to_rgb | 6.0±0.03ns | 6.0±0.04ns | 0.00% | | Matrix functions/rgb_to_xyz_matrix | **26.0±0.16ns** | 27.3±0.02ns | **+5.00%** | | Rgb family/hsl to hsv | 781.4±0.34ns | **719.2±0.42ns** | **-7.96%** | | Rgb family/hsl to linear hsl | **7.4±0.03µs** | 7.5±0.01µs | **+1.35%** | | Rgb family/hsl to rgb | **2.3±0.00µs** | 2.4±0.00µs | **+4.35%** | | Rgb family/hsv to hsl | **977.0±0.97ns** | 1011.2±2.13ns | **+3.50%** | | Rgb family/hsv to hwb | 232.8±2.38ns | 231.5±2.46ns | -0.56% | | Rgb family/hsv to linear hsv | 6.9±0.01µs | 6.9±0.01µs | 0.00% | | Rgb family/hsv to rgb | 2.1±0.02µs | 2.1±0.00µs | 0.00% | | Rgb family/hwb to hsv | 556.7±0.86ns | 556.8±1.98ns | +0.02% | | Rgb family/hwb to linear hwb | **8.2±0.01µs** | 8.3±0.00µs | **+1.22%** | | Rgb family/linear hsl to hsl | 7.5±0.00µs | 7.5±0.00µs | 0.00% | | Rgb family/linear hsv to hsv | 7.0±0.00µs | 7.0±0.00µs | 0.00% | | Rgb family/linear hwb to hwb | 8.2±0.01µs | 8.2±0.00µs | 0.00% | | Rgb family/linsrgb to rgb | **3.7±0.00µs** | 3.8±0.00µs | **+2.70%** | | Rgb family/linsrgb to rgb - wide::f32x8 | 5.1±0.00µs | **5.0±0.00µs** | **-1.96%** | | Rgb family/linsrgb_f32 to rgb_u8 | 1273.5±0.64ns | 1273.5±0.49ns | 0.00% | | Rgb family/linsrgb_f64 to rgb_u8 | 1363.8±0.52ns | 1364.1±0.81ns | +0.02% | | Rgb family/rgb to hsl | **633.5±0.48ns** | 634.0±2.35ns | **+0.08%** | | Rgb family/rgb to hsl - wide::f32x8 | 476.1±0.15ns | **475.9±0.25ns** | **-0.04%** | | Rgb family/rgb to hsv | 568.2±0.39ns | 568.4±0.35ns | +0.04% | | Rgb family/rgb to hsv - wide::f32x8 | **431.8±0.22ns** | 432.2±0.30ns | **+0.09%** | | Rgb family/rgb to linsrgb | 3.8±0.00µs | 3.8±0.00µs | 0.00% | | Rgb family/rgb to linsrgb - wide::f32x8 | 3.2±0.00µs | 3.2±0.00µs | 0.00% | | Rgb family/rgb_u8 to linsrgb_f32 | 308.1±1.06ns | **303.3±0.97ns** | **-1.56%** | | Rgb family/rgb_u8 to linsrgb_f64 | 309.2±1.36ns | 309.4±1.39ns | +0.06% | | Rgb family/xyz to linsrgb | 362.7±0.21ns | **356.3±0.31ns** | **-1.76%** | | Rgb family/xyz to linsrgb - wide::f32x8 | **248.0±0.47ns** | 248.5±0.55ns | **+0.20%** |
github-actions[bot] commented 1 year ago

Benchmark for 7f44c63

Click to view benchmark | Test | Base | PR | % | |------|--------------|------------------|---| | Cie family/lab to lch | 4.0±0.01µs | 4.0±0.09µs | 0.00% | | Cie family/lab to xyz | 926.2±0.66ns | **925.4±2.49ns** | **-0.09%** | | Cie family/lch to lab | 1460.1±1.91ns | **1446.9±11.75ns** | **-0.90%** | | Cie family/linsrgb to xyz | 382.1±0.58ns | **369.3±3.10ns** | **-3.35%** | | Cie family/linsrgb to xyz - wide::f32x8 | 302.6±1.21ns | **301.8±0.46ns** | **-0.26%** | | Cie family/xyz to lab | 10.3±0.04µs | 10.3±0.03µs | 0.00% | | Cie family/xyz to yxy | **798.6±11.01ns** | 811.7±3.60ns | **+1.64%** | | Cie family/yxy to xyz | **725.6±0.42ns** | 744.1±0.87ns | **+2.55%** | | Matrix functions/matrix_inverse | 16.7±0.01ns | 16.7±0.01ns | 0.00% | | Matrix functions/multiply_3x3 | 11.7±0.01ns | 11.7±0.02ns | 0.00% | | Matrix functions/multiply_rgb_to_xyz | 10.0±0.03ns | 10.0±0.02ns | 0.00% | | Matrix functions/multiply_xyz | 7.2±0.05ns | 7.2±0.05ns | 0.00% | | Matrix functions/multiply_xyz_to_rgb | 7.2±0.10ns | 7.2±0.05ns | 0.00% | | Matrix functions/rgb_to_xyz_matrix | 31.2±0.02ns | 31.2±0.02ns | 0.00% | | Rgb family/hsl to hsv | 938.4±3.43ns | **858.9±2.09ns** | **-8.47%** | | Rgb family/hsl to linear hsl | 9.0±0.05µs | **8.9±0.06µs** | **-1.11%** | | Rgb family/hsl to rgb | **2.8±0.00µs** | 2.9±0.01µs | **+3.57%** | | Rgb family/hsv to hsl | **1173.6±5.72ns** | 1215.5±3.95ns | **+3.57%** | | Rgb family/hsv to hwb | 281.5±3.76ns | **276.8±3.33ns** | **-1.67%** | | Rgb family/hsv to linear hsv | 8.4±0.06µs | **8.3±0.04µs** | **-1.19%** | | Rgb family/hsv to rgb | **2.4±0.06µs** | 2.5±0.02µs | **+4.17%** | | Rgb family/hwb to hsv | **668.8±0.93ns** | 670.3±2.18ns | **+0.22%** | | Rgb family/hwb to linear hwb | 9.9±0.04µs | 9.9±0.08µs | 0.00% | | Rgb family/linear hsl to hsl | **9.0±0.09µs** | 9.1±0.03µs | **+1.11%** | | Rgb family/linear hsv to hsv | 8.4±0.01µs | 8.4±0.04µs | 0.00% | | Rgb family/linear hwb to hwb | 9.9±0.02µs | **9.8±0.11µs** | **-1.01%** | | Rgb family/linsrgb to rgb | 4.5±0.06µs | 4.5±0.05µs | 0.00% | | Rgb family/linsrgb to rgb - wide::f32x8 | 6.0±0.01µs | 6.0±0.00µs | 0.00% | | Rgb family/linsrgb_f32 to rgb_u8 | 1531.1±12.22ns | **1529.3±1.17ns** | **-0.12%** | | Rgb family/linsrgb_f64 to rgb_u8 | 1637.9±2.22ns | 1638.1±2.63ns | +0.01% | | Rgb family/rgb to hsl | **755.9±3.85ns** | 770.8±5.65ns | **+1.97%** | | Rgb family/rgb to hsl - wide::f32x8 | **548.2±0.49ns** | 572.4±5.77ns | **+4.41%** | | Rgb family/rgb to hsv | **682.3±0.70ns** | 685.0±8.37ns | **+0.40%** | | Rgb family/rgb to hsv - wide::f32x8 | 519.1±0.33ns | 519.4±0.81ns | +0.06% | | Rgb family/rgb to linsrgb | 4.6±0.04µs | 4.6±0.00µs | 0.00% | | Rgb family/rgb to linsrgb - wide::f32x8 | **3.7±0.00µs** | 3.8±0.10µs | **+2.70%** | | Rgb family/rgb_u8 to linsrgb_f32 | 370.1±1.15ns | 370.8±1.49ns | +0.19% | | Rgb family/rgb_u8 to linsrgb_f64 | 381.4±1.56ns | 382.3±1.50ns | +0.24% | | Rgb family/xyz to linsrgb | 422.9±1.77ns | 422.9±0.97ns | 0.00% | | Rgb family/xyz to linsrgb - wide::f32x8 | 297.9±0.64ns | 298.2±0.87ns | +0.10% |
github-actions[bot] commented 1 year ago

Benchmark for 8f8ed28

Click to view benchmark | Test | Base | PR | % | |------|--------------|------------------|---| | Cie family/lab to lch | 3.8±0.14µs | 3.8±0.13µs | 0.00% | | Cie family/lab to xyz | 868.7±33.76ns | 881.2±31.71ns | +1.44% | | Cie family/lch to lab | 1372.6±52.67ns | 1377.8±53.26ns | +0.38% | | Cie family/linsrgb to xyz | 348.9±12.22ns | 347.1±16.02ns | -0.52% | | Cie family/linsrgb to xyz - wide::f32x8 | 285.9±8.87ns | 284.3±12.20ns | -0.56% | | Cie family/xyz to lab | **9.6±0.39µs** | 10.0±0.43µs | **+4.17%** | | Cie family/xyz to yxy | 771.6±29.12ns | 775.8±24.22ns | +0.54% | | Cie family/yxy to xyz | 698.3±22.39ns | 712.1±24.19ns | +1.98% | | Matrix functions/matrix_inverse | 15.7±0.54ns | 15.5±0.52ns | -1.27% | | Matrix functions/multiply_3x3 | 10.9±0.40ns | 10.8±0.47ns | -0.92% | | Matrix functions/multiply_rgb_to_xyz | 9.6±0.28ns | 9.6±0.33ns | 0.00% | | Matrix functions/multiply_xyz | 6.9±0.31ns | 6.8±0.26ns | -1.45% | | Matrix functions/multiply_xyz_to_rgb | 6.9±0.24ns | 6.8±0.28ns | -1.45% | | Matrix functions/rgb_to_xyz_matrix | 30.1±0.94ns | 29.6±1.02ns | -1.66% | | Rgb family/hsl to hsv | **848.1±20.43ns** | 889.9±32.26ns | **+4.93%** | | Rgb family/hsl to linear hsl | 8.7±0.26µs | 8.6±0.27µs | -1.15% | | Rgb family/hsl to rgb | 2.7±0.10µs | 2.7±0.10µs | 0.00% | | Rgb family/hsv to hsl | 1129.1±32.42ns | 1129.2±35.84ns | +0.01% | | Rgb family/hsv to hwb | 268.1±10.95ns | 263.9±9.03ns | -1.57% | | Rgb family/hsv to linear hsv | 8.0±0.29µs | 8.2±0.20µs | +2.50% | | Rgb family/hsv to rgb | 2.4±0.07µs | 2.4±0.07µs | 0.00% | | Rgb family/hwb to hsv | 675.7±28.36ns | 688.2±23.65ns | +1.85% | | Rgb family/hwb to linear hwb | 9.3±0.32µs | 9.4±0.36µs | +1.08% | | Rgb family/linear hsl to hsl | 8.6±0.28µs | 8.6±0.29µs | 0.00% | | Rgb family/linear hsv to hsv | 8.1±0.28µs | 8.1±0.25µs | 0.00% | | Rgb family/linear hwb to hwb | 9.5±0.32µs | 9.4±0.38µs | -1.05% | | Rgb family/linsrgb to rgb | 4.3±0.15µs | 4.4±0.12µs | +2.33% | | Rgb family/linsrgb to rgb - wide::f32x8 | **5.7±0.20µs** | 5.9±0.16µs | **+3.51%** | | Rgb family/linsrgb_f32 to rgb_u8 | 1434.4±58.55ns | 1461.7±49.18ns | +1.90% | | Rgb family/linsrgb_f64 to rgb_u8 | 1584.7±43.37ns | 1573.9±55.94ns | -0.68% | | Rgb family/rgb to hsl | 732.5±22.43ns | 730.9±20.64ns | -0.22% | | Rgb family/rgb to hsl - wide::f32x8 | 559.1±13.01ns | **522.9±17.16ns** | **-6.47%** | | Rgb family/rgb to hsv | 659.0±18.12ns | **569.0±17.48ns** | **-13.66%** | | Rgb family/rgb to hsv - wide::f32x8 | 508.8±9.34ns | **499.4±16.99ns** | **-1.85%** | | Rgb family/rgb to linsrgb | 4.3±0.17µs | 4.3±0.16µs | 0.00% | | Rgb family/rgb to linsrgb - wide::f32x8 | 3.6±0.15µs | 3.5±0.13µs | -2.78% | | Rgb family/rgb_u8 to linsrgb_f32 | 354.5±11.14ns | 348.9±12.64ns | -1.58% | | Rgb family/rgb_u8 to linsrgb_f64 | 357.1±8.67ns | 350.9±13.46ns | -1.74% | | Rgb family/xyz to linsrgb | **409.1±14.67ns** | 471.6±17.79ns | **+15.28%** | | Rgb family/xyz to linsrgb - wide::f32x8 | 280.7±10.78ns | 283.7±11.10ns | +1.07% |
github-actions[bot] commented 1 year ago

Benchmark for 3ee5a58

Click to view benchmark | Test | Base | PR | % | |------|--------------|------------------|---| | Cie family/lab to lch | 3.1±0.01µs | 3.1±0.00µs | 0.00% | | Cie family/lab to xyz | **773.7±1.02ns** | 774.4±0.57ns | **+0.09%** | | Cie family/lch to lab | 1144.8±4.21ns | 1144.8±1.93ns | 0.00% | | Cie family/linsrgb to xyz | 295.3±5.73ns | **284.5±0.15ns** | **-3.66%** | | Cie family/linsrgb to xyz - wide::f32x8 | **311.3±0.32ns** | 314.4±0.30ns | **+1.00%** | | Cie family/xyz to lab | 8.3±0.08µs | 8.3±0.02µs | 0.00% | | Cie family/xyz to yxy | **662.0±0.31ns** | 667.4±4.21ns | **+0.82%** | | Cie family/yxy to xyz | 611.6±3.02ns | **607.5±3.30ns** | **-0.67%** | | Matrix functions/matrix_inverse | 14.5±0.03ns | **14.3±0.03ns** | **-1.38%** | | Matrix functions/multiply_3x3 | **10.4±0.01ns** | 10.5±0.07ns | **+0.96%** | | Matrix functions/multiply_rgb_to_xyz | 10.0±0.00ns | 10.0±0.00ns | 0.00% | | Matrix functions/multiply_xyz | 6.4±0.00ns | 6.4±0.00ns | 0.00% | | Matrix functions/multiply_xyz_to_rgb | 6.4±0.01ns | 6.4±0.00ns | 0.00% | | Matrix functions/rgb_to_xyz_matrix | 29.2±0.04ns | 29.2±0.03ns | 0.00% | | Rgb family/hsl to hsv | **689.1±0.87ns** | 689.4±0.25ns | **+0.04%** | | Rgb family/hsl to linear hsl | 7.7±0.01µs | **7.6±0.00µs** | **-1.30%** | | Rgb family/hsl to rgb | **2.1±0.00µs** | 2.2±0.00µs | **+4.76%** | | Rgb family/hsv to hsl | **961.7±4.74ns** | 967.1±3.60ns | **+0.56%** | | Rgb family/hsv to hwb | 224.0±0.09ns | **223.9±0.39ns** | **-0.04%** | | Rgb family/hsv to linear hsv | **7.0±0.00µs** | 7.1±0.00µs | **+1.43%** | | Rgb family/hsv to rgb | 2.0±0.00µs | 2.0±0.00µs | 0.00% | | Rgb family/hwb to hsv | **555.3±0.43ns** | 556.7±0.36ns | **+0.25%** | | Rgb family/hwb to linear hwb | 8.2±0.01µs | **8.1±0.01µs** | **-1.22%** | | Rgb family/linear hsl to hsl | 7.7±0.00µs | **7.6±0.00µs** | **-1.30%** | | Rgb family/linear hsv to hsv | 7.1±0.00µs | 7.1±0.01µs | 0.00% | | Rgb family/linear hwb to hwb | 8.2±0.01µs | 8.2±0.01µs | 0.00% | | Rgb family/linsrgb to rgb | 3.8±0.00µs | 3.8±0.00µs | 0.00% | | Rgb family/linsrgb to rgb - wide::f32x8 | 5.5±0.05µs | 5.5±0.00µs | 0.00% | | Rgb family/linsrgb_f32 to rgb_u8 | 1325.5±50.36ns | **1311.1±0.74ns** | **-1.09%** | | Rgb family/linsrgb_f64 to rgb_u8 | **1367.7±0.79ns** | 1371.1±1.84ns | **+0.25%** | | Rgb family/rgb to hsl | **657.2±0.35ns** | 662.4±0.38ns | **+0.79%** | | Rgb family/rgb to hsl - wide::f32x8 | 490.0±0.55ns | 490.4±0.68ns | +0.08% | | Rgb family/rgb to hsv | **477.5±0.43ns** | 488.2±0.30ns | **+2.24%** | | Rgb family/rgb to hsv - wide::f32x8 | 431.0±0.82ns | **429.6±0.70ns** | **-0.32%** | | Rgb family/rgb to linsrgb | 3.8±0.04µs | 3.8±0.00µs | 0.00% | | Rgb family/rgb to linsrgb - wide::f32x8 | 3.6±0.00µs | 3.6±0.00µs | 0.00% | | Rgb family/rgb_u8 to linsrgb_f32 | **328.3±0.17ns** | 329.5±0.18ns | **+0.37%** | | Rgb family/rgb_u8 to linsrgb_f64 | 329.7±0.18ns | **328.8±0.15ns** | **-0.27%** | | Rgb family/xyz to linsrgb | 340.0±4.38ns | **328.2±0.31ns** | **-3.47%** | | Rgb family/xyz to linsrgb - wide::f32x8 | 307.1±0.27ns | **306.3±0.31ns** | **-0.26%** |
Ogeon commented 1 year ago

Getting UCS to work well is pretty challenging. The main issue is that it's based on brightness, while the "main" metric and default for PartialCam16 is lightness. The current version makes it possible to set the attributes statically, so UCS can require the input to have brightness and chroma. The downside with this is that there are essentially 7 versions of PartialCam16 (more if static and dynamic attributes are mixed), which adds a bunch of extra for a user to wrap their head around.

The good news is that this solution works relatively well with the derive macro for FromColorUnclamped. It just required a small extension (I also made errors a bit nicer). Part of the "trick" is to bypass Cam16, so PartialCam16 becomes the "parent" type for UCS. This breaks up the triangle relationship between Xyz, Cam16 and PartialCam16, and makes it so the conversions are as direct as possible.

github-actions[bot] commented 1 year ago

Benchmark for 95b77b8

Click to view benchmark | Test | Base | PR | % | |------|--------------|------------------|---| | Cie family/lab to lch | 3.1±0.00µs | 3.1±0.00µs | 0.00% | | Cie family/lab to xyz | 774.4±0.49ns | **772.2±0.56ns** | **-0.28%** | | Cie family/lch to lab | 1144.0±0.39ns | 1143.7±1.09ns | -0.03% | | Cie family/linsrgb to xyz | 322.4±8.00ns | **295.1±0.16ns** | **-8.47%** | | Cie family/linsrgb to xyz - wide::f32x8 | 334.2±0.18ns | **312.8±2.01ns** | **-6.40%** | | Cie family/xyz to lab | **8.3±0.08µs** | 8.4±0.07µs | **+1.20%** | | Cie family/xyz to yxy | 663.7±0.51ns | **661.0±0.59ns** | **-0.41%** | | Cie family/yxy to xyz | 611.8±0.39ns | **607.1±3.62ns** | **-0.77%** | | Matrix functions/matrix_inverse | **14.3±0.02ns** | 14.8±0.02ns | **+3.50%** | | Matrix functions/multiply_3x3 | 10.4±0.01ns | 10.4±0.01ns | 0.00% | | Matrix functions/multiply_rgb_to_xyz | **10.0±0.03ns** | 10.1±0.10ns | **+1.00%** | | Matrix functions/multiply_xyz | 6.4±0.01ns | 6.4±0.03ns | 0.00% | | Matrix functions/multiply_xyz_to_rgb | 6.4±0.00ns | 6.4±0.01ns | 0.00% | | Matrix functions/rgb_to_xyz_matrix | 29.1±0.02ns | 29.1±0.03ns | 0.00% | | Rgb family/hsl to hsv | 690.3±0.37ns | **688.7±0.31ns** | **-0.23%** | | Rgb family/hsl to linear hsl | 7.5±0.01µs | 7.5±0.00µs | 0.00% | | Rgb family/hsl to rgb | 2.1±0.01µs | 2.1±0.01µs | 0.00% | | Rgb family/hsv to hsl | 962.2±2.36ns | 962.1±3.34ns | -0.01% | | Rgb family/hsv to hwb | 224.0±0.10ns | 224.0±0.11ns | 0.00% | | Rgb family/hsv to linear hsv | 7.0±0.01µs | 7.0±0.00µs | 0.00% | | Rgb family/hsv to rgb | 2.0±0.00µs | 2.0±0.00µs | 0.00% | | Rgb family/hwb to hsv | **555.6±0.36ns** | 556.0±0.31ns | **+0.07%** | | Rgb family/hwb to linear hwb | **8.1±0.01µs** | 8.2±0.01µs | **+1.23%** | | Rgb family/linear hsl to hsl | 7.6±0.00µs | 7.6±0.00µs | 0.00% | | Rgb family/linear hsv to hsv | 7.1±0.01µs | 7.1±0.01µs | 0.00% | | Rgb family/linear hwb to hwb | 8.2±0.01µs | 8.2±0.02µs | 0.00% | | Rgb family/linsrgb to rgb | 3.8±0.01µs | 3.8±0.01µs | 0.00% | | Rgb family/linsrgb to rgb - wide::f32x8 | **5.4±0.01µs** | 5.5±0.01µs | **+1.85%** | | Rgb family/linsrgb_f32 to rgb_u8 | 1310.9±0.64ns | 1311.3±3.61ns | +0.03% | | Rgb family/linsrgb_f64 to rgb_u8 | 1367.8±1.35ns | 1367.3±0.98ns | -0.04% | | Rgb family/rgb to hsl | 660.8±0.45ns | **656.5±0.31ns** | **-0.65%** | | Rgb family/rgb to hsl - wide::f32x8 | 486.6±0.25ns | **485.1±0.20ns** | **-0.31%** | | Rgb family/rgb to hsv | 486.3±0.28ns | **477.9±0.24ns** | **-1.73%** | | Rgb family/rgb to hsv - wide::f32x8 | 433.4±7.58ns | **432.1±0.74ns** | **-0.30%** | | Rgb family/rgb to linsrgb | 3.8±0.00µs | 3.8±0.00µs | 0.00% | | Rgb family/rgb to linsrgb - wide::f32x8 | 3.6±0.00µs | 3.6±0.00µs | 0.00% | | Rgb family/rgb_u8 to linsrgb_f32 | 335.1±0.26ns | **328.3±0.24ns** | **-2.03%** | | Rgb family/rgb_u8 to linsrgb_f64 | 340.9±0.38ns | **330.2±0.26ns** | **-3.14%** | | Rgb family/xyz to linsrgb | 361.4±8.52ns | 368.1±7.36ns | +1.85% | | Rgb family/xyz to linsrgb - wide::f32x8 | **305.4±0.30ns** | 307.5±0.60ns | **+0.69%** |
codspeed-hq[bot] commented 1 year ago

CodSpeed Performance Report

Merging #342 will degrade performances by 11.42%

Comparing cam16 (78acbca) with master (ccc521b)

Summary

❌ 1 (👁 1) regressions ✅ 44 untouched benchmarks

🆕 1 new benchmarks

Benchmarks breakdown

Benchmark master cam16 Change
🆕 Lab improved delta E N/A 3.6 ms N/A
👁 matrix_inverse 215.6 ns 243.3 ns -11.42%
codecov[bot] commented 1 year ago

Codecov Report

Attention: Patch coverage is 92.42494% with 164 lines in your changes are missing coverage. Please review.

Project coverage is 83.48%. Comparing base (ccc521b) to head (78acbca). Report is 4 commits behind head on master.

Files Patch % Lines
palette_derive/src/meta/type_item_attributes.rs 51.61% 23 Missing and 7 partials :warning:
palette/src/cam16/parameters.rs 75.30% 20 Missing :warning:
palette/src/cam16/partial.rs 94.63% 19 Missing :warning:
palette/src/cam16/ucs_jmh.rs 89.26% 19 Missing :warning:
palette/src/cam16/ucs_jab.rs 89.74% 12 Missing :warning:
palette_derive/src/color_types.rs 92.81% 9 Missing and 2 partials :warning:
palette_derive/src/convert/from_color_unclamped.rs 89.52% 5 Missing and 6 partials :warning:
palette/src/cam16/full.rs 97.74% 9 Missing :warning:
palette_derive/src/meta/field_attributes.rs 46.15% 4 Missing and 3 partials :warning:
palette/src/cam16/math.rs 98.63% 6 Missing :warning:
... and 6 more
Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #342 +/- ## ========================================== + Coverage 82.01% 83.48% +1.47% ========================================== Files 115 125 +10 Lines 18287 20145 +1858 Branches 18287 20145 +1858 ========================================== + Hits 14998 16818 +1820 - Misses 3131 3170 +39 + Partials 158 157 -1 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

Ogeon commented 10 months ago

Splitting the colors into groups, and forcing XYZ <-> CAM16 conversion to be explicit, avoids the issue with the default parameters. Now it's up to the user to make sure they are set as expected.

Ogeon commented 10 months ago

I think this latest change solved the last major challenge with this addition. It's nice that splitting the spaghetti of conversations into groups actually seems to work so well, since I really didn't like the idea of having default parameters. It never felt right, but this is better.

Also, in case anyone wonders what's taking so long, it's both because of the tricky problems like these (I also made some other changes earlier, such as the macros, to lay a better foundation) and because I haven't been feeling like programming as much in my free time lately. This comes and goes over time, so nothing to worry about. It's just how I manage my time and energy. 🙂

Ogeon commented 5 months ago

For anyone who's watching this, feel free to start testing it. I would appreciate any input on the API and of course possible bugs.

Ogeon commented 5 months ago

I ended up changing the approach for partial CAM16. The generic struct complicated trait implementations to the degree that it didn't really save any effort, compared to a cookie cutter macro solution. That and the awkward naming and newtype structs didn't sit right with me. This new approach is easier to treat as any other type, at the price of more repetition in some places. Still not too bad.

Ogeon commented 5 months ago

The cam16 module needs some documentation, but I think it will finally be good to go after that. This is enough for today, though.

Ogeon commented 4 months ago

That's the largest squash I have ever done. I think it's ready for merging now.