//! Byte-exact calibration for the mANS entropy decoder: replay the real JPEG-AI //! `SORP` stream (main y-latent) through `MansDecoder::decode_sgm` and require an //! EXACT match to the reference `expected` (the golden was produced by the ISO //! reference `ans.so`, and this Rust is a faithful port of `decompressor.cpp`). //! No ort needed — the fixture carries the transition tables + stream + goldens. //! //! env: WAI_JPEGAI_MANS_FIXTURE = path to mans_sorp_fixture.json //! { dt:[u32; 32*256], bounds:[u8;32], mem:[u8], offsets:[u32], //! calls:[{sigma:[u8], mask:[bool], expected:[i16]}] } #![cfg(all(feature = "neural_int", feature = "legacy_int"))] use wai::jpegai_mans::MansDecoder; #[test] fn mans_sgm_byte_exact_vs_reference() { let path = match std::env::var("WAI_JPEGAI_MANS_FIXTURE") { Ok(p) if std::path::Path::new(&p).exists() => p, _ => { eprintln!("skip: set WAI_JPEGAI_MANS_FIXTURE to mans_sorp_fixture.json"); return; } }; let v: serde_json::Value = serde_json::from_slice(&std::fs::read(&path).unwrap()).unwrap(); let arr_u32 = |k: &str| v[k].as_array().unwrap().iter().map(|x| x.as_u64().unwrap() as u32).collect::>(); let dt = arr_u32("dt"); let bounds: Vec = v["bounds"].as_array().unwrap().iter().map(|x| x.as_u64().unwrap() as u8).collect(); let mem: Vec = v["mem"].as_array().unwrap().iter().map(|x| x.as_u64().unwrap() as u8).collect(); let offsets = arr_u32("offsets"); let mut dec = MansDecoder::new(&mem, &offsets); dec.set_sgm_transitions(&dt, &bounds); let mut total = 0usize; let mut mism = 0usize; let mut first: Option<(usize, usize, i16, i16)> = None; for (ci, call) in v["calls"].as_array().unwrap().iter().enumerate() { let sigma: Vec = call["sigma"].as_array().unwrap().iter().map(|x| x.as_u64().unwrap() as u8).collect(); let mask: Vec = call["mask"].as_array().unwrap().iter().map(|x| x.as_bool().unwrap()).collect(); let exp: Vec = call["expected"].as_array().unwrap().iter().map(|x| x.as_i64().unwrap() as i16).collect(); let mut out = vec![0i16; sigma.len()]; dec.decode_sgm(&sigma, &mut out, &mask); for i in 0..out.len() { total += 1; if out[i] != exp[i] { mism += 1; if first.is_none() { first = Some((ci, i, out[i], exp[i])); } } } } eprintln!("mANS decode_sgm vs reference: {}/{} exact, {} mismatched", total - mism, total, mism); if let Some((ci, i, got, exp)) = first { eprintln!("first mismatch: call {ci} pos {i}: got {got} exp {exp}"); } assert_eq!(mism, 0, "mANS decoder must be BYTE-EXACT vs the ISO reference; {mism} mismatches"); } /// Byte-exact `fac` (factorized z hyper-latent) path vs an oracle roundtrip vector. /// env: WAI_JPEGAI_MANS_FAC = path to mans_fac_fixture.json /// { cdfs:[u8; channels*63], mem:[u8], offsets:[u32], channels, spc, expected:[u8] } #[test] fn mans_fac_byte_exact_vs_reference() { let path = match std::env::var("WAI_JPEGAI_MANS_FAC") { Ok(p) if std::path::Path::new(&p).exists() => p, _ => { eprintln!("skip: set WAI_JPEGAI_MANS_FAC to mans_fac_fixture.json"); return; } }; let v: serde_json::Value = serde_json::from_slice(&std::fs::read(&path).unwrap()).unwrap(); let u8v = |k: &str| v[k].as_array().unwrap().iter().map(|x| x.as_u64().unwrap() as u8).collect::>(); let cdfs = u8v("cdfs"); let mem = u8v("mem"); let offsets: Vec = v["offsets"].as_array().unwrap().iter().map(|x| x.as_u64().unwrap() as u32).collect(); let channels = v["channels"].as_u64().unwrap() as usize; let spc = v["spc"].as_u64().unwrap() as usize; let expected = u8v("expected"); let mut dec = MansDecoder::new(&mem, &offsets); let mut out = vec![0u8; channels * spc]; dec.decode_factorize(&cdfs, &mut out, channels, spc); let mism = out.iter().zip(&expected).filter(|(a, b)| a != b).count(); eprintln!("mANS decode_factorize vs reference: {}/{} exact, {} mismatched", out.len() - mism, out.len(), mism); assert_eq!(mism, 0, "mANS fac decoder must be BYTE-EXACT; {mism} mismatches"); }