mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-28 05:12:34 +00:00
fixed codeword row error correction issue
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user