const OLL_NREF: usize = 0; const OLL_BLEN: usize = 1; const OLL_LEN: usize = 2; const OLL_FIRST: usize = 3;
const LL_CURVERSION: i16 = -100; const LL_CURHDRLEN: i16 = 7;
const LL_NREFS: usize = 0; const LL_HDRLEN: usize = 1; const LL_VERSION: usize = 2; const LL_LENLO: usize = 3; const LL_LENHI: usize = 4; const LL_BLENLO: usize = 5; const LL_BLENHI: usize = 6;
const I_SHIFT: i32 = 4096;
const I_DATAMAX: i32 = 4095;
const I_ZN: i32 = 0; const I_HN: i32 = 4; const I_PN: i32 = 5; const I_SH: i32 = 1; const I_IH: i32 = 2; const I_DH: i32 = 3; const I_IS: i32 = 6; const I_DS: i32 = 7;
const M_SH: i32 = 4096;
const M_IH: i32 = 8192;
const M_DH: i32 = 12288;
const M_HN: i32 = 16384;
const M_PN: i32 = 20480;
const M_MOVE: i16 = 16384;
pub fn pl_p2li(pxsrc: &[i32], xs: i32, lldst: &mut [i16], npix: usize) -> usize {
let mut v;
let mut dv: i32;
let mut np: i32;
let mut nv: i32 = 0;
let mut nz: i32;
if npix == 0 {
return 0;
}
lldst[LL_VERSION] = LL_CURVERSION;
lldst[LL_HDRLEN] = LL_CURHDRLEN;
lldst[LL_NREFS] = 0;
lldst[5] = 0;
lldst[6] = 0;
let xe = xs + (npix as i32) - 1;
let mut op: usize = (LL_CURHDRLEN) as usize;
let zero: i32 = 0;
let mut pv: i32 = i32::max(zero, pxsrc[xs as usize]); let mut x1: i32 = xs; let mut iz: i32 = xs; let mut hi: i32 = 1;
for ip in xs..=xe {
if ip < xe {
nv = i32::max(zero, pxsrc[(ip + 1) as usize]);
if nv == pv {
continue;
}
if pv == 0 {
pv = nv;
x1 = ip + 1;
continue;
}
} else if pv == 0 {
x1 = xe + 1;
}
np = ip - x1 + 1;
nz = x1 - iz;
if pv > 0 {
dv = pv - hi;
if dv != 0 {
hi = pv;
if dv.abs() > I_DATAMAX {
lldst[op] = ((pv & I_DATAMAX) + M_SH) as i16;
op += 1;
lldst[op] = (pv / I_SHIFT) as i16;
op += 1;
} else {
if dv < 0 {
lldst[op] = (-dv + M_DH) as i16;
} else {
lldst[op] = (dv + M_IH) as i16;
}
op += 1;
if np == 1 && nz == 0 {
v = lldst[op - 1];
lldst[op - 1] = v | M_MOVE;
np = 0; }
}
}
}
if nz > 0 {
while nz > 0 {
lldst[op] = i32::min(I_DATAMAX - 1, nz) as i16;
op += 1;
nz -= I_DATAMAX - 1
}
if np == 1 && pv > 0 {
lldst[op - 1] = lldst[op - 1] + (M_PN as i16) + 1;
np = 0; }
}
while np > 0 {
lldst[op] = (i32::min(I_DATAMAX, np) + M_HN) as i16;
op += 1;
np -= I_DATAMAX;
}
x1 = ip + 1;
iz = x1;
pv = nv;
}
lldst[3] = ((op - 1) % 32768) as i16;
lldst[4] = ((op - 1) / 32768) as i16;
op - 1
}
pub fn pl_l2pi(ll_src: &[i16], xs: i32, px_dst: &mut [i32], npix: usize) -> usize {
let mut data;
let mut otop: usize;
let lllen: i32;
let mut i1: i32;
let mut i2: i32;
let mut x2: i32;
let mut np: i32;
let mut opcode: i32;
let llfirt: i32;
if ll_src[LL_VERSION] > 0 {
lllen = ll_src[OLL_LEN] as i32;
llfirt = (OLL_FIRST as i32) - 1;
} else {
lllen = ((ll_src[LL_LENHI] << 15) + ll_src[LL_LENLO]) as i32; llfirt = (ll_src[LL_HDRLEN]) as i32; }
if npix == 0 || lllen <= 0 {
return 0;
}
let xe: i32 = xs + (npix as i32);
let mut skipwd: bool = false;
let mut op: usize = 0;
let mut x1: i32 = 1;
let mut pv: i32 = 1;
for ip in llfirt..=lllen {
if skipwd {
skipwd = false;
continue;
}
opcode = (ll_src[ip as usize] / 4096) as i32; data = (ll_src[ip as usize] & 4095) as i32;
let mut putpix = false;
match opcode {
I_ZN | I_HN | I_PN => {
x2 = x1 + data - 1;
i1 = i32::max(x1, xs);
i2 = i32::min(x2, xe);
np = i2 - i1 + 1;
if np > 0 {
otop = ((op as i32) + np - 1) as usize;
if opcode == I_HN {
for idx in op..=otop {
px_dst[idx] = pv;
}
} else {
for idx in op..=otop {
px_dst[idx] = 0;
}
if opcode == I_PN && i2 == x2 {
px_dst[otop] = pv;
}
}
op = otop + 1;
}
x1 = x2 + 1;
}
I_SH => {
pv = ((ll_src[(ip + 1) as usize] << 12) as i32) + data;
skipwd = true;
}
I_IH => {
pv += data;
}
I_DH => {
pv -= data;
}
I_IS => {
pv += data;
putpix = true;
}
I_DS => {
pv -= data;
putpix = true;
}
_ => (),
}
if putpix {
if x1 >= xs && x1 <= xe {
px_dst[op] = pv;
op += 1;
}
x1 += 1;
}
if x1 > xe {
break;
}
}
for idx in op..npix {
px_dst[idx] = 0;
}
npix
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct Data {
pub d: Vec<i32>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let input: [i32; 9] = [3, 56, 3343, 22225, 3, 66, 3, 3, 3];
let xs = 0;
let mut compressed: [i16; 200] = [0; 200];
let npix = 9;
let res = pl_p2li(&input, xs, &mut compressed, npix);
println!("Compressed items: {res}");
let mut uncompressed: [i32; 10] = [0; 10];
let res2 = pl_l2pi(&compressed, xs, &mut uncompressed, npix);
println!("Uncompressed items: {res2}");
}
}