physis 0.5.0

Library for reading and writing FFXIV data.
Documentation
// SPDX-FileCopyrightText: 2023 Rudolf Kolbe
// SPDX-License-Identifier: MIT

// macro to generate generic block decoder functions
macro_rules! block_decoder {
    ($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"]
        pub fn $name(
            data: &[u8],
            width: usize,
            height: usize,
            image: &mut [u32],
        ) -> Result<(), &'static str> {
            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.div_ceil(BLOCK_WIDTH);
            let num_blocks_y: usize = height.div_ceil(BLOCK_HEIGHT);
            let mut buffer: [u32; BLOCK_SIZE] =
                [crate::bcn::color::color(0, 0, 0, 255); BLOCK_SIZE];

            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;