#![cfg_attr(docsrs, doc(cfg(feature = "rangecoder")))]
extern crate alloc;
use alloc::vec::Vec;
use crate::error::Error;
use crate::traits::{Algorithm, RawDecoder, RawEncoder, RawProgress};
const TREE_NODES: usize = 256;
const PROB_INIT: u16 = 1 << 10;
const PROB_BITS: u32 = 11;
const MOVE_BITS: u32 = 5;
const TOP: u32 = 1 << 24;
#[derive(Debug, Clone, Copy, Default)]
pub struct RangeCoder;
impl Algorithm for RangeCoder {
const NAME: &'static str = "range";
type Encoder = Encoder;
type Decoder = Decoder;
type EncoderConfig = ();
type DecoderConfig = ();
fn encoder_with(_: ()) -> Encoder {
Encoder::new()
}
fn decoder_with(_: ()) -> Decoder {
Decoder::new()
}
}
#[derive(Debug, Clone)]
struct Model {
probs: [u16; TREE_NODES],
}
impl Model {
fn new() -> Self {
Self {
probs: [PROB_INIT; TREE_NODES],
}
}
}
#[derive(Debug)]
pub struct Encoder {
input: Vec<u8>,
out: Vec<u8>,
head: usize,
finished: bool,
}
impl Encoder {
pub fn new() -> Self {
Self {
input: Vec::new(),
out: Vec::new(),
head: 0,
finished: false,
}
}
fn encode_all(&mut self) {
self.out.clear();
self.out
.extend_from_slice(&(self.input.len() as u64).to_le_bytes());
if self.input.is_empty() {
return;
}
let mut rc = RangeEncoder::new();
let mut model = Model::new();
let input = core::mem::take(&mut self.input);
self.out.reserve(input.len() + 16);
rc.encode_bytes(&mut self.out, &mut model.probs, &input);
rc.flush(&mut self.out);
self.input = input;
}
fn drain(&mut self, output: &mut [u8]) -> usize {
let avail = self.out.len() - self.head;
let n = avail.min(output.len());
output[..n].copy_from_slice(&self.out[self.head..self.head + n]);
self.head += n;
n
}
}
impl Default for Encoder {
fn default() -> Self {
Self::new()
}
}
impl RawEncoder for Encoder {
fn raw_encode(&mut self, input: &[u8], _output: &mut [u8]) -> Result<RawProgress, Error> {
self.input.extend_from_slice(input);
Ok(RawProgress {
consumed: input.len(),
written: 0,
done: false,
})
}
fn raw_finish(&mut self, output: &mut [u8]) -> Result<RawProgress, Error> {
if !self.finished {
self.encode_all();
self.finished = true;
}
let written = self.drain(output);
let done = self.head >= self.out.len();
Ok(RawProgress {
consumed: 0,
written,
done,
})
}
fn raw_reset(&mut self) {
self.input.clear();
self.out.clear();
self.head = 0;
self.finished = false;
}
}
struct RangeEncoder {
low: u64,
range: u32,
cache: u8,
cache_size: u64,
}
impl RangeEncoder {
fn new() -> Self {
Self {
low: 0,
range: 0xFFFF_FFFF,
cache: 0,
cache_size: 1,
}
}
#[inline]
fn encode_bytes(&mut self, out: &mut Vec<u8>, probs: &mut [u16; TREE_NODES], input: &[u8]) {
let mut range = self.range;
let mut low = self.low;
for &byte in input {
let mut node = 1usize;
let mut b = byte;
for _ in 0..8 {
let bit = (b >> 7) as u32; b <<= 1;
let slot = node & (TREE_NODES - 1);
let p = probs[slot];
let bound = (range >> PROB_BITS) * (p as u32);
if bit == 0 {
range = bound;
probs[slot] = p + (((1u16 << PROB_BITS) - p) >> MOVE_BITS);
} else {
low += bound as u64;
range -= bound;
probs[slot] = p - (p >> MOVE_BITS);
}
node = (node << 1) | (bit as usize);
while range < TOP {
range <<= 8;
self.shift_low(out, &mut low);
}
}
}
self.range = range;
self.low = low;
}
#[inline]
fn shift_low(&mut self, out: &mut Vec<u8>, low: &mut u64) {
if *low < 0xFF00_0000 || *low > 0xFFFF_FFFF {
let carry = (*low >> 32) as u8;
let mut temp = self.cache;
loop {
out.push(temp.wrapping_add(carry));
temp = 0xFF;
self.cache_size -= 1;
if self.cache_size == 0 {
break;
}
}
self.cache = (*low >> 24) as u8;
}
self.cache_size += 1;
*low = (*low << 8) & 0xFFFF_FFFF;
}
fn flush(&mut self, out: &mut Vec<u8>) {
let mut low = self.low;
for _ in 0..5 {
self.shift_low(out, &mut low);
}
self.low = low;
}
}
#[derive(Debug)]
pub struct Decoder {
input: Vec<u8>,
out: Vec<u8>,
head: usize,
finished: bool,
}
impl Decoder {
pub fn new() -> Self {
Self {
input: Vec::new(),
out: Vec::new(),
head: 0,
finished: false,
}
}
fn decode_all(&mut self) -> Result<(), Error> {
self.out.clear();
if self.input.len() < 8 {
return Err(Error::UnexpectedEnd);
}
let mut len_bytes = [0u8; 8];
len_bytes.copy_from_slice(&self.input[..8]);
let out_len = u64::from_le_bytes(len_bytes);
if out_len == 0 {
if self.input.len() != 8 {
return Err(Error::Corrupt);
}
return Ok(());
}
let payload_len = self.input.len() - 8;
let max_plausible = (payload_len as u64)
.saturating_mul(256)
.saturating_add(1024);
if out_len > max_plausible {
return Err(Error::Corrupt);
}
let out_len = out_len as usize;
self.out.reserve(out_len);
let payload = core::mem::take(&mut self.input);
let result = (|| {
let mut rc = RangeDecoder::new(&payload[8..])?;
let mut model = Model::new();
rc.decode_bytes(&mut model.probs, out_len, &mut self.out)
})();
self.input = payload;
result
}
fn drain(&mut self, output: &mut [u8]) -> usize {
let avail = self.out.len() - self.head;
let n = avail.min(output.len());
output[..n].copy_from_slice(&self.out[self.head..self.head + n]);
self.head += n;
n
}
}
impl Default for Decoder {
fn default() -> Self {
Self::new()
}
}
impl RawDecoder for Decoder {
fn raw_decode(&mut self, input: &[u8], _output: &mut [u8]) -> Result<RawProgress, Error> {
self.input.extend_from_slice(input);
Ok(RawProgress {
consumed: input.len(),
written: 0,
done: false,
})
}
fn raw_finish(&mut self, output: &mut [u8]) -> Result<RawProgress, Error> {
if !self.finished {
self.decode_all()?;
self.finished = true;
}
let written = self.drain(output);
let done = self.head >= self.out.len();
Ok(RawProgress {
consumed: 0,
written,
done,
})
}
fn raw_reset(&mut self) {
self.input.clear();
self.out.clear();
self.head = 0;
self.finished = false;
}
}
struct RangeDecoder<'a> {
payload: &'a [u8],
pos: usize,
range: u32,
code: u32,
overran: bool,
}
impl<'a> RangeDecoder<'a> {
fn new(payload: &'a [u8]) -> Result<Self, Error> {
if payload.len() < 5 {
return Err(Error::UnexpectedEnd);
}
let mut d = Self {
payload,
pos: 1,
range: 0xFFFF_FFFF,
code: 0,
overran: false,
};
for _ in 0..4 {
d.code = (d.code << 8) | d.next_byte() as u32;
}
Ok(d)
}
#[inline]
fn next_byte(&mut self) -> u8 {
match self.payload.get(self.pos) {
Some(&b) => {
self.pos += 1;
b
}
None => {
self.pos += 1;
self.overran = true;
0
}
}
}
fn decode_bytes(
&mut self,
probs: &mut [u16; TREE_NODES],
out_len: usize,
out: &mut Vec<u8>,
) -> Result<(), Error> {
let mut range = self.range;
let mut code = self.code;
let mut pos = self.pos;
let payload = self.payload;
out.reserve(out_len);
for _ in 0..out_len {
let mut node = 1usize;
for _ in 0..8 {
let slot = node & (TREE_NODES - 1);
let p = probs[slot];
let bound = (range >> PROB_BITS) * (p as u32);
let bit;
if code < bound {
range = bound;
probs[slot] = p + (((1u16 << PROB_BITS) - p) >> MOVE_BITS);
bit = 0usize;
} else {
code -= bound;
range -= bound;
probs[slot] = p - (p >> MOVE_BITS);
bit = 1usize;
}
node = (node << 1) | bit;
while range < TOP {
range <<= 8;
let b = match payload.get(pos) {
Some(&b) => b,
None => {
self.overran = true;
0
}
};
pos += 1;
code = (code << 8) | b as u32;
}
}
if self.overran {
self.range = range;
self.code = code;
self.pos = pos;
return Err(Error::UnexpectedEnd);
}
out.push((node & 0xFF) as u8);
}
self.range = range;
self.code = code;
self.pos = pos;
Ok(())
}
}
#[cfg(test)]
mod tests;