#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum MeteringMode {
Average,
CenterWeighted,
Spot,
}
#[derive(Debug, Clone)]
pub struct ExposureMeterViewConfig {
pub mode: MeteringMode,
pub ev_target: f32,
pub enabled: bool,
pub show_histogram: bool,
}
impl Default for ExposureMeterViewConfig {
fn default() -> Self {
ExposureMeterViewConfig {
mode: MeteringMode::Average,
ev_target: 0.0,
enabled: true,
show_histogram: false,
}
}
}
pub fn new_exposure_meter_view() -> ExposureMeterViewConfig {
ExposureMeterViewConfig::default()
}
pub fn emv2_set_mode(cfg: &mut ExposureMeterViewConfig, mode: MeteringMode) {
cfg.mode = mode;
}
pub fn emv2_set_ev_target(cfg: &mut ExposureMeterViewConfig, ev: f32) {
cfg.ev_target = ev.clamp(-10.0, 10.0);
}
pub fn emv2_set_enabled(cfg: &mut ExposureMeterViewConfig, enabled: bool) {
cfg.enabled = enabled;
}
pub fn emv2_toggle_histogram(cfg: &mut ExposureMeterViewConfig) {
cfg.show_histogram = !cfg.show_histogram;
}
pub fn emv2_luminance_to_ev(avg_luminance: f32) -> f32 {
if avg_luminance <= 0.0 {
return -10.0;
}
avg_luminance.log2()
}
pub fn emv2_correction(cfg: &ExposureMeterViewConfig, measured_ev: f32) -> f32 {
cfg.ev_target - measured_ev
}
pub fn emv2_to_json(cfg: &ExposureMeterViewConfig) -> String {
format!(
r#"{{"mode":"{}","ev_target":{:.4},"enabled":{}}}"#,
match cfg.mode {
MeteringMode::Average => "average",
MeteringMode::CenterWeighted => "center_weighted",
MeteringMode::Spot => "spot",
},
cfg.ev_target,
cfg.enabled
)
}
pub fn emv2_mode_name(cfg: &ExposureMeterViewConfig) -> &'static str {
match cfg.mode {
MeteringMode::Average => "average",
MeteringMode::CenterWeighted => "center_weighted",
MeteringMode::Spot => "spot",
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_mode_average() {
let c = new_exposure_meter_view();
assert_eq!(
c.mode,
MeteringMode::Average,
);
}
#[test]
fn test_set_mode_spot() {
let mut c = new_exposure_meter_view();
emv2_set_mode(&mut c, MeteringMode::Spot);
assert_eq!(c.mode, MeteringMode::Spot ,);
}
#[test]
fn test_set_ev_target() {
let mut c = new_exposure_meter_view();
emv2_set_ev_target(&mut c, 1.5);
assert!((c.ev_target - 1.5).abs() < 1e-5, );
}
#[test]
fn test_set_ev_target_clamps() {
let mut c = new_exposure_meter_view();
emv2_set_ev_target(&mut c, 20.0);
assert!((c.ev_target - 10.0).abs() < 1e-5, );
}
#[test]
fn test_set_enabled_false() {
let mut c = new_exposure_meter_view();
emv2_set_enabled(&mut c, false);
assert!(!c.enabled ,);
}
#[test]
fn test_toggle_histogram() {
let mut c = new_exposure_meter_view();
emv2_toggle_histogram(&mut c);
assert!(c.show_histogram ,);
}
#[test]
fn test_luminance_to_ev_zero_luminance() {
let ev = emv2_luminance_to_ev(0.0);
assert!((ev - (-10.0)).abs() < 1e-5, );
}
#[test]
fn test_luminance_to_ev_one() {
let ev = emv2_luminance_to_ev(1.0);
assert!((ev).abs() < 1e-5 ,);
}
#[test]
fn test_correction_positive() {
let mut c = new_exposure_meter_view();
emv2_set_ev_target(&mut c, 2.0);
let corr = emv2_correction(&c, 1.0);
assert!((corr - 1.0).abs() < 1e-5, );
}
#[test]
fn test_to_json_contains_mode() {
let c = new_exposure_meter_view();
let j = emv2_to_json(&c);
assert!(j.contains("mode") ,);
}
}