use crate::utils::ordered_float::F64;
use crate::utils::static_text::StaticText;
use crate::utils::str_fmt::StrCtx;
use crate::utils::str_fmt::StrFmt;
use crate::utils::str_fmt::StrFmtFmt;
use jay_proc::StrFmt;
use jay_proc::jay_hash;
use std::fmt::Write as _;
use std::hash::Hash;
#[jay_hash]
#[derive(Copy, Clone, Debug, Eq)]
pub enum NamedPrimaries {
Srgb,
PalM,
Pal,
Ntsc,
GenericFilm,
Bt2020,
Cie1931Xyz,
DciP3,
DisplayP3,
AdobeRgb,
}
impl StrFmt for NamedPrimaries {
fn str_fmt(&self, dst: &mut String, ctx: &StrCtx<'_>) {
self.text().str_fmt(dst, ctx);
}
}
impl StaticText for NamedPrimaries {
fn text(&self) -> &'static str {
match self {
NamedPrimaries::Srgb => "srgb",
NamedPrimaries::PalM => "pal_m",
NamedPrimaries::Pal => "pal",
NamedPrimaries::Ntsc => "ntsc",
NamedPrimaries::GenericFilm => "generic_film",
NamedPrimaries::Bt2020 => "bt2020",
NamedPrimaries::Cie1931Xyz => "cie1931_xyz",
NamedPrimaries::DciP3 => "dci_p3",
NamedPrimaries::DisplayP3 => "display_p3",
NamedPrimaries::AdobeRgb => "adobe_rgb",
}
}
}
#[jay_hash]
#[derive(Copy, Clone, Debug, Eq)]
pub struct Primaries {
pub r: (F64, F64),
pub g: (F64, F64),
pub b: (F64, F64),
pub wp: (F64, F64),
}
impl Primaries {
pub const SRGB: Self = Self {
r: (F64(0.64), F64(0.33)),
g: (F64(0.3), F64(0.6)),
b: (F64(0.15), F64(0.06)),
wp: (F64(0.3127), F64(0.3290)),
};
pub const PAL_M: Self = Self {
r: (F64(0.67), F64(0.33)),
g: (F64(0.21), F64(0.71)),
b: (F64(0.14), F64(0.08)),
wp: (F64(0.310), F64(0.316)),
};
pub const PAL: Self = Self {
r: (F64(0.64), F64(0.33)),
g: (F64(0.29), F64(0.60)),
b: (F64(0.15), F64(0.06)),
wp: (F64(0.3127), F64(0.3290)),
};
pub const NTSC: Self = Self {
r: (F64(0.630), F64(0.340)),
g: (F64(0.310), F64(0.595)),
b: (F64(0.155), F64(0.070)),
wp: (F64(0.3127), F64(0.3290)),
};
pub const GENERIC_FILM: Self = Self {
r: (F64(0.681), F64(0.319)),
g: (F64(0.243), F64(0.692)),
b: (F64(0.145), F64(0.049)),
wp: (F64(0.310), F64(0.316)),
};
pub const BT2020: Self = Self {
r: (F64(0.708), F64(0.292)),
g: (F64(0.170), F64(0.797)),
b: (F64(0.131), F64(0.046)),
wp: (F64(0.3127), F64(0.3290)),
};
pub const CIE1931_XYZ: Self = Self {
r: (F64(1.0), F64(0.0)),
g: (F64(0.0), F64(1.0)),
b: (F64(0.0), F64(0.0)),
wp: (F64(1.0 / 3.0), F64(1.0 / 3.0)),
};
pub const DCI_P3: Self = Self {
r: (F64(0.680), F64(0.320)),
g: (F64(0.265), F64(0.690)),
b: (F64(0.150), F64(0.060)),
wp: (F64(0.314), F64(0.351)),
};
pub const DISPLAY_P3: Self = Self {
r: (F64(0.680), F64(0.320)),
g: (F64(0.265), F64(0.690)),
b: (F64(0.150), F64(0.060)),
wp: (F64(0.3127), F64(0.3290)),
};
pub const ADOBE_RGB: Self = Self {
r: (F64(0.64), F64(0.33)),
g: (F64(0.21), F64(0.71)),
b: (F64(0.15), F64(0.06)),
wp: (F64(0.3127), F64(0.3290)),
};
pub fn about_equal(&self, other: &Self) -> bool {
const EPSILON: f64 = 0.001;
macro_rules! ae {
($field:ident) => {
(self.$field.0.0 - other.$field.0.0).abs() < EPSILON
&& (self.$field.1.0 - other.$field.1.0).abs() < EPSILON
};
}
ae!(r) && ae!(g) && ae!(b) && ae!(wp)
}
}
impl NamedPrimaries {
pub const fn primaries(self) -> Primaries {
match self {
NamedPrimaries::Srgb => Primaries::SRGB,
NamedPrimaries::PalM => Primaries::PAL_M,
NamedPrimaries::Pal => Primaries::PAL,
NamedPrimaries::Ntsc => Primaries::NTSC,
NamedPrimaries::GenericFilm => Primaries::GENERIC_FILM,
NamedPrimaries::Bt2020 => Primaries::BT2020,
NamedPrimaries::Cie1931Xyz => Primaries::CIE1931_XYZ,
NamedPrimaries::DciP3 => Primaries::DCI_P3,
NamedPrimaries::DisplayP3 => Primaries::DISPLAY_P3,
NamedPrimaries::AdobeRgb => Primaries::ADOBE_RGB,
}
}
}
impl StrFmt for Primaries {
fn str_fmt(&self, dst: &mut String, ctx: &StrCtx<'_>) {
if ctx.fmt == StrFmtFmt::Human {
let mut first = true;
for (n, (x, y)) in [
(" r", self.r),
(" g", self.g),
(" b", self.b),
("wp", self.wp),
] {
if !first {
dst.push_str("\n");
dst.push_str(ctx.prefix);
dst.push_str(ctx.spaces);
}
first = false;
dst.push_str(n);
dst.push_str(": ");
let _ = write!(dst, "{x:.04} {y:.04}");
}
} else {
#[derive(StrFmt)]
struct F {
r: (F64, F64),
g: (F64, F64),
b: (F64, F64),
wp: (F64, F64),
}
define_ident!(self.@r);
define_ident!(self.@g);
define_ident!(self.@b);
define_ident!(self.@wp);
let f = F { r, g, b, wp };
f.str_fmt(dst, ctx);
}
}
}