1#![allow(unused)]
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
4#[repr(u8)]
5pub enum BitUnPackUElemSize {
6 _1 = 1,
7 _2 = 2,
8 _4 = 4,
9 _8 = 8,
10 _16 = 16,
11 _32 = 32,
12}
13impl BitUnPackUElemSize {
14 pub const fn elements_per_u32(self) -> usize {
15 32 >> (self as u32).trailing_zeros()
16 }
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[repr(u8)]
21pub enum BitUnPackPElemSize {
22 _1 = 1,
23 _2 = 2,
24 _4 = 4,
25 _8 = 8,
26}
27impl BitUnPackPElemSize {
28 pub const fn elements_per_u8(self) -> usize {
29 8 >> (self as u32).trailing_zeros()
30 }
31}
32
33pub const fn u32_count_to_u8_count(
34 u32_count: usize, u_elem_size: BitUnPackUElemSize,
35 p_elem_size: BitUnPackPElemSize,
36) -> BitUnpackResult<usize> {
37 let elements_per_u32 = u_elem_size.elements_per_u32();
38 let elements_per_u8 = p_elem_size.elements_per_u8();
39 let element_count = u32_count * elements_per_u32;
40 if element_count % elements_per_u8 != 0 {
41 Err(BitUnPackError::PackedElemCountSlop)
42 } else {
43 Ok(element_count / elements_per_u8)
44 }
45}
46
47pub const fn u8_count_to_u32_count(
48 u8_count: usize, p_elem_size: BitUnPackPElemSize,
49 u_elem_size: BitUnPackUElemSize,
50) -> BitUnpackResult<usize> {
51 let elements_per_u32 = u_elem_size.elements_per_u32();
52 let elements_per_u8 = p_elem_size.elements_per_u8();
53 let element_count = u8_count * elements_per_u8;
54 if element_count % elements_per_u32 != 0 {
55 Err(BitUnPackError::UnpackedElemCountSlop)
56 } else {
57 Ok(element_count / elements_per_u32)
58 }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
63pub enum BitUnPackError {
64 PackedElemCountSlop,
65 UnpackedElemCountSlop,
66}
67pub type BitUnpackResult<T> = Result<T, BitUnPackError>;
68
69pub fn pack_u32_to_u8(
71 u32_data: &[u32], unpack_z: BitUnPackUElemSize, pack_z: BitUnPackPElemSize,
72) -> BitUnpackResult<Vec<u8>> {
73 let req_capacity = u32_count_to_u8_count(u32_data.len(), unpack_z, pack_z)?;
74 let mut out_buffer = Vec::with_capacity(req_capacity);
75 let u_mask: u32 = ((1_u64 << (unpack_z as u32)) - 1) as u32;
77 let mut p_buffer: u8 = 0;
78 let mut p_bits: u32 = 0;
79 for mut u in u32_data.iter().copied() {
80 let mut u_bits = 32;
81 while u_bits > 0 {
82 let temp: u8 = (u & u_mask) as u8;
83 u_bits -= (unpack_z as u32);
84 u = u.wrapping_shl(unpack_z as u32);
85 p_buffer |= (temp << p_bits);
87 p_bits += pack_z as u32;
88 if p_bits == 8 {
89 out_buffer.push(p_buffer);
90 p_buffer = 0;
91 p_bits = 0;
92 }
93 }
94 }
95 debug_assert_eq!(p_buffer, 0);
96 debug_assert_eq!(p_bits, 0);
97 Ok(out_buffer)
99}