use super::{Texture, TextureFormat};
use anyhow::Result;
use bevy_asset::AssetLoader;
use bevy_math::Vec2;
use std::path::Path;
#[derive(Clone, Default)]
pub struct ImageTextureLoader;
impl AssetLoader<Texture> for ImageTextureLoader {
fn from_bytes(&self, asset_path: &Path, bytes: Vec<u8>) -> Result<Texture> {
use bevy_core::AsBytes;
let ext = asset_path.extension().unwrap().to_str().unwrap();
let img_format = if ext.eq_ignore_ascii_case("png") {
image::ImageFormat::Png
} else {
panic!(
"Unexpected image format {:?} for file {}, this is an error in `bevy_render`.",
ext,
asset_path.display()
)
};
let dyn_img = image::load_from_memory_with_format(bytes.as_slice(), img_format)?;
let width;
let height;
let data: Vec<u8>;
let format: TextureFormat;
match dyn_img {
image::DynamicImage::ImageLuma8(i) => {
width = i.width();
height = i.height();
format = TextureFormat::R8Unorm;
data = i.into_raw();
}
image::DynamicImage::ImageLumaA8(i) => {
width = i.width();
height = i.height();
format = TextureFormat::Rg8Unorm;
data = i.into_raw();
}
image::DynamicImage::ImageRgb8(i) => {
let i = image::DynamicImage::ImageRgb8(i).into_rgba();
width = i.width();
height = i.height();
format = TextureFormat::Rgba8UnormSrgb;
data = i.into_raw();
}
image::DynamicImage::ImageRgba8(i) => {
width = i.width();
height = i.height();
format = TextureFormat::Rgba8UnormSrgb;
data = i.into_raw();
}
image::DynamicImage::ImageBgr8(i) => {
let i = image::DynamicImage::ImageBgr8(i).into_bgra();
width = i.width();
height = i.height();
format = TextureFormat::Bgra8UnormSrgb;
data = i.into_raw();
}
image::DynamicImage::ImageBgra8(i) => {
width = i.width();
height = i.height();
format = TextureFormat::Bgra8UnormSrgb;
data = i.into_raw();
}
image::DynamicImage::ImageLuma16(i) => {
width = i.width();
height = i.height();
format = TextureFormat::R16Uint;
let raw_data = i.into_raw();
data = raw_data.as_slice().as_bytes().to_owned();
}
image::DynamicImage::ImageLumaA16(i) => {
width = i.width();
height = i.height();
format = TextureFormat::Rg16Uint;
let raw_data = i.into_raw();
data = raw_data.as_slice().as_bytes().to_owned();
}
image::DynamicImage::ImageRgb16(i) => {
width = i.width();
height = i.height();
format = TextureFormat::Rgba16Uint;
let mut d =
Vec::with_capacity(width as usize * height as usize * format.pixel_size());
for pixel in i.into_raw().chunks_exact(3) {
let r = pixel[0];
let g = pixel[1];
let b = pixel[2];
let a = u16::max_value();
d.extend_from_slice(&r.to_ne_bytes());
d.extend_from_slice(&g.to_ne_bytes());
d.extend_from_slice(&b.to_ne_bytes());
d.extend_from_slice(&a.to_ne_bytes());
}
data = d;
}
image::DynamicImage::ImageRgba16(i) => {
width = i.width();
height = i.height();
format = TextureFormat::Rgba16Uint;
let raw_data = i.into_raw();
data = raw_data.as_slice().as_bytes().to_owned();
}
}
Ok(Texture::new(
Vec2::new(width as f32, height as f32),
data,
format,
))
}
fn extensions(&self) -> &[&str] {
static EXTENSIONS: &[&str] = &["png"];
EXTENSIONS
}
}