ph-color-bake 0.1.0

Host-side generator for auditable ph-color matrices, fixed-point LUTs, and golden vectors
Documentation
//! Host-only baker for `ph-color` matrices and LUTs.
//!
//! All inversion, adaptation, and `f64` math live here. The target crate
//! never depends on this package.

pub mod emit;
pub mod golden;
pub mod lut;
pub mod matrix;
pub mod oklab;
pub mod srgb;

/// Host bake failure.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BakeError {
    /// Primaries or white point produced a non-invertible matrix.
    SingularMatrix,
}

/// CIE xy in ordinary units (not millionths).
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Xy {
    /// CIE x.
    pub x: f64,
    /// CIE y.
    pub y: f64,
}

impl Xy {
    /// Construct from CIE xy.
    #[must_use]
    pub const fn new(x: f64, y: f64) -> Self {
        Self { x, y }
    }

    /// Convert millionths used on the target crate into host `f64`.
    #[must_use]
    pub fn from_millionths(x_millionths: u32, y_millionths: u32) -> Self {
        Self {
            x: f64::from(x_millionths) / 1_000_000.0,
            y: f64::from(y_millionths) / 1_000_000.0,
        }
    }
}

/// RGB primaries plus white point.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Primaries {
    /// Red primary.
    pub r: Xy,
    /// Green primary.
    pub g: Xy,
    /// Blue primary.
    pub b: Xy,
    /// White point.
    pub white: Xy,
}

impl Primaries {
    /// ITU-R BT.709 / sRGB primaries and D65.
    #[must_use]
    pub fn srgb() -> Self {
        Self {
            r: Xy::new(0.64, 0.33),
            g: Xy::new(0.30, 0.60),
            b: Xy::new(0.15, 0.06),
            white: Xy::new(0.3127, 0.3290),
        }
    }
}