X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Fio%2Fintcode.rs;h=bc6fb0ad59ede68c3c707943bf03d6a960028e04;hb=2dbe1e64ee27b0f28a6d670daba0fc56c76a2fb1;hp=1c52d81efb3cad72fabce801a7937262eb57cdb0;hpb=e243ceb4d694cc08767ad70027bb6963f4cefea3;p=nihav.git diff --git a/nihav-core/src/io/intcode.rs b/nihav-core/src/io/intcode.rs index 1c52d81..bc6fb0a 100644 --- a/nihav-core/src/io/intcode.rs +++ b/nihav-core/src/io/intcode.rs @@ -1,27 +1,82 @@ +//! Some universal integer codes support for bitstream reader. use crate::io::bitreader::{BitReader, BitReaderError, BitReaderResult}; +/// Unsigned integer code types. #[derive(Debug)] pub enum UintCodeType { + /// Code where number is represented as run of ones with terminating zero. UnaryOnes, + /// Code where number is represented as run of zeroes with terminating one. UnaryZeroes, + /// Code for 0, 1 and 2 coded as `0`, `10` and `11` Unary012, + /// Code for 0, 1 and 2 coded as `11`, `10` and `0` Unary210, + /// General limited unary code with defined run and terminating bit. LimitedUnary(u32, u32), + /// Limited run of zeroes with terminating one (unless the code has maximum length). + /// + /// [`Unary012`] is essentially an alias for `LimitedZeroes(2)`. + /// + /// [`Unary012`]: #variant.Unary012 + LimitedZeroes(u32), + /// Limited run of one with terminating zero (unless the code has maximum length). + LimitedOnes(u32), + /// Golomb code. Golomb(u8), + /// Rice code. Rice(u8), + /// Elias Gamma code (interleaved). Gamma, + /// Elias Gamma' code (sometimes incorrectly called exp-Golomb). GammaP, } +/// Signed integer code types. pub enum IntCodeType { + /// Golomb code. Last bit represents the sign. Golomb(u8), + /// Golomb code. Last bit represents the sign. Rice(u8), + /// Elias Gamma code. Unsigned values are remapped as 0, 1, -1, 2, -2, ... Gamma, + /// Elias Gamma' code. Unsigned values are remapped as 0, 1, -1, 2, -2, ... GammaP, } +/// Universal integer code reader trait for bitstream reader. +/// +/// # Examples +/// +/// Read an unsigned Golomb code: +/// ```` +/// use nihav_core::io::bitreader::*; +/// use nihav_core::io::intcode::{IntCodeReader,UintCodeType}; +/// +/// # fn foo() -> BitReaderResult<()> { +/// let mem: [u8; 4] = [ 0, 1, 2, 3]; +/// let mut br = BitReader::new(&mem, BitReaderMode::BE); +/// let val = br.read_code(UintCodeType::Golomb(3))?; +/// # Ok(()) +/// # } +/// ```` +/// +/// Read signed Elias code: +/// ```` +/// use nihav_core::io::bitreader::*; +/// use nihav_core::io::intcode::{IntCodeReader,IntCodeType}; +/// +/// # fn foo() -> BitReaderResult<()> { +/// let mem: [u8; 4] = [ 0, 1, 2, 3]; +/// let mut br = BitReader::new(&mem, BitReaderMode::BE); +/// let val = br.read_code_signed(IntCodeType::Gamma)?; +/// # Ok(()) +/// # } +/// ```` pub trait IntCodeReader { + /// Reads an unsigned integer code of requested type. fn read_code(&mut self, t: UintCodeType) -> BitReaderResult; + /// Reads signed integer code of requested type. fn read_code_signed(&mut self, t: IntCodeType) -> BitReaderResult; } @@ -101,6 +156,8 @@ impl<'a> IntCodeReader for BitReader<'a> { match t { UintCodeType::UnaryOnes => read_unary(self, 0), UintCodeType::UnaryZeroes => read_unary(self, 1), + UintCodeType::LimitedZeroes(len) => read_unary_lim(self, len, 1), + UintCodeType::LimitedOnes(len) => read_unary_lim(self, len, 0), UintCodeType::LimitedUnary(len, term) => read_unary_lim(self, len, term), UintCodeType::Unary012 => read_unary_lim(self, 2, 0), UintCodeType::Unary210 => read_unary210(self), @@ -137,7 +194,7 @@ mod test { fn int_codes() { const GDATA: [u8; 6] = [0b000_001_01, 0b0_0110_011, 0b1_1000_100, 0b1_1010_101, 0b10_10111_1, 0b1000_0000]; let src = &GDATA; - let mut br = BitReader::new(src, src.len(), BitReaderMode::BE); + let mut br = BitReader::new(src, BitReaderMode::BE); for i in 0..11 { assert_eq!(br.read_code(UintCodeType::Golomb(5)).unwrap(), i); }