open-standards/wai/wai-rs/tests/jpegai_efn_calibration.rs
Transaction Science 3d0ce851c1 wai-rs: jpegai_pipeline::efn_filter — EFE luma-aided nonlinear chroma post-filter (float-exact)
First pixel-domain post-filter. Refines a chroma plane using the co-located luma:

  w[i]  = (weights_q15[i] - 32767) / 2^11            // deinteger, wP=16
  min   = luma_min_q/100 ; gap = (luma_max_q/100 - min)/8
  c_out = relu( w[0]·(y - min) + c_in )
        + Σ_{j=1..7} w[j]·relu( y - min - j·gap )

The reference builds a tiny 2-layer conv/ReLU net per tile (conv1 2→8 1×1 + bias,
conv2 8→1 1×1) with a fixed weight structure; that collapses to the closed form above
— one luma-gated channel carrying c_in plus seven luma-only histogram-breakpoint
channels summed with weights [1, w[1..7]].

Validated against the reference fixture (luma + input chroma + 8 Q15 tile weights +
luma min/max → filtered chroma): max|Δ| = 4.6e-5 (f32-vs-f64 rounding), SNR 149.9 dB.
Plus a unit test pinning the deinteger scale, the min/gap breakpoints, and the two
ReLU gates. Single-tile / 4:4:4; caller downsamples luma for subsampled formats.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-13 13:17:53 -04:00

41 lines
2 KiB
Rust

//! Calibration for [`wai::jpegai_pipeline::efn_filter`] — the EFE luma-aided adaptive
//! nonlinear chroma post-filter. Runs on the reference fixture (luma `y`, input chroma
//! `c_in`, the 8 Q15 tile weights, luma min/max) and compares the filtered plane to the
//! reference output `c_want`. Float arithmetic ⇒ machine-precision match expected.
//!
//! env: WAI_JPEGAI_EFN_FIXTURE = efn_fixture.json
//! { y:[f64], c_in:[f64], c_want:[f64], weights_q15:[i64], luma_min_q, luma_max_q }
#![cfg(feature = "neural_int")]
use wai::jpegai_pipeline::efn_filter;
#[test]
fn efn_filter_matches_reference() {
let path = match std::env::var("WAI_JPEGAI_EFN_FIXTURE") {
Ok(p) if std::path::Path::new(&p).exists() => p,
_ => { eprintln!("skip: set WAI_JPEGAI_EFN_FIXTURE to efn_fixture.json"); return; }
};
let v: serde_json::Value = serde_json::from_slice(&std::fs::read(&path).unwrap()).unwrap();
let f32v = |k: &str| v[k].as_array().unwrap().iter().map(|x| x.as_f64().unwrap() as f32).collect::<Vec<f32>>();
let y = f32v("y");
let c_in = f32v("c_in");
let c_want = f32v("c_want");
let weights: Vec<i64> = v["weights_q15"].as_array().unwrap().iter().map(|x| x.as_i64().unwrap()).collect();
let (lmin, lmax) = (v["luma_min_q"].as_i64().unwrap(), v["luma_max_q"].as_i64().unwrap());
let got = efn_filter(&y, &c_in, &weights, lmin, lmax);
assert_eq!(got.len(), c_want.len(), "output size mismatch");
let mut maxd = 0f32;
let mut mse = 0f64;
for i in 0..got.len() {
let d = (got[i] - c_want[i]).abs();
maxd = maxd.max(d);
mse += (d as f64) * (d as f64);
}
mse /= got.len() as f64;
let sig: f64 = c_want.iter().map(|&x| (x as f64) * (x as f64)).sum::<f64>() / got.len() as f64;
let snr = if mse > 0.0 { 10.0 * (sig / mse).log10() } else { f64::INFINITY };
eprintln!("efn_filter vs reference: max|Δ| = {maxd:.6} SNR = {snr:.2} dB");
assert!(maxd < 1e-2, "EFN filter diverged from the reference (max|Δ| = {maxd})");
}