aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-06 05:51:41 +0000
committerAkshay <[email protected]>2021-03-06 05:51:41 +0000
commita570dc384279bf9b38ff0cc9d4635c2081aa3147 (patch)
treeb7574b46fc7fdcc6a2627c8ce09cd95aee6ff0ce
parentf46b981d06128642fee7e81f83b4ff09bd5f1be8 (diff)
add image manip apis
-rw-r--r--src/lib.rs40
-rw-r--r--tests/image.rs49
2 files changed, 79 insertions, 10 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 7429101..f949d06 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,6 @@
1#![allow(unreachable_patterns)] 1#![allow(unreachable_patterns)]
2#![allow(non_snake_case)] 2#![allow(non_snake_case)]
3#![allow(dead_code)]
3 4
4use std::io; 5use std::io;
5 6
@@ -24,6 +25,7 @@ impl OBIVersion {
24} 25}
25 26
26#[non_exhaustive] 27#[non_exhaustive]
28#[derive(Debug)]
27pub struct FileHeader { 29pub struct FileHeader {
28 pub file_size: u32, 30 pub file_size: u32,
29 pub data_offset: u32, 31 pub data_offset: u32,
@@ -45,6 +47,7 @@ impl FileHeader {
45} 47}
46 48
47#[non_exhaustive] 49#[non_exhaustive]
50#[derive(Debug)]
48pub struct ImageInfoHeader { 51pub struct ImageInfoHeader {
49 pub width: u32, 52 pub width: u32,
50 pub height: u32, 53 pub height: u32,
@@ -82,6 +85,7 @@ impl CompressionType {
82 } 85 }
83} 86}
84 87
88#[derive(Debug)]
85pub struct Image { 89pub struct Image {
86 pub file_header: FileHeader, 90 pub file_header: FileHeader,
87 pub image_info_header: ImageInfoHeader, 91 pub image_info_header: ImageInfoHeader,
@@ -90,11 +94,15 @@ pub struct Image {
90 94
91impl Image { 95impl Image {
92 pub fn new(width: u32, height: u32) -> Self { 96 pub fn new(width: u32, height: u32) -> Self {
97 Self::new_with(width, height, false)
98 }
99
100 pub fn new_with(width: u32, height: u32, default_val: bool) -> Self {
93 // round to the nearest multiple of 8 101 // round to the nearest multiple of 8
94 // convert to number of bytes by dividing by 8 102 // convert to number of bytes by dividing by 8
95 let mut data_size = width * height + 7; 103 let mut data_size = width * height + 7;
96 data_size = data_size - (data_size % 8); 104 data_size = data_size - (data_size % 8);
97 let data = vec![false; data_size as usize]; 105 let data = vec![default_val; data_size as usize];
98 106
99 Self { 107 Self {
100 file_header: FileHeader::new(OBIVersion::One, data_size / 8), 108 file_header: FileHeader::new(OBIVersion::One, data_size / 8),
@@ -111,20 +119,32 @@ impl Image {
111 self.image_info_header.height 119 self.image_info_header.height
112 } 120 }
113 121
114 fn to_index(&self, x: u32, y: u32) -> usize { 122 #[doc(hidden)]
115 (y * self.width() + x) as usize 123 pub fn index(&self, x: u32, y: u32) -> OBIResult<usize> {
116 } 124 if x >= self.width() || y >= self.height() {
117
118 pub fn set_pixel(&mut self, x: u32, y: u32, val: bool) -> OBIResult<()> {
119 if x >= self.width() || y > self.height() {
120 Err(OBIError::Image) 125 Err(OBIError::Image)
121 } else { 126 } else {
122 let index = self.to_index(x, y); 127 return Ok((y * self.width() + x) as usize);
123 self.data[index] = val;
124 Ok(())
125 } 128 }
126 } 129 }
127 130
131 pub fn set(&mut self, x: u32, y: u32, val: bool) -> OBIResult<()> {
132 let index = self.index(x, y)?;
133 self.data[index] = val;
134 Ok(())
135 }
136
137 pub fn flip(&mut self, x: u32, y: u32) -> OBIResult<()> {
138 let index = self.index(x, y)?;
139 self.data[index] = !self.data[index];
140 Ok(())
141 }
142
143 pub fn get(&self, x: u32, y: u32) -> OBIResult<bool> {
144 let index = self.index(x, y)?;
145 Ok(self.data[index])
146 }
147
128 pub fn encode(&self) -> OBIResult<Vec<u8>> { 148 pub fn encode(&self) -> OBIResult<Vec<u8>> {
129 encode::encode_image(self) 149 encode::encode_image(self)
130 } 150 }
diff --git a/tests/image.rs b/tests/image.rs
new file mode 100644
index 0000000..2006a3b
--- /dev/null
+++ b/tests/image.rs
@@ -0,0 +1,49 @@
1use obi::Image;
2
3#[test]
4fn image_indexing() {
5 let (width, height) = (30, 50);
6 let img = Image::new(width, height);
7 for x in 0..width {
8 for y in 0..height {
9 assert_eq!((y * width + x) as usize, img.index(x, y).unwrap());
10 }
11 }
12}
13
14#[test]
15#[should_panic]
16fn x_value_out_of_bounds() {
17 let img = Image::new(30, 50);
18 img.index(30, 0).unwrap();
19}
20
21#[test]
22#[should_panic]
23fn y_value_out_of_bounds() {
24 let img = Image::new(30, 50);
25 img.index(0, 50).unwrap();
26}
27
28#[test]
29fn pixel_setter_and_getters() {
30 let mut img = Image::new(100, 200);
31 img.set(2, 3, true).unwrap();
32 assert!(img.get(2, 3).unwrap());
33 assert_eq!(1, img.data.iter().filter(|&&x| x).count());
34}
35
36#[test]
37fn flip_bits() {
38 let (width, height) = (100, 200);
39 let mut img = Image::new(width, height);
40 img.set(2, 3, true).expect("Indexing error");
41 for i in 0..width {
42 for j in 0..height {
43 img.flip(i, j).unwrap();
44 }
45 }
46 let mut expected = Image::new_with(width, height, true);
47 expected.set(2, 3, false).expect("Indexing error");
48 assert_eq!(expected.data, img.data);
49}