use crate::generator::DistanceMapping;
use crate::math::scalar::median;
#[derive(Debug, Clone, Copy)]
pub struct MultiDistance {
pub r: f64,
pub g: f64,
pub b: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct MultiAndTrueDistance {
pub r: f64,
pub g: f64,
pub b: f64,
pub a: f64,
}
pub trait DistanceValue: Copy {
fn neg_max() -> Self;
fn resolve(self) -> f64;
fn write_mapped(self, mapping: &DistanceMapping, px: &mut [f32]);
}
impl DistanceValue for f64 {
#[inline]
fn neg_max() -> Self {
f64::MIN
}
#[inline]
fn resolve(self) -> f64 {
self
}
#[inline]
fn write_mapped(self, mapping: &DistanceMapping, px: &mut [f32]) {
px[0] = mapping.map(self) as f32;
}
}
impl DistanceValue for MultiDistance {
#[inline]
fn neg_max() -> Self {
MultiDistance {
r: f64::MIN,
g: f64::MIN,
b: f64::MIN,
}
}
#[inline]
fn resolve(self) -> f64 {
median(self.r, self.g, self.b)
}
#[inline]
fn write_mapped(self, mapping: &DistanceMapping, px: &mut [f32]) {
px[0] = mapping.map(self.r) as f32;
px[1] = mapping.map(self.g) as f32;
px[2] = mapping.map(self.b) as f32;
}
}
impl DistanceValue for MultiAndTrueDistance {
#[inline]
fn neg_max() -> Self {
MultiAndTrueDistance {
r: f64::MIN,
g: f64::MIN,
b: f64::MIN,
a: f64::MIN,
}
}
#[inline]
fn resolve(self) -> f64 {
median(self.r, self.g, self.b)
}
#[inline]
fn write_mapped(self, mapping: &DistanceMapping, px: &mut [f32]) {
px[0] = mapping.map(self.r) as f32;
px[1] = mapping.map(self.g) as f32;
px[2] = mapping.map(self.b) as f32;
px[3] = mapping.map(self.a) as f32;
}
}