colr-types 0.2.0

Color model ZSTs and marker traits for colr.
Documentation
//! CIELab and CIELCh color models.

use core::marker::PhantomData;

use crate::{BackingStore, ChannelMap};
use crate::illuminant::{D65, Illuminant};

/// CIE 1976 L*a*b* color space under reference white W.
///
/// Perceptually uniform for small color differences. L* is lightness
/// [0, 100], a* is green-red [-128, 127], b* is blue-yellow [-128, 127].
/// Reference: CIE 015:2018.
///
/// `OFFSET` is the storage index of the first color channel. `0` (default)
/// places color channels at [0, 1, 2] with alpha at 3. `1` places color
/// channels at [1, 2, 3] with alpha at 0, matching alpha-first texture layouts.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Lab<W: Illuminant = D65, const OFFSET: usize = 0>(PhantomData<W>);

/// CIE L*C*h*, the polar form of CIELab.
///
/// L* is lightness, C* is chroma, h is hue angle in radians [0, 2pi).
///
/// `OFFSET` is the storage index of the first color channel. `0` (default)
/// places color channels at [0, 1, 2] with alpha at 3. `1` places color
/// channels at [1, 2, 3] with alpha at 0, matching alpha-first texture layouts.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct LCh<W: Illuminant = D65, const OFFSET: usize = 0>(PhantomData<W>);

impl<W: Illuminant, const OFFSET: usize> BackingStore<[f32; 3]> for Lab<W, OFFSET> {}
impl<W: Illuminant, const OFFSET: usize> BackingStore<[f32; 4]> for Lab<W, OFFSET> {}
impl<W: Illuminant, const OFFSET: usize> BackingStore<[f32; 3]> for LCh<W, OFFSET> {}
impl<W: Illuminant, const OFFSET: usize> BackingStore<[f32; 4]> for LCh<W, OFFSET> {}

impl<W: Illuminant, const OFFSET: usize> ChannelMap<4> for Lab<W, OFFSET> {
    const INDICES: [usize; 4] = [OFFSET, OFFSET + 1, OFFSET + 2, 3 - OFFSET * 3];
}

impl<W: Illuminant, const OFFSET: usize> ChannelMap<4> for LCh<W, OFFSET> {
    const INDICES: [usize; 4] = [OFFSET, OFFSET + 1, OFFSET + 2, 3 - OFFSET * 3];
}

#[cfg(feature = "glam")]
mod glam_impls {
    use super::*;
    impl<W: Illuminant, const OFFSET: usize> BackingStore<glam::Vec3> for Lab<W, OFFSET> {}
    impl<W: Illuminant, const OFFSET: usize> BackingStore<glam::Vec3A> for Lab<W, OFFSET> {}
    impl<W: Illuminant, const OFFSET: usize> BackingStore<glam::Vec4> for Lab<W, OFFSET> {}
    impl<W: Illuminant, const OFFSET: usize> BackingStore<glam::Vec3> for LCh<W, OFFSET> {}
    impl<W: Illuminant, const OFFSET: usize> BackingStore<glam::Vec3A> for LCh<W, OFFSET> {}
    impl<W: Illuminant, const OFFSET: usize> BackingStore<glam::Vec4> for LCh<W, OFFSET> {}
}