use crate::entropy::EcDec;
#[derive(Debug, Clone)]
pub(crate) struct PulseDecode {
pub yy: u32,
pub pulses: Vec<i32>,
pub nc: u32,
pub index: u32,
}
fn ncwrs_urow(n: usize, k: usize) -> (Vec<u32>, u32) {
let len = k + 2;
let mut u = vec![0u32; len];
u[0] = 0;
u[1] = 1;
for (idx, item) in u.iter_mut().enumerate().skip(2) {
*item = ((idx as u32) << 1) - 1;
}
for _ in 2..n {
unext(&mut u[1..], 1);
}
let v = u[k].wrapping_add(u[k + 1]);
(u, v)
}
fn unext(u: &mut [u32], mut u0: u32) {
if u.len() < 2 {
return;
}
for j in 1..u.len() {
let u1 = u[j].wrapping_add(u[j - 1]).wrapping_add(u0);
u[j - 1] = u0;
u0 = u1;
}
let last = u.len() - 1;
u[last] = u0;
}
fn uprev(u: &mut [u32], mut u0: u32) {
if u.len() < 2 {
return;
}
for j in 1..u.len() {
let u1 = u[j].wrapping_sub(u[j - 1]).wrapping_sub(u0);
u[j - 1] = u0;
u0 = u1;
}
let last = u.len() - 1;
u[last] = u0;
}
fn cwrsi(n: usize, mut k: usize, mut idx: u32, u: &mut [u32]) -> (u32, Vec<i32>) {
let mut yy = 0u32;
let mut y = vec![0i32; n];
for yj in y.iter_mut().take(n) {
let p = u[k + 1];
let neg = idx >= p;
if neg {
idx = idx.wrapping_sub(p);
}
let yk = k;
let mut cur = u[k];
while cur > idx {
k -= 1;
cur = u[k];
}
idx = idx.wrapping_sub(cur);
let mut val = (yk - k) as i32;
if neg {
val = -val;
}
*yj = val;
yy = yy.wrapping_add((val * val) as u32);
uprev(&mut u[..=k + 1], 0);
}
(yy, y)
}
pub(crate) fn decode_pulses(dec: &mut EcDec<'_>, n: usize, k: usize) -> PulseDecode {
if n == 0 || k == 0 {
return PulseDecode {
yy: 0,
pulses: vec![0; n],
nc: 0,
index: 0,
};
}
let (mut u, nc) = ncwrs_urow(n, k);
let idx = dec.dec_uint(nc.max(2));
let (yy, pulses) = cwrsi(n, k, idx, &mut u);
PulseDecode {
yy,
pulses,
nc,
index: idx,
}
}