pub fn unpack_bits(bytes: &[u8], width: u32, count: usize) -> Vec<u32> {
let mut out = Vec::with_capacity(count);
let mut bit_pos = 0usize;
for _ in 0..count {
let mut value = 0u32;
for _ in 0..width {
let byte = bytes.get(bit_pos / 8).copied().unwrap_or(0);
let bit = (byte >> (7 - bit_pos % 8)) & 1;
value = (value << 1) | bit as u32;
bit_pos += 1;
}
out.push(value);
}
out
}
#[cfg(test)]
mod tests {
use crate::{pack_bits, unpack_bits};
#[test]
fn round_trips_pack_bits() {
let values = [0, 1, 5, 2, 7, 0, 255, 128];
for width in [1, 3, 8] {
let masked: Vec<u32> = values.iter().map(|v| v & ((1 << width) - 1)).collect();
let packed = pack_bits(&masked, width);
assert_eq!(
unpack_bits(&packed, width, masked.len()),
masked,
"width {width}"
);
}
}
}