palette/cam16/math/
chromaticity.rs

1use crate::{
2    bool_mask::{LazySelect, Select},
3    cam16::{
4        math::{self, DependentParameters},
5        BakedParameters,
6    },
7    num::{Arithmetics, FromScalar, PartialCmp, Real, Sqrt, Zero},
8};
9
10/// One the apparent chromatic intensity metrics of CAM16.
11#[derive(Clone, Copy, PartialEq, Eq, Debug)]
12pub(crate) enum ChromaticityType<T> {
13    /// The [chroma](https://en.wikipedia.org/wiki/Colorfulness#Chroma) (C) of a
14    /// color.
15    Chroma(T),
16
17    /// The [colorfulness](https://en.wikipedia.org/wiki/Colorfulness) (M) of a
18    /// color.
19    Colorfulness(T),
20
21    /// The [saturation](https://en.wikipedia.org/wiki/Colorfulness#Saturation)
22    /// (s) of a color.
23    Saturation(T),
24}
25
26impl<T> ChromaticityType<T> {
27    pub(crate) fn into_cam16<Wp>(
28        self,
29        lightness: T,
30        parameters: BakedParameters<Wp, T::Scalar>,
31    ) -> (T, T, T)
32    where
33        T: Real + FromScalar + Zero + Arithmetics + Sqrt + PartialCmp + Clone,
34        T::Mask: LazySelect<T> + Clone,
35    {
36        let DependentParameters { c, a_w, f_l_4, .. } = parameters.inner;
37        let is_black = lightness.eq(&T::zero());
38
39        match self {
40            ChromaticityType::Chroma(chroma) => {
41                let colorfulness = lazy_select! {
42                    if is_black.clone() => T::zero(),
43                    else => math::chroma_to_colorfulness(chroma.clone(), T::from_scalar(f_l_4))
44                };
45                let saturation = lazy_select! {
46                        if is_black.clone() => T::zero(),
47                        else => math::chroma_to_saturation(
48                        chroma.clone(),
49                        lightness,
50                        T::from_scalar(c),
51                        T::from_scalar(a_w),
52                    )
53                };
54                let chroma = is_black.select(T::zero(), chroma);
55
56                (chroma, colorfulness, saturation)
57            }
58            ChromaticityType::Colorfulness(colorfulness) => {
59                let chroma = lazy_select! {
60                    if is_black.clone() => T::zero(),
61                    else => math::colorfulness_to_chroma(colorfulness.clone(), T::from_scalar(f_l_4))
62                };
63                let saturation = lazy_select! {
64                        if is_black.clone() => T::zero(),
65                        else => math::chroma_to_saturation(
66                        chroma.clone(),
67                        lightness,
68                        T::from_scalar(c),
69                        T::from_scalar(a_w),
70                    )
71                };
72                let colorfulness = is_black.select(T::zero(), colorfulness);
73
74                (chroma, colorfulness, saturation)
75            }
76            ChromaticityType::Saturation(saturation) => {
77                let chroma = lazy_select! {
78                        if is_black.clone() => T::zero(),
79                        else => math::saturation_to_chroma(
80                        saturation.clone(),
81                        lightness,
82                        T::from_scalar(c),
83                        T::from_scalar(a_w),
84                    )
85                };
86                let colorfulness = lazy_select! {
87                    if is_black.clone() => T::zero(),
88                    else => math::chroma_to_colorfulness(chroma.clone(), T::from_scalar(f_l_4))
89                };
90                let saturation = is_black.select(T::zero(), saturation);
91
92                (chroma, colorfulness, saturation)
93            }
94        }
95    }
96}