Path: blob/main/crates/bevy_image/src/exr_texture_loader.rs
6595 views
use crate::{Image, TextureAccessError, TextureFormatPixelInfo};1use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages};2use image::ImageDecoder;3use serde::{Deserialize, Serialize};4use thiserror::Error;5use wgpu_types::{Extent3d, TextureDimension, TextureFormat};67/// Loads EXR textures as Texture assets8#[derive(Clone, Default)]9#[cfg(feature = "exr")]10pub struct ExrTextureLoader;1112#[derive(Serialize, Deserialize, Default, Debug)]13#[cfg(feature = "exr")]14pub struct ExrTextureLoaderSettings {15pub asset_usage: RenderAssetUsages,16}1718/// Possible errors that can be produced by [`ExrTextureLoader`]19#[non_exhaustive]20#[derive(Debug, Error)]21#[cfg(feature = "exr")]22pub enum ExrTextureLoaderError {23#[error(transparent)]24Io(#[from] std::io::Error),25#[error(transparent)]26ImageError(#[from] image::ImageError),27#[error("Texture access error: {0}")]28TextureAccess(#[from] TextureAccessError),29}3031impl AssetLoader for ExrTextureLoader {32type Asset = Image;33type Settings = ExrTextureLoaderSettings;34type Error = ExrTextureLoaderError;3536async fn load(37&self,38reader: &mut dyn Reader,39settings: &Self::Settings,40_load_context: &mut LoadContext<'_>,41) -> Result<Image, Self::Error> {42let format = TextureFormat::Rgba32Float;43debug_assert_eq!(44format.pixel_size()?,454 * 4,46"Format should have 32bit x 4 size"47);4849let mut bytes = Vec::new();50reader.read_to_end(&mut bytes).await?;51let decoder = image::codecs::openexr::OpenExrDecoder::with_alpha_preference(52std::io::Cursor::new(bytes),53Some(true),54)?;55let (width, height) = decoder.dimensions();5657let total_bytes = decoder.total_bytes() as usize;5859let mut buf = vec![0u8; total_bytes];60decoder.read_image(buf.as_mut_slice())?;6162Ok(Image::new(63Extent3d {64width,65height,66depth_or_array_layers: 1,67},68TextureDimension::D2,69buf,70format,71settings.asset_usage,72))73}7475fn extensions(&self) -> &[&str] {76&["exr"]77}78}798081