image-blp 1.2.0

Library to encode/decode Blizzard BLP texture format
Documentation
use super::error::Error;
use super::mipmap::generate_mipmaps;
use crate::types::*;
use ::image::{imageops::FilterType, DynamicImage, RgbaImage};

pub fn raw3_to_image(
    header: &BlpHeader,
    image: &BlpRaw3,
    mipmap_level: usize,
) -> Result<DynamicImage, Error> {
    if mipmap_level >= image.images.len() {
        return Err(Error::MissingImage(mipmap_level));
    }
    let raw_image = &image.images[mipmap_level];
    let (width, height) = header.mipmap_size(mipmap_level);
    if (width as usize) * (height as usize) != raw_image.pixels.len() {
        return Err(Error::MismatchSizes(
            mipmap_level,
            width,
            height,
            raw_image.pixels.len(),
        ));
    }

    let mut res_image = RgbaImage::new(width, height);
    for (i, pixel) in res_image.pixels_mut().enumerate() {
        let color = raw_image.pixels[i];
        let blue = (color & 0xFF) as u8;
        let green = ((color >> 8) & 0xFF) as u8;
        let red = ((color >> 16) & 0xFF) as u8;
        let alpha = (color >> 24) as u8;
        pixel.0 = [red, green, blue, alpha];
    }
    Ok(DynamicImage::ImageRgba8(res_image))
}

pub fn image_to_raw3(
    image: DynamicImage,
    make_mipmaps: bool,
    mipmap_filter: FilterType,
) -> Result<BlpRaw3, Error> {
    let raw_images = if make_mipmaps {
        generate_mipmaps(image, mipmap_filter)?.into_iter()
    } else {
        vec![image].into_iter()
    };

    let mut images = vec![];
    for image in raw_images {
        let rgba = image.into_rgba8();
        let pixels_num = (rgba.width() as usize) * (rgba.height() as usize);
        let mut pixels = Vec::with_capacity(pixels_num);
        for pixel in rgba.pixels() {
            let red = (pixel[0] as u32) << 16;
            let green = (pixel[1] as u32) << 8;
            let blue = pixel[2] as u32;
            let alpha = (pixel[3] as u32) << 24;
            pixels.push(red + green + blue + alpha);
        }
        images.push(Raw3Image { pixels })
    }

    Ok(BlpRaw3 {
        cmap: vec![0; 256],
        images,
    })
}