pub struct Interleaver {
bytes_needed : usize,
num_bits : usize,
i_from_uint_vector : Vec<usize>,
i_from_uint_bit : Vec<usize>,
i_to_byte_vector : Vec<usize>,
i_to_byte_bit : Vec<usize>
}
impl Interleaver {
pub fn new(dimensions : usize, bit_depth : usize) -> Self {
let bytes_needed = (bit_depth * dimensions + 7) >> 3;
let num_bits = dimensions * bit_depth;
let pad_bits = bytes_needed * 8 - num_bits;
let mut i_from_uint_vector : Vec<usize> = vec![0;num_bits];
let mut i_from_uint_bit : Vec<usize> = vec![0;num_bits];
let mut i_to_byte_vector : Vec<usize> = vec![0;num_bits];
let mut i_to_byte_bit : Vec<usize> = vec![0;num_bits];
for i_bit in 0 .. num_bits
{
i_from_uint_vector[i_bit] = i_bit % dimensions;
i_from_uint_bit[i_bit] = bit_depth - (i_bit / dimensions) - 1;
i_to_byte_vector[i_bit] = (i_bit + pad_bits) >> 3;
i_to_byte_bit[i_bit] = 0x7 - ((i_bit + pad_bits) & 0x7);
}
Interleaver {
bytes_needed,
num_bits,
i_from_uint_vector,
i_from_uint_bit,
i_to_byte_vector,
i_to_byte_bit
}
}
pub fn interleave(&self, vector : &[u32]) -> Vec<u8>
{
let mut byte_vector = vec![0_u8; self.bytes_needed];
for i_bit in 0 .. self.num_bits
{
let bit : u8 = (((vector[self.i_from_uint_vector[i_bit]] >> self.i_from_uint_bit[i_bit]) & 1_u32) << self.i_to_byte_bit[i_bit]) as u8;
byte_vector[self.i_to_byte_vector[i_bit]] |= bit;
}
byte_vector
}
}
#[cfg(test)]
mod tests {
#[allow(unused_imports)]
use spectral::prelude::*;
use crate::transform::fast_hilbert;
use crate::interleaver::Interleaver;
#[test]
fn interleave() {
let dimensions = 3;
let bit_depth = 5;
let axes : Vec<u32> = vec![17, 24, 6];
let interleaver = Interleaver::new(dimensions, bit_depth);
let actual = fast_hilbert::interleave_be(&axes, 5, Some(&interleaver));
let expected : Vec<u8> = vec![100,76];
asserting("Correct interleave result using Interleaver").that(&actual).is_equal_to(expected);
}
}