//! Bit streams. use crate::err::*; /// Reads `width` bits from `b` starting at bit `cr_bit` into an integer, most /// significant bit first. /// /// # Errors /// /// The function will return an error if `width` is more than 64, or if /// `(cr_bit + width - 1) / 8` would overflow an index into `b`. pub fn read_bits_b(b: &[u8], cr_bit: usize, width: u8) -> ResultS { if width == 0 { return Ok(0); } if width > 64 { bail!("invalid number of bits"); } let last = (cr_bit + usize::from(width) - 1) / 8; if last >= b.len() { bail!("not enough data"); } let mut byte_ptr = cr_bit / 8; let mut bits_ptr = cr_bit % 8; let mut res = 0; for _ in 0..width { res <<= 1; if b[byte_ptr] & (1 << bits_ptr) != 0 { res |= 1; } bits_ptr += 1; if bits_ptr > 7 { bits_ptr = 0; byte_ptr += 1; } } Ok(res) } /// The same as `read_bits_b`, but least-significant bit first. pub fn read_bits_l(b: &[u8], cr_bit: usize, width: u8) -> ResultS { if width == 0 { Ok(0) } else { let res = read_bits_b(b, cr_bit, width)?; Ok(reverse_bits(res) >> (64 - width)) } } // FIXME: change this to u64::reverse_bits when stabilized const fn reverse_bits(v: u64) -> u64 { let v = v >> 1 & 0x5555_5555_5555_5555 | ((v & 0x5555_5555_5555_5555) << 1); let v = v >> 2 & 0x3333_3333_3333_3333 | ((v & 0x3333_3333_3333_3333) << 2); let v = v >> 4 & 0x0F0F_0F0F_0F0F_0F0F | ((v & 0x0F0F_0F0F_0F0F_0F0F) << 4); v.swap_bytes() } #[test] fn bit_tests() { const INPUT: &[u8] = &[0b01100101, 0b10101010, 0b00010000, 0b00000000, 0b11111111, 0b11100001, 0b10101100, 0b00110011, 0b10100101, 0b11100000, 0b00000111, 0b00000001, 0b11001010, 0b10101111, 0b00101011, 0b01101010, 0b11010101, 0b10100011, 0b01010101, 0b11000001]; let mut p = 0; let n = read_bits_b(INPUT, p, 3).unwrap(); assert_eq!(n, 0b101); p += 3; let n = read_bits_b(INPUT, p, 63).unwrap(); assert_eq!(n, 0b001100101010100001000000000001111111110000111001101011100110010); p += 63; let n = read_bits_b(INPUT, p, 4).unwrap(); assert_eq!(n, 0b1001); p += 4; let n = read_bits_b(INPUT, p, 7).unwrap(); assert_eq!(n, 0b0100000); p += 7; let n = read_bits_b(INPUT, p, 17).unwrap(); assert_eq!(n, 0b11111100000100000); p += 17; let n = read_bits_b(INPUT, p, 27).unwrap(); assert_eq!(n, 0b000101001111110101110101000); p += 27; let n = read_bits_b(INPUT, p, 33).unwrap(); assert_eq!(n, 0b101011010101011110001011010101010); p += 33; let n = read_bits_b(INPUT, p, 6).unwrap(); assert_eq!(n, 0b000011); p += 6; let e = read_bits_b(INPUT, p, 1); assert!(if let Err(_) = e {true} else {false}); let e = read_bits_b(INPUT, p, 2); assert!(if let Err(_) = e {true} else {false}); let mut p = 0; let n = read_bits_l(INPUT, 0, 3).unwrap(); assert_eq!(n, 0b101); p += 3; let n = read_bits_l(INPUT, p, 63).unwrap(); assert_eq!(n, 0b010011001110101100111000011111111100000000000100001010101001100); p += 63; let n = read_bits_l(INPUT, p, 4).unwrap(); assert_eq!(n, 0b1001); p += 4; let n = read_bits_l(INPUT, p, 7).unwrap(); assert_eq!(n, 0b0000010); p += 7; let n = read_bits_l(INPUT, p, 17).unwrap(); assert_eq!(n, 0b00000100000111111); p += 17; let n = read_bits_l(INPUT, p, 27).unwrap(); assert_eq!(n, 0b000101011101011111100101000); p += 27; let n = read_bits_l(INPUT, p, 33).unwrap(); assert_eq!(n, 0b010101010110100011110101010110101); p += 33; let n = read_bits_l(INPUT, p, 6).unwrap(); assert_eq!(n, 0b110000); p += 6; let e = read_bits_l(INPUT, p, 1); assert!(if let Err(_) = e {true} else {false}); let e = read_bits_l(INPUT, p, 2); assert!(if let Err(_) = e {true} else {false}); } // EOF