unity_asset_decode/texture/
mod.rs1pub mod converter;
36pub mod decoders;
37pub mod formats;
38pub mod helpers;
39pub mod types;
40
41pub use converter::{Texture2DConverter, Texture2DProcessor}; pub use decoders::{Decoder, TextureDecoder};
44pub use formats::{TextureFormat, TextureFormatInfo};
45pub use helpers::{TextureExporter, TextureSwizzler};
46pub use types::{GLTextureSettings, StreamingInfo, Texture2D};
47
48pub use decoders::{BasicDecoder, CompressedDecoder, CrunchDecoder, MobileDecoder};
50
51pub use helpers::export::ExportOptions;
53
54pub struct TextureProcessor {
59 converter: Texture2DConverter,
60 decoder: TextureDecoder,
61}
62
63impl TextureProcessor {
64 pub fn new(version: crate::unity_version::UnityVersion) -> Self {
66 Self {
67 converter: Texture2DConverter::new(version),
68 decoder: TextureDecoder::new(),
69 }
70 }
71
72 pub fn convert_object(
74 &self,
75 obj: &crate::object::UnityObject,
76 ) -> crate::error::Result<Texture2D> {
77 self.converter.from_unity_object(obj)
78 }
79
80 pub fn decode_texture(&self, texture: &Texture2D) -> crate::error::Result<image::RgbaImage> {
82 self.decoder.decode(texture)
83 }
84
85 pub fn process_and_export<P: AsRef<std::path::Path>>(
87 &self,
88 obj: &crate::object::UnityObject,
89 output_path: P,
90 ) -> crate::error::Result<()> {
91 let texture = self.convert_object(obj)?;
92 let image = self.decode_texture(&texture)?;
93 TextureExporter::export_auto(&image, output_path)
94 }
95
96 pub fn can_process(&self, format: TextureFormat) -> bool {
98 self.decoder.can_decode(format)
99 }
100
101 pub fn supported_formats(&self) -> Vec<TextureFormat> {
103 self.decoder.supported_formats()
104 }
105}
106
107impl Default for TextureProcessor {
108 fn default() -> Self {
109 Self::new(crate::unity_version::UnityVersion::default())
110 }
111}
112
113pub fn create_processor() -> TextureProcessor {
116 TextureProcessor::default()
117}
118
119pub fn is_format_supported(format: TextureFormat) -> bool {
121 let decoder = TextureDecoder::new();
122 decoder.can_decode(format)
123}
124
125pub fn get_supported_formats() -> Vec<TextureFormat> {
127 let decoder = TextureDecoder::new();
128 decoder.supported_formats()
129}
130
131pub fn decode_texture_data(
133 format: TextureFormat,
134 width: u32,
135 height: u32,
136 data: Vec<u8>,
137) -> crate::error::Result<image::RgbaImage> {
138 let texture = Texture2D {
139 name: "decoded_texture".to_string(),
140 width: width as i32,
141 height: height as i32,
142 format,
143 image_data: data,
144 ..Default::default()
145 };
146
147 let decoder = TextureDecoder::new();
148 decoder.decode(&texture)
149}
150
151pub fn export_image<P: AsRef<std::path::Path>>(
153 image: &image::RgbaImage,
154 path: P,
155) -> crate::error::Result<()> {
156 TextureExporter::export_auto(image, path)
157}
158
159#[cfg(test)]
160mod tests {
161 use super::*;
162
163 #[test]
164 fn test_format_support() {
165 assert!(is_format_supported(TextureFormat::RGBA32));
167 assert!(is_format_supported(TextureFormat::RGB24));
168 assert!(is_format_supported(TextureFormat::ARGB32));
169 }
170
171 #[test]
172 fn test_processor_creation() {
173 let processor = create_processor();
174 assert!(processor.can_process(TextureFormat::RGBA32));
175 }
176
177 #[test]
178 fn test_supported_formats_list() {
179 let formats = get_supported_formats();
180 assert!(!formats.is_empty());
181 assert!(formats.contains(&TextureFormat::RGBA32));
182 }
183
184 #[test]
185 fn test_texture_format_info() {
186 let format = TextureFormat::RGBA32;
187 let info = format.info();
188 assert_eq!(info.name, "RGBA32");
189 assert_eq!(info.bits_per_pixel, 32);
190 assert!(!info.compressed);
191 assert!(info.has_alpha);
192 assert!(info.supported);
193 }
194
195 #[test]
196 fn test_format_categories() {
197 assert!(TextureFormat::RGBA32.is_basic_format());
198 assert!(!TextureFormat::RGBA32.is_compressed_format());
199 assert!(!TextureFormat::RGBA32.is_mobile_format());
200 assert!(!TextureFormat::RGBA32.is_crunch_compressed());
201
202 assert!(TextureFormat::DXT1.is_compressed_format());
203 assert!(!TextureFormat::DXT1.is_basic_format());
204
205 assert!(TextureFormat::ETC2_RGB.is_mobile_format());
206 assert!(!TextureFormat::ETC2_RGB.is_basic_format());
207
208 assert!(TextureFormat::DXT1Crunched.is_crunch_compressed());
209 assert!(!TextureFormat::DXT1Crunched.is_basic_format());
210 }
211}