use crate::utils::math_utils::MathUtils;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ContrastCurve {
pub low: f64,
pub normal: f64,
pub medium: f64,
pub high: f64,
}
impl ContrastCurve {
#[must_use]
pub const fn new(low: f64, normal: f64, medium: f64, high: f64) -> Self {
Self {
low,
normal,
medium,
high,
}
}
#[must_use]
pub fn get(&self, contrast_level: f64) -> f64 {
match contrast_level {
x if x <= -1.0 => self.low,
x if x < 0.0 => MathUtils::lerp(self.low, self.normal, x + 1.0),
x if x < 0.5 => MathUtils::lerp(self.normal, self.medium, x / 0.5),
x if x < 1.0 => MathUtils::lerp(self.medium, self.high, (x - 0.5) / 0.5),
_ => self.high,
}
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::float_cmp)]
use super::*;
#[test]
fn test_contrast_curve_get() {
let curve = ContrastCurve::new(3.0, 4.5, 7.0, 11.0);
assert_eq!(curve.get(-1.0), 3.0);
assert_eq!(curve.get(0.0), 4.5);
assert_eq!(curve.get(0.5), 7.0);
assert_eq!(curve.get(1.0), 11.0);
assert_eq!(curve.get(-2.0), 3.0);
assert_eq!(curve.get(2.0), 11.0);
assert!((curve.get(-0.5) - 3.75).abs() < 1e-9);
assert!((curve.get(0.25) - 5.75).abs() < 1e-9);
assert!((curve.get(0.75) - 9.0).abs() < 1e-9);
}
}