#![allow(dead_code)]
pub const ACES_AP0_WHITE: [f32; 2] = [0.32168, 0.33767];
pub const ACES_AP1_WHITE: [f32; 2] = [0.32168, 0.33767];
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AcesVariant {
Ap0,
Ap1,
AcesCct,
AcesProxy,
}
#[derive(Debug, Clone)]
pub struct AcesExportConfig {
pub variant: AcesVariant,
pub exposure_offset: f32,
pub include_lut: bool,
}
impl Default for AcesExportConfig {
fn default() -> Self {
Self {
variant: AcesVariant::Ap1,
exposure_offset: 0.0,
include_lut: false,
}
}
}
#[derive(Debug, Clone)]
pub struct AcesExportResult {
pub variant_name: String,
pub config_blob: Vec<u8>,
}
pub fn export_aces_config(cfg: &AcesExportConfig) -> AcesExportResult {
let name = match cfg.variant {
AcesVariant::Ap0 => "ACES-AP0",
AcesVariant::Ap1 => "ACES-AP1",
AcesVariant::AcesCct => "ACEScct",
AcesVariant::AcesProxy => "ACESproxy",
};
let blob = format!("aces_variant={name},exposure={}", cfg.exposure_offset).into_bytes();
AcesExportResult {
variant_name: name.to_string(),
config_blob: blob,
}
}
pub fn apply_exposure(value: f32, stops: f32) -> f32 {
value * 2.0f32.powf(stops)
}
pub fn acescg_to_ap0(rgb: [f32; 3]) -> [f32; 3] {
rgb
}
pub fn is_log_variant(variant: AcesVariant) -> bool {
matches!(variant, AcesVariant::AcesCct | AcesVariant::AcesProxy)
}
pub fn variant_bit_depth(variant: AcesVariant) -> u32 {
match variant {
AcesVariant::AcesProxy => 10,
AcesVariant::AcesCct => 16,
_ => 32,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
assert_eq!(AcesExportConfig::default().variant, AcesVariant::Ap1);
}
#[test]
fn test_export_aces_ap0_name() {
let cfg = AcesExportConfig {
variant: AcesVariant::Ap0,
..Default::default()
};
assert_eq!(export_aces_config(&cfg).variant_name, "ACES-AP0");
}
#[test]
fn test_export_config_blob_nonempty() {
let result = export_aces_config(&AcesExportConfig::default());
assert!(!result.config_blob.is_empty());
}
#[test]
fn test_apply_exposure_zero() {
assert!((apply_exposure(1.0, 0.0) - 1.0).abs() < f32::EPSILON);
}
#[test]
fn test_apply_exposure_one_stop() {
assert!((apply_exposure(1.0, 1.0) - 2.0).abs() < f32::EPSILON);
}
#[test]
fn test_apply_exposure_negative() {
assert!((apply_exposure(1.0, -1.0) - 0.5).abs() < f32::EPSILON);
}
#[test]
fn test_acescg_to_ap0_stub() {
let rgb = [0.5f32, 0.3, 0.1];
assert_eq!(acescg_to_ap0(rgb), rgb);
}
#[test]
fn test_is_log_variant_cct() {
assert!(is_log_variant(AcesVariant::AcesCct));
}
#[test]
fn test_is_log_variant_ap0() {
assert!(!is_log_variant(AcesVariant::Ap0));
}
#[test]
fn test_variant_bit_depth_proxy() {
assert_eq!(variant_bit_depth(AcesVariant::AcesProxy), 10);
}
}