lyra-engine/lyra-resource/src/loader/texture.rs

87 lines
2.4 KiB
Rust

use std::{fs::File, sync::Arc, path::Path, ffi::OsStr, io::Read};
use image::ImageError;
use crate::{resource_manager::ResourceStorage, texture::Texture, resource::Resource};
use super::{LoaderError, ResourceLoader};
impl From<ImageError> for LoaderError {
fn from(value: ImageError) -> Self {
LoaderError::DecodingError(value.into())
}
}
/// A struct that implements the `ResourceLoader` trait used for loading textures.
#[derive(Default)]
pub struct TextureLoader;
impl ResourceLoader for TextureLoader {
fn extensions(&self) -> &[&str] {
&[
// the extensions of these are the names of the formats
"bmp", "dds", "gif", "ico", "jpeg", "jpg", "png", "qoi", "tga", "tiff", "webp",
// farbfeld
"ff",
// pnm
"pnm", "pbm", "pgm", "ppm", "pam",
]
}
fn load(&self, path: &str) -> Result<Arc<dyn ResourceStorage>, LoaderError> {
// check if the file is supported by this loader
if !self.does_support_file(path) {
return Err(LoaderError::UnsupportedExtension(path.to_string()));
}
// read file bytes
let mut file = File::open(path)?;
let mut buf = vec![];
file.read_to_end(&mut buf)?;
// load the image and construct Resource<Texture>
let image = image::load_from_memory(&buf)
.map_err(|e| match e {
ImageError::IoError(e) => LoaderError::IoError(e),
_ => LoaderError::DecodingError(e.into()),
})?;
let texture = Texture {
image,
};
let res = Resource::with_data(path, texture);
Ok(Arc::new(res))
}
}
#[cfg(test)]
mod tests {
use super::*;
fn get_image(path: &str) -> String {
let manifest = std::env::var("CARGO_MANIFEST_DIR").unwrap();
format!("{manifest}/test_files/img/{path}")
}
#[test]
fn check_unsupport() {
let loader = TextureLoader::default();
assert_eq!(loader.does_support_file("test.gltf"), false);
}
/// Tests loading an image
#[test]
fn image_load() {
let loader = TextureLoader::default();
loader.load(&get_image("squiggles.png")).unwrap();
}
#[test]
fn image_load_unsupported() {
let loader = TextureLoader::default();
assert!(loader.load(&get_image("squiggles.gltf")).is_err());
}
}