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
use channel::Channel;
use num_traits::{Float, one, zero};
use color_space::{WhitePoint, D65};
use xyz::{ToXyz, Xyz};
use std::ops::{Add, AddAssign, Sub, Mul, Div};
pub struct Yxy<T = f32, Wp = D65> {
pub x: T,
pub y: T,
pub luma: T,
pub white_point: Wp,
}
impl<T: Channel + Float, Wp: WhitePoint> Yxy<T,Wp> {
pub fn new(x: T, y: T, luma: T) -> Yxy<T,Wp> {
Yxy {
x,
y,
luma,
white_point: Wp::default(),
}
}
}
pub trait ToYxy{
type WhitePoint: WhitePoint;
fn to_yxy<T: Channel + Float>(&self) -> Yxy<T, Self::WhitePoint>;
}
impl<T: Channel + Float, Wp: WhitePoint> ToXyz for Yxy<T,Wp> {
type WhitePoint = Wp;
fn to_xyz<U: Channel + Float>(&self) -> Xyz<U, Wp> {
let y = self.luma;
let x;
let z;
if self.y < zero() || self.y > zero() {
x = self.luma * self.x / self.y;
z = self.luma * (one::<T>() - self.x - self.y) / self.y;
}else{
x = Wp::xyz().x;
z = Wp::xyz().z;
}
Xyz::new(x.to_channel(), y.to_channel(), z.to_channel())
}
}
impl<T, Wp> Add<Yxy<T, Wp>> for Yxy<T, Wp>
where
T: Channel + Float,
Wp: WhitePoint,
{
type Output = Yxy<T, Wp>;
fn add(self, other: Yxy<T, Wp>) -> Self::Output {
Yxy {
x: self.x + other.x,
y: self.y + other.y,
luma: self.luma + other.luma,
white_point: Wp::default(),
}
}
}