mod state;
pub use state::{AutoExposureState, HISTOGRAM_BINS, LUM_LOG2_MAX, LUM_LOG2_MIN};
const MIN_SPEED: f32 = 1.0e-3;
const MAX_SPEED: f32 = 20.0;
const EV_LIMIT: f32 = 16.0;
pub const HDR_MIDDLE_GREY_LOG2: f32 = -2.473;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct AutoExposureSettings {
pub min_ev: f32,
pub max_ev: f32,
pub speed: f32,
pub target_log_lum: f32,
}
impl AutoExposureSettings {
pub fn resolve(min_ev: f32, max_ev: f32, speed: f32, hdr_aware: bool) -> Self {
let min = min_ev.clamp(-EV_LIMIT, EV_LIMIT);
let max = max_ev.clamp(-EV_LIMIT, EV_LIMIT);
let (lo, hi) = if min <= max { (min, max) } else { (max, min) };
Self {
min_ev: lo,
max_ev: hi,
speed: speed.clamp(MIN_SPEED, MAX_SPEED),
target_log_lum: if hdr_aware { HDR_MIDDLE_GREY_LOG2 } else { 0.0 },
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn resolve_clamps_speed_and_orders_ev_bounds() {
let s = AutoExposureSettings::resolve(8.0, -2.0, 0.0, false);
assert_eq!(s.min_ev, -2.0);
assert_eq!(s.max_ev, 8.0);
assert!(s.speed >= MIN_SPEED);
let s = AutoExposureSettings::resolve(-100.0, 100.0, 1.0e9, false);
assert_eq!(s.min_ev, -EV_LIMIT);
assert_eq!(s.max_ev, EV_LIMIT);
assert_eq!(s.speed, MAX_SPEED);
}
}