#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BlockInterleaver {
rows: usize,
cols: usize,
}
impl BlockInterleaver {
pub fn new(rows: usize, cols: usize) -> Self {
assert!(
rows > 0 && cols > 0,
"interleaver dimensions must be nonzero"
);
Self { rows, cols }
}
#[inline]
pub fn block_len(&self) -> usize {
self.rows * self.cols
}
pub fn rows(&self) -> usize {
self.rows
}
pub fn cols(&self) -> usize {
self.cols
}
pub fn interleave<T: Copy>(&self, input: &[T], output: &mut [T]) {
let n = self.block_len();
assert_eq!(input.len(), n, "interleave input must be one full block");
assert_eq!(output.len(), n, "interleave output must be one full block");
for r in 0..self.rows {
for c in 0..self.cols {
output[c * self.rows + r] = input[r * self.cols + c];
}
}
}
pub fn deinterleave<T: Copy>(&self, input: &[T], output: &mut [T]) {
let n = self.block_len();
assert_eq!(input.len(), n, "deinterleave input must be one full block");
assert_eq!(
output.len(),
n,
"deinterleave output must be one full block"
);
for r in 0..self.rows {
for c in 0..self.cols {
output[r * self.cols + c] = input[c * self.rows + r];
}
}
}
}