image-blp 1.2.0

Library to encode/decode Blizzard BLP texture format
Documentation
use super::super::error::Error;
use super::super::types::Parser;
use crate::types::*;
use log::*;
use nom::{multi::count, number::complete::le_u8, Err};

pub fn parse_raw1<'a>(
    blp_header: &BlpHeader,
    original_input: &'a [u8],
    offsets: &[u32],
    sizes: &[u32],
    images: &mut Vec<Raw1Image>,
    input: &'a [u8],
) -> Parser<'a, ()> {
    let mut read_image = |i: usize| {
        let offset = offsets[i];
        let size = sizes[i];
        if offset as usize >= original_input.len() {
            error!(
                "Offset of mipmap {} is out of bounds! {} >= {}",
                i,
                offset,
                original_input.len()
            );
            return Err(Err::Failure(Error::<&[u8]>::OutOfBounds(0)));
        }
        if (offset + size) as usize > original_input.len() {
            error!(
                "Offset+size of mipmap {} is out of bounds! {} > {}",
                i,
                offset + size,
                original_input.len()
            );
            return Err(Err::Failure(Error::OutOfBounds(0)));
        }

        let image_bytes = &original_input[offset as usize..(offset + size) as usize];
        let n = blp_header.mipmap_pixels(i);
        let (input, indexed_rgb) = count(le_u8, n as usize)(image_bytes)?;
        let an = (n * blp_header.alpha_bits() + 7) / 8;
        let (_, indexed_alpha) = count(le_u8, an as usize)(input)?;

        images.push(Raw1Image {
            indexed_rgb,
            indexed_alpha,
        });
        Ok(())
    };

    trace!("Mipmaps count: {}", blp_header.mipmaps_count());
    read_image(0)?;
    if blp_header.has_mipmaps() {
        for i in 1..(blp_header.mipmaps_count() + 1).min(16) {
            read_image(i)?;
        }
    }
    Ok((input, ()))
}