aboutsummaryrefslogtreecommitdiff
path: root/lvc/src/huff.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lvc/src/huff.rs')
-rw-r--r--lvc/src/huff.rs39
1 files changed, 22 insertions, 17 deletions
diff --git a/lvc/src/huff.rs b/lvc/src/huff.rs
index b21d38d..b00aaa0 100644
--- a/lvc/src/huff.rs
+++ b/lvc/src/huff.rs
@@ -6,9 +6,8 @@ enum HT {
Terminal(u8),
}
-pub fn write_huffman(buf: &[u8], w: &mut impl Write) -> Result<usize> {
+pub fn write_huff(buf: &[u8], w: &mut impl Write) -> Result<usize> {
let mut w = BitIO::new(w);
-
assert!(buf.len() <= 0xffffff, "huff frame too big");
w.wbyte((buf.len() & 0xff) as u8)?;
w.wbyte(((buf.len() >> 8) & 0xff) as u8)?;
@@ -26,16 +25,17 @@ pub fn write_huffman(buf: &[u8], w: &mut impl Write) -> Result<usize> {
for b in buf {
let mut k = table[*b as usize];
while k != 1 {
- w.wbit((k & 1) != 0)?;
+ w.wbit((k & 1) == 1)?;
k >>= 1;
}
}
-
+
w.flush()?;
+ eprintln!("{}", w.position);
Ok(w.position)
}
-pub fn read_huffman(r: &mut impl Read, buf: &mut Vec<u8>) -> Result<usize> {
+pub fn read_huff(r: &mut impl Read, buf: &mut Vec<u8>) -> Result<usize> {
let mut r = BitIO::new(r);
let mut len = 0usize;
@@ -43,29 +43,30 @@ pub fn read_huffman(r: &mut impl Read, buf: &mut Vec<u8>) -> Result<usize> {
len |= (r.rbyte()? as usize) << 8;
len |= (r.rbyte()? as usize) << 16;
- eprintln!("{len:?}");
+ eprintln!("len={len:?}");
let root = HT::read(&mut r)?;
- eprintln!("{root:?}");
+ // eprintln!("{root:?}");
let root = match &root {
HT::Branch(a, b) => [a, b],
_ => panic!("no!"),
};
- let mut cn = root;
- for _ in 0..len * 8 {
+ let mut cursor = root;
+ while buf.len() != len {
let v = r.rbit()?;
- match cn[v as usize].as_ref() {
+ match cursor[v as usize].as_ref() {
HT::Branch(a, b) => {
- cn = [a, b];
+ cursor = [a, b];
}
HT::Terminal(n) => {
buf.push(*n);
- cn = root;
+ cursor = root;
}
}
}
-
- Ok(len)
+ eprintln!("len(buf)={}", buf.len());
+ eprintln!("{}", r.position);
+ Ok(r.position)
}
impl HT {
@@ -83,12 +84,16 @@ impl HT {
}
parts[0].1.clone()
}
- pub fn create_lut(&self, table: &mut [u32; 256], prefix: u32) {
+ pub fn create_lut(&self, table: &mut [u32; 256], mut prefix: u32) {
assert!(self.depth() < 30, "too deep! doesnt fit {}", self.depth());
match self {
HT::Branch(a, b) => {
- a.create_lut(table, (prefix << 1) | 0);
- b.create_lut(table, (prefix << 1) | 1);
+ let pz = 32 - prefix.leading_zeros();
+ prefix ^= 1 << pz;
+ prefix ^= 1 << (pz - 1);
+ a.create_lut(table, prefix);
+ prefix ^= 1 << (pz - 1);
+ b.create_lut(table, prefix);
}
HT::Terminal(n) => {
assert_eq!(table[*n as usize], 0);