A photo manager for VRChat.
at main 2.2 kB view raw
1use std::str; 2 3use serde::Serialize; 4 5#[derive(Clone, Debug, Serialize)] 6pub struct PNGImage { 7 pub width: u32, 8 pub height: u32, 9 pub bit_depth: u8, 10 pub colour_type: u8, 11 pub compression_method: u8, 12 pub filter_method: u8, 13 pub interlace_method: u8, 14 pub metadata: String, 15 pub path: String, 16 pub error: bool 17} 18 19impl PNGImage { 20 pub fn new(buff: Vec<u8>, path: String) -> Result<PNGImage, &'static str> { 21 if buff[0] != 0x89 22 || buff[1] != 0x50 23 || buff[2] != 0x4E 24 || buff[3] != 0x47 25 || buff[4] != 0x0D 26 || buff[5] != 0x0A 27 || buff[6] != 0x1A 28 || buff[7] != 0x0A 29 { 30 dbg!(path); 31 return Err("Image is not a PNG file"); 32 } 33 34 let mut img = PNGImage { 35 width: 0, 36 height: 0, 37 bit_depth: 0, 38 colour_type: 0, 39 compression_method: 0, 40 filter_method: 0, 41 interlace_method: 0, 42 metadata: "".to_string(), 43 path: path, 44 error: false 45 }; 46 47 img.read_png_chunk(8, buff); 48 Ok(img) 49 } 50 51 fn read_png_chunk(&mut self, start_byte: usize, buff: Vec<u8>) { 52 let data_buff = buff[start_byte..].to_vec(); 53 54 let length = u32::from_le_bytes([data_buff[3], data_buff[2], data_buff[1], data_buff[0]]); 55 let chunk_type = str::from_utf8(&data_buff[4..8]).unwrap(); 56 57 match chunk_type { 58 "IHDR" => { 59 self.width = u32::from_le_bytes([data_buff[11], data_buff[10], data_buff[9], data_buff[8]]); 60 61 self.height = 62 u32::from_le_bytes([data_buff[15], data_buff[14], data_buff[13], data_buff[12]]); 63 64 self.bit_depth = data_buff[16]; 65 self.colour_type = data_buff[17]; 66 self.compression_method = data_buff[18]; 67 self.filter_method = data_buff[19]; 68 self.interlace_method = data_buff[20]; 69 70 self.read_png_chunk((length + 12) as usize, data_buff); 71 } 72 "iTXt" => { 73 let end_byte = (8 + length) as usize; 74 let d = str::from_utf8(&data_buff[8..end_byte]).unwrap(); 75 76 self.metadata = d.to_string(); 77 78 self.read_png_chunk((length + 12) as usize, data_buff); 79 } 80 "IEND" => {} 81 "IDAT" => {} 82 _ => { 83 self.read_png_chunk((length + 12) as usize, data_buff); 84 } 85 } 86 } 87}