fix read_bits API (bits should come right to left)

png-branch
an 2019-03-12 02:28:51 -04:00
parent 9b73cb3513
commit 49b4b56aea
2 changed files with 95 additions and 90 deletions

View File

@ -351,8 +351,7 @@ pub fn rd_array_num<T, F>(b: &[u8], n: usize, read: F)
///
/// # Panics
///
/// A panic will occur if the `read` function returns a disjoint index or
/// otherwise panics (by an out of bounds index to `b` or otherwise.)
/// A panic will occur if the `read` function panics.
///
/// # Errors
///

View File

@ -7,53 +7,57 @@ use crate::durandal::err::*;
///
/// # Errors
///
/// The function will return an error if `width` is 0 or more than 64, or if
/// 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<(usize, u64)>
pub fn read_bits_b(b: &[u8], cr_bit: usize, width: u8) -> ResultS<u64>
{
if width < 1 || width > 64 {
if width == 0 {
return Ok(0);
}
if width > 64 {
bail!("invalid number of bits");
}
let nx_bit = cr_bit + usize::from(width);
let ed_bit = nx_bit - 1;
let last = (cr_bit + usize::from(width) - 1) / 8;
let cr_byte = cr_bit / 8;
let ed_byte = ed_bit / 8;
check_data!(ed_byte + 1, b);
let cr_bits = cr_bit as u32 % 8;
let nx_bits = nx_bit as u32 % 8;
let nx_mask = ((1_u128 << nx_bits) - 1) as u64;
let num_bytes = ed_byte - cr_byte;
let bytes = get_bytes(b, num_bytes, cr_byte);
let bits = u64::from_be_bytes(bytes);
let bits = bits.wrapping_shl(cr_bits);
let bits = bits >> (64 - width);
// special case for over byte boundary
if num_bytes == 8 {
let lbyt = u64::from(b[ed_byte]);
let lbyt = lbyt >> (8 - nx_bits);
let lbyt = lbyt & nx_mask;
Ok((nx_bit, bits & !nx_mask | lbyt))
} else {
Ok((nx_bit, bits))
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<(usize, u64)>
pub fn read_bits_l(b: &[u8], cr_bit: usize, width: u8) -> ResultS<u64>
{
let (nx_bit, res) = read_bits_b(b, cr_bit, width)?;
if width == 0 {
Ok(0)
} else {
let res = read_bits_b(b, cr_bit, width)?;
Ok((nx_bit, reverse_bits(res) >> (64 - width)))
Ok(reverse_bits(res) >> (64 - width))
}
}
fn reverse_bits(v: u64) -> u64
@ -65,56 +69,48 @@ fn reverse_bits(v: u64) -> u64
v.swap_bytes()
}
fn get_bytes(b: &[u8], num_bytes: usize, f: usize) -> [u8; 8]
{
match num_bytes {
8 |
7 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], b[f+6], b[f+7]],
6 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], b[f+6], 0 ],
5 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], 0, 0 ],
4 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], 0, 0, 0 ],
3 => [b[f], b[f+1], b[f+2], b[f+3], 0, 0, 0, 0 ],
2 => [b[f], b[f+1], b[f+2], 0, 0, 0, 0, 0 ],
1 => [b[f], b[f+1], 0, 0, 0, 0, 0, 0 ],
0 => [b[f], 0, 0, 0, 0, 0, 0, 0 ],
_ => {
panic!("invalid number of bytes to read ({})", num_bytes);
}
}
}
#[test]
fn bit_tests()
{
const INPUT: &[u8] = &[0b011_00101, 0b10101010, 0b00010000, 0b00000000,
0b11111111, 0b11100001, 0b10101100, 0b00110011,
0b10_1001_01, 0b11100_000, 0b00000111, 0b000000_01,
0b11001010, 0b10101111, 0b00101011, 0b0_1101010,
0b11010101, 0b10100011, 0b01010101, 0b11_000001];
const INPUT: &[u8] = &[0b01100101, 0b10101010, 0b00010000, 0b00000000,
0b11111111, 0b11100001, 0b10101100, 0b00110011,
0b10100101, 0b11100000, 0b00000111, 0b00000001,
0b11001010, 0b10101111, 0b00101011, 0b01101010,
0b11010101, 0b10100011, 0b01010101, 0b11000001];
let (p, n) = read_bits_b(INPUT, 0, 3).unwrap();
assert_eq!(n, 0b011);
let mut p = 0;
let (p, n) = read_bits_b(INPUT, p, 63).unwrap();
assert_eq!(n, 0b001011010101000010000000000001111111111100001101011000011001110);
let n = read_bits_b(INPUT, p, 3).unwrap();
assert_eq!(n, 0b101);
p += 3;
let (p, n) = read_bits_b(INPUT, p, 4).unwrap();
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 (p, n) = read_bits_b(INPUT, p, 7).unwrap();
assert_eq!(n, 0b0111100);
let n = read_bits_b(INPUT, p, 7).unwrap();
assert_eq!(n, 0b0100000);
p += 7;
let (p, n) = read_bits_b(INPUT, p, 17).unwrap();
assert_eq!(n, 0b00000000111000000);
let n = read_bits_b(INPUT, p, 17).unwrap();
assert_eq!(n, 0b11111100000100000);
p += 17;
let (p, n) = read_bits_b(INPUT, p, 27).unwrap();
assert_eq!(n, 0b011100101010101111001010110);
let n = read_bits_b(INPUT, p, 27).unwrap();
assert_eq!(n, 0b000101001111110101110101000);
p += 27;
let (p, n) = read_bits_b(INPUT, p, 33).unwrap();
assert_eq!(n, 0b110101011010101101000110101010111);
let n = read_bits_b(INPUT, p, 33).unwrap();
assert_eq!(n, 0b101011010101011110001011010101010);
p += 33;
let (p, n) = read_bits_b(INPUT, p, 6).unwrap();
assert_eq!(n, 0b000001);
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});
@ -122,29 +118,39 @@ fn bit_tests()
let e = read_bits_b(INPUT, p, 2);
assert!(if let Err(_) = e {true} else {false});
let (p, n) = read_bits_l(INPUT, 0, 3).unwrap();
assert_eq!(n, 0b110);
let mut p = 0;
let (p, n) = read_bits_l(INPUT, p, 63).unwrap();
assert_eq!(n, 0b011100110000110101100001111111111100000000000010000101010110100);
let n = read_bits_l(INPUT, 0, 3).unwrap();
assert_eq!(n, 0b101);
p += 3;
let (p, n) = read_bits_l(INPUT, p, 4).unwrap();
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 (p, n) = read_bits_l(INPUT, p, 7).unwrap();
assert_eq!(n, 0b0011110);
let n = read_bits_l(INPUT, p, 7).unwrap();
assert_eq!(n, 0b0000010);
p += 7;
let (p, n) = read_bits_l(INPUT, p, 17).unwrap();
assert_eq!(n, 0b00000011100000000);
let n = read_bits_l(INPUT, p, 17).unwrap();
assert_eq!(n, 0b00000100000111111);
p += 17;
let (p, n) = read_bits_l(INPUT, p, 27).unwrap();
assert_eq!(n, 0b011010100111101010101001110);
let n = read_bits_l(INPUT, p, 27).unwrap();
assert_eq!(n, 0b000101011101011111100101000);
p += 27;
let (p, n) = read_bits_l(INPUT, p, 33).unwrap();
assert_eq!(n, 0b111010101011000101101010110101011);
let n = read_bits_l(INPUT, p, 33).unwrap();
assert_eq!(n, 0b010101010110100011110101010110101);
p += 33;
let (p, n) = read_bits_l(INPUT, p, 6).unwrap();
assert_eq!(n, 0b100000);
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});