use std::io::Cursor;
use bytemuck::cast_slice_mut;
use bytes::Buf;
use crate::CODE_MAGIC;
fn ffpmsg(_m: &str) {}
#[derive(Debug, PartialEq)]
pub enum DecodeError {
BadBitPlaneValues,
MemoryAllocationError,
BadFormatCode,
BadFileFormat,
NumericalOverflow,
IncorrectAllocationSize,
}
struct Buffer2 {
pub buffer2: i32, pub bits_to_go: i32, }
pub struct HCDecoder {}
impl Default for HCDecoder {
fn default() -> Self {
Self::new()
}
}
impl HCDecoder {
pub fn new() -> Self {
Self {}
}
pub fn read(
&mut self,
inputz: &[u8],
smooth: i32,
a: &mut [i32],
) -> Result<(usize, usize, i32), DecodeError> {
let mut input = Cursor::new(inputz);
let (nx, ny, scale) = decode(&mut input, a)?;
undigitize(a, nx, ny, scale);
let stat = hinv(a, nx, ny, smooth, scale);
stat?;
Ok((nx, ny, scale))
}
pub fn read64(
&mut self,
inputz: &[u8],
smooth: i32,
a: &mut [i64],
) -> Result<(usize, usize, i32), DecodeError> {
let mut input = Cursor::new(inputz);
let (nx, ny, scale) = decode64(&mut input, a)?;
undigitize64(a, nx, ny, scale);
let stat = hinv64(a, nx, ny, smooth, scale);
stat?;
let nval = (nx) * (ny);
let mut iarray = Vec::with_capacity(nval);
a.iter().take(nval).for_each(|&x| {
iarray.push(x as i32);
});
let a_int: &mut [i32] = cast_slice_mut(a);
a_int[..nval].copy_from_slice(&iarray[..nval]);
Ok((nx, ny, scale))
}
}
fn hinv(a: &mut [i32], nx: usize, ny: usize, smooth: i32, scale: i32) -> Result<(), DecodeError> {
let mut lowbit0;
let mut lowbit1;
let mut h0: i32;
let mut hx: i32;
let mut hy: i32;
let mut hc: i32;
let mut oddx: usize;
let mut oddy: usize;
let mut s10: usize;
let mut s00: usize;
let nmax: usize = if nx > ny { nx } else { ny };
let mut log2n: usize = ((nmax as f64).ln() / 2.0_f64.ln() + 0.5) as usize;
if nmax > (1 << log2n) {
log2n += 1;
}
let mut tmp: Vec<i32> = Vec::new();
if tmp.try_reserve_exact(nmax.div_ceil(2)).is_err() {
ffpmsg("hinv: insufficient memory");
return Err(DecodeError::MemoryAllocationError);
} else {
tmp.resize(nmax.div_ceil(2), 0);
}
let mut shift = 1;
let mut bit0 = 1 << (log2n - 1);
let mut bit1 = bit0 << 1;
let bit2 = bit0 << 2;
let mut mask0 = -bit0;
let mut mask1 = mask0 << 1;
let mask2 = mask0 << 2;
let mut prnd0 = bit0 >> 1;
let mut prnd1 = bit1 >> 1;
let prnd2 = bit2 >> 1;
let mut nrnd0 = prnd0 - 1;
let mut nrnd1 = prnd1 - 1;
let nrnd2 = prnd2 - 1;
a[0] = (a[0] + (if a[0] >= 0 { prnd2 } else { nrnd2 })) & mask2;
let mut nxtop = 1;
let mut nytop = 1;
let mut nxf = nx;
let mut nyf = ny;
let mut c = 1 << log2n;
for k in (0..log2n).rev() {
c >>= 1;
nxtop <<= 1;
nytop <<= 1;
if nxf <= c {
nxtop -= 1;
} else {
nxf -= c;
}
if nyf <= c {
nytop -= 1;
} else {
nyf -= c;
}
if k == 0 {
nrnd0 = 0;
shift = 2;
}
for i in 0..nxtop {
unshuffle(&mut a[ny * i..], nytop, 1, &mut tmp);
}
for j in 0..nytop {
unshuffle(&mut a[j..], nxtop, ny, &mut tmp);
}
if smooth > 0 {
hsmooth(a, nxtop, nytop, ny, scale);
}
oddx = nxtop % 2;
oddy = nytop % 2;
for i in (0..(nxtop - oddx)).step_by(2) {
s00 = ny * i; s10 = s00 + ny;
for _j in (0..(nytop - oddy)).step_by(2) {
h0 = a[s00];
hx = a[s10];
hy = a[s00 + 1];
hc = a[s10 + 1];
hx = (hx + (if hx >= 0 { prnd1 } else { nrnd1 })) & mask1;
hy = (hy + (if hy >= 0 { prnd1 } else { nrnd1 })) & mask1;
hc = (hc + (if hc >= 0 { prnd0 } else { nrnd0 })) & mask0;
lowbit0 = hc & bit0;
hx = if hx >= 0 { hx - lowbit0 } else { hx + lowbit0 };
hy = if hy >= 0 { hy - lowbit0 } else { hy + lowbit0 };
lowbit1 = (hc ^ hx ^ hy) & bit1;
h0 = if h0 >= 0 {
h0 + lowbit0 - lowbit1
} else {
h0 + (if lowbit0 == 0 {
lowbit1
} else {
lowbit0 - lowbit1
})
};
a[s10 + 1] = (h0 + hx + hy + hc) >> shift;
a[s10] = (h0 + hx - hy - hc) >> shift;
a[s00 + 1] = (h0 - hx + hy - hc) >> shift;
a[s00] = (h0 - hx - hy + hc) >> shift;
s00 += 2;
s10 += 2;
}
if oddy > 0 {
h0 = a[s00];
hx = a[s10];
hx = (if hx >= 0 { hx + prnd1 } else { hx + nrnd1 }) & mask1;
lowbit1 = hx & bit1;
h0 = if h0 >= 0 { h0 - lowbit1 } else { h0 + lowbit1 };
a[s10] = (h0 + hx) >> shift;
a[s00] = (h0 - hx) >> shift;
}
}
if oddx > 0 {
s00 = ny * (nxtop - 1);
for _j in (0..(nytop - oddy)).step_by(2) {
h0 = a[s00];
hy = a[s00 + 1];
hy = (if hy >= 0 { hy + prnd1 } else { hy + nrnd1 }) & mask1;
lowbit1 = hy & bit1;
h0 = if h0 >= 0 { h0 - lowbit1 } else { h0 + lowbit1 };
a[s00 + 1] = (h0 + hy) >> shift;
a[s00] = (h0 - hy) >> shift;
s00 += 2;
}
if oddy > 0 {
h0 = a[s00];
a[s00] = h0 >> shift;
}
}
bit1 = bit0;
bit0 >>= 1;
mask1 = mask0;
mask0 >>= 1;
prnd1 = prnd0;
prnd0 >>= 1;
nrnd1 = nrnd0;
nrnd0 = prnd0 - 1;
}
Ok(())
}
fn hinv64(a: &mut [i64], nx: usize, ny: usize, smooth: i32, scale: i32) -> Result<(), DecodeError> {
let mut lowbit0;
let mut lowbit1;
let mut h0: i64;
let mut hx: i64;
let mut hy: i64;
let mut hc: i64;
let mut oddx: usize;
let mut oddy: usize;
let mut s10: usize;
let mut s00: usize;
let nmax: usize = if nx > ny { nx } else { ny };
let mut log2n: usize = ((nmax as f64).ln() / 2.0_f64.ln() + 0.5) as usize;
if nmax > (1 << log2n) {
log2n += 1;
}
let mut tmp: Vec<i64> = Vec::new();
if tmp.try_reserve_exact(nmax.div_ceil(2)).is_err() {
ffpmsg("hinv64: insufficient memory");
return Err(DecodeError::MemoryAllocationError);
} else {
tmp.resize(nmax.div_ceil(2), 0);
}
let mut shift = 1;
let mut bit0 = 1 << (log2n - 1);
let mut bit1 = bit0 << 1;
let bit2 = bit0 << 2;
let mut mask0 = -bit0;
let mut mask1 = mask0 << 1;
let mask2 = mask0 << 2;
let mut prnd0 = bit0 >> 1;
let mut prnd1 = bit1 >> 1;
let prnd2 = bit2 >> 1;
let mut nrnd0 = prnd0 - 1;
let mut nrnd1 = prnd1 - 1;
let nrnd2 = prnd2 - 1;
a[0] = (a[0] + (if a[0] >= 0 { prnd2 } else { nrnd2 })) & mask2;
let mut nxtop = 1;
let mut nytop = 1;
let mut nxf = nx;
let mut nyf = ny;
let mut c = 1 << log2n;
for k in (0..log2n).rev() {
c >>= 1;
nxtop <<= 1;
nytop <<= 1;
if nxf <= c {
nxtop -= 1;
} else {
nxf -= c;
}
if nyf <= c {
nytop -= 1;
} else {
nyf -= c;
}
if k == 0 {
nrnd0 = 0;
shift = 2;
}
for i in 0..nxtop {
unshuffle64(&mut a[ny * i..], nytop, 1, &mut tmp);
}
for j in 0..nytop {
unshuffle64(&mut a[j..], nxtop, ny, &mut tmp);
}
if smooth > 0 {
hsmooth64(a, nxtop, nytop, ny, scale);
}
oddx = nxtop % 2;
oddy = nytop % 2;
for i in (0..(nxtop - oddx)).step_by(2) {
s00 = ny * i; s10 = s00 + ny;
for _j in (0..(nytop - oddy)).step_by(2) {
h0 = a[s00];
hx = a[s10];
hy = a[s00 + 1];
hc = a[s10 + 1];
hx = (hx + (if hx >= 0 { prnd1 } else { nrnd1 })) & mask1;
hy = (hy + (if hy >= 0 { prnd1 } else { nrnd1 })) & mask1;
hc = (hc + (if hc >= 0 { prnd0 } else { nrnd0 })) & mask0;
lowbit0 = hc & bit0;
hx = if hx >= 0 { hx - lowbit0 } else { hx + lowbit0 };
hy = if hy >= 0 { hy - lowbit0 } else { hy + lowbit0 };
lowbit1 = (hc ^ hx ^ hy) & bit1;
h0 = if h0 >= 0 {
h0 + lowbit0 - lowbit1
} else {
h0 + (if lowbit0 == 0 {
lowbit1
} else {
lowbit0 - lowbit1
})
};
a[s10 + 1] = (h0 + hx + hy + hc) >> shift;
a[s10] = (h0 + hx - hy - hc) >> shift;
a[s00 + 1] = (h0 - hx + hy - hc) >> shift;
a[s00] = (h0 - hx - hy + hc) >> shift;
s00 += 2;
s10 += 2;
}
if oddy > 0 {
h0 = a[s00];
hx = a[s10];
hx = (if hx >= 0 { hx + prnd1 } else { hx + nrnd1 }) & mask1;
lowbit1 = hx & bit1;
h0 = if h0 >= 0 { h0 - lowbit1 } else { h0 + lowbit1 };
a[s10] = (h0 + hx) >> shift;
a[s00] = (h0 - hx) >> shift;
}
}
if oddx > 0 {
s00 = ny * (nxtop - 1);
for _j in (0..(nytop - oddy)).step_by(2) {
h0 = a[s00];
hy = a[s00 + 1];
hy = (if hy >= 0 { hy + prnd1 } else { hy + nrnd1 }) & mask1;
lowbit1 = hy & bit1;
h0 = if h0 >= 0 { h0 - lowbit1 } else { h0 + lowbit1 };
a[s00 + 1] = (h0 + hy) >> shift;
a[s00] = (h0 - hy) >> shift;
s00 += 2;
}
if oddy > 0 {
h0 = a[s00];
a[s00] = h0 >> shift;
}
}
bit1 = bit0;
bit0 >>= 1;
mask1 = mask0;
mask0 >>= 1;
prnd1 = prnd0;
prnd0 >>= 1;
nrnd1 = nrnd0;
nrnd0 = prnd0 - 1;
}
Ok(())
}
fn unshuffle(a: &mut [i32], n: usize, n2: usize, tmp: &mut [i32]) {
let nhalf = (n + 1) >> 1;
let mut pt = 0;
let mut p1 = n2 * nhalf;
for _i in nhalf..n {
tmp[pt] = a[p1];
p1 += n2;
pt += 1;
}
let mut p2 = n2 * (nhalf - 1); p1 = (n2 * (nhalf - 1)) << 1;
for i in (0..nhalf).rev() {
a[p1] = a[p2];
if i == 0 {
break;
}
p2 -= n2;
p1 -= n2 + n2;
}
pt = 0;
p1 = n2; for _i in (1..n).step_by(2) {
a[p1] = tmp[pt];
p1 += n2 + n2;
pt += 1;
}
}
fn unshuffle64(a: &mut [i64], n: usize, n2: usize, tmp: &mut [i64]) {
let nhalf = (n + 1) >> 1;
let mut pt = 0;
let mut p1 = n2 * nhalf;
for _i in nhalf..n {
tmp[pt] = a[p1];
p1 += n2;
pt += 1;
}
let mut p2 = n2 * (nhalf - 1); p1 = (n2 * (nhalf - 1)) << 1; for _i in (0..nhalf).rev() {
a[p1] = a[p2];
if _i > 0 {
p2 -= n2;
p1 -= n2 + n2;
}
}
pt = 0;
p1 = n2; for _i in (1..n).step_by(2) {
a[p1] = tmp[pt];
p1 += n2 + n2;
pt += 1;
}
}
fn hsmooth(a: &mut [i32], nxtop: usize, nytop: usize, ny: usize, scale: i32)
{
let mut m1;
let mut m2;
let mut hm;
let mut h0;
let mut hp;
let mut hmm;
let mut hpm;
let mut hmp;
let mut hpp;
let mut hx2;
let mut hy2;
let mut diff;
let mut dmax;
let mut dmin;
let mut s;
let mut s00: usize;
let mut s10: usize;
let smax = scale >> 1;
if smax <= 0 {
return;
}
let ny2 = ny << 1;
for i in (2..(nxtop - 2)).step_by(2) {
s00 = ny * i; s10 = s00 + ny;
for _j in (0..nytop).step_by(2) {
hm = a[s00 - ny2];
h0 = a[s00];
hp = a[s00 + ny2];
diff = hp - hm;
dmax = i32::max(i32::min(hp - h0, h0 - hm), 0) << 2;
dmin = i32::min(i32::max(hp - h0, h0 - hm), 0) << 2;
if dmin < dmax {
diff = i32::max(i32::min(diff, dmax), dmin);
s = diff - (a[s10] << 3);
s = if s >= 0 { s >> 3 } else { (s + 7) >> 3 };
s = i32::max(i32::min(s, smax), -smax);
a[s10] += s;
}
s00 += 2;
s10 += 2;
}
}
for i in (0..nxtop).step_by(2) {
s00 = ny * i + 2;
for _j in (2..(nytop - 2)).step_by(2) {
hm = a[s00 - 2];
h0 = a[s00];
hp = a[s00 + 2];
diff = hp - hm;
dmax = i32::max(i32::min(hp - h0, h0 - hm), 0) << 2;
dmin = i32::min(i32::max(hp - h0, h0 - hm), 0) << 2;
if dmin < dmax {
diff = i32::max(i32::min(diff, dmax), dmin);
s = diff - (a[s00 + 1] << 3);
s = if s >= 0 { s >> 3 } else { (s + 7) >> 3 };
s = i32::max(i32::min(s, smax), -smax);
a[s00 + 1] += s;
}
s00 += 2;
}
}
for i in (2..(nxtop - 2)).step_by(2) {
s00 = ny * i + 2;
s10 = s00 + ny;
for _j in (2..(nytop - 2)).step_by(2) {
hmm = a[s00 - ny2 - 2];
hpm = a[s00 + ny2 - 2];
hmp = a[s00 - ny2 + 2];
hpp = a[s00 + ny2 + 2];
h0 = a[s00];
diff = hpp + hmm - hmp - hpm;
hx2 = a[s10] << 1;
hy2 = a[s00 + 1] << 1;
m1 = i32::min(
i32::max(hpp - h0, 0) - hx2 - hy2,
i32::max(h0 - hpm, 0) + hx2 - hy2,
);
m2 = i32::min(
i32::max(h0 - hmp, 0) - hx2 + hy2,
i32::max(hmm - h0, 0) + hx2 + hy2,
);
dmax = i32::min(m1, m2) << 4;
m1 = i32::max(
i32::min(hpp - h0, 0) - hx2 - hy2,
i32::min(h0 - hpm, 0) + hx2 - hy2,
);
m2 = i32::max(
i32::min(h0 - hmp, 0) - hx2 + hy2,
i32::min(hmm - h0, 0) + hx2 + hy2,
);
dmin = i32::max(m1, m2) << 4;
if dmin < dmax {
diff = i32::max(i32::min(diff, dmax), dmin);
s = diff - (a[s10 + 1] << 6);
s = if s >= 0 { s >> 6 } else { (s + 63) >> 6 };
s = i32::max(i32::min(s, smax), -smax);
a[s10 + 1] += s;
}
s00 += 2;
s10 += 2;
}
}
}
fn hsmooth64(a: &mut [i64], nxtop: usize, nytop: usize, ny: usize, scale: i32)
{
let mut hm;
let mut h0;
let mut hp;
let mut hmm;
let mut hpm;
let mut hmp;
let mut hpp;
let mut hx2;
let mut hy2;
let mut diff;
let mut dmax;
let mut dmin;
let mut s;
let mut s00: usize;
let mut s10: usize;
let mut m1;
let mut m2;
let smax = i64::from(scale >> 1);
if smax <= 0 {
return;
}
let ny2 = ny << 1;
for i in (2..(nxtop - 2)).step_by(2) {
s00 = ny * i; s10 = s00 + ny;
for _j in (0..nytop).step_by(2) {
hm = a[s00 - ny2];
h0 = a[s00];
hp = a[s00 + ny2];
diff = hp - hm;
dmax = i64::max(i64::min(hp - h0, h0 - hm), 0) << 2;
dmin = i64::min(i64::max(hp - h0, h0 - hm), 0) << 2;
if dmin < dmax {
diff = i64::max(i64::min(diff, dmax), dmin);
s = diff - (a[s10] << 3);
s = if s >= 0 { s >> 3 } else { (s + 7) >> 3 };
s = i64::max(i64::min(s, smax), -smax);
a[s10] += s;
}
s00 += 2;
s10 += 2;
}
}
for i in (0..nxtop).step_by(2) {
s00 = ny * i + 2;
for _j in (2..(nytop - 2)).step_by(2) {
hm = a[s00 - 2];
h0 = a[s00];
hp = a[s00 + 2];
diff = hp - hm;
dmax = i64::max(i64::min(hp - h0, h0 - hm), 0) << 2;
dmin = i64::min(i64::max(hp - h0, h0 - hm), 0) << 2;
if dmin < dmax {
diff = i64::max(i64::min(diff, dmax), dmin);
s = diff - (a[s00 + 1] << 3);
s = if s >= 0 { s >> 3 } else { (s + 7) >> 3 };
s = i64::max(i64::min(s, smax), -smax);
a[s00 + 1] += s;
}
s00 += 2;
}
}
for i in (2..(nxtop - 2)).step_by(2) {
s00 = ny * i + 2;
s10 = s00 + ny;
for _j in (2..(nytop - 2)).step_by(2) {
hmm = a[s00 - ny2 - 2];
hpm = a[s00 + ny2 - 2];
hmp = a[s00 - ny2 + 2];
hpp = a[s00 + ny2 + 2];
h0 = a[s00];
diff = hpp + hmm - hmp - hpm;
hx2 = a[s10] << 1;
hy2 = a[s00 + 1] << 1;
m1 = i64::min(
i64::max(hpp - h0, 0) - hx2 - hy2,
i64::max(h0 - hpm, 0) + hx2 - hy2,
);
m2 = i64::min(
i64::max(h0 - hmp, 0) - hx2 + hy2,
i64::max(hmm - h0, 0) + hx2 + hy2,
);
dmax = i64::min(m1, m2) << 4;
m1 = i64::max(
i64::min(hpp - h0, 0) - hx2 - hy2,
i64::min(h0 - hpm, 0) + hx2 - hy2,
);
m2 = i64::max(
i64::min(h0 - hmp, 0) - hx2 + hy2,
i64::min(hmm - h0, 0) + hx2 + hy2,
);
dmin = i64::max(m1, m2) << 4;
if dmin < dmax {
diff = i64::max(i64::min(diff, dmax), dmin);
s = diff - (a[s10 + 1] << 6);
s = if s >= 0 { s >> 6 } else { (s + 63) >> 6 };
s = i64::max(i64::min(s, smax), -smax);
a[s10 + 1] += s;
}
s00 += 2;
s10 += 2;
}
}
}
fn undigitize(a: &mut [i32], nx: usize, ny: usize, scale: i32) {
if scale <= 1 {
return;
}
if nx == 0 || ny == 0 {
return;
}
for item in a.iter_mut().take(nx * ny - 1) {
*item *= scale;
}
}
fn undigitize64(a: &mut [i64], nx: usize, ny: usize, scale: i32) {
if scale <= 1 {
return;
}
let scale64: i64 = i64::from(scale);
if nx == 0 || ny == 0 {
return;
}
a.iter_mut().take(nx * ny - 1).for_each(|x| *x *= scale64);
}
fn decode(infile: &mut Cursor<&[u8]>, a: &mut [i32]) -> Result<(usize, usize, i32), DecodeError> {
let mut nbitplanes: [u8; 3] = [0; 3];
let mut tmagic: [u8; 2] = [0; 2];
qread(infile, &mut tmagic, 2);
if !tmagic.eq(&CODE_MAGIC) {
ffpmsg("bad file format");
return Err(DecodeError::BadFileFormat);
}
let nx = readint(infile) as usize; let ny = readint(infile) as usize; let scale = readint(infile);
if (nx) > (i32::MAX as usize) / (ny) {
ffpmsg("numerical overflow during decompression");
return Err(DecodeError::NumericalOverflow);
}
if (nx) * (ny) > a.len() {
ffpmsg("wrong allocation size during decompression");
return Err(DecodeError::IncorrectAllocationSize);
}
let sumall = readlonglong(infile);
let len = nbitplanes.len();
qread(infile, &mut nbitplanes, len);
let stat = dodecode(infile, a, nx, ny, nbitplanes);
a[0] = sumall as i32;
match stat {
Ok(_) => Ok((nx, ny, scale)),
Err(e) => Err(e),
}
}
fn decode64(infile: &mut Cursor<&[u8]>, a: &mut [i64]) -> Result<(usize, usize, i32), DecodeError> {
let mut nbitplanes: [u8; 3] = [0; 3];
let mut tmagic: [u8; 2] = [0; 2];
qread(infile, &mut tmagic, 2);
if !tmagic.eq(&CODE_MAGIC) {
ffpmsg("bad file format");
return Err(DecodeError::BadFileFormat);
}
let nx = readint(infile) as usize; let ny = readint(infile) as usize; let scale = readint(infile);
if (nx) > (i32::MAX as usize) / (ny) {
ffpmsg("numerical overflow during decompression");
return Err(DecodeError::NumericalOverflow);
}
if (nx) * (ny) > a.len() {
ffpmsg("wrong allocation size during decompression");
return Err(DecodeError::IncorrectAllocationSize);
}
let sumall = readlonglong(infile);
let len = nbitplanes.len();
qread(infile, &mut nbitplanes, len);
let stat = dodecode64(infile, a, nx, ny, nbitplanes);
a[0] = sumall;
match stat {
Ok(_) => Ok((nx, ny, scale)),
Err(e) => Err(e),
}
}
fn dodecode(
infile: &mut Cursor<&[u8]>,
a: &mut [i32],
nx: usize,
ny: usize,
nbitplanes: [u8; 3],
) -> Result<(), DecodeError> {
let nel = nx * ny;
let nx2 = nx.div_ceil(2);
let ny2 = ny.div_ceil(2);
a.iter_mut().take(nel).for_each(|x| *x = 0);
let mut b2 = start_inputing_bits();
qtree_decode(infile, a, ny, nx2, ny2, i32::from(nbitplanes[0]), &mut b2)?;
qtree_decode(
infile,
&mut a[ny2..],
ny,
nx2,
ny / 2,
i32::from(nbitplanes[1]),
&mut b2,
)?;
qtree_decode(
infile,
&mut a[(ny * nx2)..],
ny,
nx / 2,
ny2,
i32::from(nbitplanes[1]),
&mut b2,
)?;
if ny * nx2 + ny2 < a.len() {
qtree_decode(
infile,
&mut a[(ny * nx2 + ny2)..],
ny,
nx / 2,
ny / 2,
i32::from(nbitplanes[2]),
&mut b2,
)?;
}
if input_nybble(infile, &mut b2) != 0 {
ffpmsg("dodecode: bad bit plane values");
return Err(DecodeError::BadBitPlaneValues);
}
let mut b2 = start_inputing_bits();
for item in a.iter_mut().take(nel) {
if *item > 0 {
if input_bit(infile, &mut b2) > 0 {
*item = -*item;
}
}
}
Ok(())
}
fn dodecode64(
infile: &mut Cursor<&[u8]>,
a: &mut [i64],
nx: usize,
ny: usize,
nbitplanes: [u8; 3],
) -> Result<(), DecodeError> {
let nel = nx * ny;
let nx2 = nx.div_ceil(2);
let ny2 = ny.div_ceil(2);
a.iter_mut().take(nel).for_each(|x| *x = 0);
let mut b2 = start_inputing_bits();
qtree_decode64(infile, a, ny, nx2, ny2, i32::from(nbitplanes[0]), &mut b2)?;
qtree_decode64(
infile,
&mut a[ny2..],
ny,
nx2,
ny / 2,
i32::from(nbitplanes[1]),
&mut b2,
)?;
qtree_decode64(
infile,
&mut a[(ny * nx2)..],
ny,
nx / 2,
ny2,
i32::from(nbitplanes[1]),
&mut b2,
)?;
if ny * nx2 + ny2 < a.len() {
qtree_decode64(
infile,
&mut a[(ny * nx2 + ny2)..],
ny,
nx / 2,
ny / 2,
i32::from(nbitplanes[2]),
&mut b2,
)?;
}
if input_nybble(infile, &mut b2) != 0 {
ffpmsg("dodecode64: bad bit plane values");
return Err(DecodeError::BadBitPlaneValues);
}
let mut b2 = start_inputing_bits();
for item in a.iter_mut().take(nel) {
if *item > 0 && input_bit(infile, &mut b2) > 0 {
*item = -*item;
}
}
Ok(())
}
fn qtree_decode(
infile: &mut Cursor<&[u8]>,
a: &mut [i32],
n: usize,
nqx: usize,
nqy: usize,
nbitplanes: i32,
b2: &mut Buffer2,
) -> Result<(), DecodeError> {
let mut b;
let mut nfx;
let mut nfy;
let mut c;
let mut nx: usize;
let mut ny: usize;
let nqmax: usize = if nqx > nqy { nqx } else { nqy };
let mut log2n: usize = ((nqmax as f32).ln() / 2.0_f32.ln() + 0.5) as usize;
if nqmax > (1 << log2n) {
log2n += 1;
}
let nqx2 = nqx.div_ceil(2);
let nqy2 = nqy.div_ceil(2);
let mut scratch: Vec<u8> = Vec::new();
let scratch_len = (nqx2 + 1) * (nqy2 + 1);
if scratch.try_reserve_exact(scratch_len).is_err() {
ffpmsg("qtree_decode: memory allocation error");
return Err(DecodeError::MemoryAllocationError);
} else {
scratch.resize(scratch_len, 0);
}
for bit in (0..nbitplanes).rev() {
b = input_nybble(infile, b2);
if b == 0 {
read_bdirect(infile, a, n, nqx, nqy, &mut scratch, bit, b2);
} else if b != 0xf {
ffpmsg("qtree_decode: bad format code");
return Err(DecodeError::BadFormatCode);
} else {
scratch[0] = input_huffman(infile, b2) as u8;
nx = 1;
ny = 1;
nfx = nqx;
nfy = nqy;
c = 1 << log2n;
for _k in 1..log2n {
c >>= 1;
nx <<= 1;
ny <<= 1;
if nfx <= c {
nx -= 1;
} else {
nfx -= c;
}
if nfy <= c {
ny -= 1;
} else {
nfy -= c;
}
qtree_expand(infile, &mut scratch, nx, ny, b2);
}
qtree_bitins(&mut scratch, nqx, nqy, a, n, bit);
}
}
Ok(())
}
fn qtree_decode64(
infile: &mut Cursor<&[u8]>,
a: &mut [i64],
n: usize,
nqx: usize,
nqy: usize,
nbitplanes: i32,
b2: &mut Buffer2,
) -> Result<(), DecodeError> {
let mut b;
let mut nfx;
let mut nfy;
let mut c;
let mut nx: usize;
let mut ny: usize;
let nqmax: usize = if nqx > nqy { nqx } else { nqy };
let mut log2n: usize = ((nqmax as f32).ln() / 2.0_f32.ln() + 0.5) as usize;
if nqmax > (1 << log2n) {
log2n += 1;
}
let nqx2 = nqx.div_ceil(2);
let nqy2 = nqy.div_ceil(2);
let mut scratch: Vec<u8> = Vec::new();
let scratch_len = (nqx2 + 1) * (nqy2 + 1);
if scratch.try_reserve_exact(scratch_len).is_err() {
ffpmsg("qtree_decode64: memory allocation error");
return Err(DecodeError::MemoryAllocationError);
} else {
scratch.resize(scratch_len, 0);
}
for bit in (0..nbitplanes).rev() {
b = input_nybble(infile, b2);
if b == 0 {
read_bdirect64(infile, a, n, nqx, nqy, &mut scratch, bit, b2);
} else if b != 0xf {
ffpmsg("qtree_decode64: bad format code");
return Err(DecodeError::BadFormatCode);
} else {
scratch[0] = input_huffman(infile, b2) as u8;
nx = 1;
ny = 1;
nfx = nqx;
nfy = nqy;
c = 1 << log2n;
for _k in 1..log2n {
c >>= 1;
nx <<= 1;
ny <<= 1;
if nfx <= c {
nx -= 1;
} else {
nfx -= c;
}
if nfy <= c {
ny -= 1;
} else {
nfy -= c;
}
qtree_expand(infile, &mut scratch, nx, ny, b2);
}
qtree_bitins64(&mut scratch, nqx, nqy, a, n, bit);
}
}
Ok(())
}
fn qtree_expand(infile: &mut Cursor<&[u8]>, a: &mut [u8], nx: usize, ny: usize, b2: &mut Buffer2) {
qtree_copy(a, nx, ny, ny);
for i in (0..(nx * ny)).rev() {
if a[i] > 0 {
a[i] = input_huffman(infile, b2) as u8;
}
}
}
fn qtree_copy(a: &mut [u8], nx: usize, ny: usize, n: usize)
{
let mut s00: usize;
let mut s10: usize;
let nx2 = nx.div_ceil(2);
let ny2 = ny.div_ceil(2);
let mut k = ny2 * (nx2 - 1) + ny2; for i in (0..nx2).rev() {
s00 = 2 * (n * i + ny2 - 1) + 2; for _j in (0..ny2).rev() {
k -= 1;
s00 -= 2;
a[s00] = a[k];
}
}
let oddx = nx % 2;
let oddy = ny % 2;
if nx == 0 {
return;
}
for i in (0..(nx - 1)).step_by(2) {
s00 = n * i; s10 = s00 + n;
if ny == 0 {
continue;
}
for _j in (0..(ny - 1)).step_by(2) {
match a[s00] {
0 => {
a[s10 + 1] = 0;
a[s10] = 0;
a[s00 + 1] = 0;
a[s00] = 0;
}
1 => {
a[s10 + 1] = 1;
a[s10] = 0;
a[s00 + 1] = 0;
a[s00] = 0;
}
2 => {
a[s10 + 1] = 0;
a[s10] = 1;
a[s00 + 1] = 0;
a[s00] = 0;
}
3 => {
a[s10 + 1] = 1;
a[s10] = 1;
a[s00 + 1] = 0;
a[s00] = 0;
}
4 => {
a[s10 + 1] = 0;
a[s10] = 0;
a[s00 + 1] = 1;
a[s00] = 0;
}
5 => {
a[s10 + 1] = 1;
a[s10] = 0;
a[s00 + 1] = 1;
a[s00] = 0;
}
6 => {
a[s10 + 1] = 0;
a[s10] = 1;
a[s00 + 1] = 1;
a[s00] = 0;
}
7 => {
a[s10 + 1] = 1;
a[s10] = 1;
a[s00 + 1] = 1;
a[s00] = 0;
}
8 => {
a[s10 + 1] = 0;
a[s10] = 0;
a[s00 + 1] = 0;
a[s00] = 1;
}
9 => {
a[s10 + 1] = 1;
a[s10] = 0;
a[s00 + 1] = 0;
a[s00] = 1;
}
10 => {
a[s10 + 1] = 0;
a[s10] = 1;
a[s00 + 1] = 0;
a[s00] = 1;
}
11 => {
a[s10 + 1] = 1;
a[s10] = 1;
a[s00 + 1] = 0;
a[s00] = 1;
}
12 => {
a[s10 + 1] = 0;
a[s10] = 0;
a[s00 + 1] = 1;
a[s00] = 1;
}
13 => {
a[s10 + 1] = 1;
a[s10] = 0;
a[s00 + 1] = 1;
a[s00] = 1;
}
14 => {
a[s10 + 1] = 0;
a[s10] = 1;
a[s00 + 1] = 1;
a[s00] = 1;
}
15 => {
a[s10 + 1] = 1;
a[s10] = 1;
a[s00 + 1] = 1;
a[s00] = 1;
}
_ => (),
}
s00 += 2;
s10 += 2;
}
if oddy > 0 {
a[s10] = (a[s00] >> 1) & 1;
a[s00] = (a[s00] >> 3) & 1;
}
}
if oddx > 0 {
s00 = n * (nx - 1);
if ny == 0 {
return;
}
for _j in (0..(ny - 1)).step_by(2) {
a[s00 + 1] = (a[s00] >> 2) & 1;
a[s00] = (a[s00] >> 3) & 1;
s00 += 2;
}
if oddy > 0 {
a[s00] = (a[s00] >> 3) & 1;
}
}
}
fn qtree_bitins(a: &mut [u8], nx: usize, ny: usize, b: &mut [i32], n: usize, bit: i32) {
let mut s00: usize;
let plane_val = 1 << bit;
let mut k: usize = 0; let oddx = nx % 2;
let oddy = ny % 2;
if nx == 0 {
return;
}
for i in (0..(nx - 1)).step_by(2) {
s00 = n * i;
if ny == 0 {
continue;
}
for _j in (0..(ny - 1)).step_by(2) {
match a[k] {
0 => (),
1 => {
b[s00 + n + 1] |= plane_val;
}
2 => {
b[s00 + n] |= plane_val;
}
3 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
}
4 => {
b[s00 + 1] |= plane_val;
}
5 => {
b[s00 + n + 1] |= plane_val;
b[s00 + 1] |= plane_val;
}
6 => {
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
}
7 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
}
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00 + n + 1] |= plane_val;
b[s00] |= plane_val;
}
10 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
11 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
12 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
13 => {
b[s00 + n + 1] |= plane_val;
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
14 => {
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
15 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
_ => (),
}
s00 += 2;
k += 1;
}
if oddy > 0 {
match a[k] {
2 => {
b[s00 + n] |= plane_val;
}
3 => {
b[s00 + n] |= plane_val;
}
6 => {
b[s00 + n] |= plane_val;
}
7 => {
b[s00 + n] |= plane_val;
}
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00] |= plane_val;
}
10 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
11 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
12 => {
b[s00] |= plane_val;
}
13 => {
b[s00] |= plane_val;
}
14 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
15 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
_ => (),
}
k += 1;
}
}
if oddx > 0 {
s00 = n * (nx - 1);
if ny == 0 {
return;
}
for _j in (0..(ny - 1)).step_by(2) {
match a[k] {
4 => {
b[s00 + 1] |= plane_val;
}
5 => {
b[s00 + 1] |= plane_val;
}
6 => {
b[s00 + 1] |= plane_val;
}
7 => {
b[s00 + 1] |= plane_val;
}
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00] |= plane_val;
}
10 => {
b[s00] |= plane_val;
}
11 => {
b[s00] |= plane_val;
}
12 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
13 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
14 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
15 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
_ => (),
}
s00 += 2;
k += 1;
}
if oddy > 0 {
match a[k] {
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00] |= plane_val;
}
10 => {
b[s00] |= plane_val;
}
11 => {
b[s00] |= plane_val;
}
12 => {
b[s00] |= plane_val;
}
13 => {
b[s00] |= plane_val;
}
14 => {
b[s00] |= plane_val;
}
15 => {
b[s00] |= plane_val;
}
_ => (),
}
}
}
}
fn qtree_bitins64(a: &mut [u8], nx: usize, ny: usize, b: &mut [i64], n: usize, bit: i32) {
let mut s00: usize;
let plane_val: i64 = 1 << bit;
let mut k: usize = 0; let oddx = nx % 2;
let oddy = ny % 2;
if nx == 0 {
return;
}
for i in (0..(nx - 1)).step_by(2) {
s00 = n * i;
if ny == 0 {
continue;
}
for _j in (0..(ny - 1)).step_by(2) {
match a[k] {
0 => (),
1 => {
b[s00 + n + 1] |= plane_val;
}
2 => {
b[s00 + n] |= plane_val;
}
3 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
}
4 => {
b[s00 + 1] |= plane_val;
}
5 => {
b[s00 + n + 1] |= plane_val;
b[s00 + 1] |= plane_val;
}
6 => {
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
}
7 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
}
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00 + n + 1] |= plane_val;
b[s00] |= plane_val;
}
10 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
11 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
12 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
13 => {
b[s00 + n + 1] |= plane_val;
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
14 => {
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
15 => {
b[s00 + n + 1] |= plane_val;
b[s00 + n] |= plane_val;
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
_ => (),
}
s00 += 2;
k += 1;
}
if oddy > 0 {
match a[k] {
2 => {
b[s00 + n] |= plane_val;
}
3 => {
b[s00 + n] |= plane_val;
}
6 => {
b[s00 + n] |= plane_val;
}
7 => {
b[s00 + n] |= plane_val;
}
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00] |= plane_val;
}
10 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
11 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
12 => {
b[s00] |= plane_val;
}
13 => {
b[s00] |= plane_val;
}
14 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
15 => {
b[s00 + n] |= plane_val;
b[s00] |= plane_val;
}
_ => (),
}
k += 1;
}
}
if oddx > 0 {
s00 = n * (nx - 1);
if ny == 0 {
return;
}
for _j in (0..(ny - 1)).step_by(2) {
match a[k] {
4 => {
b[s00 + 1] |= plane_val;
}
5 => {
b[s00 + 1] |= plane_val;
}
6 => {
b[s00 + 1] |= plane_val;
}
7 => {
b[s00 + 1] |= plane_val;
}
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00] |= plane_val;
}
10 => {
b[s00] |= plane_val;
}
11 => {
b[s00] |= plane_val;
}
12 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
13 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
14 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
15 => {
b[s00 + 1] |= plane_val;
b[s00] |= plane_val;
}
_ => (),
}
s00 += 2;
k += 1;
}
if oddy > 0 {
match a[k] {
8 => {
b[s00] |= plane_val;
}
9 => {
b[s00] |= plane_val;
}
10 => {
b[s00] |= plane_val;
}
11 => {
b[s00] |= plane_val;
}
12 => {
b[s00] |= plane_val;
}
13 => {
b[s00] |= plane_val;
}
14 => {
b[s00] |= plane_val;
}
15 => {
b[s00] |= plane_val;
}
_ => (),
}
}
}
}
#[allow(clippy::too_many_arguments)]
fn read_bdirect(
infile: &mut Cursor<&[u8]>,
a: &mut [i32],
n: usize,
nqx: usize,
nqy: usize,
scratch: &mut [u8],
bit: i32,
b2: &mut Buffer2,
) {
input_nnybble(infile, nqx.div_ceil(2) * nqy.div_ceil(2), scratch, b2);
qtree_bitins(scratch, nqx, nqy, a, n, bit);
}
#[allow(clippy::too_many_arguments)]
fn read_bdirect64(
infile: &mut Cursor<&[u8]>,
a: &mut [i64],
n: usize,
nqx: usize,
nqy: usize,
scratch: &mut [u8],
bit: i32,
b2: &mut Buffer2,
) {
input_nnybble(infile, nqx.div_ceil(2) * nqy.div_ceil(2), scratch, b2);
qtree_bitins64(scratch, nqx, nqy, a, n, bit);
}
fn input_huffman(infile: &mut Cursor<&[u8]>, b2: &mut Buffer2) -> i32 {
let mut c: i32 = input_nbits(infile, 3, b2);
if c < 4 {
return 1 << c;
}
c = input_bit(infile, b2) | (c << 1);
if c < 13 {
match c {
8 => return 3,
9 => return 5,
10 => return 10,
11 => return 12,
12 => return 15,
_ => (),
}
}
c = input_bit(infile, b2) | (c << 1);
if c < 31 {
match c {
26 => return 6,
27 => return 7,
28 => return 9,
29 => return 11,
30 => return 13,
_ => (),
}
}
c = input_bit(infile, b2) | (c << 1);
if c == 62 { 0 } else { 14 }
}
#[must_use]
fn readint(infile: &mut Cursor<&[u8]>) -> i32 {
let mut b: [u8; 4] = [0; 4];
qread(infile, &mut b, 4);
let mut a: i32 = i32::from(b[0]);
for &byte in &b[1..4] {
a = (a << 8) + i32::from(byte);
}
a
}
#[must_use]
fn readlonglong(infile: &mut Cursor<&[u8]>) -> i64 {
let mut b: [u8; 8] = [0; 8];
for i in 0..8 {
qread(infile, &mut b[i..], 1);
}
let mut a: i64 = i64::from(b[0]);
for &byte in &b[1..8] {
a = (a << 8) + i64::from(byte);
}
a
}
fn qread(file: &mut Cursor<&[u8]>, buffer: &mut [u8], n: usize) {
file.copy_to_slice(&mut buffer[0..n]);
}
#[must_use]
fn start_inputing_bits() -> Buffer2 {
Buffer2 {
buffer2: 0, bits_to_go: 0, }
}
fn input_bit(infile: &mut Cursor<&[u8]>, b2: &mut Buffer2) -> i32 {
if b2.bits_to_go == 0 {
b2.buffer2 = infile.get_u8() as i32;
b2.bits_to_go = 8;
}
b2.bits_to_go -= 1;
(b2.buffer2 >> b2.bits_to_go) & 1
}
fn input_nbits(infile: &mut Cursor<&[u8]>, n: usize, b2: &mut Buffer2) -> i32 {
let mask: [i32; 9] = [0, 1, 3, 7, 15, 31, 63, 127, 255];
if b2.bits_to_go < n as i32 {
b2.buffer2 = (b2.buffer2 << 8) | infile.get_u8() as i32;
b2.bits_to_go += 8;
}
b2.bits_to_go -= n as i32;
(b2.buffer2 >> b2.bits_to_go) & (mask[n])
}
fn input_nybble(infile: &mut Cursor<&[u8]>, b2: &mut Buffer2) -> i32 {
if b2.bits_to_go < 4 {
b2.buffer2 = (b2.buffer2 << 8) | infile.get_u8() as i32;
b2.bits_to_go += 8;
}
b2.bits_to_go -= 4;
(b2.buffer2 >> b2.bits_to_go) & 15
}
fn input_nnybble(infile: &mut Cursor<&[u8]>, n: usize, array: &mut [u8], b2: &mut Buffer2) -> i32 {
let mut _ii: usize;
if n == 1 {
array[0] = input_nybble(infile, b2) as u8;
return 0;
}
if b2.bits_to_go == 8 {
infile.set_position(infile.position() - 1);
b2.bits_to_go = 0;
}
let shift1: i32 = b2.bits_to_go + 4; let shift2: i32 = b2.bits_to_go; let mut kk: usize = 0;
if b2.bits_to_go == 0 {
for _ii in 0..(n / 2) {
b2.buffer2 = (b2.buffer2 << 8) | infile.get_u8() as i32;
array[kk] = ((b2.buffer2 >> 4) & 15) as u8;
array[kk + 1] = ((b2.buffer2) & 15) as u8; kk += 2;
}
} else {
for _ii in 0..(n / 2) {
b2.buffer2 = (b2.buffer2 << 8) | infile.get_u8() as i32;
array[kk] = ((b2.buffer2 >> shift1) & 15) as u8;
array[kk + 1] = ((b2.buffer2 >> shift2) & 15) as u8;
kk += 2;
}
}
let ii = n / 2;
if ii * 2 != n {
array[n - 1] = input_nybble(infile, b2) as u8;
}
(b2.buffer2 >> b2.bits_to_go) & 15
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fits_decompress() {
let input: [u8; 48] = [
221, 153, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 5, 5, 5, 245,
231, 227, 199, 253, 227, 199, 253, 247, 255, 120, 249, 245, 239, 254, 241, 255, 124,
120, 251, 0, 68, 200,
];
let mut output: Vec<i32> = vec![0; 16];
let mut decoder = HCDecoder::new();
let res = decoder.read(&input, 0, &mut output).unwrap();
assert_eq!(output.len(), 16);
assert_eq!(res.0, 4);
assert_eq!(res.1, 4);
assert_eq!(output, [2, 2, 1, 2, 3, 2, 7, 7, 4, 2, 2, 1, 2, 4, 25, 2]);
assert_eq!(
input,
[
221, 153, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 5, 5, 5,
245, 231, 227, 199, 253, 227, 199, 253, 247, 255, 120, 249, 245, 239, 254, 241,
255, 124, 120, 251, 0, 68, 200
]
);
}
#[test]
fn test_fits_decompress_strange() {
let input: [u8; 101] = [
221, 153, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 109, 64,
16, 17, 0, 2, 136, 255, 191, 224, 40, 143, 251, 254, 246, 207, 253, 238, 168, 251, 53,
238, 168, 255, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 253, 255,
127, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 178, 255, 239, 251,
217, 127, 247, 178, 253, 151, 255, 127, 222, 234, 143, 186, 163, 255, 123, 170, 62,
234, 143, 186, 163, 238, 168, 255, 192, 100,
];
let mut output: Vec<i32> = vec![0; 10];
let mut decoder = HCDecoder::new();
let res = decoder.read(&input, 0, &mut output).unwrap();
assert_eq!(res.0, 10);
assert_eq!(res.1, 1);
assert_eq!(res.2, 0);
assert_eq!(output.len(), 10);
assert_eq!(output, [-1, -1, -112, -1, 9983, -28528, -112, -1, -1, -1]);
assert_eq!(
input,
[
221, 153, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 109,
64, 16, 17, 0, 2, 136, 255, 191, 224, 40, 143, 251, 254, 246, 207, 253, 238, 168,
251, 53, 238, 168, 255, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247,
253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 178,
255, 239, 251, 217, 127, 247, 178, 253, 151, 255, 127, 222, 234, 143, 186, 163,
255, 123, 170, 62, 234, 143, 186, 163, 238, 168, 255, 192, 100
]
);
}
#[test]
fn test_fits_decompress_strange2() {
let input: [u8; 106] = [
221, 153, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 251, 193, 64,
17, 16, 0, 246, 79, 151, 94, 233, 144, 42, 143, 46, 128, 170, 0, 130, 128, 42, 0, 32,
128, 130, 0, 130, 0, 162, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239,
251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 224, 40, 47, 46,
189, 150, 5, 4, 1, 20, 5, 5, 229, 215, 178, 252, 182, 4, 21, 236, 191, 45, 249, 111,
203, 96, 81, 95, 240, 0, 175, 0,
];
let mut output: Vec<i32> = vec![0; 12];
let mut decoder = HCDecoder::new();
let res = decoder.read(&input, 0, &mut output).unwrap();
assert_eq!(res.0, 12);
assert_eq!(res.1, 1);
assert_eq!(res.2, 0);
assert_eq!(output.len(), 12);
assert_eq!(
output,
[
-1, -1, -9584, -28561, -112, -24321, -1, -1, -1, -9584, -28561, -112
]
);
assert_eq!(
input,
[
221, 153, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 251, 193,
64, 17, 16, 0, 246, 79, 151, 94, 233, 144, 42, 143, 46, 128, 170, 0, 130, 128, 42,
0, 32, 128, 130, 0, 130, 0, 162, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255,
191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191,
224, 40, 47, 46, 189, 150, 5, 4, 1, 20, 5, 5, 229, 215, 178, 252, 182, 4, 21, 236,
191, 45, 249, 111, 203, 96, 81, 95, 240, 0, 175, 0
]
);
}
#[test]
fn test_fits_decompress_strange3() {
let input: [u8; 140] = [
221, 153, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 254, 197, 32,
19, 17, 0, 246, 207, 253, 245, 68, 211, 250, 117, 84, 126, 153, 116, 5, 21, 31, 78,
153, 63, 84, 106, 171, 234, 139, 170, 2, 138, 175, 170, 102, 143, 186, 39, 233, 146,
126, 155, 100, 8, 160, 190, 153, 170, 242, 207, 253, 255, 127, 223, 247, 253, 255, 127,
223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 222, 75,
250, 167, 85, 95, 77, 183, 245, 78, 137, 2, 42, 175, 170, 109, 191, 166, 89, 8, 40,
143, 170, 116, 104, 8, 136, 190, 137, 103, 234, 153, 39, 233, 178, 66, 136, 163, 234,
155, 53, 244, 77, 31, 248, 0, 158, 248,
];
let mut output: Vec<i32> = vec![0; 16];
let mut decoder = HCDecoder::new();
let res = decoder.read(&input, 0, &mut output).unwrap();
assert_eq!(res.0, 16);
assert_eq!(res.1, 1);
assert_eq!(res.2, 0);
assert_eq!(output.len(), 16);
assert_eq!(
output,
[
2570, 28560, -5778, -28528, 28816, 28816, 2671, -246, -1, -28417, -5778, -28528,
28304, -28439, -28528, -5791
]
);
assert_eq!(
input,
[
221, 153, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 254, 197,
32, 19, 17, 0, 246, 207, 253, 245, 68, 211, 250, 117, 84, 126, 153, 116, 5, 21, 31,
78, 153, 63, 84, 106, 171, 234, 139, 170, 2, 138, 175, 170, 102, 143, 186, 39, 233,
146, 126, 155, 100, 8, 160, 190, 153, 170, 242, 207, 253, 255, 127, 223, 247, 253,
255, 127, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 253, 255,
127, 222, 75, 250, 167, 85, 95, 77, 183, 245, 78, 137, 2, 42, 175, 170, 109, 191,
166, 89, 8, 40, 143, 170, 116, 104, 8, 136, 190, 137, 103, 234, 153, 39, 233, 178,
66, 136, 163, 234, 155, 53, 244, 77, 31, 248, 0, 158, 248
]
);
}
#[test]
fn test_fits_decompress_strange4() {
let input: [u8; 154] = [
221, 153, 0, 0, 0, 82, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 253, 245, 0,
18, 14, 0, 246, 219, 103, 254, 246, 217, 103, 219, 101, 159, 109, 150, 125, 182, 89,
246, 221, 50, 79, 182, 233, 209, 100, 10, 32, 136, 130, 0, 160, 160, 128, 0, 136, 35,
221, 55, 69, 146, 91, 247, 77, 209, 100, 150, 253, 211, 117, 76, 146, 91, 126, 233,
186, 166, 104, 150, 232, 251, 167, 84, 203, 44, 151, 79, 217, 116, 232, 183, 236, 179,
76, 255, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127,
223, 247, 253, 255, 121, 101, 183, 255, 127, 223, 247, 211, 166, 106, 137, 162, 219,
166, 89, 108, 159, 251, 254, 255, 191, 239, 251, 254, 255, 189, 211, 102, 139, 166, 89,
255, 128, 141, 59, 83, 9, 0,
];
let mut output: Vec<i32> = vec![0; 82];
let mut decoder = HCDecoder::new();
let res = decoder.read(&input, 0, &mut output).unwrap();
assert_eq!(res.0, 82);
assert_eq!(res.1, 1);
assert_eq!(res.2, 0);
assert_eq!(output.len(), 82);
assert_eq!(
output,
[
-1, -1, 1, -256, -1, 0, 0, 0, 0, 0, -256, 1, -256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 255, 0, 0, 0, 0, -256, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, -256, -4097, -1,
]
);
assert_eq!(
input,
[
221, 153, 0, 0, 0, 82, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 253, 245,
0, 18, 14, 0, 246, 219, 103, 254, 246, 217, 103, 219, 101, 159, 109, 150, 125, 182,
89, 246, 221, 50, 79, 182, 233, 209, 100, 10, 32, 136, 130, 0, 160, 160, 128, 0,
136, 35, 221, 55, 69, 146, 91, 247, 77, 209, 100, 150, 253, 211, 117, 76, 146, 91,
126, 233, 186, 166, 104, 150, 232, 251, 167, 84, 203, 44, 151, 79, 217, 116, 232,
183, 236, 179, 76, 255, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247,
253, 255, 127, 223, 247, 253, 255, 121, 101, 183, 255, 127, 223, 247, 211, 166,
106, 137, 162, 219, 166, 89, 108, 159, 251, 254, 255, 191, 239, 251, 254, 255, 189,
211, 102, 139, 166, 89, 255, 128, 141, 59, 83, 9, 0
]
);
}
#[test]
fn test_fits_decompress_strange6() {
let input: [u8; 84] = [
221, 153, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 250, 185, 160,
20, 9, 0, 246, 215, 253, 237, 95, 253, 238, 237, 123, 87, 238, 237, 127, 223, 247, 182,
189, 221, 175, 119, 107, 221, 218, 246, 175, 221, 218, 246, 175, 254, 255, 191, 239,
251, 219, 127, 247, 253, 255, 127, 222, 219, 246, 223, 253, 255, 127, 223, 247, 253,
255, 127, 223, 247, 253, 255, 127, 192, 128,
];
let mut output: Vec<i32> = vec![0; 10];
let mut decoder = HCDecoder::new();
let res = decoder.read(&input, 0, &mut output).unwrap();
assert_eq!(res.0, 1);
assert_eq!(res.1, 10);
assert_eq!(res.2, 0);
assert_eq!(output.len(), 10);
assert_eq!(
output,
[
-28662, -28528, 18761, 18761, 18761, 18761, 18761, 18761, -28528, -28528
]
);
assert_eq!(
input,
[
221, 153, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 0, 255, 255, 255, 255, 255, 250, 185,
160, 20, 9, 0, 246, 215, 253, 237, 95, 253, 238, 237, 123, 87, 238, 237, 127, 223,
247, 182, 189, 221, 175, 119, 107, 221, 218, 246, 175, 221, 218, 246, 175, 254,
255, 191, 239, 251, 219, 127, 247, 253, 255, 127, 222, 219, 246, 223, 253, 255,
127, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 192, 128
]
);
}
#[test]
fn test_fits_decompress_strange7() {
let input: [u8; 146] = [
221, 153, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 31, 28, 0, 246,
255, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239,
251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251, 254,
255, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191,
239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251, 254, 255, 191, 239, 251,
254, 255, 191, 239, 251, 203, 126, 91, 242, 223, 150, 252, 183, 229, 191, 45, 249, 111,
203, 126, 91, 242, 223, 150, 252, 183, 229, 191, 45, 249, 111, 203, 126, 91, 242, 223,
150, 252, 183, 229, 191, 45, 249, 111, 203, 126, 91, 242, 223, 252, 0, 0,
];
let mut output: Vec<i32> = vec![0; 10];
let mut decoder = HCDecoder::new();
let res = decoder.read(&input, 0, &mut output);
assert!(res.is_err());
assert!(res.unwrap_err() == DecodeError::BadFormatCode);
}
#[test]
fn test_decomp_64bit_input1() {
let input: [u8; 32] = [
221, 153, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 255,
191, 239, 127, 240, 0, 0,
];
let mut output: Vec<i32> = vec![0; 4];
let mut decoder = HCDecoder::new();
let res = decoder
.read64(&input, 0, cast_slice_mut(&mut output))
.unwrap();
assert_eq!(res.0, 2);
assert_eq!(res.1, 1);
assert_eq!(res.2, 0);
assert_eq!(output[..2], [0, 1]);
}
#[test]
fn test_qread() {
let input: [u8; 4] = [1, 2, 3, 4];
let mut input_c = Cursor::new(&input[..]);
let mut buffer = [99, 99, 99, 99];
qread(&mut input_c, &mut buffer, 2);
assert_eq!(input_c.position(), 2);
assert_eq!(buffer, [1, 2, 99, 99]);
let mut input_c = Cursor::new(&input[..]);
let mut buffer = [99, 99, 99, 99];
qread(&mut input_c, &mut buffer[2..], 2);
assert_eq!(input_c.position(), 2);
assert_eq!(buffer, [99, 99, 1, 2]);
}
#[test]
fn test_hinv() {
let mut a = [32, 16, -2, 2, 12, 6, 0, -24, 2, 12, -1, -1, 0, 24, 4, -22];
let nx = 4;
let ny = 4;
let smooth = 0;
let scale = 0;
hinv(&mut a[0..], nx, ny, smooth, scale).unwrap();
assert_eq!(a, [2, 2, 1, 2, 3, 2, 7, 7, 4, 2, 2, 1, 2, 4, 25, 2]);
}
#[test]
fn test_qtree_bitins() {
let mut a = [0, 2, 0, 0];
let nx = 6;
let ny = 1;
let mut b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let n = 1;
let bit = 16;
qtree_bitins(&mut a, nx, ny, &mut b, n, bit);
let expected = [0, 0, 0, 65536, 0, 0, 0, 0, 0, 0, 0, 0];
assert_eq!(b, expected);
}
#[test]
fn test_input_nnybble() {
let n = 4;
let mut array = [0, 10, 8, 0];
let mut b2 = Buffer2 {
bits_to_go: 5,
buffer2: 2123985925,
};
let input: [u8; 140] = [
221, 153, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 255, 255, 255, 255, 255, 254, 197, 32,
19, 17, 0, 246, 207, 253, 245, 68, 211, 250, 117, 84, 126, 153, 116, 5, 21, 31, 78,
153, 63, 84, 106, 171, 234, 139, 170, 2, 138, 175, 170, 102, 143, 186, 39, 233, 146,
126, 155, 100, 8, 160, 190, 153, 170, 242, 207, 253, 255, 127, 223, 247, 253, 255, 127,
223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 223, 247, 253, 255, 127, 222, 75,
250, 167, 85, 95, 77, 183, 245, 78, 137, 2, 42, 175, 170, 109, 191, 166, 89, 8, 40,
143, 170, 116, 104, 8, 136, 190, 137, 103, 234, 153, 39, 233, 178, 66, 136, 163, 234,
155, 53, 244, 77, 31, 248, 0, 158, 248,
];
let mut infile = Cursor::new(&input[..]);
infile.set_position(38);
let res = input_nnybble(&mut infile, n, &mut array, &mut b2);
assert_eq!(res, 8);
assert_eq!(b2.bits_to_go, 5);
assert_eq!(b2.buffer2, 1946490143);
assert_eq!(array, [2, 8, 10, 8]);
}
}