mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
likely fix to row indicator problem now a trait
This commit is contained in:
@@ -18,7 +18,10 @@ use std::fmt::Display;
|
|||||||
|
|
||||||
use crate::pdf417::pdf_417_common;
|
use crate::pdf417::pdf_417_common;
|
||||||
|
|
||||||
use super::{BarcodeMetadata, BoundingBox, Codeword, DetectionRXingResultColumn};
|
use super::{
|
||||||
|
BarcodeMetadata, BoundingBox, Codeword, DetectionRXingResultColumn,
|
||||||
|
DetectionRXingResultRowIndicatorColumn,
|
||||||
|
};
|
||||||
|
|
||||||
const ADJUST_ROW_NUMBER_SKIP: u32 = 2;
|
const ADJUST_ROW_NUMBER_SKIP: u32 = 2;
|
||||||
|
|
||||||
@@ -50,10 +53,9 @@ impl<'a> DetectionRXingResult<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDetectionRXingResultColumns(&mut self) -> &Vec<Option<DetectionRXingResultColumn>> {
|
pub fn getDetectionRXingResultColumns(&mut self) -> &Vec<Option<DetectionRXingResultColumn>> {
|
||||||
self.adjustIndicatorColumnRowNumbers(&self.detectionRXingResultColumns[0]);
|
self.adjustIndicatorColumnRowNumbers(0);
|
||||||
self.adjustIndicatorColumnRowNumbers(
|
let pos = self.barcodeColumnCount + 1;
|
||||||
&self.detectionRXingResultColumns[self.barcodeColumnCount + 1],
|
self.adjustIndicatorColumnRowNumbers(pos);
|
||||||
);
|
|
||||||
let mut unadjustedCodewordCount = pdf_417_common::MAX_CODEWORDS_IN_BARCODE;
|
let mut unadjustedCodewordCount = pdf_417_common::MAX_CODEWORDS_IN_BARCODE;
|
||||||
let mut previousUnadjustedCount;
|
let mut previousUnadjustedCount;
|
||||||
loop {
|
loop {
|
||||||
@@ -67,15 +69,18 @@ impl<'a> DetectionRXingResult<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn adjustIndicatorColumnRowNumbers(
|
fn adjustIndicatorColumnRowNumbers(
|
||||||
&self,
|
&mut self,
|
||||||
detectionRXingResultColumn: &Option<DetectionRXingResultColumn>,
|
pos: usize,
|
||||||
|
// detectionRXingResultColumn: &mut Option<DetectionRXingResultColumn>,
|
||||||
) {
|
) {
|
||||||
if let Some(col) = detectionRXingResultColumn {
|
if self.detectionRXingResultColumns[pos].is_some() {
|
||||||
// if (detectionRXingResultColumn != null) {
|
// if (detectionRXingResultColumn != null) {
|
||||||
// ((DetectionRXingResultRowIndicatorColumn) detectionRXingResultColumn)
|
// ((DetectionRXingResultRowIndicatorColumn) detectionRXingResultColumn)
|
||||||
// .adjustCompleteIndicatorColumnRowNumbers(barcodeMetadata);
|
// .adjustCompleteIndicatorColumnRowNumbers(barcodeMetadata);
|
||||||
// }
|
// }
|
||||||
col.as_row_indicator()
|
self.detectionRXingResultColumns[pos]
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
.adjustCompleteIndicatorColumnRowNumbers(&self.barcodeMetadata);
|
.adjustCompleteIndicatorColumnRowNumbers(&self.barcodeMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const MAX_NEARBY_DISTANCE: u32 = 5;
|
|||||||
pub struct DetectionRXingResultColumn<'a> {
|
pub struct DetectionRXingResultColumn<'a> {
|
||||||
boundingBox: BoundingBox<'a>,
|
boundingBox: BoundingBox<'a>,
|
||||||
codewords: Vec<Option<Codeword>>,
|
codewords: Vec<Option<Codeword>>,
|
||||||
|
pub(super) isLeft: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DetectionRXingResultColumn<'_> {
|
impl<'a> DetectionRXingResultColumn<'_> {
|
||||||
@@ -34,11 +35,23 @@ impl<'a> DetectionRXingResultColumn<'_> {
|
|||||||
DetectionRXingResultColumn {
|
DetectionRXingResultColumn {
|
||||||
boundingBox: BoundingBox::from_other(boundingBox),
|
boundingBox: BoundingBox::from_other(boundingBox),
|
||||||
codewords: vec![None; (boundingBox.getMaxY() - boundingBox.getMinY() + 1) as usize],
|
codewords: vec![None; (boundingBox.getMaxY() - boundingBox.getMinY() + 1) as usize],
|
||||||
|
isLeft: None,
|
||||||
}
|
}
|
||||||
// this.boundingBox = new BoundingBox(boundingBox);
|
// this.boundingBox = new BoundingBox(boundingBox);
|
||||||
// codewords = new Codeword[boundingBox.getMaxY() - boundingBox.getMinY() + 1];
|
// codewords = new Codeword[boundingBox.getMaxY() - boundingBox.getMinY() + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_with_is_left(
|
||||||
|
boundingBox: &'a BoundingBox,
|
||||||
|
isLeft: bool,
|
||||||
|
) -> DetectionRXingResultColumn<'a> {
|
||||||
|
DetectionRXingResultColumn {
|
||||||
|
boundingBox: BoundingBox::from_other(boundingBox),
|
||||||
|
codewords: vec![None; (boundingBox.getMaxY() - boundingBox.getMinY() + 1) as usize],
|
||||||
|
isLeft: Some(isLeft),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getCodewordNearby(&self, imageRow: u32) -> &Option<Codeword> {
|
pub fn getCodewordNearby(&self, imageRow: u32) -> &Option<Codeword> {
|
||||||
let mut codeword = self.getCodeword(imageRow);
|
let mut codeword = self.getCodeword(imageRow);
|
||||||
if codeword.is_some() {
|
if codeword.is_some() {
|
||||||
@@ -87,13 +100,16 @@ impl<'a> DetectionRXingResultColumn<'_> {
|
|||||||
pub(super) fn getCodewordsMut(&mut self) -> &mut [Option<Codeword>] {
|
pub(super) fn getCodewordsMut(&mut self) -> &mut [Option<Codeword>] {
|
||||||
&mut self.codewords
|
&mut self.codewords
|
||||||
}
|
}
|
||||||
pub fn as_row_indicator(&self) -> DetectionRXingResultRowIndicatorColumn {
|
// pub fn as_row_indicator(&self) -> DetectionRXingResultRowIndicatorColumn {
|
||||||
DetectionRXingResultRowIndicatorColumn::new(&self.boundingBox, false)
|
// DetectionRXingResultRowIndicatorColumn::new(&self.boundingBox, false)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DetectionRXingResultColumn<'_> {
|
impl Display for DetectionRXingResultColumn<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.isLeft.is_some() {
|
||||||
|
write!(f, "IsLeft: {} \n", self.isLeft.as_ref().unwrap());
|
||||||
|
}
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,48 +23,42 @@ use super::{BarcodeMetadata, BarcodeValue, BoundingBox, Codeword, DetectionRXing
|
|||||||
/**
|
/**
|
||||||
* @author Guenther Grau
|
* @author Guenther Grau
|
||||||
*/
|
*/
|
||||||
pub struct DetectionRXingResultRowIndicatorColumn<'a>(DetectionRXingResultColumn<'a>, bool);
|
pub trait DetectionRXingResultRowIndicatorColumn {
|
||||||
impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
// TODO implement properly
|
||||||
|
// TODO maybe we should add missing codewords to store the correct row number to make
|
||||||
|
// finding row numbers for other columns easier
|
||||||
|
// use row height count to make detection of invalid row numbers more reliable
|
||||||
|
fn adjustCompleteIndicatorColumnRowNumbers(&mut self, barcodeMetadata: &BarcodeMetadata);
|
||||||
|
fn getRowHeights(&mut self) -> Option<Vec<u32>>;
|
||||||
|
fn getBarcodeMetadata(&mut self) -> Option<BarcodeMetadata>;
|
||||||
|
fn isLeft(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DetectionRXingResultRowIndicatorColumn for DetectionRXingResultColumn<'_> {
|
||||||
// private final boolean isLeft;
|
// private final boolean isLeft;
|
||||||
|
|
||||||
pub fn new(
|
|
||||||
boundingBox: &'a BoundingBox,
|
|
||||||
isLeft: bool,
|
|
||||||
) -> DetectionRXingResultRowIndicatorColumn<'a> {
|
|
||||||
DetectionRXingResultRowIndicatorColumn(DetectionRXingResultColumn::new(boundingBox), isLeft)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setRowNumbers(&mut self) {
|
|
||||||
for codeword_opt in self.0.getCodewordsMut() {
|
|
||||||
// for (Codeword codeword : getCodewords()) {
|
|
||||||
if let Some(codeword) = codeword_opt {
|
|
||||||
// if (codeword != null) {
|
|
||||||
codeword.setRowNumberAsRowIndicatorColumn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO implement properly
|
// TODO implement properly
|
||||||
// TODO maybe we should add missing codewords to store the correct row number to make
|
// TODO maybe we should add missing codewords to store the correct row number to make
|
||||||
// finding row numbers for other columns easier
|
// finding row numbers for other columns easier
|
||||||
// use row height count to make detection of invalid row numbers more reliable
|
// use row height count to make detection of invalid row numbers more reliable
|
||||||
pub fn adjustCompleteIndicatorColumnRowNumbers(&mut self, barcodeMetadata: &BarcodeMetadata) {
|
fn adjustCompleteIndicatorColumnRowNumbers(&mut self, barcodeMetadata: &BarcodeMetadata) {
|
||||||
// let codewords = self.0.getCodewordsMut();
|
// let codewords = self.0.getCodewordsMut();
|
||||||
self.setRowNumbers();
|
setRowNumbers(self.getCodewordsMut());
|
||||||
Self::removeIncorrectCodewords(self.0.getCodewordsMut(), barcodeMetadata, self.1);
|
let isLeft = self.isLeft.unwrap();
|
||||||
let boundingBox = self.0.getBoundingBox();
|
removeIncorrectCodewords(self.getCodewordsMut(), barcodeMetadata, isLeft);
|
||||||
let top = if self.1 {
|
let boundingBox = self.getBoundingBox();
|
||||||
|
let top = if self.isLeft() {
|
||||||
boundingBox.getTopLeft()
|
boundingBox.getTopLeft()
|
||||||
} else {
|
} else {
|
||||||
boundingBox.getTopRight()
|
boundingBox.getTopRight()
|
||||||
};
|
};
|
||||||
let bottom = if self.1 {
|
let bottom = if self.isLeft() {
|
||||||
boundingBox.getBottomLeft()
|
boundingBox.getBottomLeft()
|
||||||
} else {
|
} else {
|
||||||
boundingBox.getBottomRight()
|
boundingBox.getBottomRight()
|
||||||
};
|
};
|
||||||
let firstRow = self.0.imageRowToCodewordIndex(top.getY() as u32);
|
let firstRow = self.imageRowToCodewordIndex(top.getY() as u32);
|
||||||
let lastRow = self.0.imageRowToCodewordIndex(bottom.getY() as u32);
|
let lastRow = self.imageRowToCodewordIndex(bottom.getY() as u32);
|
||||||
// We need to be careful using the average row height. Barcode could be skewed so that we have smaller and
|
// We need to be careful using the average row height. Barcode could be skewed so that we have smaller and
|
||||||
// taller rows
|
// taller rows
|
||||||
//float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.getRowCount();
|
//float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.getRowCount();
|
||||||
@@ -73,7 +67,7 @@ impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
|||||||
let mut currentRowHeight = 0;
|
let mut currentRowHeight = 0;
|
||||||
for codewordsRow in firstRow..lastRow {
|
for codewordsRow in firstRow..lastRow {
|
||||||
// for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
|
// for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
|
||||||
if let Some(codeword) = self.0.getCodewordsMut()[codewordsRow] {
|
if let Some(codeword) = self.getCodewordsMut()[codewordsRow] {
|
||||||
// if (codewords[codewordsRow] == null) {
|
// if (codewords[codewordsRow] == null) {
|
||||||
// continue;
|
// continue;
|
||||||
// }
|
// }
|
||||||
@@ -93,7 +87,7 @@ impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
|||||||
|| codeword.getRowNumber() >= barcodeMetadata.getRowCount() as i32
|
|| codeword.getRowNumber() >= barcodeMetadata.getRowCount() as i32
|
||||||
|| rowDifference > codewordsRow as i32
|
|| rowDifference > codewordsRow as i32
|
||||||
{
|
{
|
||||||
self.0.getCodewordsMut()[codewordsRow] = None;
|
self.getCodewordsMut()[codewordsRow] = None;
|
||||||
} else {
|
} else {
|
||||||
let checkedRows;
|
let checkedRows;
|
||||||
if maxRowHeight > 2 {
|
if maxRowHeight > 2 {
|
||||||
@@ -108,12 +102,12 @@ impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
|||||||
// there must be (height * rowDifference) number of codewords missing. For now we assume height = 1.
|
// there must be (height * rowDifference) number of codewords missing. For now we assume height = 1.
|
||||||
// This should hopefully get rid of most problems already.
|
// This should hopefully get rid of most problems already.
|
||||||
closePreviousCodewordFound =
|
closePreviousCodewordFound =
|
||||||
self.0.getCodewords()[codewordsRow as usize - i as usize].is_some();
|
self.getCodewords()[codewordsRow as usize - i as usize].is_some();
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
if closePreviousCodewordFound {
|
if closePreviousCodewordFound {
|
||||||
self.0.getCodewordsMut()[codewordsRow] = None;
|
self.getCodewordsMut()[codewordsRow] = None;
|
||||||
} else {
|
} else {
|
||||||
barcodeRow = codeword.getRowNumber();
|
barcodeRow = codeword.getRowNumber();
|
||||||
currentRowHeight = 1;
|
currentRowHeight = 1;
|
||||||
@@ -126,11 +120,11 @@ impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
|||||||
//return (int) (averageRowHeight + 0.5);
|
//return (int) (averageRowHeight + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getRowHeights(&mut self) -> Option<Vec<u32>> {
|
fn getRowHeights(&mut self) -> Option<Vec<u32>> {
|
||||||
if let Some(barcodeMetadata) = self.getBarcodeMetadata() {
|
if let Some(barcodeMetadata) = self.getBarcodeMetadata() {
|
||||||
self.adjustIncompleteIndicatorColumnRowNumbers(&barcodeMetadata);
|
adjustIncompleteIndicatorColumnRowNumbers(self, &barcodeMetadata);
|
||||||
let mut result = vec![0; barcodeMetadata.getRowCount() as usize];
|
let mut result = vec![0; barcodeMetadata.getRowCount() as usize];
|
||||||
for codeword_opt in self.0.getCodewords() {
|
for codeword_opt in self.getCodewords() {
|
||||||
// for (Codeword codeword : getCodewords()) {
|
// for (Codeword codeword : getCodewords()) {
|
||||||
if let Some(codeword) = codeword_opt {
|
if let Some(codeword) = codeword_opt {
|
||||||
let rowNumber = codeword.getRowNumber();
|
let rowNumber = codeword.getRowNumber();
|
||||||
@@ -151,59 +145,9 @@ impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO maybe we should add missing codewords to store the correct row number to make
|
fn getBarcodeMetadata(&mut self) -> Option<BarcodeMetadata> {
|
||||||
// finding row numbers for other columns easier
|
let isLeft = self.isLeft.unwrap();
|
||||||
// use row height count to make detection of invalid row numbers more reliable
|
let codewords = self.getCodewordsMut();
|
||||||
fn adjustIncompleteIndicatorColumnRowNumbers(&mut self, barcodeMetadata: &BarcodeMetadata) {
|
|
||||||
let boundingBox = self.0.getBoundingBox();
|
|
||||||
let top = if self.1 {
|
|
||||||
boundingBox.getTopLeft()
|
|
||||||
} else {
|
|
||||||
boundingBox.getTopRight()
|
|
||||||
};
|
|
||||||
let bottom = if self.1 {
|
|
||||||
boundingBox.getBottomLeft()
|
|
||||||
} else {
|
|
||||||
boundingBox.getBottomRight()
|
|
||||||
};
|
|
||||||
let firstRow = self.0.imageRowToCodewordIndex(top.getY() as u32);
|
|
||||||
let lastRow = self.0.imageRowToCodewordIndex(bottom.getY() as u32);
|
|
||||||
//float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.getRowCount();
|
|
||||||
let codewords = self.0.getCodewordsMut();
|
|
||||||
let mut barcodeRow = -1;
|
|
||||||
let mut maxRowHeight = 1;
|
|
||||||
let mut currentRowHeight = 0;
|
|
||||||
for codewordsRow in firstRow..lastRow {
|
|
||||||
// for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
|
|
||||||
|
|
||||||
if let Some(codeword) = &mut codewords[codewordsRow] {
|
|
||||||
codeword.setRowNumberAsRowIndicatorColumn();
|
|
||||||
|
|
||||||
let rowDifference = codeword.getRowNumber() - barcodeRow;
|
|
||||||
|
|
||||||
// TODO improve handling with case where first row indicator doesn't start with 0
|
|
||||||
|
|
||||||
if rowDifference == 0 {
|
|
||||||
currentRowHeight += 1;
|
|
||||||
} else if rowDifference == 1 {
|
|
||||||
maxRowHeight = maxRowHeight.max(currentRowHeight);
|
|
||||||
currentRowHeight = 1;
|
|
||||||
barcodeRow = codeword.getRowNumber();
|
|
||||||
} else if codeword.getRowNumber() >= barcodeMetadata.getRowCount() as i32 {
|
|
||||||
codewords[codewordsRow] = None;
|
|
||||||
} else {
|
|
||||||
barcodeRow = codeword.getRowNumber();
|
|
||||||
currentRowHeight = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//return (int) (averageRowHeight + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getBarcodeMetadata(&mut self) -> Option<BarcodeMetadata> {
|
|
||||||
let codewords = self.0.getCodewordsMut();
|
|
||||||
let mut barcodeColumnCount = BarcodeValue::new();
|
let mut barcodeColumnCount = BarcodeValue::new();
|
||||||
let mut barcodeRowCountUpperPart = BarcodeValue::new();
|
let mut barcodeRowCountUpperPart = BarcodeValue::new();
|
||||||
let mut barcodeRowCountLowerPart = BarcodeValue::new();
|
let mut barcodeRowCountLowerPart = BarcodeValue::new();
|
||||||
@@ -214,7 +158,7 @@ impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
|||||||
codeword.setRowNumberAsRowIndicatorColumn();
|
codeword.setRowNumberAsRowIndicatorColumn();
|
||||||
let rowIndicatorValue = codeword.getValue() % 30;
|
let rowIndicatorValue = codeword.getValue() % 30;
|
||||||
let mut codewordRowNumber = codeword.getRowNumber();
|
let mut codewordRowNumber = codeword.getRowNumber();
|
||||||
if !self.1 {
|
if !isLeft {
|
||||||
codewordRowNumber += 2;
|
codewordRowNumber += 2;
|
||||||
}
|
}
|
||||||
match codewordRowNumber % 3 {
|
match codewordRowNumber % 3 {
|
||||||
@@ -249,63 +193,128 @@ impl<'a> DetectionRXingResultRowIndicatorColumn<'_> {
|
|||||||
barcodeRowCountLowerPart.getValue()[0],
|
barcodeRowCountLowerPart.getValue()[0],
|
||||||
barcodeECLevel.getValue()[0],
|
barcodeECLevel.getValue()[0],
|
||||||
);
|
);
|
||||||
Self::removeIncorrectCodewords(codewords, &barcodeMetadata, self.1);
|
removeIncorrectCodewords(codewords, &barcodeMetadata, isLeft);
|
||||||
|
|
||||||
Some(barcodeMetadata)
|
Some(barcodeMetadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn removeIncorrectCodewords(
|
fn isLeft(&self) -> bool {
|
||||||
codewords: &mut [Option<Codeword>],
|
self.isLeft.unwrap()
|
||||||
barcodeMetadata: &BarcodeMetadata,
|
}
|
||||||
isLeft: bool,
|
}
|
||||||
) {
|
|
||||||
// Remove codewords which do not match the metadata
|
// impl Display for DetectionRXingResultRowIndicatorColumn {
|
||||||
// TODO Maybe we should keep the incorrect codewords for the start and end positions?
|
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
for codewordRow in 0..codewords.len() {
|
// write!(f, "IsLeft: {} \n {}", self.1, self.0)
|
||||||
// for (int codewordRow = 0; codewordRow < codewords.length; codewordRow++) {
|
// }
|
||||||
if let Some(codeword) = codewords[codewordRow] {
|
// }
|
||||||
let rowIndicatorValue = codeword.getValue() % 30;
|
|
||||||
let mut codewordRowNumber = codeword.getRowNumber();
|
fn setRowNumbers(code_words: &mut [Option<Codeword>]) {
|
||||||
if codewordRowNumber > barcodeMetadata.getRowCount() as i32 {
|
for codeword_opt in code_words {
|
||||||
codewords[codewordRow] = None;
|
//self.0.getCodewordsMut() {
|
||||||
continue;
|
// for (Codeword codeword : getCodewords()) {
|
||||||
}
|
if let Some(codeword) = codeword_opt {
|
||||||
if !isLeft {
|
// if (codeword != null) {
|
||||||
codewordRowNumber += 2;
|
codeword.setRowNumberAsRowIndicatorColumn();
|
||||||
}
|
|
||||||
match codewordRowNumber % 3 {
|
|
||||||
0 => {
|
|
||||||
if rowIndicatorValue * 3 + 1 != barcodeMetadata.getRowCountUpperPart() {
|
|
||||||
codewords[codewordRow] = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
if rowIndicatorValue / 3 != barcodeMetadata.getErrorCorrectionLevel()
|
|
||||||
|| rowIndicatorValue % 3 != barcodeMetadata.getRowCountLowerPart()
|
|
||||||
{
|
|
||||||
codewords[codewordRow] = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2 => {
|
|
||||||
if rowIndicatorValue + 1 != barcodeMetadata.getColumnCount() {
|
|
||||||
codewords[codewordRow] = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn isLeft(&self) -> bool {
|
fn removeIncorrectCodewords(
|
||||||
self.1
|
codewords: &mut [Option<Codeword>],
|
||||||
|
barcodeMetadata: &BarcodeMetadata,
|
||||||
|
isLeft: bool,
|
||||||
|
) {
|
||||||
|
// Remove codewords which do not match the metadata
|
||||||
|
// TODO Maybe we should keep the incorrect codewords for the start and end positions?
|
||||||
|
for codewordRow in 0..codewords.len() {
|
||||||
|
// for (int codewordRow = 0; codewordRow < codewords.length; codewordRow++) {
|
||||||
|
if let Some(codeword) = codewords[codewordRow] {
|
||||||
|
let rowIndicatorValue = codeword.getValue() % 30;
|
||||||
|
let mut codewordRowNumber = codeword.getRowNumber();
|
||||||
|
if codewordRowNumber > barcodeMetadata.getRowCount() as i32 {
|
||||||
|
codewords[codewordRow] = None;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if !isLeft {
|
||||||
|
codewordRowNumber += 2;
|
||||||
|
}
|
||||||
|
match codewordRowNumber % 3 {
|
||||||
|
0 => {
|
||||||
|
if rowIndicatorValue * 3 + 1 != barcodeMetadata.getRowCountUpperPart() {
|
||||||
|
codewords[codewordRow] = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
if rowIndicatorValue / 3 != barcodeMetadata.getErrorCorrectionLevel()
|
||||||
|
|| rowIndicatorValue % 3 != barcodeMetadata.getRowCountLowerPart()
|
||||||
|
{
|
||||||
|
codewords[codewordRow] = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
if rowIndicatorValue + 1 != barcodeMetadata.getColumnCount() {
|
||||||
|
codewords[codewordRow] = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DetectionRXingResultRowIndicatorColumn<'_> {
|
// TODO maybe we should add missing codewords to store the correct row number to make
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
// finding row numbers for other columns easier
|
||||||
write!(f, "IsLeft: {} \n {}", self.1, self.0)
|
// use row height count to make detection of invalid row numbers more reliable
|
||||||
|
fn adjustIncompleteIndicatorColumnRowNumbers(
|
||||||
|
col: &mut DetectionRXingResultColumn,
|
||||||
|
barcodeMetadata: &BarcodeMetadata,
|
||||||
|
) {
|
||||||
|
let boundingBox = col.getBoundingBox();
|
||||||
|
let top = if col.isLeft() {
|
||||||
|
boundingBox.getTopLeft()
|
||||||
|
} else {
|
||||||
|
boundingBox.getTopRight()
|
||||||
|
};
|
||||||
|
let bottom = if col.isLeft() {
|
||||||
|
boundingBox.getBottomLeft()
|
||||||
|
} else {
|
||||||
|
boundingBox.getBottomRight()
|
||||||
|
};
|
||||||
|
let firstRow = col.imageRowToCodewordIndex(top.getY() as u32);
|
||||||
|
let lastRow = col.imageRowToCodewordIndex(bottom.getY() as u32);
|
||||||
|
//float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.getRowCount();
|
||||||
|
let codewords = col.getCodewordsMut();
|
||||||
|
let mut barcodeRow = -1;
|
||||||
|
let mut maxRowHeight = 1;
|
||||||
|
let mut currentRowHeight = 0;
|
||||||
|
for codewordsRow in firstRow..lastRow {
|
||||||
|
// for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
|
||||||
|
|
||||||
|
if let Some(codeword) = &mut codewords[codewordsRow] {
|
||||||
|
codeword.setRowNumberAsRowIndicatorColumn();
|
||||||
|
|
||||||
|
let rowDifference = codeword.getRowNumber() - barcodeRow;
|
||||||
|
|
||||||
|
// TODO improve handling with case where first row indicator doesn't start with 0
|
||||||
|
|
||||||
|
if rowDifference == 0 {
|
||||||
|
currentRowHeight += 1;
|
||||||
|
} else if rowDifference == 1 {
|
||||||
|
maxRowHeight = maxRowHeight.max(currentRowHeight);
|
||||||
|
currentRowHeight = 1;
|
||||||
|
barcodeRow = codeword.getRowNumber();
|
||||||
|
} else if codeword.getRowNumber() >= barcodeMetadata.getRowCount() as i32 {
|
||||||
|
codewords[codewordsRow] = None;
|
||||||
|
} else {
|
||||||
|
barcodeRow = codeword.getRowNumber();
|
||||||
|
currentRowHeight = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//return (int) (averageRowHeight + 0.5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,4 +23,4 @@ pub use detection_result_row_indicator_column::*;
|
|||||||
mod detection_result;
|
mod detection_result;
|
||||||
pub use detection_result::*;
|
pub use detection_result::*;
|
||||||
|
|
||||||
// pub mod pdf_417_scanning_decoder;
|
// pub mod pdf_417_scanning_decoder;
|
||||||
|
|||||||
Reference in New Issue
Block a user