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
use crate::encoding::TransferFn;
use crate::float::Float;
use crate::luma::LumaStandard;
use crate::rgb::{Primaries, RgbSpace, RgbStandard};
use crate::white_point::{WhitePoint, D65};
use crate::{from_f64, FromF64};
use crate::{FloatComponent, Yxy};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Srgb;
impl Primaries for Srgb {
fn red<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T> {
Yxy::with_wp(from_f64(0.6400), from_f64(0.3300), from_f64(0.212656))
}
fn green<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T> {
Yxy::with_wp(from_f64(0.3000), from_f64(0.6000), from_f64(0.715158))
}
fn blue<Wp: WhitePoint, T: FloatComponent>() -> Yxy<Wp, T> {
Yxy::with_wp(from_f64(0.1500), from_f64(0.0600), from_f64(0.072186))
}
}
impl RgbSpace for Srgb {
type Primaries = Srgb;
type WhitePoint = D65;
}
impl RgbStandard for Srgb {
type Space = Srgb;
type TransferFn = Srgb;
}
impl LumaStandard for Srgb {
type WhitePoint = D65;
type TransferFn = Srgb;
}
impl TransferFn for Srgb {
fn into_linear<T: Float + FromF64>(x: T) -> T {
if x <= from_f64(0.04045) {
x * from_f64::<T>(12.92).recip()
} else {
((x + from_f64(0.055)) * from_f64::<T>(1.055).recip()).powf(from_f64(2.4))
}
}
fn from_linear<T: Float + FromF64>(x: T) -> T {
if x <= from_f64(0.0031308) {
x * from_f64(12.92)
} else {
x.powf(T::one() / from_f64(2.4)) * from_f64(1.055) - from_f64(0.055)
}
}
}