#![allow(clippy::excessive_precision)]
use crate::ColorModel;
use crate::chan::{Ch8, Ch16, Ch32, Channel, Linear, Premultiplied, Straight};
use crate::el::{Pix, PixRgba, Pixel};
use std::ops::Range;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Xyz {}
impl Xyz {
pub fn x<P>(p: P) -> P::Chan
where
P: Pixel<Model = Self>,
{
p.get::<0>()
}
pub fn x_mut<P>(p: &mut P) -> &mut P::Chan
where
P: Pixel<Model = Self>,
{
p.get_mut::<0>()
}
pub fn y<P>(p: P) -> P::Chan
where
P: Pixel<Model = Self>,
{
p.get::<1>()
}
pub fn y_mut<P>(p: &mut P) -> &mut P::Chan
where
P: Pixel<Model = Self>,
{
p.get_mut::<1>()
}
pub fn z<P>(p: P) -> P::Chan
where
P: Pixel<Model = Self>,
{
p.get::<2>()
}
pub fn z_mut<P>(p: &mut P) -> &mut P::Chan
where
P: Pixel<Model = Self>,
{
p.get_mut::<2>()
}
}
impl ColorModel for Xyz {
const CIRCULAR: Range<usize> = 0..0;
const LINEAR: Range<usize> = 0..3;
const ALPHA: usize = 3;
fn into_rgba<P>(p: P) -> PixRgba<P>
where
P: Pixel<Model = Self>,
{
let px = Self::x(p).to_f32();
let py = Self::y(p).to_f32();
let pz = Self::z(p).to_f32();
let red = px * 3.2406 + py * -1.5372 + pz * -0.4986;
let green = px * -0.9689 + py * 1.8758 + pz * 0.0415;
let blue = px * 0.0557 + py * -0.2040 + pz * 1.0570;
PixRgba::<P>::new(red, green, blue, p.alpha().to_f32())
}
fn from_rgba<P>(rgba: PixRgba<P>) -> P
where
P: Pixel<Model = Self>,
{
let chan = rgba.channels();
let red = chan[0].to_f32();
let green = chan[1].to_f32();
let blue = chan[2].to_f32();
let alpha = chan[3];
let x = red * 0.4124 + green * 0.3576 + blue * 0.1805;
let y = red * 0.2126 + green * 0.7152 + blue * 0.0722;
let z = red * 0.0193 + green * 0.1192 + blue * 0.9505;
P::from_channels(&[x.into(), y.into(), z.into(), alpha])
}
}
pub type Xyz8 = Pix<3, Ch8, Xyz, Straight, Linear>;
pub type Xyz16 = Pix<3, Ch16, Xyz, Straight, Linear>;
pub type Xyz32 = Pix<3, Ch32, Xyz, Straight, Linear>;
pub type Xyza8 = Pix<4, Ch8, Xyz, Straight, Linear>;
pub type Xyza16 = Pix<4, Ch16, Xyz, Straight, Linear>;
pub type Xyza32 = Pix<4, Ch32, Xyz, Straight, Linear>;
pub type Xyza8p = Pix<4, Ch8, Xyz, Premultiplied, Linear>;
pub type Xyza16p = Pix<4, Ch16, Xyz, Premultiplied, Linear>;
pub type Xyza32p = Pix<4, Ch32, Xyz, Premultiplied, Linear>;
#[cfg(test)]
mod test {
#[test]
fn xyz_to_rgb() {
}
}