Fix decompress function

This commit is contained in:
Lucas Schumacher 2024-09-07 01:14:28 -04:00
parent 8ea134e008
commit 5eac451458
3 changed files with 26 additions and 39 deletions

View File

@ -4,3 +4,4 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
num = "0.4.3"

View File

@ -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] {

View File

@ -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,25 +63,7 @@ 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> {
@ -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;
} }