| 56 | /// Unpack a value from a byte array at the given bit offset. |
| 57 | #[inline] |
| 58 | pub(super) fn unpack_bits(packed: &[u8], bit_offset: usize, bit_width: u8) -> u64 { |
| 59 | let bw = bit_width as usize; |
| 60 | if bw == 0 { |
| 61 | return 0; |
| 62 | } |
| 63 | |
| 64 | let byte_idx = bit_offset / 8; |
| 65 | let bit_idx = bit_offset % 8; |
| 66 | |
| 67 | // How many bits available in the first byte. |
| 68 | let first_bits = (8 - bit_idx).min(bw); |
| 69 | let mut value = ((packed[byte_idx] >> bit_idx) & low_mask_u8(first_bits)) as u64; |
| 70 | |
| 71 | let mut collected = first_bits; |
| 72 | let mut bi = byte_idx + 1; |
| 73 | |
| 74 | // Read full bytes. |
| 75 | while collected + 8 <= bw { |
| 76 | value |= (packed[bi] as u64) << collected; |
| 77 | collected += 8; |
| 78 | bi += 1; |
| 79 | } |
| 80 | |
| 81 | // Read last partial byte. |
| 82 | let remaining = bw - collected; |
| 83 | if remaining > 0 { |
| 84 | value |= ((packed[bi] & low_mask_u8(remaining)) as u64) << collected; |
| 85 | } |
| 86 | |
| 87 | value |
| 88 | } |