palette/encoding/
gamma.rs1use core::{marker::PhantomData, ops::Div};
4
5use crate::{
6 luma::LumaStandard,
7 num::{One, Powf, Real},
8 rgb::{RgbSpace, RgbStandard},
9};
10
11use super::{FromLinear, IntoLinear};
12
13#[derive(Copy, Clone, Debug, PartialEq, Eq)]
25pub struct Gamma<S, N: Number = F2p2>(PhantomData<(S, N)>);
26
27impl<Sp, N> RgbStandard for Gamma<Sp, N>
28where
29 Sp: RgbSpace,
30 N: Number,
31{
32 type Space = Sp;
33 type TransferFn = GammaFn<N>;
34}
35
36impl<Wp, N> LumaStandard for Gamma<Wp, N>
37where
38 N: Number,
39{
40 type WhitePoint = Wp;
41 type TransferFn = GammaFn<N>;
42}
43
44#[derive(Copy, Clone, Debug, PartialEq, Eq)]
54pub struct GammaFn<N: Number = F2p2>(PhantomData<N>);
55
56impl<T, N> IntoLinear<T, T> for GammaFn<N>
57where
58 T: Real + One + Powf + Div<Output = T>,
59 N: Number,
60{
61 #[inline]
62 fn into_linear(x: T) -> T {
63 x.powf(T::one() / T::from_f64(N::VALUE))
64 }
65}
66
67impl<T, N> FromLinear<T, T> for GammaFn<N>
68where
69 T: Real + Powf,
70 N: Number,
71{
72 #[inline]
73 fn from_linear(x: T) -> T {
74 x.powf(T::from_f64(N::VALUE))
75 }
76}
77
78pub trait Number: 'static {
80 const VALUE: f64;
82}
83
84#[derive(Copy, Clone, Debug, PartialEq, Eq)]
86pub struct F2p2;
87
88impl Number for F2p2 {
89 const VALUE: f64 = 2.2;
90}