-impl<'a, 'b> BoolEncoder<'a, 'b> {
- pub fn new(bw: &'a mut ByteWriter<'b>) -> Self {
- Self {
- bw,
- val: 0,
- range: 255,
- bits: 0,
- saved: 0,
- run: 0,
- }
- }
- pub fn put_bool(&mut self, bit: bool, prob: u8) -> EncoderResult<()> {
- let split = 1 + (((self.range - 1) * u32::from(prob)) >> 8);
- if bit {
- self.range -= split;
- self.val += split;
- } else {
- self.range = split;
- }
-
- if self.range < 128 {
- self.renorm()?;
- }
- Ok(())
- }
- fn flush_run(&mut self, overflow: bool) -> EncoderResult<()> {
- if self.run > 0 {
- self.bw.write_byte(self.saved + (overflow as u8))?;
- if !overflow {
- for _ in 1..self.run {
- self.bw.write_byte(0xFF)?;
- }
- } else {
- for _ in 1..self.run {
- self.bw.write_byte(0)?;
- }
- }
- self.run = 0;
- }
- Ok(())
- }
- fn renorm(&mut self) -> EncoderResult<()> {
- let bits = (self.range.leading_zeros() & 7) as u8;
- self.range <<= bits;
- if self.bits + bits < 23 {
- self.bits += bits;
- self.val <<= bits;
- } else {
- for _ in 0..bits {
- if (self.bits == 23) && ((self.val >> 31) != 0) {
- self.flush_run(true)?;
- }
- self.val <<= 1;
- self.bits += 1;
- if self.bits == 24 {
- let tbyte = (self.val >> 24) as u8;
- let nbyte = (self.val >> 16) as u8;
- if tbyte < 0xFF {
- self.flush_run(false)?;
- if nbyte < 0xFE {
- self.bw.write_byte(tbyte)?;
- } else {
- self.saved = tbyte;
- self.run = 1;
- }
- } else {
- self.run += 1;
- }
- self.val &= 0xFFFFFF;
- self.bits -= 8;
- }
- }
- }
- Ok(())
- }
- pub fn flush(mut self) -> EncoderResult<()> {
- self.flush_run(false)?;
- self.val <<= 24 - self.bits;
- self.bw.write_u32be(self.val)?;
- Ok(())
- }
-
- pub fn put_bits(&mut self, val: u32, len: u8) -> EncoderResult<()> {
- let mut mask = 1 << (len - 1);
- while mask != 0 {
- self.put_bool((val & mask) != 0, 128)?;
- mask >>= 1;
- }
- Ok(())
- }
- fn put_probability(&mut self, prob: u8) -> EncoderResult<()> {
- self.put_bits(u32::from(prob >> 1), 7)
- }
- fn encode_probability(&mut self, new: u8, old: u8, prob: u8) -> EncoderResult<()> {
- self.put_bool(new != old, prob)?;
- if new != old {
- self.put_probability(new)?;
- }
- Ok(())
- }
- pub fn write_el<T: PartialEq>(&mut self, el: T, tree: &[TokenSeq<T>], probs: &[u8]) -> EncoderResult<()> {
- for entry in tree.iter() {
- if entry.val == el {
- for seq in entry.seq.iter() {
- self.put_bool(seq.bit, probs[seq.idx as usize])?;
- }
- return Ok(());
- }
- }
- Err(EncoderError::Bug)
- }