diff --git a/color/src/colorspace.rs b/color/src/colorspace.rs index cb32052..19ce79e 100644 --- a/color/src/colorspace.rs +++ b/color/src/colorspace.rs @@ -1669,4 +1669,69 @@ mod tests { 1e-4, )); } + + /// Test whether `ColorSpace::convert` with implicit chromatic adaptation results in the same + /// color as `ColorSpace::convert_absolute` in combination with explicit chromatic adaptation + /// through `Colorspace::chromatically_adapt`. + #[test] + fn implicit_vs_explicit_chromatic_adaptation() { + fn test(src: [f32; 3]) { + let convert = Source::convert::(src); + let convert_absolute_then_adapt = Dest::chromatically_adapt( + Source::convert_absolute::(src), + Source::WHITE_POINT, + Dest::WHITE_POINT, + ); + let adapt_then_convert_absolute = Source::convert_absolute::( + Source::chromatically_adapt(src, Source::WHITE_POINT, Dest::WHITE_POINT), + ); + + // The error is measured in linear sRGB. This adds more conversions, but makes it + // easier to reason about the component ranges. + assert!(almost_equal::( + Dest::to_linear_srgb(convert), + Dest::to_linear_srgb(convert_absolute_then_adapt), + 1e-4, + )); + assert!(almost_equal::( + Dest::to_linear_srgb(convert), + Dest::to_linear_srgb(adapt_then_convert_absolute), + 1e-4, + )); + } + + // From a D65 whitepoint to everything + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + + // From an ACES whitepoint to everything + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + test::([0.5, 0.2, 0.4]); + } }