Fix decompress function
This commit is contained in:
parent
8ea134e008
commit
5eac451458
@ -4,3 +4,4 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
num = "0.4.3"
|
||||||
|
|||||||
@ -32,7 +32,21 @@ impl BitWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Poppable {
|
impl Into<Vec<u8>> for BitWriter {
|
||||||
|
fn into(self) -> Vec<u8> {
|
||||||
|
self.flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl IntoIterator for BitWriter {
|
||||||
|
type Item = u8;
|
||||||
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.flush().into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Poppable {
|
||||||
fn pop(&mut self) -> Option<u8>;
|
fn pop(&mut self) -> Option<u8>;
|
||||||
}
|
}
|
||||||
impl Poppable for &[u8] {
|
impl Poppable for &[u8] {
|
||||||
|
|||||||
@ -11,13 +11,11 @@ use crate::bit_buffer::{BitWriter, Poppable};
|
|||||||
|
|
||||||
trait Digits {
|
trait Digits {
|
||||||
const PRECISION: usize;
|
const PRECISION: usize;
|
||||||
fn as_byte(&self) -> u8;
|
|
||||||
}
|
}
|
||||||
macro_rules! unsignedImplDigits {
|
macro_rules! unsignedImplDigits {
|
||||||
($($type: ident),*) => { $(
|
($($type: ident),*) => { $(
|
||||||
impl Digits for $type {
|
impl Digits for $type {
|
||||||
const PRECISION: usize = (std::mem::size_of::<$type>() * 8);
|
const PRECISION: usize = (std::mem::size_of::<$type>() * 8);
|
||||||
fn as_byte(&self) -> u8 {*self as u8}
|
|
||||||
}
|
}
|
||||||
)* };
|
)* };
|
||||||
}
|
}
|
||||||
@ -25,12 +23,11 @@ macro_rules! signedImplDigits {
|
|||||||
($($type: ident),*) => { $(
|
($($type: ident),*) => { $(
|
||||||
impl Digits for $type {
|
impl Digits for $type {
|
||||||
const PRECISION: usize = (std::mem::size_of::<$type>() * 8) - 1;
|
const PRECISION: usize = (std::mem::size_of::<$type>() * 8) - 1;
|
||||||
fn as_byte(&self) -> u8 {*self as u8}
|
|
||||||
}
|
}
|
||||||
)* };
|
)* };
|
||||||
}
|
}
|
||||||
unsignedImplDigits!(u16, u32, u64, u128);
|
unsignedImplDigits!(u32, u64);
|
||||||
signedImplDigits!(i16, i32, i64, i128);
|
signedImplDigits!(i32, i64, i128);
|
||||||
|
|
||||||
pub trait Metrics:
|
pub trait Metrics:
|
||||||
Integer + FromPrimitive + Copy + BitAnd<Output = Self> + Shl<Output = Self>
|
Integer + FromPrimitive + Copy + BitAnd<Output = Self> + Shl<Output = Self>
|
||||||
@ -39,15 +36,17 @@ pub trait Metrics:
|
|||||||
|
|
||||||
const FREQUENCY_BITS: usize = (Self::PRECISION / 2) - 1;
|
const FREQUENCY_BITS: usize = (Self::PRECISION / 2) - 1;
|
||||||
const CODE_VALUE_BITS: usize = Self::FREQUENCY_BITS + 2;
|
const CODE_VALUE_BITS: usize = Self::FREQUENCY_BITS + 2;
|
||||||
const MAX_CODE: usize = (1 << Self::CODE_VALUE_BITS) - 1;
|
const MAX_CODE: usize = if Self::CODE_VALUE_BITS == 64 {
|
||||||
|
u64::MAX as usize
|
||||||
|
} else {
|
||||||
|
(1 << Self::CODE_VALUE_BITS) - 1
|
||||||
|
};
|
||||||
const MAX_FREQ: usize = (1 << Self::FREQUENCY_BITS) - 1;
|
const MAX_FREQ: usize = (1 << Self::FREQUENCY_BITS) - 1;
|
||||||
|
|
||||||
const ONE_FOURTH: usize = 1 << (Self::CODE_VALUE_BITS - 2);
|
const ONE_FOURTH: usize = 1 << (Self::CODE_VALUE_BITS - 2);
|
||||||
const ONE_HALF: usize = 2 * Self::ONE_FOURTH;
|
const ONE_HALF: usize = 2 * Self::ONE_FOURTH;
|
||||||
const THREE_FOURTHS: usize = 3 * Self::ONE_FOURTH;
|
const THREE_FOURTHS: usize = 3 * Self::ONE_FOURTH;
|
||||||
|
|
||||||
fn as_byte(&self) -> u8;
|
|
||||||
|
|
||||||
fn print_metrics() {
|
fn print_metrics() {
|
||||||
println!("--------- Metrics ---------");
|
println!("--------- Metrics ---------");
|
||||||
println!(" PRECISION: {}", Self::PRECISION);
|
println!(" PRECISION: {}", Self::PRECISION);
|
||||||
@ -64,26 +63,8 @@ impl<T: Digits + Integer + FromPrimitive + Copy + BitAnd<Output = Self> + Shl<Ou
|
|||||||
Metrics for T
|
Metrics for T
|
||||||
{
|
{
|
||||||
const PRECISION: usize = T::PRECISION;
|
const PRECISION: usize = T::PRECISION;
|
||||||
fn as_byte(&self) -> u8 {
|
|
||||||
self.as_byte()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
const PRECISION: u32 = 32;
|
|
||||||
|
|
||||||
// 15 bits for frequency count
|
|
||||||
const FREQUENCY_BITS: u32 = (PRECISION / 2) - 1;
|
|
||||||
// 17 bits for CODE_VALUE
|
|
||||||
const VALUE_BITS: u32 = FREQUENCY_BITS + 2;
|
|
||||||
|
|
||||||
const MAX_CODE: u32 = !((!0) << VALUE_BITS);
|
|
||||||
const MAX_FREQ: u32 = !((!0) << FREQUENCY_BITS);
|
|
||||||
const HALF: u32 = 1 << (VALUE_BITS - 1);
|
|
||||||
const LOW_CONVERGE: u32 = 0b10 << (VALUE_BITS - 2);
|
|
||||||
const HIGH_CONVERGE: u32 = 0b01 << (VALUE_BITS - 2);
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Prob<T> {
|
struct Prob<T> {
|
||||||
low: T,
|
low: T,
|
||||||
@ -123,13 +104,11 @@ impl<'a> InputBits<'a> {
|
|||||||
} else {
|
} else {
|
||||||
self.last_mask >>= 1;
|
self.last_mask >>= 1;
|
||||||
}
|
}
|
||||||
return (self.current_byte & self.last_mask) != 0;
|
let bit = (self.current_byte & self.last_mask) != 0;
|
||||||
|
return bit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: use unified trait
|
|
||||||
//trait CodeValue: Metrics + Integer + Into<u8> {}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub struct ModelA<CODE_VALUE> {
|
pub struct ModelA<CODE_VALUE> {
|
||||||
@ -151,7 +130,6 @@ impl<T: Metrics> Default for ModelA<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
impl<CODE_VALUE: Metrics + Display> ModelA<CODE_VALUE> {
|
impl<CODE_VALUE: Metrics + Display> ModelA<CODE_VALUE> {
|
||||||
@ -220,7 +198,7 @@ impl<CODE_VALUE: Metrics + Display> ModelA<CODE_VALUE> {
|
|||||||
if c > 255 || c < 0 {
|
if c > 255 || c < 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
output.push(value.as_byte());
|
output.push(c as u8);
|
||||||
high = low + (range * p.high) / p.total - ONE;
|
high = low + (range * p.high) / p.total - ONE;
|
||||||
low = low + (range * p.low) / p.total;
|
low = low + (range * p.low) / p.total;
|
||||||
loop {
|
loop {
|
||||||
@ -261,8 +239,6 @@ impl<CODE_VALUE: Metrics + Display> ModelA<CODE_VALUE> {
|
|||||||
for mut c in input.iter().map(|b| *b as i32).chain([256_i32]) {
|
for mut c in input.iter().map(|b| *b as i32).chain([256_i32]) {
|
||||||
if c > 255 || c < 0 {
|
if c > 255 || c < 0 {
|
||||||
c = 256;
|
c = 256;
|
||||||
} else {
|
|
||||||
println!("c: '{}'", c as u8 as char);
|
|
||||||
}
|
}
|
||||||
let p = self.getProbability(c);
|
let p = self.getProbability(c);
|
||||||
let range: CODE_VALUE = high - low + ONE;
|
let range: CODE_VALUE = high - low + ONE;
|
||||||
@ -288,7 +264,6 @@ impl<CODE_VALUE: Metrics + Display> ModelA<CODE_VALUE> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("EOF");
|
|
||||||
pending_bits += 1;
|
pending_bits += 1;
|
||||||
if low < ONE_FORTH {
|
if low < ONE_FORTH {
|
||||||
Self::write_with_pending(false, &mut pending_bits, &mut output);
|
Self::write_with_pending(false, &mut pending_bits, &mut output);
|
||||||
@ -296,16 +271,13 @@ impl<CODE_VALUE: Metrics + Display> ModelA<CODE_VALUE> {
|
|||||||
Self::write_with_pending(true, &mut pending_bits, &mut output);
|
Self::write_with_pending(true, &mut pending_bits, &mut output);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("");
|
|
||||||
return output.into();
|
return output.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_with_pending(bit: bool, pending: &mut i32, output: &mut BitWriter) {
|
fn write_with_pending(bit: bool, pending: &mut i32, output: &mut BitWriter) {
|
||||||
print!("{}\n", if bit { "1" } else { "0" });
|
|
||||||
output.write(bit);
|
output.write(bit);
|
||||||
for _ in 0..*pending {
|
for _ in 0..*pending {
|
||||||
output.write(!bit);
|
output.write(!bit);
|
||||||
print!("{}\n", if !bit { "1" } else { "0" });
|
|
||||||
}
|
}
|
||||||
*pending = 0;
|
*pending = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user