use std::borrow::Cow;
use crate::{Binarizer, LuminanceSource};
use super::{BitArray, BitMatrix, LineOrientation};
pub struct BitMatrixSource {
base_bitmatrix: BitMatrix,
byte_array: Box<[u8]>,
}
impl BitMatrixSource {
pub fn new(base_bitmatrix: BitMatrix) -> Self {
let mut tmp =
Vec::with_capacity((base_bitmatrix.getWidth() * base_bitmatrix.getHeight()) as usize);
for y in 0..base_bitmatrix.getHeight() {
for x in 0..base_bitmatrix.getWidth() {
tmp.push(if base_bitmatrix.get(x, y) { 255 } else { 0 });
}
}
Self {
base_bitmatrix,
byte_array: tmp.into_boxed_slice(),
}
}
}
impl LuminanceSource for BitMatrixSource {
fn get_row(&self, y: usize) -> Option<Cow<'_, [u8]>> {
let row: Vec<u8> = self.base_bitmatrix.getRow(y as u32).into();
Some(Cow::Owned(row))
}
fn get_column(&self, x: usize) -> Vec<u8> {
self.base_bitmatrix.getCol(x as u32).into()
}
fn get_matrix(&self) -> Vec<u8> {
self.byte_array.to_vec()
}
fn get_width(&self) -> usize {
self.base_bitmatrix.getWidth() as usize
}
fn get_height(&self) -> usize {
self.base_bitmatrix.getHeight() as usize
}
fn invert(&mut self) {
for byte in self.byte_array.iter_mut() {
match byte {
0 => *byte = 255,
255 => *byte = 0,
_ => unreachable!(),
}
}
}
fn get_luma8_point(&self, x: usize, y: usize) -> u8 {
if !self.base_bitmatrix.get(x as u32, y as u32) {
0
} else {
255
}
}
}
pub struct BitMatrixBinarizer(BitMatrixSource);
impl Binarizer for BitMatrixBinarizer {
type Source = BitMatrixSource;
fn get_luminance_source(&self) -> &Self::Source {
&self.0
}
fn get_black_row(&self, y: usize) -> super::Result<std::borrow::Cow<BitArray>> {
Ok(Cow::Owned(self.0.get_row(y).unwrap_or().to_vec().into()))
}
fn get_black_row_from_matrix(
&self,
y: usize,
) -> super::Result<std::borrow::Cow<super::BitArray>> {
self.get_black_row(y)
}
fn get_black_matrix(&self) -> super::Result<&super::BitMatrix> {
Ok(&self.0.base_bitmatrix)
}
fn get_black_line(
&self,
l: usize,
lt: super::LineOrientation,
) -> super::Result<std::borrow::Cow<super::BitArray>> {
match lt {
LineOrientation::Row => self.get_black_row(l),
LineOrientation::Column => Ok(Cow::Owned(self.0.get_column(l).into())),
}
}
fn create_binarizer(&self, source: Self::Source) -> Self
where
Self: Sized,
{
Self(source)
}
fn get_width(&self) -> usize {
self.0.get_width()
}
fn get_height(&self) -> usize {
self.0.get_height()
}
}