mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
adding result points to sampler
This commit is contained in:
@@ -83,6 +83,14 @@ impl BitArray {
|
||||
(self.bits[i / 32] & (1 << (i & 0x1F))) != 0
|
||||
}
|
||||
|
||||
pub fn try_get(&self, i:usize) -> Option<bool> {
|
||||
if (i / 32) >= self.bits.len() {
|
||||
None
|
||||
}else {
|
||||
Some(self.get(i))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bit i.
|
||||
*
|
||||
|
||||
@@ -222,6 +222,10 @@ impl BitMatrix {
|
||||
// ((self.bits[offset] >> (x & 0x1f)) & 1) != 0
|
||||
}
|
||||
|
||||
pub fn get_index<T: Into<usize>>(&self, index: T) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn get_offset(&self, y: u32, x: u32) -> usize {
|
||||
y as usize * self.row_size + (x as usize / 32)
|
||||
@@ -748,6 +752,19 @@ impl fmt::Display for BitMatrix {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&BitMatrix> for Vec<bool> {
|
||||
fn from(value: &BitMatrix) -> Self {
|
||||
let mut arr = vec![false;(value.width * value.height) as usize];
|
||||
for x in 0..value.width {
|
||||
for y in 0..value.height {
|
||||
let insert_pos = ((y * value.width) + x )as usize;
|
||||
arr[insert_pos] = value.get(x, y);
|
||||
}
|
||||
}
|
||||
arr
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// This should only be used if you *know* that the `DynamicImage` is binary.
|
||||
impl TryFrom<image::DynamicImage> for BitMatrix {
|
||||
|
||||
@@ -68,7 +68,7 @@ pub fn ReadSymmetricPattern<const N: usize, Cursor: BitMatrixCursorTrait>(
|
||||
|
||||
for i in 0..=s_2 {
|
||||
// for (int i = 0; i <= s_2; ++i) {
|
||||
if !next(cur, i) != 0 || !next(&mut cuo, -i) != 0 {
|
||||
if !next(cur, i) == 0 || !next(&mut cuo, -i) == 0 {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@@ -124,14 +124,14 @@ pub fn CheckSymmetricPattern<
|
||||
}
|
||||
}
|
||||
|
||||
if !(IsPattern(
|
||||
if IsPattern(
|
||||
&PatternView::new(&res),
|
||||
&FixedPattern::<LEN, SUM, false>::with_reference(pattern),
|
||||
None,
|
||||
0.0,
|
||||
0.0,
|
||||
Some(RELAXED_THRESHOLD),
|
||||
) != 0.0)
|
||||
) == 0.0
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -220,9 +220,9 @@ pub fn CenterOfRing(
|
||||
n += 1;
|
||||
|
||||
// find out if we come full circle around the center. 8 bits have to be set in the end.
|
||||
neighbourMask |= 1
|
||||
<< (4.0 + Point::dot(Point::bresenhamDirection(cur.p() - center), point(1.0, 3.0)))
|
||||
as u32;
|
||||
neighbourMask |= (1
|
||||
<< (4.0 + Point::dot(Point::round(Point::bresenhamDirection(cur.p() - center)), point(1.0, 3.0)))
|
||||
as u32);
|
||||
|
||||
if !cur.stepAlongEdge(edgeDir, None) {
|
||||
return None;
|
||||
|
||||
@@ -182,7 +182,7 @@ impl<'a> EdgeTracer<'_> {
|
||||
EdgeTracer {
|
||||
img: image,
|
||||
p,
|
||||
d,
|
||||
d: Point::bresenhamDirection(d), //d,
|
||||
history: None,
|
||||
state: 0,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use crate::common::BitArray;
|
||||
|
||||
use super::BitMatrixCursorTrait;
|
||||
|
||||
pub struct FastEdgeToEdgeCounter {
|
||||
@@ -7,66 +5,77 @@ pub struct FastEdgeToEdgeCounter {
|
||||
// int stride = 0;
|
||||
// int stepsToBorder = 0;
|
||||
p: u32, // = nullptr;
|
||||
stride: u32, // = 0;
|
||||
stepsToBorder: u32, // = 0;
|
||||
arr: BitArray,
|
||||
stride: isize, // = 0;
|
||||
stepsToBorder: i32, // = 0;
|
||||
//arr: BitArray,
|
||||
_arr: isize,
|
||||
under_arry: Vec<bool>,
|
||||
}
|
||||
|
||||
impl FastEdgeToEdgeCounter {
|
||||
pub fn new<T: BitMatrixCursorTrait>(cur: &T) -> Self {
|
||||
let stride = cur.d().y as u32 * cur.img().width() as u32 + cur.d().x as u32;
|
||||
let p = /*cur.img().getRow(cur.p().y).begin()*/ 0 + cur.p().x as u32;
|
||||
let stride = cur.d().y as isize * cur.img().width() as isize + cur.d().x as isize;
|
||||
let p = ((cur.p().y as isize * cur.img().width() as isize).abs() as i32 + cur.p().x as i32) as u32; // P IS SET WRONG IN REVERSE
|
||||
|
||||
let maxStepsX = if cur.d().x != 0.0 {
|
||||
(if cur.d().x > 0.0 {
|
||||
if cur.d().x > 0.0 {
|
||||
cur.img().width() - 1 - cur.p().x as u32
|
||||
} else {
|
||||
cur.p().x as u32
|
||||
})
|
||||
}
|
||||
} else {
|
||||
u32::MAX
|
||||
};
|
||||
let maxStepsY = if cur.d().y != 0.0 {
|
||||
(if cur.d().y > 0.0 {
|
||||
if cur.d().y > 0.0 {
|
||||
cur.img().height() - 1 - cur.p().y as u32
|
||||
} else {
|
||||
cur.p().y as u32
|
||||
})
|
||||
}
|
||||
} else {
|
||||
u32::MAX
|
||||
};
|
||||
let stepsToBorder = std::cmp::min(maxStepsX, maxStepsY);
|
||||
let stepsToBorder = std::cmp::min(maxStepsX, maxStepsY) as i32;
|
||||
|
||||
Self {
|
||||
p,
|
||||
stride,
|
||||
stepsToBorder,
|
||||
arr: cur.img().getRow(cur.p().y as u32),
|
||||
_arr: cur.p().y as isize * stride as isize, //cur.img().getRow(cur.p().y as u32),
|
||||
under_arry: cur.img().into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stepToNextEdge(&mut self, range: u32) -> u32 {
|
||||
let maxSteps = std::cmp::min(self.stepsToBorder, range);
|
||||
let maxSteps = std::cmp::min(self.stepsToBorder, range as i32);
|
||||
let mut steps = 0;
|
||||
loop {
|
||||
steps += 1;
|
||||
if (steps > maxSteps) {
|
||||
if (maxSteps == self.stepsToBorder) {
|
||||
break;
|
||||
if steps > maxSteps {
|
||||
if maxSteps == self.stepsToBorder {
|
||||
break false;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if !(self.arr.get((self.p + steps * self.stride) as usize)
|
||||
== self.arr.get((self.p + 0) as usize))
|
||||
{
|
||||
break;
|
||||
}
|
||||
} // while (p[steps * stride] == p[0]);
|
||||
|
||||
self.p += steps * self.stride;
|
||||
let idx_pt = self.get_array_check_index(steps);
|
||||
|
||||
if !(self.under_arry[idx_pt]
|
||||
== self.under_arry[self.p as usize])
|
||||
{
|
||||
break true;
|
||||
}
|
||||
}; // while (p[steps * stride] == p[0]);
|
||||
|
||||
self.p = (self.p as isize + (steps as isize * self.stride)).abs() as u32;
|
||||
self.stepsToBorder -= steps;
|
||||
|
||||
return steps;
|
||||
return steps as u32;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn get_array_check_index(&self, steps: i32) -> usize {
|
||||
(self.p as isize + (steps as isize * self.stride)) as usize
|
||||
}
|
||||
}
|
||||
@@ -60,17 +60,22 @@ impl From<Vec<PatternType>> for PatternRow {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for PatternView<'_> {
|
||||
pub struct PatternViewIterator<'a> {
|
||||
pattern_view: &'a PatternView<'a>,
|
||||
current_position: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for PatternViewIterator<'_> {
|
||||
type Item = PatternType;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.current + 1 > self.count {
|
||||
if self.current_position + 1 > self.pattern_view.count {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.current += 1;
|
||||
self.current_position += 1;
|
||||
|
||||
Some(*self.data.0.get(self.current + self.start)?)
|
||||
Some(*self.pattern_view.data.0.get(self.current_position - 1 + self.pattern_view.start + self.pattern_view.current)?)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +87,7 @@ pub struct PatternView<'a> {
|
||||
current: usize,
|
||||
}
|
||||
|
||||
impl<'a> PatternView<'_> {
|
||||
impl<'a> PatternView<'a> {
|
||||
// A PatternRow always starts with the width of whitespace in front of the first black bar.
|
||||
// The first element of the PatternView is the first bar.
|
||||
pub fn new(bars: &'a PatternRow) -> PatternView<'a> {
|
||||
@@ -126,6 +131,10 @@ impl<'a> PatternView<'_> {
|
||||
|
||||
// int sum(int n = 0) const { return std::accumulate(_data, _data + (n == 0 ? _size : n), 0); }
|
||||
pub fn sum(&self, n: Option<usize>) -> PatternType {
|
||||
if self.count == self.data.len() {
|
||||
return self.data.0.iter().sum::<PatternType>();
|
||||
}
|
||||
|
||||
let n = n.unwrap_or(self.count);
|
||||
|
||||
self.data
|
||||
@@ -137,6 +146,10 @@ impl<'a> PatternView<'_> {
|
||||
.sum::<PatternType>()
|
||||
}
|
||||
|
||||
pub fn iter(&'a self) -> PatternViewIterator<'a> {
|
||||
PatternViewIterator { pattern_view: self, current_position: 0 }
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
self.count
|
||||
}
|
||||
@@ -149,8 +162,7 @@ impl<'a> PatternView<'_> {
|
||||
self.data
|
||||
.0
|
||||
.iter()
|
||||
.skip(self.start)
|
||||
.take(self.current)
|
||||
.take(self.start + self.current)
|
||||
.copied()
|
||||
.sum::<PatternType>() /*return std::accumulate(_base, _data, 0);*/
|
||||
}
|
||||
@@ -170,8 +182,8 @@ impl<'a> PatternView<'_> {
|
||||
}
|
||||
pub fn isValidWithN(&self, n: usize) -> bool {
|
||||
!self.data.0.is_empty()
|
||||
&& self.start <= self.current
|
||||
&& self.start + n <= (self.start + self.count)
|
||||
&& self.start <= self.current + self.start
|
||||
&& self.current + n <= (self.data.0.len())
|
||||
/*return _data && _data >= _base && _data + n <= _end;*/
|
||||
}
|
||||
pub fn isValid(&self) -> bool {
|
||||
@@ -201,7 +213,7 @@ impl<'a> PatternView<'_> {
|
||||
// return (acceptIfAtLastBar && isAtLastBar()) || _data[_size] >= sum() * scale;
|
||||
// }
|
||||
|
||||
pub fn subView(&'a self, offset: usize, size: Option<usize>) -> PatternView<'a> {
|
||||
pub fn subView(&self, offset: usize, size: Option<usize>) -> PatternView<'a> {
|
||||
let mut size = size.unwrap_or(0);
|
||||
if size == 0 {
|
||||
size = self.count - offset;
|
||||
@@ -252,7 +264,7 @@ impl<'a> PatternView<'_> {
|
||||
}
|
||||
|
||||
pub fn extend(&mut self) {
|
||||
self.count = std::cmp::max(0, self.count - self.start)
|
||||
self.count = std::cmp::max(0, self.data.len() - (self.current + self.start))
|
||||
}
|
||||
|
||||
fn try_get_index(&self, index: isize) -> Option<PatternType> {
|
||||
@@ -275,6 +287,10 @@ impl<'a> std::ops::Index<isize> for PatternView<'_> {
|
||||
type Output = PatternType;
|
||||
|
||||
fn index(&self, index: isize) -> &Self::Output {
|
||||
if self.count == self.data.len() {
|
||||
return &self.data[index.abs() as usize]
|
||||
}
|
||||
|
||||
if index > self.data.0.len() as isize {
|
||||
panic!("array index out of bounds")
|
||||
}
|
||||
@@ -294,6 +310,10 @@ impl<'a> std::ops::Index<usize> for PatternView<'_> {
|
||||
type Output = PatternType;
|
||||
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
if self.count == self.data.len() {
|
||||
return &self.data[index]
|
||||
}
|
||||
|
||||
if index > self.data.0.len() {
|
||||
panic!("array index out of bounds")
|
||||
}
|
||||
@@ -442,7 +462,7 @@ pub fn IsPattern<const LEN: usize, const SUM: usize, const SPARSE: bool>(
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
if (module_size_ref == 0.0) {
|
||||
if module_size_ref == 0.0 {
|
||||
module_size_ref = module_size;
|
||||
}
|
||||
|
||||
@@ -485,7 +505,7 @@ pub fn IsRightGuard<const N: usize, const SUM: usize, const IS_SPARCE: bool>(
|
||||
}
|
||||
|
||||
pub fn FindLeftGuardBy<'a, const LEN: usize, Pred: Fn(&PatternView, Option<f32>) -> bool>(
|
||||
view: &'a PatternView,
|
||||
view: PatternView<'a>,
|
||||
minSize: usize,
|
||||
isGuard: Pred,
|
||||
) -> Result<PatternView<'a>> {
|
||||
@@ -517,7 +537,7 @@ pub fn FindLeftGuardBy<'a, const LEN: usize, Pred: Fn(&PatternView, Option<f32>)
|
||||
}
|
||||
|
||||
pub fn FindLeftGuard<'a, const LEN: usize, const SUM: usize, const IS_SPARCE: bool>(
|
||||
view: &'a PatternView,
|
||||
view: PatternView<'a>,
|
||||
minSize: usize,
|
||||
pattern: &FixedPattern<LEN, SUM, IS_SPARCE>,
|
||||
minQuietZone: f32,
|
||||
@@ -526,8 +546,8 @@ pub fn FindLeftGuard<'a, const LEN: usize, const SUM: usize, const IS_SPARCE: bo
|
||||
// perform a fast plausability test for 1:1:3:1:1 pattern
|
||||
// dbg!(window[2], 2 as PatternType * std::cmp::max(window[0], window[4]));
|
||||
// dbg!(window[2] < std::cmp::max(window[1], window[3]));
|
||||
if (window[2] < 2 as PatternType * std::cmp::max(window[0], window[4])
|
||||
|| window[2] < std::cmp::max(window[1], window[3]))
|
||||
if window[2] < 2 as PatternType * std::cmp::max(window[0], window[4])
|
||||
|| window[2] < std::cmp::max(window[1], window[3])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ impl GridSampler for DefaultGridSampler {
|
||||
dimensionX: u32,
|
||||
dimensionY: u32,
|
||||
controls: &[SamplerControl],
|
||||
) -> Result<BitMatrix> {
|
||||
) -> Result<(BitMatrix,[Point;4])> {
|
||||
if dimensionX <= 0 || dimensionY <= 0 {
|
||||
return Err(Exceptions::NOT_FOUND);
|
||||
}
|
||||
@@ -89,11 +89,11 @@ impl GridSampler for DefaultGridSampler {
|
||||
Point::default()
|
||||
};
|
||||
|
||||
let _tl = projectCorner(point(0.0, 0.0));
|
||||
let _tr = projectCorner(Point::from((dimensionX, 0)));
|
||||
let _bl = projectCorner(Point::from((dimensionX, dimensionY)));
|
||||
let _br = projectCorner(Point::from((0, dimensionX)));
|
||||
let tl = projectCorner(point(0.0, 0.0));
|
||||
let tr = projectCorner(Point::from((dimensionX, 0)));
|
||||
let bl = projectCorner(Point::from((dimensionX, dimensionY)));
|
||||
let br = projectCorner(Point::from((0, dimensionX)));
|
||||
|
||||
Ok(bits)
|
||||
Ok((bits, [tl,tr,bl,br]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ pub trait GridSampler {
|
||||
dimensionY: u32,
|
||||
dst: Quadrilateral,
|
||||
src: Quadrilateral,
|
||||
) -> Result<BitMatrix> {
|
||||
) -> Result<(BitMatrix,[Point;4])> {
|
||||
let transform = PerspectiveTransform::quadrilateralToQuadrilateral(dst, src)?;
|
||||
|
||||
self.sample_grid(
|
||||
@@ -112,7 +112,7 @@ pub trait GridSampler {
|
||||
dimensionX: u32,
|
||||
dimensionY: u32,
|
||||
controls: &[SamplerControl],
|
||||
) -> Result<BitMatrix> {
|
||||
) -> Result<(BitMatrix,[Point;4])> {
|
||||
if dimensionX == 0 || dimensionY == 0 {
|
||||
return Err(Exceptions::NOT_FOUND);
|
||||
}
|
||||
@@ -172,7 +172,7 @@ pub trait GridSampler {
|
||||
}
|
||||
// dbg!(bits.to_string());
|
||||
|
||||
Ok(bits)
|
||||
Ok((bits, [Point::default(), Point::default(), Point::default(), Point::default()]))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user