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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use crate::encoding::{self, Gamma, Linear, TransferFn};
use crate::white_point::WhitePoint;
use crate::{Component, FloatComponent, FromComponent, Yxy};
pub use self::packed::{channels, Packed, RgbChannels};
pub use self::rgb::{FromHexError, Rgb, Rgba};
mod packed;
mod rgb;
pub type Srgb<T = f32> = Rgb<encoding::Srgb, T>;
pub type Srgba<T = f32> = Rgba<encoding::Srgb, T>;
#[doc(alias = "linear")]
pub type LinSrgb<T = f32> = Rgb<Linear<encoding::Srgb>, T>;
#[doc(alias = "linear")]
pub type LinSrgba<T = f32> = Rgba<Linear<encoding::Srgb>, T>;
pub type GammaSrgb<T = f32> = Rgb<Gamma<encoding::Srgb>, T>;
pub type GammaSrgba<T = f32> = Rgba<Gamma<encoding::Srgb>, T>;
pub trait RgbStandard: 'static {
type Space: RgbSpace;
type TransferFn: TransferFn;
}
impl<S: RgbSpace, T: TransferFn> RgbStandard for (S, T) {
type Space = S;
type TransferFn = T;
}
impl<P: Primaries, W: WhitePoint, T: TransferFn> RgbStandard for (P, W, T) {
type Space = (P, W);
type TransferFn = T;
}
pub trait RgbSpace: 'static {
type Primaries: Primaries;
type WhitePoint: WhitePoint;
}
impl<P: Primaries, W: WhitePoint> RgbSpace for (P, W) {
type Primaries = P;
type WhitePoint = W;
}
pub trait Primaries: 'static {
fn red<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T>;
fn green<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T>;
fn blue<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T>;
}
impl<T, U> From<LinSrgb<T>> for Srgb<U>
where
T: FloatComponent,
U: Component + FromComponent<T>,
{
fn from(lin_srgb: LinSrgb<T>) -> Self {
let non_lin = Srgb::<T>::from_linear(lin_srgb);
non_lin.into_format()
}
}
impl<T, U> From<Srgb<T>> for LinSrgb<U>
where
T: FloatComponent,
U: Component + FromComponent<T>,
{
fn from(srgb: Srgb<T>) -> Self {
srgb.into_linear().into_format()
}
}
impl<T, U> From<LinSrgb<T>> for Srgba<U>
where
T: FloatComponent,
U: Component + FromComponent<T>,
{
fn from(lin_srgb: LinSrgb<T>) -> Self {
let non_lin = Srgb::<T>::from_linear(lin_srgb);
let new_fmt = Srgb::<U>::from_format(non_lin);
new_fmt.into()
}
}
impl<T, U> From<LinSrgba<T>> for Srgba<U>
where
T: FloatComponent,
U: Component + FromComponent<T>,
{
fn from(lin_srgba: LinSrgba<T>) -> Self {
let non_lin = Srgba::<T>::from_linear(lin_srgba);
non_lin.into_format()
}
}
impl<T, U> From<Srgb<T>> for LinSrgba<U>
where
T: FloatComponent,
U: Component + FromComponent<T>,
{
fn from(srgb: Srgb<T>) -> Self {
srgb.into_linear().into_format().into()
}
}
impl<T, U> From<Srgba<T>> for LinSrgba<U>
where
T: FloatComponent,
U: Component + FromComponent<T>,
{
fn from(srgba: Srgba<T>) -> Self {
srgba.into_linear().into_format()
}
}