#![allow(deprecated)]
use crate::{
common::{BitMatrix, Result},
point_f, Exceptions, Point,
};
const MAX_MODULES: i32 = 32;
#[deprecated]
pub struct MonochromeRectangleDetector<'a> {
image: &'a BitMatrix,
}
impl<'a> MonochromeRectangleDetector<'_> {
pub fn new(image: &'a BitMatrix) -> MonochromeRectangleDetector<'a> {
MonochromeRectangleDetector { image }
}
pub fn detect(&self) -> Result<[Point; 4]> {
let height = self.image.getHeight() as i32;
let width = self.image.getWidth() as i32;
let halfHeight = height / 2;
let halfWidth = width / 2;
let deltaY = 1.max(height / (MAX_MODULES * 8));
let deltaX = 1.max(width / (MAX_MODULES * 8));
let mut top = 0;
let mut bottom = height;
let mut left = 0;
let mut right = width;
let mut pointA = self.findCornerFromCenter(
halfWidth,
0,
left,
right,
halfHeight,
-deltaY,
top,
bottom,
halfWidth / 2,
)?;
top = (pointA.y - 1f32) as i32;
let pointB = self.findCornerFromCenter(
halfWidth,
-deltaX,
left,
right,
halfHeight,
0,
top,
bottom,
halfHeight / 2,
)?;
left = (pointB.x - 1f32) as i32;
let pointC = self.findCornerFromCenter(
halfWidth,
deltaX,
left,
right,
halfHeight,
0,
top,
bottom,
halfHeight / 2,
)?;
right = (pointC.x + 1f32) as i32;
let pointD = self.findCornerFromCenter(
halfWidth,
0,
left,
right,
halfHeight,
deltaY,
top,
bottom,
halfWidth / 2,
)?;
bottom = (pointD.y + 1f32) as i32;
pointA = self.findCornerFromCenter(
halfWidth,
0,
left,
right,
halfHeight,
-deltaY,
top,
bottom,
halfWidth / 4,
)?;
Ok([pointA, pointB, pointC, pointD])
}
#[allow(clippy::too_many_arguments)]
fn findCornerFromCenter(
&self,
centerX: i32,
deltaX: i32,
left: i32,
right: i32,
centerY: i32,
deltaY: i32,
top: i32,
bottom: i32,
maxWhiteRun: i32,
) -> Result<Point> {
let mut lastRange_z: Option<[i32; 2]> = None;
let mut y: i32 = centerY;
let mut x: i32 = centerX;
while y < bottom && y >= top && x < right && x >= left {
let range: Option<[i32; 2]> = if deltaX == 0 {
self.blackWhiteRange(y, maxWhiteRun, left, right, true)
} else {
self.blackWhiteRange(x, maxWhiteRun, top, bottom, false)
};
if range.is_none() {
if let Some(lastRange) = lastRange_z {
if deltaX == 0 {
let lastY = y - deltaY;
if lastRange[0] < centerX {
if lastRange[1] > centerX {
return Ok(point_f(
lastRange[usize::from(deltaY <= 0)] as f32,
lastY as f32,
));
}
return Ok(point_f(lastRange[0] as f32, lastY as f32));
} else {
return Ok(point_f(lastRange[1] as f32, lastY as f32));
}
} else {
let lastX = x - deltaX;
if lastRange[0] < centerY {
if lastRange[1] > centerY {
return Ok(point_f(
lastX as f32,
lastRange[usize::from(deltaX >= 0)] as f32,
));
}
return Ok(point_f(lastX as f32, lastRange[0] as f32));
} else {
return Ok(point_f(lastX as f32, lastRange[1] as f32));
}
}
}
} else {
return Err(Exceptions::NOT_FOUND);
}
lastRange_z = range;
y += deltaY;
x += deltaX
}
Err(Exceptions::NOT_FOUND)
}
fn blackWhiteRange(
&self,
fixedDimension: i32,
maxWhiteRun: i32,
minDim: i32,
maxDim: i32,
horizontal: bool,
) -> Option<[i32; 2]> {
let center = (minDim + maxDim) / 2;
let mut start = center;
while start >= minDim {
if if horizontal {
self.image.get(start as u32, fixedDimension as u32)
} else {
self.image.get(fixedDimension as u32, start as u32)
} {
start -= 1;
} else {
let whiteRunStart = start;
start -= 1;
while start >= minDim
&& !(if horizontal {
self.image.get(start as u32, fixedDimension as u32)
} else {
self.image.get(fixedDimension as u32, start as u32)
})
{
start -= 1;
}
let whiteRunSize = whiteRunStart - start;
if start < minDim || whiteRunSize > maxWhiteRun {
start = whiteRunStart;
break;
}
}
}
start += 1;
let mut end = center;
while end < maxDim {
if if horizontal {
self.image.get(end as u32, fixedDimension as u32)
} else {
self.image.get(fixedDimension as u32, end as u32)
} {
end += 1;
} else {
let whiteRunStart = end;
end += 1;
while end < maxDim
&& !(if horizontal {
self.image.get(end as u32, fixedDimension as u32)
} else {
self.image.get(fixedDimension as u32, end as u32)
})
{
end += 1;
}
let whiteRunSize = end - whiteRunStart;
if end >= maxDim || whiteRunSize > maxWhiteRun {
end = whiteRunStart;
break;
}
}
}
end -= 1;
if end > start {
Some([start, end])
} else {
None
}
}
}