diff options
Diffstat (limited to 'src/decode.rs')
-rw-r--r-- | src/decode.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/decode.rs b/src/decode.rs new file mode 100644 index 0000000..59dae97 --- /dev/null +++ b/src/decode.rs | |||
@@ -0,0 +1,50 @@ | |||
1 | use std::io::{self, Cursor, Read}; | ||
2 | |||
3 | use bitvec::prelude::*; | ||
4 | use byteorder::{LittleEndian, ReadBytesExt}; | ||
5 | |||
6 | use crate::{FileHeader, Image, ImageInfoHeader}; | ||
7 | |||
8 | pub fn decode_image(obi_data: &mut Cursor<Vec<u8>>) -> io::Result<Image> { | ||
9 | // file header | ||
10 | let version = obi_data.read_u16::<LittleEndian>()?; | ||
11 | let file_size = obi_data.read_u32::<LittleEndian>()?; | ||
12 | let data_offset = obi_data.read_u32::<LittleEndian>()?; | ||
13 | let file_header = FileHeader { | ||
14 | version, | ||
15 | file_size, | ||
16 | data_offset, | ||
17 | }; | ||
18 | |||
19 | // image info header | ||
20 | let width = obi_data.read_u32::<LittleEndian>()?; | ||
21 | let height = obi_data.read_u32::<LittleEndian>()?; | ||
22 | let compression_type = obi_data.read_u32::<LittleEndian>()?; | ||
23 | let post_compression_size = obi_data.read_u32::<LittleEndian>()?; | ||
24 | let image_info_header = ImageInfoHeader { | ||
25 | width, | ||
26 | height, | ||
27 | compression_type, | ||
28 | post_compression_size, | ||
29 | }; | ||
30 | |||
31 | // pixmap data | ||
32 | let mut data_bytes = vec![]; | ||
33 | obi_data.read_to_end(&mut data_bytes)?; | ||
34 | let data = data_bytes | ||
35 | .iter() | ||
36 | .map(|&b| { | ||
37 | BitVec::<Lsb0, u8>::from_element(b) | ||
38 | .into_iter() | ||
39 | .map(|e| e as bool) | ||
40 | .collect::<Vec<bool>>() | ||
41 | }) | ||
42 | .flatten() | ||
43 | .collect::<Vec<_>>(); | ||
44 | |||
45 | return Ok(Image { | ||
46 | file_header, | ||
47 | image_info_header, | ||
48 | data, | ||
49 | }); | ||
50 | } | ||