1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use glam::f64::DVec3;

use crate::color::Color;

/// A color space whose colors are closed under basic linear algebra operations and can be
/// represented as vectors.
pub trait ColorVecSpace {
    /// The underlying vector type of colors in this space.
    type Vector: Sized;
}

/// A color space consisting of one luma channel *L* and two opponent channels
/// *x* and *y*.  Color spaces deriving this trait will automatically support
/// conversion to and from Lch (cylindrical) and Lch (conical)
/// parameterizations.
pub trait OpponentSpace: ColorVecSpace {
    /// Create an appropriate color given luma and chroma channels
    fn from_lxy(lxy: DVec3) -> Color<Self>;

    /// Unwrap a color into its luma and chroma channels
    fn into_lxy(clr: Color<Self>) -> DVec3;
}

/// The CIE 1931 (XYZ) color space.  Used as an intermediary for other color
/// formats.
#[derive(Debug)]
pub struct Ciexyz;
/// Linear sRGB.  Cannot be used directly, needs to either be converted to XYZ
/// or gamma-corrected.
#[derive(Debug)]
pub struct LinearSrgb;
/// The Oklab opponent color space.  For more information, see
/// [this blog post](https://bottosson.github.io/posts/oklab/).
#[derive(Debug)]
pub struct Oklab;
/// The sRGB display standard.  Supports virtually all displays, but cannot
/// render wide-gamut color.
#[derive(Debug)]
pub struct Srgb;
/// A Lab color space akin to CIELAB, but with some improvements.  For more
/// information, see [this page](https://www.magnetkern.de/srlab2.html).
#[derive(Debug)]
pub struct Srlab2;

impl ColorVecSpace for Ciexyz {
    type Vector = DVec3;
}

impl ColorVecSpace for LinearSrgb {
    type Vector = DVec3;
}

impl ColorVecSpace for Oklab {
    type Vector = DVec3;
}

impl OpponentSpace for Oklab {
    fn from_lxy(lxy: DVec3) -> Color<Self> { Color::new(lxy) }

    fn into_lxy(clr: Color<Self>) -> DVec3 { clr.into_inner() }
}

impl ColorVecSpace for Srgb {
    type Vector = DVec3;
}