1use crate::{Image, TextureFormatPixelInfo};
2use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages};
3use bevy_reflect::TypePath;
4use image::ImageDecoder;
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7use wgpu_types::{Extent3d, TextureDimension, TextureFormat};
8
9#[derive(#[automatically_derived]
impl ::core::clone::Clone for ExrTextureLoader {
#[inline]
fn clone(&self) -> ExrTextureLoader { ExrTextureLoader }
}Clone, #[automatically_derived]
impl ::core::default::Default for ExrTextureLoader {
#[inline]
fn default() -> ExrTextureLoader { ExrTextureLoader {} }
}Default, const _: () =
{
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for ExrTextureLoader where {
fn type_path() -> &'static str {
"bevy_image::exr_texture_loader::ExrTextureLoader"
}
fn short_type_path() -> &'static str { "ExrTextureLoader" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("ExrTextureLoader")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_image::exr_texture_loader".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_image::exr_texture_loader")
}
}
};TypePath)]
11#[cfg(feature = "exr")]
12pub struct ExrTextureLoader;
13
14#[derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl _serde::Serialize for ExrTextureLoaderSettings {
fn serialize<__S>(&self, __serializer: __S)
-> _serde::__private228::Result<__S::Ok, __S::Error> where
__S: _serde::Serializer {
let mut __serde_state =
_serde::Serializer::serialize_struct(__serializer,
"ExrTextureLoaderSettings", false as usize + 1)?;
_serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
"asset_usage", &self.asset_usage)?;
_serde::ser::SerializeStruct::end(__serde_state)
}
}
};Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
{
#[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
;
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for ExrTextureLoaderSettings {
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
#[allow(non_camel_case_types)]
#[doc(hidden)]
enum __Field { __field0, __ignore, }
#[doc(hidden)]
struct __FieldVisitor;
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"field identifier")
}
fn visit_u64<__E>(self, __value: u64)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
0u64 => _serde::__private228::Ok(__Field::__field0),
_ => _serde::__private228::Ok(__Field::__ignore),
}
}
fn visit_str<__E>(self, __value: &str)
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
"asset_usage" =>
_serde::__private228::Ok(__Field::__field0),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
fn visit_bytes<__E>(self, __value: &[u8])
-> _serde::__private228::Result<Self::Value, __E> where
__E: _serde::de::Error {
match __value {
b"asset_usage" =>
_serde::__private228::Ok(__Field::__field0),
_ => { _serde::__private228::Ok(__Field::__ignore) }
}
}
}
#[automatically_derived]
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(__deserializer: __D)
-> _serde::__private228::Result<Self, __D::Error> where
__D: _serde::Deserializer<'de> {
_serde::Deserializer::deserialize_identifier(__deserializer,
__FieldVisitor)
}
}
#[doc(hidden)]
struct __Visitor<'de> {
marker: _serde::__private228::PhantomData<ExrTextureLoaderSettings>,
lifetime: _serde::__private228::PhantomData<&'de ()>,
}
#[automatically_derived]
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
type Value = ExrTextureLoaderSettings;
fn expecting(&self,
__formatter: &mut _serde::__private228::Formatter)
-> _serde::__private228::fmt::Result {
_serde::__private228::Formatter::write_str(__formatter,
"struct ExrTextureLoaderSettings")
}
#[inline]
fn visit_seq<__A>(self, mut __seq: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<'de> {
let __field0 =
match _serde::de::SeqAccess::next_element::<RenderAssetUsages>(&mut __seq)?
{
_serde::__private228::Some(__value) => __value,
_serde::__private228::None =>
return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
&"struct ExrTextureLoaderSettings with 1 element")),
};
_serde::__private228::Ok(ExrTextureLoaderSettings {
asset_usage: __field0,
})
}
#[inline]
fn visit_map<__A>(self, mut __map: __A)
-> _serde::__private228::Result<Self::Value, __A::Error>
where __A: _serde::de::MapAccess<'de> {
let mut __field0:
_serde::__private228::Option<RenderAssetUsages> =
_serde::__private228::None;
while let _serde::__private228::Some(__key) =
_serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
match __key {
__Field::__field0 => {
if _serde::__private228::Option::is_some(&__field0) {
return _serde::__private228::Err(<__A::Error as
_serde::de::Error>::duplicate_field("asset_usage"));
}
__field0 =
_serde::__private228::Some(_serde::de::MapAccess::next_value::<RenderAssetUsages>(&mut __map)?);
}
_ => {
let _ =
_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
}
}
}
let __field0 =
match __field0 {
_serde::__private228::Some(__field0) => __field0,
_serde::__private228::None =>
_serde::__private228::de::missing_field("asset_usage")?,
};
_serde::__private228::Ok(ExrTextureLoaderSettings {
asset_usage: __field0,
})
}
}
#[doc(hidden)]
const FIELDS: &'static [&'static str] = &["asset_usage"];
_serde::Deserializer::deserialize_struct(__deserializer,
"ExrTextureLoaderSettings", FIELDS,
__Visitor {
marker: _serde::__private228::PhantomData::<ExrTextureLoaderSettings>,
lifetime: _serde::__private228::PhantomData,
})
}
}
};Deserialize, #[automatically_derived]
impl ::core::default::Default for ExrTextureLoaderSettings {
#[inline]
fn default() -> ExrTextureLoaderSettings {
ExrTextureLoaderSettings {
asset_usage: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::fmt::Debug for ExrTextureLoaderSettings {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ExrTextureLoaderSettings", "asset_usage", &&self.asset_usage)
}
}Debug)]
16#[cfg(feature = "exr")]
17pub struct ExrTextureLoaderSettings {
18 pub asset_usage: RenderAssetUsages,
20}
21
22#[non_exhaustive]
24#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ExrTextureLoaderError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ExrTextureLoaderError::Io(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Io",
&__self_0),
ExrTextureLoaderError::ImageError(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ImageError", &__self_0),
}
}
}Debug, fn from(source: image::ImageError) -> Self {
ExrTextureLoaderError::ImageError { 0: source }
}Error, const _: () =
{
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for ExrTextureLoaderError where {
fn type_path() -> &'static str {
"bevy_image::exr_texture_loader::ExrTextureLoaderError"
}
fn short_type_path() -> &'static str { "ExrTextureLoaderError" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("ExrTextureLoaderError")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_image::exr_texture_loader".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_image::exr_texture_loader")
}
}
};TypePath)]
25#[cfg(feature = "exr")]
26pub enum ExrTextureLoaderError {
27 #[error(transparent)]
29 Io(#[from] std::io::Error),
30 #[error(transparent)]
32 ImageError(#[from] image::ImageError),
33}
34
35impl AssetLoader for ExrTextureLoader {
36 type Asset = Image;
37 type Settings = ExrTextureLoaderSettings;
38 type Error = ExrTextureLoaderError;
39
40 async fn load(
41 &self,
42 reader: &mut dyn Reader,
43 settings: &Self::Settings,
44 _load_context: &mut LoadContext<'_>,
45 ) -> Result<Image, Self::Error> {
46 let format = TextureFormat::Rgba32Float;
47 if true {
match (&format.pixel_size().unwrap(), &(4 * 4)) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val,
::core::option::Option::Some(format_args!("Format should have 32bit x 4 size")));
}
}
};
};debug_assert_eq!(
48 format.pixel_size().unwrap(),
50 4 * 4,
51 "Format should have 32bit x 4 size"
52 );
53
54 let mut bytes = Vec::new();
55 reader.read_to_end(&mut bytes).await?;
56 let decoder = image::codecs::openexr::OpenExrDecoder::with_alpha_preference(
57 std::io::Cursor::new(bytes),
58 Some(true),
59 )?;
60 let (width, height) = decoder.dimensions();
61
62 let total_bytes = decoder.total_bytes() as usize;
63
64 let mut buf = ::alloc::vec::from_elem(0u8, total_bytes)vec![0u8; total_bytes];
65 decoder.read_image(buf.as_mut_slice())?;
66
67 Ok(Image::new(
68 Extent3d {
69 width,
70 height,
71 depth_or_array_layers: 1,
72 },
73 TextureDimension::D2,
74 buf,
75 format,
76 settings.asset_usage,
77 ))
78 }
79
80 fn extensions(&self) -> &[&str] {
81 &["exr"]
82 }
83}