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
use math::round::half_up;
pub type LabColor = [f64; 3];
pub fn sub(color: LabColor, other: LabColor) -> LabColor {
[
color[0] - other[0],
color[1] - other[1],
color[2] - other[2],
]
}
pub fn rgb_2_lab(color: [f64; 3]) -> LabColor {
let mut rgb = [0.0; 3];
for i in 0..color.len() {
rgb[i] = rgb_stab(color[i]);
}
let mut xyz = [0.0; 3];
xyz[0] = xyz_stab(half_up(rgb[0] * 0.4124 + rgb[1] * 0.3576 + rgb[2] * 0.1805, 4) / 95.047);
xyz[1] = xyz_stab(half_up(rgb[0] * 0.2126 + rgb[1] * 0.7152 + rgb[2] * 0.0722, 4) / 100.0);
xyz[2] = xyz_stab(half_up(rgb[0] * 0.0193 + rgb[1] * 0.1192 + rgb[2] * 0.9504, 4) / 108.883);
[
half_up((116.0 * xyz[1]) - 16.0, 4),
half_up(500.0 * (xyz[0] - xyz[1]), 4),
half_up(200.0 * (xyz[1] - xyz[2]), 4),
]
}
fn xyz_stab(c: f64) -> f64 {
if c > 0.008856 {
c.powf(0.3333333333333333)
} else {
(7.787 * c) + (16.0 / 116.0)
}
}
fn rgb_stab(c: f64) -> f64 {
let d = c / 255.0;
if d > 0.04045 {
((d + 0.055) / 1.055).powf(2.4) * 100.0
} else {
d / 12.92 * 100.0
}
}