1 use core::slice::Iter; 2 3 pub struct BitIter<'a> { 4 fgcolor: u32, 5 bkcolor: u32, 6 _color_pattern: EndianPattern, 7 _dst_pattern: EndianPattern, 8 src: Iter<'a, u8>, 9 read_mask: u8, 10 byte_per_pixel: u32, 11 buffer: u32, 12 current: u8, 13 left_byte: u32, 14 done: bool, 15 consumed_bit: u32, 16 image_width: u32, 17 } 18 19 impl<'a> BitIter<'a> { new( fgcolor: u32, bkcolor: u32, dst_pattern: EndianPattern, color_pattern: EndianPattern, byte_per_pixel: u32, src: Iter<'a, u8>, image_width: u32, ) -> Self20 pub fn new( 21 fgcolor: u32, 22 bkcolor: u32, 23 dst_pattern: EndianPattern, 24 color_pattern: EndianPattern, 25 byte_per_pixel: u32, 26 src: Iter<'a, u8>, 27 image_width: u32, 28 ) -> Self { 29 let mut fgcolor = fgcolor; 30 let mut bkcolor = bkcolor; 31 if dst_pattern != color_pattern { 32 fgcolor = Self::reverse(fgcolor, byte_per_pixel); 33 bkcolor = Self::reverse(bkcolor, byte_per_pixel); 34 } 35 36 let mut ans = Self { 37 fgcolor, 38 bkcolor, 39 _color_pattern: color_pattern, 40 _dst_pattern: dst_pattern, 41 src, 42 read_mask: 0b10000000, 43 byte_per_pixel, 44 buffer: 0, 45 current: 0, 46 left_byte: 0, 47 done: false, 48 consumed_bit: 0, 49 image_width, 50 }; 51 ans.current = *ans.src.next().unwrap(); 52 return ans; 53 } 54 reverse(num: u32, byte_per_pixel: u32) -> u3255 fn reverse(num: u32, byte_per_pixel: u32) -> u32 { 56 let mask = 0x000000ff; 57 let mut ans = 0; 58 let mut num = num; 59 for _ in 0..3 { 60 ans |= mask & num; 61 ans <<= 8; 62 num >>= 8; 63 } 64 ans |= mask & num; 65 ans >>= (4 - byte_per_pixel) * 8; 66 return ans; 67 } 68 move_mask(&mut self) -> bool69 fn move_mask(&mut self) -> bool { 70 self.consumed_bit += 1; 71 self.read_mask >>= 1; 72 if self.read_mask == 0b000000000 { 73 self.read_mask = 0b10000000; 74 self.current = match self.src.next() { 75 Some(x) => *x, 76 None => { 77 return false; 78 } 79 }; 80 return true; 81 } else { 82 return true; 83 } 84 } 85 full_buffer(&mut self) -> Result<PixelLineStatus, PixelLineStatus>86 fn full_buffer(&mut self) -> Result<PixelLineStatus, PixelLineStatus> { 87 let same_endian = if self._dst_pattern == self._color_pattern { 88 1 89 } else { 90 -1 91 }; 92 let mut color = self.read_bit() << (self.left_byte << 3); 93 let mut buffer_pointer = if self._dst_pattern == self._color_pattern { 94 0 95 } else { 96 3 97 }; 98 let mask = 0x000000ff << ((self.byte_per_pixel - 1) << 3); 99 let mut temp; 100 // while buffer_pointer >= 0 && buffer_pointer <= 3 { 101 while (0..=3).contains(&buffer_pointer) { 102 if self.consumed_bit >= self.image_width { 103 self.consumed_bit = 0; 104 return Ok(PixelLineStatus::Full(self.buffer)); 105 } 106 temp = color & mask; 107 color <<= 8; 108 temp <<= (4 - self.byte_per_pixel) * 8; 109 temp >>= buffer_pointer * 8; 110 self.buffer |= temp; 111 buffer_pointer += same_endian; 112 self.left_byte += 1; 113 if self.left_byte >= self.byte_per_pixel { 114 self.left_byte = 0; 115 if !self.move_mask() { 116 return Err(PixelLineStatus::Full(self.buffer)); 117 } 118 color = self.read_bit(); 119 } 120 } 121 if self.consumed_bit >= self.image_width { 122 self.consumed_bit = 0; 123 return Ok(PixelLineStatus::Full(self.buffer)); 124 } 125 return Ok(PixelLineStatus::NotFull(self.buffer)); 126 } 127 read_bit(&self) -> u32128 fn read_bit(&self) -> u32 { 129 match self.read_mask & self.current { 130 0 => self.bkcolor, 131 _ => self.fgcolor, 132 } 133 } 134 } 135 136 impl Iterator for BitIter<'_> { 137 type Item = (u32, bool); next(&mut self) -> Option<Self::Item>138 fn next(&mut self) -> Option<Self::Item> { 139 if self.done { 140 return None; 141 } 142 match self.full_buffer() { 143 Ok(x) => { 144 self.buffer = 0; 145 return Some(x.unwarp()); 146 } 147 Err(x) => { 148 self.done = true; 149 return Some(x.unwarp()); 150 } 151 } 152 } 153 } 154 #[derive(PartialEq, PartialOrd)] 155 pub enum EndianPattern { 156 Big, 157 Little, 158 } 159 160 pub enum PixelLineStatus { 161 Full(u32), 162 NotFull(u32), 163 } 164 165 impl PixelLineStatus { unwarp(self) -> (u32, bool)166 pub fn unwarp(self) -> (u32, bool) { 167 match self { 168 PixelLineStatus::Full(x) => (x, true), 169 PixelLineStatus::NotFull(x) => (x, false), 170 } 171 } 172 } 173