From 81198d59f73e2b2160b64dc11b52f0cc21ba027b Mon Sep 17 00:00:00 2001 From: Akshay Date: Mon, 1 Mar 2021 18:37:43 +0530 Subject: redefine pixel as bool, implement encoding --- Cargo.toml | 2 ++ src/encode.rs | 34 ++++++++++++++++++++++++++++++++++ src/lib.rs | 32 ++++++++++++++++++-------------- 3 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 src/encode.rs diff --git a/Cargo.toml b/Cargo.toml index d3ca6e4..d343a43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +byteorder = "1.4.2" +bitvec = "0.21.0" diff --git a/src/encode.rs b/src/encode.rs new file mode 100644 index 0000000..24d3792 --- /dev/null +++ b/src/encode.rs @@ -0,0 +1,34 @@ +use std::io; + +use bitvec::prelude::*; +use bitvec::slice::BitSlice; +use byteorder::{LittleEndian, WriteBytesExt}; + +use crate::Image; + +pub fn encode_image(obi_image: Image) -> io::Result> { + let mut obi_data = Vec::with_capacity(obi_image.file_header.file_size as usize); + + // file header + let file_header = obi_image.file_header; + obi_data.write_u16::(file_header.version)?; + obi_data.write_u32::(file_header.file_size)?; + obi_data.write_u32::(file_header.data_offset)?; + + // image info header + let image_info_header = obi_image.image_info_header; + obi_data.write_u32::(image_info_header.width)?; + obi_data.write_u32::(image_info_header.height)?; + obi_data.write_u32::(image_info_header.compression_type)?; + obi_data.write_u32::(image_info_header.post_compression_size)?; + + // pixmap data + let pixmap = obi_image.data; + for byte in pixmap.chunks(8) { + let bits_as_u8 = byte.iter().map(|&e| e as u8).collect::>(); + let slice = BitSlice::::from_slice(&bits_as_u8).unwrap(); + obi_data.write_u8(slice.load::())?; + } + + return Ok(obi_data); +} diff --git a/src/lib.rs b/src/lib.rs index 1471aa8..61ca7a8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,7 @@ #![allow(unreachable_patterns)] #![allow(non_snake_case)] -#[non_exhaustive] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Pixel { - On, - Off, -} + +pub mod encode; #[non_exhaustive] #[derive(Copy, Clone, Debug, PartialEq)] @@ -16,16 +12,16 @@ pub enum OBIVersion { impl OBIVersion { pub fn header_size(&self) -> u32 { match self { - One => 26, + OBIVersion::One => 26, } } } #[non_exhaustive] pub struct FileHeader { - pub version: u16, pub file_size: u32, pub data_offset: u32, + pub version: u16, } impl FileHeader { @@ -82,15 +78,19 @@ impl CompressionType { pub struct Image { pub file_header: FileHeader, pub image_info_header: ImageInfoHeader, - pub data: Vec, + pub data: Vec, } impl Image { pub fn new(width: u32, height: u32) -> Self { - let data_size = width * height; - let data = vec![Pixel::Off; data_size as usize]; + // round to the nearest multiple of 8 + // convert to number of bytes by dividing by 8 + let mut data_size = width * height + 7; + data_size = data_size - (data_size % 8); + let data = vec![false; data_size as usize]; + Self { - file_header: FileHeader::new(OBIVersion::One, data_size), + file_header: FileHeader::new(OBIVersion::One, data_size / 8), image_info_header: ImageInfoHeader::new(width, height), data, } @@ -99,8 +99,12 @@ impl Image { #[cfg(test)] mod tests { + use super::*; + use std::mem::size_of; + #[test] - fn it_works() { - assert_eq!(2 + 2, 4); + fn size_of_image_info_header() { + let file_header_size = size_of::(); + assert_eq!(16, file_header_size); } } -- cgit v1.2.3