#![allow(dead_code)]
pub fn block_count(width: usize, height: usize) -> usize {
let bw = width.div_ceil(4);
let bh = height.div_ceil(4);
bw * bh
}
pub fn block_grid(width: usize, height: usize) -> Vec<(usize, usize)> {
let bw = width.div_ceil(4);
let bh = height.div_ceil(4);
let mut coords = Vec::with_capacity(bw * bh);
for by in 0..bh {
for bx in 0..bw {
coords.push((bx * 4, by * 4));
}
}
coords
}
pub fn extract_block(
plane: &[u8],
stride: usize,
bx: usize,
by: usize,
w: usize,
h: usize,
) -> [u8; 16] {
let mut block = [0u8; 16];
for r in 0..4 {
for c in 0..4 {
let px = bx + c;
let py = by + r;
if px < w && py < h {
block[r * 4 + c] = plane[py * stride + px];
}
}
}
block
}
pub fn place_block(
plane: &mut [u8],
stride: usize,
bx: usize,
by: usize,
w: usize,
h: usize,
block: &[u8; 16],
) {
for r in 0..4 {
for c in 0..4 {
let px = bx + c;
let py = by + r;
if px < w && py < h {
plane[py * stride + px] = block[r * 4 + c];
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_block_count_exact_multiples() {
assert_eq!(block_count(4, 4), 1);
assert_eq!(block_count(8, 8), 4);
assert_eq!(block_count(16, 8), 8);
}
#[test]
fn test_block_count_non_multiples() {
assert_eq!(block_count(5, 5), 4);
assert_eq!(block_count(7, 9), 6);
assert_eq!(block_count(1, 1), 1);
}
#[test]
fn test_block_grid_order() {
let grid = block_grid(8, 8);
assert_eq!(grid.len(), 4);
assert_eq!(grid[0], (0, 0));
assert_eq!(grid[1], (4, 0));
assert_eq!(grid[2], (0, 4));
assert_eq!(grid[3], (4, 4));
}
#[test]
fn test_block_grid_single_block() {
let grid = block_grid(4, 4);
assert_eq!(grid, vec![(0usize, 0usize)]);
}
#[test]
fn test_extract_block_full() {
let plane: Vec<u8> = (0u8..32).collect();
let block = extract_block(&plane, 8, 0, 0, 8, 4);
assert_eq!(block[0], 0);
assert_eq!(block[1], 1);
assert_eq!(block[4], 8); assert_eq!(block[15], 27); }
#[test]
fn test_extract_block_at_boundary() {
let plane = vec![1u8; 36]; let block = extract_block(&plane, 6, 4, 4, 6, 6);
assert_eq!(block[0], 1); assert_eq!(block[1], 1); assert_eq!(block[2], 0); assert_eq!(block[3], 0); assert_eq!(block[4], 1); assert_eq!(block[5], 1); assert_eq!(block[6], 0); assert_eq!(block[8], 0); }
#[test]
fn test_place_block_and_extract_round_trip() {
let mut plane = vec![0u8; 64]; let block: [u8; 16] = [
10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
];
place_block(&mut plane, 8, 0, 0, 8, 8, &block);
let extracted = extract_block(&plane, 8, 0, 0, 8, 8);
assert_eq!(extracted, block);
}
#[test]
fn test_place_block_boundary_clipping() {
let mut plane = vec![0u8; 36]; let block = [255u8; 16];
place_block(&mut plane, 6, 4, 4, 6, 6, &block);
assert_eq!(plane[4 * 6 + 4], 255);
assert_eq!(plane[4 * 6 + 5], 255);
assert_eq!(plane[5 * 6 + 4], 255);
assert_eq!(plane[5 * 6 + 5], 255);
}
}