A photo manager for VRChat.
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}