use crate::{CmsError, XyY, XyYRepresentable, Xyz, Xyzd};
#[derive(Clone, Debug, Copy)]
#[repr(C)]
pub struct Chromaticity {
pub x: f32,
pub y: f32,
}
impl Chromaticity {
#[inline]
pub const fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
#[inline]
pub const fn to_xyz(&self) -> Xyz {
let reciprocal = if self.y != 0. { 1. / self.y } else { 0. };
Xyz {
x: self.x * reciprocal,
y: 1f32,
z: (1f32 - self.x - self.y) * reciprocal,
}
}
#[inline]
pub const fn to_scaled_xyzd(&self) -> Xyzd {
let z = 1.0 - self.x as f64 - self.y as f64;
Xyzd::new(self.x as f64, self.y as f64, z)
}
#[inline]
pub const fn to_scaled_xyz(&self) -> Xyz {
let z = 1.0 - self.x - self.y;
Xyz::new(self.x, self.y, z)
}
#[inline]
pub const fn to_xyzd(&self) -> Xyzd {
let reciprocal = if self.y != 0. { 1. / self.y } else { 0. };
Xyzd {
x: self.x as f64 * reciprocal as f64,
y: 1f64,
z: (1f64 - self.x as f64 - self.y as f64) * reciprocal as f64,
}
}
#[inline]
pub const fn to_xyyb(&self) -> XyY {
XyY {
x: self.x as f64,
y: self.y as f64,
yb: 1.,
}
}
pub const D65: Chromaticity = Chromaticity {
x: 0.31272,
y: 0.32903,
};
pub const D50: Chromaticity = Chromaticity {
x: 0.34567,
y: 0.35850,
};
}
impl XyYRepresentable for Chromaticity {
fn to_xyy(self) -> XyY {
self.to_xyyb()
}
}
impl TryFrom<Xyz> for Chromaticity {
type Error = CmsError;
#[inline]
fn try_from(xyz: Xyz) -> Result<Self, Self::Error> {
let sum = xyz.x + xyz.y + xyz.z;
if sum == 0.0 {
return Err(CmsError::DivisionByZero);
}
let rec = 1f32 / sum;
let chromaticity_x = xyz.x * rec;
let chromaticity_y = xyz.y * rec;
Ok(Chromaticity {
x: chromaticity_x,
y: chromaticity_y,
})
}
}