aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-01 16:40:12 +0000
committerAkshay <[email protected]>2021-03-01 16:40:12 +0000
commit654be91de3768f7c01acb36ab82460765927493a (patch)
tree3aadb59fc081751b1ac37da0c33981418d24cecf
parent81198d59f73e2b2160b64dc11b52f0cc21ba027b (diff)
add decode logic
-rw-r--r--src/decode.rs50
-rw-r--r--src/encode.rs11
-rw-r--r--src/lib.rs8
3 files changed, 64 insertions, 5 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 @@
1use std::io::{self, Cursor, Read};
2
3use bitvec::prelude::*;
4use byteorder::{LittleEndian, ReadBytesExt};
5
6use crate::{FileHeader, Image, ImageInfoHeader};
7
8pub 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}
diff --git a/src/encode.rs b/src/encode.rs
index 24d3792..e5760a8 100644
--- a/src/encode.rs
+++ b/src/encode.rs
@@ -1,7 +1,6 @@
1use std::io; 1use std::io;
2 2
3use bitvec::prelude::*; 3use bitvec::{prelude::*, vec::BitVec};
4use bitvec::slice::BitSlice;
5use byteorder::{LittleEndian, WriteBytesExt}; 4use byteorder::{LittleEndian, WriteBytesExt};
6 5
7use crate::Image; 6use crate::Image;
@@ -25,9 +24,11 @@ pub fn encode_image(obi_image: Image) -> io::Result<Vec<u8>> {
25 // pixmap data 24 // pixmap data
26 let pixmap = obi_image.data; 25 let pixmap = obi_image.data;
27 for byte in pixmap.chunks(8) { 26 for byte in pixmap.chunks(8) {
28 let bits_as_u8 = byte.iter().map(|&e| e as u8).collect::<Vec<_>>(); 27 let mut bv = BitVec::<Lsb0, u8>::new();
29 let slice = BitSlice::<Lsb0, _>::from_slice(&bits_as_u8).unwrap(); 28 for &b in byte {
30 obi_data.write_u8(slice.load::<u8>())?; 29 bv.push(b);
30 }
31 obi_data.write_u8(bv.load::<u8>())?;
31 } 32 }
32 33
33 return Ok(obi_data); 34 return Ok(obi_data);
diff --git a/src/lib.rs b/src/lib.rs
index 61ca7a8..cd7923c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
1#![allow(unreachable_patterns)] 1#![allow(unreachable_patterns)]
2#![allow(non_snake_case)] 2#![allow(non_snake_case)]
3 3
4pub mod decode;
4pub mod encode; 5pub mod encode;
5 6
6#[non_exhaustive] 7#[non_exhaustive]
@@ -107,4 +108,11 @@ mod tests {
107 let file_header_size = size_of::<ImageInfoHeader>(); 108 let file_header_size = size_of::<ImageInfoHeader>();
108 assert_eq!(16, file_header_size); 109 assert_eq!(16, file_header_size);
109 } 110 }
111
112 #[test]
113 fn encode_decode() {
114 let img = Image::new(100, 80);
115 let encoded = encode::encode_image(img).unwrap();
116 assert_eq!(encoded.len(), 1026);
117 }
110} 118}