const NONZERO_COUNT: [i32; 256] = [
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
];
#[derive(Debug)]
enum RICEState {
Start,
FS {
b: u32,
i: i32,
lastpix: i32,
nbits: i32,
},
LowEntropyDecoding {
b: u32,
i: i32,
imax: i32,
lastpix: i32,
nbits: i32,
},
HighEntropyDecoding {
b: u32,
i: i32,
imax: i32,
nbits: i32,
lastpix: i32,
},
RICEDecoding {
b: u32,
fs: i32,
i: i32,
imax: i32,
lastpix: i32,
nbits: i32,
},
}
use std::marker::PhantomData;
#[derive(Debug)]
pub(crate) struct RICEDecoder<R, T> {
pub reader: R,
state: RICEState,
nblock: i32,
nx: i32,
_t: PhantomData<T>,
}
impl<R, T> RICEDecoder<R, T> {
pub(crate) fn new(reader: R, nblock: i32, nx: i32) -> Self {
Self {
reader,
state: RICEState::Start,
nblock,
nx,
_t: PhantomData,
}
}
}
use std::io::Error;
use std::io::Read;
trait FromBytes {
fn from_be_bytes<R: Read>(reader: &mut R) -> Result<Self, Error>
where
Self: Sized;
}
impl FromBytes for u8 {
fn from_be_bytes<R: Read>(reader: &mut R) -> Result<Self, Error> {
reader.read_u8()
}
}
impl FromBytes for i16 {
fn from_be_bytes<R: Read>(reader: &mut R) -> Result<Self, Error> {
reader.read_i16::<BigEndian>()
}
}
impl FromBytes for i32 {
fn from_be_bytes<R: Read>(reader: &mut R) -> Result<Self, Error> {
reader.read_i32::<BigEndian>()
}
}
trait RICE: Sized + Into<i32> + FromBytes {
const FSBITS: i32;
const FSMAX: i32;
const BBITS: i32 = 1 << Self::FSBITS;
fn size_of() -> usize {
std::mem::size_of::<Self>()
}
}
impl RICE for u8 {
const FSBITS: i32 = 3;
const FSMAX: i32 = 6;
}
impl RICE for i16 {
const FSBITS: i32 = 4;
const FSMAX: i32 = 14;
}
impl RICE for i32 {
const FSBITS: i32 = 5;
const FSMAX: i32 = 25;
}
use byteorder::BigEndian;
use byteorder::ReadBytesExt;
impl<R, T> Read for RICEDecoder<R, T>
where
R: Read,
T: RICE,
{
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let mut j = 0;
loop {
match self.state {
RICEState::Start => {
let lastpix = T::from_be_bytes(&mut self.reader)?.into();
let b = self.reader.read_u8()? as u32;
let nbits = 8;
let i = 0;
self.state = RICEState::FS {
nbits,
b,
i,
lastpix,
};
}
RICEState::FS {
mut nbits,
mut b,
i,
lastpix,
} => {
nbits -= T::FSBITS;
while nbits < 0 {
b = (b << 8) | (self.reader.read_u8()? as u32);
nbits += 8;
}
let fs = (b >> nbits) as i32 - 1;
b &= (1 << nbits) - 1;
let imax = (i + self.nblock).min(self.nx);
self.state = if fs < 0 {
RICEState::LowEntropyDecoding {
i,
lastpix,
imax,
b,
nbits,
}
} else if fs == T::FSMAX {
RICEState::HighEntropyDecoding {
i,
b,
nbits,
lastpix,
imax,
}
} else {
RICEState::RICEDecoding {
i,
nbits,
b,
fs,
lastpix,
imax,
}
}
}
RICEState::LowEntropyDecoding {
b,
nbits,
mut i,
lastpix,
imax,
} => {
while j < buf.len() && i < imax {
buf[j..(j + T::size_of())]
.copy_from_slice(&lastpix.to_ne_bytes()[..T::size_of()]);
j += T::size_of();
i += 1;
}
if i == imax {
self.state = RICEState::FS {
nbits,
b,
i,
lastpix,
}
}
if j == buf.len() {
return Ok(j);
}
}
RICEState::HighEntropyDecoding {
nbits,
mut b,
mut i,
mut lastpix,
imax,
} => {
while j < buf.len() && i < imax {
let mut k = T::BBITS - nbits;
let mut diff = ((b as u64) << k) as u32;
k -= 8;
while k >= 0 {
b = self.reader.read_u8()? as u32;
diff |= b << k;
k -= 8;
}
if nbits > 0 {
b = self.reader.read_u8()? as u32;
diff |= b >> (-k);
b &= (1 << nbits) - 1;
} else {
b = 0;
}
if (diff & 1) == 0 {
diff >>= 1;
} else {
diff = !(diff >> 1);
}
let curpix = (diff as i32) + lastpix;
buf[j..(j + T::size_of())]
.copy_from_slice(&curpix.to_ne_bytes()[..T::size_of()]);
lastpix = curpix;
i += 1;
j += T::size_of();
}
if i == imax {
self.state = RICEState::FS {
nbits,
b,
i,
lastpix,
}
}
if j == buf.len() {
return Ok(j);
}
}
RICEState::RICEDecoding {
mut nbits,
mut b,
mut i,
mut lastpix,
fs,
imax,
} => {
while j < buf.len() && i < imax {
while b == 0 {
nbits += 8;
b = self.reader.read_u8()? as u32;
}
let nzero = nbits - NONZERO_COUNT[b as usize];
nbits -= nzero + 1;
b ^= 1 << nbits;
nbits -= fs;
while nbits < 0 {
b = (b << 8) | (self.reader.read_u8()? as u32);
nbits += 8;
}
let mut diff = ((nzero as u32) << fs) | (b >> nbits);
b &= (1 << nbits) - 1;
if (diff & 1) == 0 {
diff >>= 1;
} else {
diff = !(diff >> 1);
}
let curpix = (diff as i32) + lastpix;
buf[j..(j + T::size_of())]
.copy_from_slice(&curpix.to_ne_bytes()[..T::size_of()]);
lastpix = curpix;
i += 1;
j += T::size_of();
}
if i == imax {
self.state = RICEState::FS {
nbits,
b,
i,
lastpix,
}
}
if j == buf.len() {
return Ok(j);
}
}
}
}
}
}