2025-03-10 17:15:14 -04:00
|
|
|
// SPDX-FileCopyrightText: 2023 Rudolf Kolbe
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
// macro to generate generic block decoder functions
|
2025-03-11 16:25:59 -04:00
|
|
|
macro_rules! block_decoder {
|
2025-03-10 17:15:14 -04:00
|
|
|
($name: ident, $block_width: expr, $block_height: expr, $raw_block_size: expr, $block_decode_func: expr) => {
|
|
|
|
//#[doc = "Decodes a " $name " encoded texture into an image"]
|
2025-03-11 16:25:59 -04:00
|
|
|
pub fn $name(
|
|
|
|
data: &[u8],
|
|
|
|
width: usize,
|
|
|
|
height: usize,
|
|
|
|
image: &mut [u32],
|
|
|
|
) -> Result<(), &'static str> {
|
2025-03-10 17:15:14 -04:00
|
|
|
const BLOCK_WIDTH: usize = $block_width;
|
|
|
|
const BLOCK_HEIGHT: usize = $block_height;
|
|
|
|
const BLOCK_SIZE: usize = BLOCK_WIDTH * BLOCK_HEIGHT;
|
|
|
|
let num_blocks_x: usize = (width + BLOCK_WIDTH - 1) / BLOCK_WIDTH;
|
|
|
|
let num_blocks_y: usize = (height + BLOCK_WIDTH - 1) / BLOCK_HEIGHT;
|
2025-03-11 16:25:59 -04:00
|
|
|
let mut buffer: [u32; BLOCK_SIZE] =
|
|
|
|
[crate::bcn::color::color(0, 0, 0, 255); BLOCK_SIZE];
|
2025-03-10 17:15:14 -04:00
|
|
|
|
|
|
|
if data.len() < num_blocks_x * num_blocks_y * $raw_block_size {
|
|
|
|
return Err("Not enough data to decode image!");
|
|
|
|
}
|
|
|
|
|
|
|
|
if image.len() < width * height {
|
|
|
|
return Err("Image buffer is too small!");
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut data_offset = 0;
|
|
|
|
(0..num_blocks_y).for_each(|by| {
|
|
|
|
(0..num_blocks_x).for_each(|bx| {
|
|
|
|
$block_decode_func(&data[data_offset..], &mut buffer);
|
|
|
|
crate::bcn::color::copy_block_buffer(
|
|
|
|
bx,
|
|
|
|
by,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
BLOCK_WIDTH,
|
|
|
|
BLOCK_HEIGHT,
|
|
|
|
&buffer,
|
|
|
|
image,
|
|
|
|
);
|
|
|
|
data_offset += $raw_block_size;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) use block_decoder;
|