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
use crate::{Format, Rgb};
use crate::alpha::{Alpha, Opaque, Translucent};
use crate::channel::{Channel, Ch8, Ch16, Ch32};
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[repr(C)]
pub struct Srgb<C: Channel, A: Alpha> {
red: C,
green: C,
blue: C,
alpha: A,
}
impl<C, H, A, B> From<Rgb<H, B>> for Srgb<C, A>
where C: Channel, C: From<H>, H: Channel, A: Alpha<Chan=C>, A: From<B>,
B: Alpha
{
fn from(c: Rgb<H, B>) -> Self {
let red = C::from(c.red());
let green = C::from(c.green());
let blue = C::from(c.blue());
let alpha = A::from(c.alpha());
let a = alpha.value();
Srgb {
red: (red / a).encode_gamma(),
green: (green / a).encode_gamma(),
blue: (blue / a).encode_gamma(),
alpha,
}
}
}
impl<C, H, A, B> From<Srgb<H, B>> for Rgb<C, A>
where C: Channel, C: From<H>, H: Channel, A: Alpha, A: From<B>,
B: Alpha
{
fn from(srgb: Srgb<H, B>) -> Self {
let r = C::from(srgb.red()).decode_gamma();
let g = C::from(srgb.green()).decode_gamma();
let b = C::from(srgb.blue()).decode_gamma();
let a = A::from(srgb.alpha());
Rgb::with_alpha(r, g, b, a)
}
}
impl<C: Channel, A: Alpha> Srgb<C, A> {
pub fn new<V>(red: V, green: V, blue: V) -> Self
where C: From<V>
{
let red = C::from(red);
let green = C::from(green);
let blue = C::from(blue);
let alpha = A::default();
Srgb { red, green, blue, alpha }
}
pub fn red(self) -> C {
self.red
}
pub fn green(self) -> C {
self.green
}
pub fn blue(self) -> C {
self.blue
}
pub fn alpha(self) -> A {
self.alpha
}
}
impl<C: Channel, A: Alpha> Format for Srgb<C, A> {
type Chan = C;
}
pub type Srgb8 = Srgb<Ch8, Opaque<Ch8>>;
pub type Srgb16 = Srgb<Ch16, Opaque<Ch16>>;
pub type Srgb32 = Srgb<Ch32, Opaque<Ch32>>;
pub type Srgba8 = Srgb<Ch8, Translucent<Ch8>>;
pub type Srgba16 = Srgb<Ch16, Translucent<Ch16>>;
pub type Srgba32 = Srgb<Ch32, Translucent<Ch32>>;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn check_sizes() {
assert!(std::mem::size_of::<Srgb8>() == 3);
assert!(std::mem::size_of::<Srgb16>() == 6);
assert!(std::mem::size_of::<Srgb32>() == 12);
assert!(std::mem::size_of::<Srgba8>() == 4);
assert!(std::mem::size_of::<Srgba16>() == 8);
assert!(std::mem::size_of::<Srgba32>() == 16);
}
}