fixed codeword row error correction issue

This commit is contained in:
Henry Schimke
2022-12-28 17:45:55 -06:00
parent cba6a10c4b
commit db674f0adf
6 changed files with 354 additions and 206 deletions

View File

@@ -147,9 +147,12 @@ impl DetectionRXingResult {
} }
fn adjustRowNumbersFromBothRI(&mut self) { fn adjustRowNumbersFromBothRI(&mut self) {
if self.detectionRXingResultColumns[0].is_some() if self.detectionRXingResultColumns[0].is_none()
&& self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].is_some() && self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].is_none()
{ {
return;
}
// let LRIcodewords = self.detectionRXingResultColumns[0].as_ref().unwrap().getCodewords(); // let LRIcodewords = self.detectionRXingResultColumns[0].as_ref().unwrap().getCodewords();
// let RRIcodewords = self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].as_ref().unwrap().getCodewords(); // let RRIcodewords = self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].as_ref().unwrap().getCodewords();
for codewordsRow in 0..self.detectionRXingResultColumns[0] for codewordsRow in 0..self.detectionRXingResultColumns[0]
@@ -245,32 +248,54 @@ impl DetectionRXingResult {
} }
} }
} }
}
// if (detectionRXingResultColumns[0] == null || detectionRXingResultColumns[barcodeColumnCount + 1] == null) { // if (detectionRXingResultColumns[0] == null || detectionRXingResultColumns[barcodeColumnCount + 1] == null) {
// return; // return;
// } // }
} }
fn adjustRowNumbersFromRRI(&self) -> u32 { fn adjustRowNumbersFromRRI(&mut self) -> u32 {
if let Some(col) = &self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] { if self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].is_none() {
return 0;
}
// if let Some(col) = &self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] {
let mut unadjustedCount = 0; let mut unadjustedCount = 0;
let codewords = col.getCodewords(); let codewords_len = self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1]
for codewordsRow in 0..codewords.len() { .as_ref()
.unwrap()
.getCodewords()
.len();
for codewordsRow in 0..codewords_len {
// for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) { // for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) {
if let Some(codeword_col) = codewords[codewordsRow] { // if let Some(codeword_col) = codewords[codewordsRow] {
let rowIndicatorRowNumber = codeword_col.getRowNumber(); if self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1]
.as_ref()
.unwrap()
.getCodewords()[codewordsRow]
.is_none()
{
continue;
}
let rowIndicatorRowNumber = self.detectionRXingResultColumns
[self.barcodeColumnCount as usize + 1]
.as_ref()
.unwrap()
.getCodewords()[codewordsRow]
.as_ref()
.unwrap()
.getRowNumber();
let mut invalidRowCounts = 0; let mut invalidRowCounts = 0;
let mut barcodeColumn = self.barcodeColumnCount as usize + 1; let mut barcodeColumn = self.barcodeColumnCount as usize + 1;
while barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP { while barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP {
// for (int barcodeColumn = barcodeColumnCount + 1; // for (int barcodeColumn = barcodeColumnCount + 1;
// barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; // barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP;
// barcodeColumn--) { // barcodeColumn--) {
if let Some(bc_col) = &self.detectionRXingResultColumns[barcodeColumn] { if let Some(bc_col) = &mut self.detectionRXingResultColumns[barcodeColumn] {
if let Some(codeword) = bc_col.getCodewords()[codewordsRow] { if let Some(codeword) = &mut bc_col.getCodewordsMut()[codewordsRow] {
invalidRowCounts = Self::adjustRowNumberIfValid( invalidRowCounts = Self::adjustRowNumberIfValid(
rowIndicatorRowNumber, rowIndicatorRowNumber,
invalidRowCounts, invalidRowCounts,
&mut Some(codeword), codeword,
); );
if !codeword.hasValidRowNumber() { if !codeword.hasValidRowNumber() {
unadjustedCount += 1; unadjustedCount += 1;
@@ -279,14 +304,14 @@ impl DetectionRXingResult {
} }
barcodeColumn -= 1; barcodeColumn -= 1;
} }
} else { // } else {
continue; // continue;
} // }
} }
unadjustedCount unadjustedCount
} else { // } else {
0 // 0
} // }
// if (detectionRXingResultColumns[barcodeColumnCount + 1] == null) { // if (detectionRXingResultColumns[barcodeColumnCount + 1] == null) {
// return 0; // return 0;
// } // }
@@ -313,14 +338,36 @@ impl DetectionRXingResult {
// return unadjustedCount; // return unadjustedCount;
} }
fn adjustRowNumbersFromLRI(&self) -> u32 { fn adjustRowNumbersFromLRI(&mut self) -> u32 {
if let Some(col) = &self.detectionRXingResultColumns[0] { if self.detectionRXingResultColumns[0].is_none() {
return 0;
}
// if let Some(col) = &self.detectionRXingResultColumns[0] {
let mut unadjustedCount = 0; let mut unadjustedCount = 0;
let codewords = col.getCodewords(); let codewords_len = self.detectionRXingResultColumns[0]
for codewordsRow in 0..codewords.len() { .as_ref()
.unwrap()
.getCodewords()
.len();
for codewordsRow in 0..codewords_len {
// for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) { // for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) {
if let Some(codeword_in_row) = codewords[codewordsRow] { // if let Some(codeword_in_row) = codewords[codewordsRow] {
let rowIndicatorRowNumber = codeword_in_row.getRowNumber(); if self.detectionRXingResultColumns[0]
.as_ref()
.unwrap()
.getCodewords()[codewordsRow]
.is_none()
{
continue;
}
let rowIndicatorRowNumber = self.detectionRXingResultColumns[0]
.as_ref()
.unwrap()
.getCodewords()[codewordsRow]
.as_ref()
.unwrap()
.getRowNumber();
let mut invalidRowCounts = 0; let mut invalidRowCounts = 0;
let mut barcodeColumn = 1_usize; let mut barcodeColumn = 1_usize;
while barcodeColumn < self.barcodeColumnCount as usize + 1 while barcodeColumn < self.barcodeColumnCount as usize + 1
@@ -329,12 +376,12 @@ impl DetectionRXingResult {
// for (int barcodeColumn = 1; // for (int barcodeColumn = 1;
// barcodeColumn < barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; // barcodeColumn < barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP;
// barcodeColumn++) { // barcodeColumn++) {
if let Some(bc_column) = &self.detectionRXingResultColumns[barcodeColumn] { if let Some(bc_column) = &mut self.detectionRXingResultColumns[barcodeColumn] {
if let Some(codeword) = bc_column.getCodewords()[codewordsRow] { if let Some(codeword) = &mut bc_column.getCodewordsMut()[codewordsRow] {
invalidRowCounts = Self::adjustRowNumberIfValid( invalidRowCounts = Self::adjustRowNumberIfValid(
rowIndicatorRowNumber, rowIndicatorRowNumber,
invalidRowCounts, invalidRowCounts,
&mut Some(codeword), codeword,
); );
if !codeword.hasValidRowNumber() { if !codeword.hasValidRowNumber() {
unadjustedCount += 1; unadjustedCount += 1;
@@ -350,9 +397,9 @@ impl DetectionRXingResult {
// } // }
barcodeColumn += 1; barcodeColumn += 1;
} }
} else { // } else {
continue; // continue;
} // }
// if (codewords[codewordsRow] == null) { // if (codewords[codewordsRow] == null) {
// continue; // continue;
// } // }
@@ -371,9 +418,9 @@ impl DetectionRXingResult {
// } // }
} }
unadjustedCount unadjustedCount
} else { // } else {
0 // 0
} // }
// if (detectionRXingResultColumns[0] == null) { // if (detectionRXingResultColumns[0] == null) {
// return 0; // return 0;
@@ -404,9 +451,9 @@ impl DetectionRXingResult {
fn adjustRowNumberIfValid( fn adjustRowNumberIfValid(
rowIndicatorRowNumber: i32, rowIndicatorRowNumber: i32,
mut invalidRowCounts: u32, mut invalidRowCounts: u32,
codeword: &mut Option<Codeword>, codeword: &mut Codeword,
) -> u32 { ) -> u32 {
if let Some(codeword) = codeword { // if let Some(codeword) = codeword {
if !codeword.hasValidRowNumber() { if !codeword.hasValidRowNumber() {
if codeword.isValidRowNumber(rowIndicatorRowNumber) { if codeword.isValidRowNumber(rowIndicatorRowNumber) {
codeword.setRowNumber(rowIndicatorRowNumber); codeword.setRowNumber(rowIndicatorRowNumber);
@@ -416,9 +463,9 @@ impl DetectionRXingResult {
} }
} }
invalidRowCounts invalidRowCounts
} else { // } else {
invalidRowCounts // invalidRowCounts
} // }
// if (codeword == null) { // if (codeword == null) {
// return invalidRowCounts; // return invalidRowCounts;
// } // }
@@ -548,6 +595,13 @@ impl DetectionRXingResult {
) -> &Option<Box<dyn DetectionRXingResultColumnTrait>> { ) -> &Option<Box<dyn DetectionRXingResultColumnTrait>> {
&self.detectionRXingResultColumns[barcodeColumn] &self.detectionRXingResultColumns[barcodeColumn]
} }
pub fn getDetectionRXingResultColumnMut(
&mut self,
barcodeColumn: usize,
) -> &mut Option<Box<dyn DetectionRXingResultColumnTrait>> {
&mut self.detectionRXingResultColumns[barcodeColumn]
}
} }
impl Display for DetectionRXingResult { impl Display for DetectionRXingResult {

View File

@@ -73,16 +73,16 @@ impl DetectionRXingResultColumnTrait for DetectionRXingResultColumn {
} }
for i in 1..MAX_NEARBY_DISTANCE as usize { for i in 1..MAX_NEARBY_DISTANCE as usize {
// for (int i = 1; i < MAX_NEARBY_DISTANCE; i++) { // for (int i = 1; i < MAX_NEARBY_DISTANCE; i++) {
let mut nearImageRow = self.imageRowToCodewordIndex(imageRow) - i; let mut nearImageRow = self.imageRowToCodewordIndex(imageRow) as isize - i as isize;
if nearImageRow >= 0 { if nearImageRow >= 0 {
codeword = &self.codewords[nearImageRow]; codeword = &self.codewords[nearImageRow as usize];
if codeword.is_some() { if codeword.is_some() {
return codeword; return codeword;
} }
} }
nearImageRow = self.imageRowToCodewordIndex(imageRow) + i; nearImageRow = self.imageRowToCodewordIndex(imageRow) as isize + i as isize;
if nearImageRow < self.codewords.len() { if nearImageRow < self.codewords.len() as isize {
codeword = &self.codewords[nearImageRow]; codeword = &self.codewords[nearImageRow as usize];
if codeword.is_some() { if codeword.is_some() {
return codeword; return codeword;
} }

View File

@@ -24,7 +24,7 @@ use crate::pdf417::pdf_417_common;
// const RATIOS_TABLE :[[f32]] = // const RATIOS_TABLE :[[f32]] =
// [[0.0;pdf_417_common::SYMBOL_TABLE.len()];pdf_417_common::BARS_IN_MODULE]; // [[0.0;pdf_417_common::SYMBOL_TABLE.len()];pdf_417_common::BARS_IN_MODULE];
const RATIOS_TABLE: [[f64; pdf_417_common::BARS_IN_MODULE as usize]; 2787] = { const RATIOS_TABLE: [[f32; pdf_417_common::BARS_IN_MODULE as usize]; 2787] = {
let mut table = let mut table =
[[0.0; pdf_417_common::BARS_IN_MODULE as usize]; pdf_417_common::SYMBOL_TABLE.len()]; [[0.0; pdf_417_common::BARS_IN_MODULE as usize]; pdf_417_common::SYMBOL_TABLE.len()];
// Pre-computes the symbol ratio table. // Pre-computes the symbol ratio table.
@@ -43,7 +43,7 @@ const RATIOS_TABLE: [[f64; pdf_417_common::BARS_IN_MODULE as usize]; 2787] = {
} }
currentBit = currentSymbol & 0x1; currentBit = currentSymbol & 0x1;
table[i][pdf_417_common::BARS_IN_MODULE as usize - j - 1] = table[i][pdf_417_common::BARS_IN_MODULE as usize - j - 1] =
size / pdf_417_common::MODULES_IN_CODEWORD as f64; size / pdf_417_common::MODULES_IN_CODEWORD as f32;
j += 1; j += 1;
} }
@@ -70,8 +70,8 @@ fn sampleBitCounts(moduleBitCount: &[u32]) -> [u32; 8] {
for i in 0..pdf_417_common::MODULES_IN_CODEWORD { for i in 0..pdf_417_common::MODULES_IN_CODEWORD {
// for (int i = 0; i < PDF417Common.MODULES_IN_CODEWORD; i++) { // for (int i = 0; i < PDF417Common.MODULES_IN_CODEWORD; i++) {
let sampleIndex: f32 = bitCountSum as f32 let sampleIndex: f32 = bitCountSum as f32
/ (2 * pdf_417_common::MODULES_IN_CODEWORD) as f32 / (2.0 * pdf_417_common::MODULES_IN_CODEWORD as f32)
+ (i * bitCountSum) as f32 / pdf_417_common::MODULES_IN_CODEWORD as f32; + (i as f32 * bitCountSum as f32) / pdf_417_common::MODULES_IN_CODEWORD as f32;
if sumPreviousBits as f32 + moduleBitCount[bitCountIndex] as f32 <= sampleIndex { if sumPreviousBits as f32 + moduleBitCount[bitCountIndex] as f32 <= sampleIndex {
sumPreviousBits += moduleBitCount[bitCountIndex]; sumPreviousBits += moduleBitCount[bitCountIndex];
bitCountIndex += 1; bitCountIndex += 1;
@@ -108,15 +108,15 @@ fn getClosestDecodedValue(moduleBitCount: &[u32]) -> i32 {
if bitCountSum > 1 { if bitCountSum > 1 {
for i in 0..bitCountRatios.len() { for i in 0..bitCountRatios.len() {
// for (int i = 0; i < bitCountRatios.length; i++) { // for (int i = 0; i < bitCountRatios.length; i++) {
bitCountRatios[i] = moduleBitCount[i] as f64 / bitCountSum as f64; bitCountRatios[i] = moduleBitCount[i] as f32 / bitCountSum as f32;
} }
} }
let mut bestMatchError = f64::MAX; let mut bestMatchError = f32::MAX;
let mut bestMatch = -1_i32; let mut bestMatch = -1_i32;
for j in 0..RATIOS_TABLE.len() { for j in 0..RATIOS_TABLE.len() {
// for (int j = 0; j < RATIOS_TABLE.length; j++) { // for (int j = 0; j < RATIOS_TABLE.length; j++) {
let mut error = 0.0; let mut error = 0.0;
let ratioTableRow = RATIOS_TABLE[j]; let ratioTableRow = &RATIOS_TABLE[j];
for k in 0..pdf_417_common::BARS_IN_MODULE as usize { for k in 0..pdf_417_common::BARS_IN_MODULE as usize {
// for (int k = 0; k < PDF417Common.BARS_IN_MODULE; k++) { // for (int k = 0; k < PDF417Common.BARS_IN_MODULE; k++) {
let diff = ratioTableRow[k] - bitCountRatios[k]; let diff = ratioTableRow[k] - bitCountRatios[k];
@@ -132,3 +132,57 @@ fn getClosestDecodedValue(moduleBitCount: &[u32]) -> i32 {
} }
bestMatch bestMatch
} }
#[cfg(test)]
mod test {
use crate::pdf417::decoder::pdf_417_codeword_decoder::getDecodedValue;
#[test]
fn test_cw_227() {
let sample_data = [2, 2, 3, 1, 6, 4, 3, 4];
assert_ne!(getDecodedValue(&sample_data), 110360);
assert_eq!(getDecodedValue(&sample_data), 93980);
}
#[test]
fn test_2() {
let sample = [2, 1, 4, 2, 5, 3, 7, 2];
assert_ne!(95134, getDecodedValue(&sample));
}
#[test]
fn test_128268() {
let sample = [7, 2, 1, 2, 2, 5, 3, 3];
assert_eq!(128268, getDecodedValue(&sample));
}
#[test]
fn test_125304() {
let sample = [6, 1, 2, 2, 2, 2, 6, 4];
assert_eq!(125304, getDecodedValue(&sample));
}
#[test]
fn test_125216() {
let sample = [6, 1, 2, 2, 2, 3, 2, 7];
assert_eq!(125216, getDecodedValue(&sample));
}
#[test]
fn test_83768() {
let sample = [1, 2, 1, 4, 5, 3, 5, 4];
assert_eq!(83768, getDecodedValue(&sample));
}
#[test]
fn test_96060() {
let sample = [2, 1, 4, 2, 5, 3, 7, 2];
assert_eq!(96060, getDecodedValue(&sample));
}
#[test]
fn test_97372() {
let sample = [3, 1, 7, 4, 2, 2, 4, 2];
assert_eq!(97372, getDecodedValue(&sample));
}
}

View File

@@ -126,15 +126,16 @@ pub fn decode(
// This will be the case for the opposite row indicator column, which doesn't need to be decoded again. // This will be the case for the opposite row indicator column, which doesn't need to be decoded again.
continue; continue;
} }
let mut detectionRXingResultColumn = if barcodeColumn == 0 let detectionRXingResultColumn = if barcodeColumn == 0 || barcodeColumn == maxBarcodeColumn
|| barcodeColumn == maxBarcodeColumn
{ {
DetectionRXingResultColumn::new_with_is_left(boundingBox.clone(), barcodeColumn == 0) DetectionRXingResultColumn::new_with_is_left(boundingBox.clone(), barcodeColumn == 0)
} else { } else {
DetectionRXingResultColumn::new(boundingBox.clone()) DetectionRXingResultColumn::new(boundingBox.clone())
}; };
detectionRXingResult detectionRXingResult
.setDetectionRXingResultColumn(barcodeColumn, Some(detectionRXingResultColumn.clone())); .setDetectionRXingResultColumn(barcodeColumn, Some(detectionRXingResultColumn));
let mut startColumn: i32 = -1; let mut startColumn: i32 = -1;
let mut previousStartColumn = startColumn; let mut previousStartColumn = startColumn;
// TODO start at a row for which we know the start position, then detect upwards and downwards from there. // TODO start at a row for which we know the start position, then detect upwards and downwards from there.
@@ -160,10 +161,15 @@ pub fn decode(
); );
if codeword.is_some() { if codeword.is_some() {
let codeword = codeword.unwrap(); let codeword = codeword.unwrap();
detectionRXingResultColumn.setCodeword(imageRow, codeword); //detectionRXingResultColumn.setCodeword(imageRow, codeword);
detectionRXingResult
.getDetectionRXingResultColumnMut(barcodeColumn)
.as_mut()
.unwrap()
.setCodeword(imageRow, codeword);
previousStartColumn = startColumn; previousStartColumn = startColumn;
minCodewordWidth = minCodewordWidth.min(codeword.getWidth()); minCodewordWidth = minCodewordWidth.min(codeword.getWidth());
maxCodewordWidth = maxCodewordWidth.min(codeword.getWidth()); maxCodewordWidth = maxCodewordWidth.max(codeword.getWidth());
} }
} }
} }
@@ -416,7 +422,7 @@ fn createDecoderRXingResult(
detectionRXingResult: &mut DetectionRXingResult, detectionRXingResult: &mut DetectionRXingResult,
) -> Result<DecoderRXingResult, Exceptions> { ) -> Result<DecoderRXingResult, Exceptions> {
let mut barcodeMatrix = createBarcodeMatrix(detectionRXingResult); let mut barcodeMatrix = createBarcodeMatrix(detectionRXingResult);
adjustCodewordCount(detectionRXingResult, &mut barcodeMatrix); adjustCodewordCount(detectionRXingResult, &mut barcodeMatrix)?;
let mut erasures = Vec::new(); //new ArrayList<>(); let mut erasures = Vec::new(); //new ArrayList<>();
let mut codewords = vec![ let mut codewords = vec![
0; 0;
@@ -521,8 +527,8 @@ fn createDecoderRXingResultFromAmbiguousValues(
fn createBarcodeMatrix(detectionRXingResult: &mut DetectionRXingResult) -> Vec<Vec<BarcodeValue>> { fn createBarcodeMatrix(detectionRXingResult: &mut DetectionRXingResult) -> Vec<Vec<BarcodeValue>> {
let mut barcodeMatrix = let mut barcodeMatrix =
vec![ vec![
vec![BarcodeValue::new(); detectionRXingResult.getBarcodeRowCount() as usize]; vec![BarcodeValue::new(); detectionRXingResult.getBarcodeColumnCount() + 2];
detectionRXingResult.getBarcodeColumnCount() + 2 detectionRXingResult.getBarcodeRowCount() as usize
]; ];
// BarcodeValue[][] barcodeMatrix = // BarcodeValue[][] barcodeMatrix =
// new BarcodeValue[detectionRXingResult.getBarcodeRowCount()][detectionRXingResult.getBarcodeColumnCount() + 2]; // new BarcodeValue[detectionRXingResult.getBarcodeRowCount()][detectionRXingResult.getBarcodeColumnCount() + 2];
@@ -559,7 +565,8 @@ fn createBarcodeMatrix(detectionRXingResult: &mut DetectionRXingResult) -> Vec<V
} }
fn isValidBarcodeColumn(detectionRXingResult: &DetectionRXingResult, barcodeColumn: usize) -> bool { fn isValidBarcodeColumn(detectionRXingResult: &DetectionRXingResult, barcodeColumn: usize) -> bool {
barcodeColumn >= 0 && barcodeColumn <= detectionRXingResult.getBarcodeColumnCount() + 1 /*barcodeColumn >= 0 &&*/
barcodeColumn <= detectionRXingResult.getBarcodeColumnCount() + 1
} }
fn getStartColumn( fn getStartColumn(
@@ -585,11 +592,17 @@ fn getStartColumn(
codeword.getStartX() codeword.getStartX()
}; };
} }
if detectionRXingResult
.getDetectionRXingResultColumn(barcodeColumn as usize)
.is_some()
{
codeword = detectionRXingResult codeword = detectionRXingResult
.getDetectionRXingResultColumn(barcodeColumn as usize) .getDetectionRXingResultColumn(barcodeColumn as usize)
.as_ref() .as_ref()
.unwrap() .unwrap()
.getCodewordNearby(imageRow); .getCodewordNearby(imageRow);
}
if let Some(codeword) = codeword { if let Some(codeword) = codeword {
return if leftToRight { return if leftToRight {
@@ -827,7 +840,7 @@ fn decodeCodewords(
let numECCodewords = 1 << (ecLevel + 1); let numECCodewords = 1 << (ecLevel + 1);
let correctedErrorsCount = correctErrors(codewords, erasures, numECCodewords)?; let correctedErrorsCount = correctErrors(codewords, erasures, numECCodewords)?;
verifyCodewordCount(codewords, numECCodewords); verifyCodewordCount(codewords, numECCodewords)?;
// Decode the codewords // Decode the codewords
let mut decoderRXingResult = let mut decoderRXingResult =
@@ -853,7 +866,7 @@ fn correctErrors(
numECCodewords: u32, numECCodewords: u32,
) -> Result<usize, Exceptions> { ) -> Result<usize, Exceptions> {
if !erasures.is_empty() && erasures.len() as u32 > numECCodewords / 2 + MAX_ERRORS if !erasures.is_empty() && erasures.len() as u32 > numECCodewords / 2 + MAX_ERRORS
|| numECCodewords < 0 /*|| numECCodewords < 0*/
|| numECCodewords > MAX_EC_CODEWORDS || numECCodewords > MAX_EC_CODEWORDS
{ {
// Too many errors or EC Codewords is corrupted // Too many errors or EC Codewords is corrupted
@@ -902,7 +915,7 @@ fn getBitCountForCodeword(codeword: u32) -> [u32; 8] {
break; break;
} }
} }
result[i as usize ] += 1; result[i as usize] += 1;
codeword >>= 1; codeword >>= 1;
} }
@@ -914,7 +927,10 @@ fn getCodewordBucketNumber(codeword: u32) -> u32 {
} }
fn getCodewordBucketNumberArray(moduleBitCount: &[u32]) -> u32 { fn getCodewordBucketNumberArray(moduleBitCount: &[u32]) -> u32 {
(moduleBitCount[0] - moduleBitCount[2] + moduleBitCount[4] - moduleBitCount[6] + 9) % 9 (moduleBitCount[0] as i32 - moduleBitCount[2] as i32 + moduleBitCount[4] as i32
- moduleBitCount[6] as i32
+ 9) as u32
% 9
} }
// fn toString( barcodeMatrix:Vec<Vec<BarcodeValue>>) -> String{ // fn toString( barcodeMatrix:Vec<Vec<BarcodeValue>>) -> String{

View File

@@ -299,6 +299,12 @@ fn findRowsWithPattern(
skippedRowCount += 1; skippedRowCount += 1;
} }
} }
} else {
if skippedRowCount > SKIPPED_ROW_COUNT_MAX {
break;
} else {
skippedRowCount += 1;
}
} }
stopRow += 1; stopRow += 1;
@@ -415,7 +421,7 @@ fn patternMatchVariance(counters: &[u32], pattern: &[u32]) -> f32 {
// We're going to fake floating-point math in integers. We just need to use more bits. // We're going to fake floating-point math in integers. We just need to use more bits.
// Scale up patternLength so that intermediate values below like scaledCounter will have // Scale up patternLength so that intermediate values below like scaledCounter will have
// more "significant digits". // more "significant digits".
let unitBarWidth: f32 = (total / patternLength) as f32; let unitBarWidth: f32 = total as f32 / patternLength as f32;
let maxIndividualVariance = MAX_INDIVIDUAL_VARIANCE * unitBarWidth; let maxIndividualVariance = MAX_INDIVIDUAL_VARIANCE * unitBarWidth;
let mut totalVariance = 0.0; let mut totalVariance = 0.0;

View File

@@ -16,14 +16,17 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
fs::{read_dir, read_to_string}, fs::{read_dir, read_to_string, File},
io::Read,
path::{Path, PathBuf}, path::{Path, PathBuf},
rc::Rc, rc::Rc,
}; };
use encoding::Encoding;
use rxing::{ use rxing::{
common::HybridBinarizer, BarcodeFormat, BinaryBitmap, BufferedImageLuminanceSource, common::HybridBinarizer, pdf417::PDF417RXingResultMetadata, BarcodeFormat, BinaryBitmap,
DecodeHintType, DecodeHintValue, RXingResultMetadataType, RXingResultMetadataValue, Reader, pdf417::PDF417RXingResultMetadata, BufferedImageLuminanceSource, DecodeHintType, DecodeHintValue, RXingResultMetadataType,
RXingResultMetadataValue, Reader,
}; };
use super::TestRXingResult; use super::TestRXingResult;
@@ -208,7 +211,9 @@ impl<T: Reader> AbstractBlackBoxTestCase<T> {
RXingResultMetadataValue::UpcEanExtension(v) RXingResultMetadataValue::UpcEanExtension(v)
} }
RXingResultMetadataType::PDF417_EXTRA_METADATA => { RXingResultMetadataType::PDF417_EXTRA_METADATA => {
RXingResultMetadataValue::Pdf417ExtraMetadata(Rc::new(PDF417RXingResultMetadata::default())) RXingResultMetadataValue::Pdf417ExtraMetadata(Rc::new(
PDF417RXingResultMetadata::default(),
))
} }
RXingResultMetadataType::STRUCTURED_APPEND_SEQUENCE => { RXingResultMetadataType::STRUCTURED_APPEND_SEQUENCE => {
RXingResultMetadataValue::StructuredAppendSequence( RXingResultMetadataValue::StructuredAppendSequence(
@@ -222,7 +227,7 @@ impl<T: Reader> AbstractBlackBoxTestCase<T> {
} }
RXingResultMetadataType::SYMBOLOGY_IDENTIFIER => { RXingResultMetadataType::SYMBOLOGY_IDENTIFIER => {
RXingResultMetadataValue::SymbologyIdentifier(v) RXingResultMetadataValue::SymbologyIdentifier(v)
}, }
}; };
} }
@@ -474,7 +479,20 @@ impl<T: Reader> AbstractBlackBoxTestCase<T> {
} }
fn read_file_as_string(file: PathBuf) -> Result<String, std::io::Error> { fn read_file_as_string(file: PathBuf) -> Result<String, std::io::Error> {
let string_contents = read_to_string(&file)?; //new String(Files.readAllBytes(file), charset); let string_contents = if let Some(ext) = file.extension() {
if ext == "bin" {
let mut buffer: Vec<u8> = Vec::new();
File::open(&file)?.read_to_end(&mut buffer)?;
encoding::all::ISO_8859_1
.decode(&buffer, encoding::DecoderTrap::Replace)
.expect("decode")
} else {
read_to_string(&file).expect("ok")
}
} else {
"".to_owned()
};
// let string_contents = read_to_string(&file)?; //new String(Files.readAllBytes(file), charset);
if string_contents.ends_with('\n') { if string_contents.ends_with('\n') {
log::info(format!("String contents of file {} end with a newline. This may not be intended and cause a test failure",file.to_string_lossy())); log::info(format!("String contents of file {} end with a newline. This may not be intended and cause a test failure",file.to_string_lossy()));
} }