use super::super::drawable::*;
use super::super::transform::*;
use super::Image;
use coord::{Coord, ToUnsigned};
#[derive(Debug)]
pub struct Image1BPP<'a> {
width: u32,
height: u32,
imagedata: &'a [u8],
pub offset: Coord,
}
impl<'a> Image<'a> for Image1BPP<'a> {
fn new(imagedata: &'a [u8], width: u32, height: u32) -> Self {
Self {
width,
height,
imagedata,
offset: Coord::new(0, 0),
}
}
}
impl<'a> IntoIterator for &'a Image1BPP<'a> {
type Item = Pixel;
type IntoIter = Image1BPPIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
Image1BPPIterator {
im: self,
x: 0,
y: 0,
}
}
}
#[derive(Debug)]
pub struct Image1BPPIterator<'a> {
x: u32,
y: u32,
im: &'a Image1BPP<'a>,
}
impl<'a> Iterator for Image1BPPIterator<'a> {
type Item = Pixel;
fn next(&mut self) -> Option<Self::Item> {
if (self.im.offset[0] + self.im.width as i32) < 0
&& (self.im.offset[1] + self.im.height as i32) < 0
{
return None;
}
let current_pixel = loop {
let w = self.im.width;
let h = self.im.height;
let x = self.x;
let y = self.y;
if x >= w || y >= h {
return None;
}
let bytes_in_row = (w / 8) + if w % 8 > 0 { 1 } else { 0 };
let row_start = bytes_in_row * y;
let row_byte_index = x / 8;
let byte_index = row_start + row_byte_index;
let bit_offset = 7 - (x - (row_byte_index * 8));
let bit_value = (self.im.imagedata[byte_index as usize] >> bit_offset) & 1;
let current_pixel = self.im.offset + Coord::new(x as i32, y as i32);
self.x += 1;
if self.x >= w {
self.x = 0;
self.y += 1;
}
if current_pixel[0] >= 0 && current_pixel[1] >= 0 {
break (current_pixel.to_unsigned(), bit_value);
}
};
Some(current_pixel)
}
}
impl<'a> Drawable for Image1BPP<'a> {}
impl<'a> Transform for Image1BPP<'a> {
fn translate(&self, by: Coord) -> Self {
Self {
offset: self.offset + by,
..*self
}
}
fn translate_mut(&mut self, by: Coord) -> &mut Self {
self.offset += by;
self
}
}