#![allow(dead_code)]
pub(crate) use crate::prob_tables::*;
const MAX_PROB: i32 = 255;
fn inv_recenter_nonneg(v: i32, m: i32) -> i32 {
if v > 2 * m {
v
} else if v & 1 != 0 {
m - ((v + 1) >> 1)
} else {
m + (v >> 1)
}
}
pub fn inv_remap_prob(v: i32, m: i32) -> u8 {
let v = INV_MAP_TABLE[v as usize] as i32;
let m = m - 1;
if (m << 1) <= MAX_PROB {
(1 + inv_recenter_nonneg(v, m)) as u8
} else {
(MAX_PROB - inv_recenter_nonneg(v, MAX_PROB - 1 - m)) as u8
}
}
pub const ENTROPY_NODES: usize = 11;
const PIVOT_NODE: usize = 2;
pub fn model_to_full(model: &[u8; 3]) -> [u8; ENTROPY_NODES] {
let mut full = [0u8; ENTROPY_NODES];
full[..3].copy_from_slice(model);
full[3..].copy_from_slice(&PARETO8_FULL[model[PIVOT_NODE] as usize - 1]);
full
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn inv_map_table_is_a_near_permutation() {
assert_eq!(INV_MAP_TABLE.len(), 255);
assert_eq!(INV_MAP_TABLE[0], 7);
assert_eq!(INV_MAP_TABLE[19], 254);
assert_eq!(INV_MAP_TABLE[20], 1);
assert_eq!(INV_MAP_TABLE[254], 253);
assert!(INV_MAP_TABLE.iter().all(|&v| (1..=254).contains(&v)));
}
#[test]
fn inv_remap_always_yields_valid_prob() {
for v in 0..255i32 {
for m in 1..=255i32 {
let p = inv_remap_prob(v, m);
assert!((1..=255).contains(&p), "v={v} m={m} -> {p}");
}
}
assert_eq!(inv_remap_prob(20, 100), 99);
}
#[test]
fn pareto_and_model_expansion() {
assert_eq!(PARETO8_FULL.len(), 255);
assert!(PARETO8_FULL.iter().flatten().all(|&v| v >= 1));
assert_eq!(PARETO8_FULL[127], [213, 145, 170, 238, 173, 255, 237, 252]);
let model = [10u8, 50, 128];
let full = model_to_full(&model);
assert_eq!(&full[..3], &model);
assert_eq!(&full[3..], &PARETO8_FULL[127]);
}
#[test]
fn default_tables_well_formed() {
assert_eq!(DEFAULT_COEF_PROBS[0][0][0][0][0], [195, 29, 183]);
for tx in &DEFAULT_COEF_PROBS {
for plane in tx {
for refr in plane {
for (band, ctxs) in refr.iter().enumerate() {
let nctx = if band == 0 { 3 } else { 6 };
for ctx in &ctxs[..nctx] {
assert!(ctx.iter().all(|&p| (1..=255).contains(&p)));
}
}
}
}
}
assert_eq!(
KF_UV_MODE_PROBS[0],
[144, 11, 54, 157, 195, 130, 46, 58, 108]
);
assert_eq!(KF_PARTITION_PROBS[0], [158, 97, 94]);
assert_eq!(DEFAULT_SKIP_PROB, [192, 128, 64]);
assert!(KF_Y_MODE_PROBS
.iter()
.flatten()
.flatten()
.all(|&p| (1..=255).contains(&p)));
}
}