Skip to content

Commit

Permalink
Alternative API with only a single generic argument for BitTree
Browse files Browse the repository at this point in the history
  • Loading branch information
chyyran committed Aug 9, 2022
1 parent 2587208 commit 37e09d1
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 26 deletions.
4 changes: 2 additions & 2 deletions src/decode/lzma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ pub(crate) struct DecoderState {
pub(crate) lzma_props: LzmaProperties,
unpacked_size: Option<u64>,
literal_probs: Vec2D<u16>,
pos_slot_decoder: [BitTree<6, { bittree_probs_len::<6>() }>; 4],
align_decoder: BitTree<4, { bittree_probs_len::<4>() }>,
pos_slot_decoder: [BitTree<{ bittree_probs_len::<6>() }>; 4],
align_decoder: BitTree<{ bittree_probs_len::<4>() }>,
pos_decoders: [u16; 115],
is_match: [u16; 192], // true = LZ, false = literal
is_rep: [u16; 12],
Expand Down
31 changes: 9 additions & 22 deletions src/decode/rangecoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,62 +150,49 @@ where
}
}

/// macro for compile-time const assertions
macro_rules! const_assert {
($($list:ident : $ty:ty),* => $expr:expr) => {{
struct Assert<$(const $list: $ty,)*>;
impl<$(const $list: $ty,)*> Assert<$($list,)*> {
const OK: u8 = 0 - !($expr) as u8;
}
Assert::<$($list,)*>::OK
}};
($expr:expr) => {
const OK: u8 = 0 - !($expr) as u8;
};
}

// const fn helper to parameterize the length of the bittree probability array.
pub const fn bittree_probs_len<const NUM_BITS: usize>() -> usize {
1 << NUM_BITS
}

#[derive(Debug, Clone)]
pub struct BitTree<const NUM_BITS: usize, const PROBS_ARRAY_LEN: usize> {
pub struct BitTree<const PROBS_ARRAY_LEN: usize> {
probs: [u16; PROBS_ARRAY_LEN],
}

impl<const NUM_BITS: usize, const PROBS_ARRAY_LEN: usize> BitTree<NUM_BITS, PROBS_ARRAY_LEN> {
impl<const PROBS_ARRAY_LEN: usize> BitTree<PROBS_ARRAY_LEN> {
pub fn new() -> Self {
const_assert!(NUM_BITS: usize, PROBS_ARRAY_LEN: usize => PROBS_ARRAY_LEN == bittree_probs_len::<NUM_BITS>());
BitTree {
probs: [0x400; PROBS_ARRAY_LEN],
}
}

const NUM_BITS: usize = PROBS_ARRAY_LEN.trailing_zeros() as usize;

pub fn parse<R: io::BufRead>(
&mut self,
rangecoder: &mut RangeDecoder<R>,
update: bool,
) -> io::Result<u32> {
rangecoder.parse_bit_tree(NUM_BITS, &mut self.probs, update)
rangecoder.parse_bit_tree(Self::NUM_BITS, &mut self.probs, update)
}

pub fn parse_reverse<R: io::BufRead>(
&mut self,
rangecoder: &mut RangeDecoder<R>,
update: bool,
) -> io::Result<u32> {
rangecoder.parse_reverse_bit_tree(NUM_BITS, &mut self.probs, 0, update)
rangecoder.parse_reverse_bit_tree(Self::NUM_BITS, &mut self.probs, 0, update)
}
}

#[derive(Debug)]
pub struct LenDecoder {
choice: u16,
choice2: u16,
low_coder: [BitTree<3, { bittree_probs_len::<3>() }>; 16],
mid_coder: [BitTree<3, { bittree_probs_len::<3>() }>; 16],
high_coder: BitTree<8, { bittree_probs_len::<8>() }>,
low_coder: [BitTree<{ bittree_probs_len::<3>() }>; 16],
mid_coder: [BitTree<{ bittree_probs_len::<3>() }>; 16],
high_coder: BitTree<{ bittree_probs_len::<8>() }>,
}

impl LenDecoder {
Expand Down
4 changes: 2 additions & 2 deletions src/encode/rangecoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ mod test {

let mut bufread = BufReader::new(buf.as_slice());
let mut decoder = RangeDecoder::new(&mut bufread).unwrap();
let mut tree = decode::rangecoder::BitTree::<NUM_BITS, PROBS_LEN>::new();
let mut tree = decode::rangecoder::BitTree::<PROBS_LEN>::new();
for &v in values {
assert_eq!(tree.parse(&mut decoder, true).unwrap(), v);
}
Expand Down Expand Up @@ -313,7 +313,7 @@ mod test {

let mut bufread = BufReader::new(buf.as_slice());
let mut decoder = RangeDecoder::new(&mut bufread).unwrap();
let mut tree = decode::rangecoder::BitTree::<NUM_BITS, PROBS_LEN>::new();
let mut tree = decode::rangecoder::BitTree::<PROBS_LEN>::new();
for &v in values {
assert_eq!(tree.parse_reverse(&mut decoder, true).unwrap(), v);
}
Expand Down

0 comments on commit 37e09d1

Please sign in to comment.