Mii rendering and parsing library
at gpu_texture_decompression 67 lines 1.8 kB view raw
1use std::{ 2 error::Error, 3 io::{self, Read, SeekFrom}, 4}; 5 6pub fn u16_to_f32(num: u16) -> f32 { 7 half::f16::from_bits(num).to_f32() 8} 9 10/// Signed, normalized Vec3 + w component packed in a u32. 11/// [x: 10; y: 10; z: 10; w: 2] 12pub struct Vec3PackedSnorm(pub u32); 13 14impl Vec3PackedSnorm { 15 /// The w component is discarded. 16 #[allow(clippy::cast_precision_loss, clippy::cast_possible_wrap)] 17 pub fn unpack(self) -> [f32; 3] { 18 let packed = self.0; 19 20 let nx = (packed << 22) as i32 >> 22; 21 let ny = (packed << 12) as i32 >> 22; 22 let nz = (packed << 2) as i32 >> 22; 23 24 [nx as f32 / 511.0, ny as f32 / 511.0, nz as f32 / 511.0] 25 } 26} 27 28/// Abstraction over anything that can be read as Seek or Read 29pub trait ReadSeek: std::io::Seek + std::io::Read {} 30impl<T: ?Sized> ReadSeek for T where T: std::io::Seek + std::io::Read {} 31 32pub(crate) fn read_byte_slice( 33 file: &mut dyn ReadSeek, // Dynamic param: Anything that impl's Read + Seek 34 start: u64, 35 count: usize, 36) -> Result<Vec<u8>, Box<dyn Error>> { 37 file.seek(SeekFrom::Start(start))?; 38 let mut buf = vec![0; count]; 39 file.read_exact(&mut buf)?; 40 41 Ok(buf) 42} 43 44#[cfg(feature = "res")] 45pub(crate) fn inflate_bytes(bytes: &[u8]) -> io::Result<Vec<u8>> { 46 use flate2::read::ZlibDecoder; 47 48 let mut z = ZlibDecoder::new(bytes); 49 // z.read_to_string(&mut s)?; 50 let mut vec = Vec::new(); 51 z.read_to_end(&mut vec)?; 52 Ok(vec) 53} 54 55#[cfg(test)] 56mod tests { 57 use super::Vec3PackedSnorm; 58 59 #[test] 60 fn vec3_packed_snorm_test() { 61 for test in [0x567a_67ca, 0x567_a6436, 0x5675_9fca, 0x5675_9c36] { 62 for x in Vec3PackedSnorm(test).unpack() { 63 assert!(x.abs() <= 1.0, "Not normalised!"); 64 } 65 } 66 } 67}