diff --git a/src/pdf417/decoder/detection_result.rs b/src/pdf417/decoder/detection_result.rs index c7d58a4..f21007c 100644 --- a/src/pdf417/decoder/detection_result.rs +++ b/src/pdf417/decoder/detection_result.rs @@ -147,146 +147,171 @@ impl DetectionRXingResult { } fn adjustRowNumbersFromBothRI(&mut self) { - if self.detectionRXingResultColumns[0].is_some() - && self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].is_some() + if self.detectionRXingResultColumns[0].is_none() + && self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].is_none() { - // let LRIcodewords = self.detectionRXingResultColumns[0].as_ref().unwrap().getCodewords(); - // let RRIcodewords = self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].as_ref().unwrap().getCodewords(); - for codewordsRow in 0..self.detectionRXingResultColumns[0] + return; + } + + // let LRIcodewords = self.detectionRXingResultColumns[0].as_ref().unwrap().getCodewords(); + // let RRIcodewords = self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1].as_ref().unwrap().getCodewords(); + for codewordsRow in 0..self.detectionRXingResultColumns[0] + .as_ref() + .unwrap() + .getCodewords() + .len() + { + // for (int codewordsRow = 0; codewordsRow < LRIcodewords.length; codewordsRow++) { + if + //let (Some(lricw), Some(rricw)) = + self.detectionRXingResultColumns[0] .as_ref() .unwrap() - .getCodewords() - .len() - { - // for (int codewordsRow = 0; codewordsRow < LRIcodewords.length; codewordsRow++) { - if - //let (Some(lricw), Some(rricw)) = - self.detectionRXingResultColumns[0] + .getCodewords()[codewordsRow] + .is_some() + && self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] .as_ref() .unwrap() .getCodewords()[codewordsRow] .is_some() - && self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] - .as_ref() - .unwrap() - .getCodewords()[codewordsRow] - .is_some() - { - if self.detectionRXingResultColumns[0] + { + if self.detectionRXingResultColumns[0] + .as_ref() + .unwrap() + .getCodewords()[codewordsRow] + .as_ref() + .unwrap() + .getRowNumber() + == self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] .as_ref() .unwrap() .getCodewords()[codewordsRow] .as_ref() .unwrap() .getRowNumber() - == self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] - .as_ref() - .unwrap() - .getCodewords()[codewordsRow] - .as_ref() - .unwrap() - .getRowNumber() - { - // if (LRIcodewords[codewordsRow] != null && - // RRIcodewords[codewordsRow] != null && - // LRIcodewords[codewordsRow].getRowNumber() == RRIcodewords[codewordsRow].getRowNumber()) { - for barcodeColumn in 1..=self.barcodeColumnCount { - // for (int barcodeColumn = 1; barcodeColumn <= barcodeColumnCount; barcodeColumn++) { - if self.detectionRXingResultColumns[barcodeColumn].is_some() - //let Some(dc_col) = - //&mut self.detectionRXingResultColumns[barcodeColumn] + { + // if (LRIcodewords[codewordsRow] != null && + // RRIcodewords[codewordsRow] != null && + // LRIcodewords[codewordsRow].getRowNumber() == RRIcodewords[codewordsRow].getRowNumber()) { + for barcodeColumn in 1..=self.barcodeColumnCount { + // for (int barcodeColumn = 1; barcodeColumn <= barcodeColumnCount; barcodeColumn++) { + if self.detectionRXingResultColumns[barcodeColumn].is_some() + //let Some(dc_col) = + //&mut self.detectionRXingResultColumns[barcodeColumn] + { + if self.detectionRXingResultColumns[barcodeColumn] + .as_mut() + .unwrap() + .getCodewordsMut()[codewordsRow] + .is_some() { - if self.detectionRXingResultColumns[barcodeColumn] + //let Some(codeword) = &mut self.detectionRXingResultColumns[barcodeColumn].as_mut().unwrap().getCodewordsMut()[codewordsRow] { + let new_row_number = self.detectionRXingResultColumns[0] + .as_ref() + .unwrap() + .getCodewords()[codewordsRow] + .as_ref() + .unwrap() + .getRowNumber(); + self.detectionRXingResultColumns[barcodeColumn] .as_mut() .unwrap() .getCodewordsMut()[codewordsRow] - .is_some() + .as_mut() + .unwrap() + .setRowNumber(new_row_number); + if !self.detectionRXingResultColumns[barcodeColumn] + .as_mut() + .unwrap() + .getCodewordsMut()[codewordsRow] + .as_ref() + .unwrap() + .hasValidRowNumber() { - //let Some(codeword) = &mut self.detectionRXingResultColumns[barcodeColumn].as_mut().unwrap().getCodewordsMut()[codewordsRow] { - let new_row_number = self.detectionRXingResultColumns[0] - .as_ref() - .unwrap() - .getCodewords()[codewordsRow] - .as_ref() - .unwrap() - .getRowNumber(); + // self.detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow] = None; self.detectionRXingResultColumns[barcodeColumn] .as_mut() .unwrap() - .getCodewordsMut()[codewordsRow] - .as_mut() - .unwrap() - .setRowNumber(new_row_number); - if !self.detectionRXingResultColumns[barcodeColumn] - .as_mut() - .unwrap() - .getCodewordsMut()[codewordsRow] - .as_ref() - .unwrap() - .hasValidRowNumber() - { - // self.detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow] = None; - self.detectionRXingResultColumns[barcodeColumn] - .as_mut() - .unwrap() - .getCodewordsMut()[codewordsRow] = None; - } - } else { - continue; + .getCodewordsMut()[codewordsRow] = None; } } else { continue; } - // let codeword = self.detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow]; - // if (codeword == null) { - // continue; - // } + } else { + continue; } + // let codeword = self.detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow]; + // if (codeword == null) { + // continue; + // } } } } } + // if (detectionRXingResultColumns[0] == null || detectionRXingResultColumns[barcodeColumnCount + 1] == null) { // return; // } } - fn adjustRowNumbersFromRRI(&self) -> u32 { - if let Some(col) = &self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] { - let mut unadjustedCount = 0; - let codewords = col.getCodewords(); - for codewordsRow in 0..codewords.len() { - // for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) { - if let Some(codeword_col) = codewords[codewordsRow] { - let rowIndicatorRowNumber = codeword_col.getRowNumber(); - let mut invalidRowCounts = 0; - let mut barcodeColumn = self.barcodeColumnCount as usize + 1; - while barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP { - // for (int barcodeColumn = barcodeColumnCount + 1; - // barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; - // barcodeColumn--) { - if let Some(bc_col) = &self.detectionRXingResultColumns[barcodeColumn] { - if let Some(codeword) = bc_col.getCodewords()[codewordsRow] { - invalidRowCounts = Self::adjustRowNumberIfValid( - rowIndicatorRowNumber, - invalidRowCounts, - &mut Some(codeword), - ); - if !codeword.hasValidRowNumber() { - unadjustedCount += 1; - } - } - } - barcodeColumn -= 1; - } - } else { - continue; - } - } - unadjustedCount - } else { - 0 + fn adjustRowNumbersFromRRI(&mut self) -> u32 { + 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 codewords_len = self.detectionRXingResultColumns[self.barcodeColumnCount as usize + 1] + .as_ref() + .unwrap() + .getCodewords() + .len(); + for codewordsRow in 0..codewords_len { + // for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) { + // if let Some(codeword_col) = codewords[codewordsRow] { + 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 barcodeColumn = self.barcodeColumnCount as usize + 1; + while barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP { + // for (int barcodeColumn = barcodeColumnCount + 1; + // barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; + // barcodeColumn--) { + if let Some(bc_col) = &mut self.detectionRXingResultColumns[barcodeColumn] { + if let Some(codeword) = &mut bc_col.getCodewordsMut()[codewordsRow] { + invalidRowCounts = Self::adjustRowNumberIfValid( + rowIndicatorRowNumber, + invalidRowCounts, + codeword, + ); + if !codeword.hasValidRowNumber() { + unadjustedCount += 1; + } + } + } + barcodeColumn -= 1; + } + // } else { + // continue; + // } + } + unadjustedCount + // } else { + // 0 + // } // if (detectionRXingResultColumns[barcodeColumnCount + 1] == null) { // return 0; // } @@ -313,67 +338,89 @@ impl DetectionRXingResult { // return unadjustedCount; } - fn adjustRowNumbersFromLRI(&self) -> u32 { - if let Some(col) = &self.detectionRXingResultColumns[0] { - let mut unadjustedCount = 0; - let codewords = col.getCodewords(); - for codewordsRow in 0..codewords.len() { - // for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) { - if let Some(codeword_in_row) = codewords[codewordsRow] { - let rowIndicatorRowNumber = codeword_in_row.getRowNumber(); - let mut invalidRowCounts = 0; - let mut barcodeColumn = 1_usize; - while barcodeColumn < self.barcodeColumnCount as usize + 1 - && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP - { - // for (int barcodeColumn = 1; - // barcodeColumn < barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; - // barcodeColumn++) { - if let Some(bc_column) = &self.detectionRXingResultColumns[barcodeColumn] { - if let Some(codeword) = bc_column.getCodewords()[codewordsRow] { - invalidRowCounts = Self::adjustRowNumberIfValid( - rowIndicatorRowNumber, - invalidRowCounts, - &mut Some(codeword), - ); - if !codeword.hasValidRowNumber() { - unadjustedCount += 1; - } - } - } - // let codeword = self.detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow]; - // if (codeword != null) { - // invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword); - // if (!codeword.hasValidRowNumber()) { - // unadjustedCount+=1; - // } - // } - barcodeColumn += 1; - } - } else { - continue; - } - // if (codewords[codewordsRow] == null) { - // continue; - // } - // let rowIndicatorRowNumber = codewords[codewordsRow].getRowNumber(); - // let invalidRowCounts = 0; + fn adjustRowNumbersFromLRI(&mut self) -> u32 { + if self.detectionRXingResultColumns[0].is_none() { + return 0; + } + + // if let Some(col) = &self.detectionRXingResultColumns[0] { + let mut unadjustedCount = 0; + let codewords_len = self.detectionRXingResultColumns[0] + .as_ref() + .unwrap() + .getCodewords() + .len(); + for codewordsRow in 0..codewords_len { + // for (int codewordsRow = 0; codewordsRow < codewords.length; codewordsRow++) { + // if let Some(codeword_in_row) = codewords[codewordsRow] { + 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 barcodeColumn = 1_usize; + while barcodeColumn < self.barcodeColumnCount as usize + 1 + && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP + { // for (int barcodeColumn = 1; // barcodeColumn < barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; // barcodeColumn++) { - // Codeword codeword = detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow]; - // if (codeword != null) { - // invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword); - // if (!codeword.hasValidRowNumber()) { - // unadjustedCount++; - // } + if let Some(bc_column) = &mut self.detectionRXingResultColumns[barcodeColumn] { + if let Some(codeword) = &mut bc_column.getCodewordsMut()[codewordsRow] { + invalidRowCounts = Self::adjustRowNumberIfValid( + rowIndicatorRowNumber, + invalidRowCounts, + codeword, + ); + if !codeword.hasValidRowNumber() { + unadjustedCount += 1; + } + } + } + // let codeword = self.detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow]; + // if (codeword != null) { + // invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword); + // if (!codeword.hasValidRowNumber()) { + // unadjustedCount+=1; // } // } + barcodeColumn += 1; } - unadjustedCount - } else { - 0 + // } else { + // continue; + // } + // if (codewords[codewordsRow] == null) { + // continue; + // } + // let rowIndicatorRowNumber = codewords[codewordsRow].getRowNumber(); + // let invalidRowCounts = 0; + // for (int barcodeColumn = 1; + // barcodeColumn < barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; + // barcodeColumn++) { + // Codeword codeword = detectionRXingResultColumns[barcodeColumn].getCodewords()[codewordsRow]; + // if (codeword != null) { + // invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword); + // if (!codeword.hasValidRowNumber()) { + // unadjustedCount++; + // } + // } + // } } + unadjustedCount + // } else { + // 0 + // } // if (detectionRXingResultColumns[0] == null) { // return 0; @@ -404,21 +451,21 @@ impl DetectionRXingResult { fn adjustRowNumberIfValid( rowIndicatorRowNumber: i32, mut invalidRowCounts: u32, - codeword: &mut Option, + codeword: &mut Codeword, ) -> u32 { - if let Some(codeword) = codeword { - if !codeword.hasValidRowNumber() { - if codeword.isValidRowNumber(rowIndicatorRowNumber) { - codeword.setRowNumber(rowIndicatorRowNumber); - invalidRowCounts = 0; - } else { - invalidRowCounts += 1; - } + // if let Some(codeword) = codeword { + if !codeword.hasValidRowNumber() { + if codeword.isValidRowNumber(rowIndicatorRowNumber) { + codeword.setRowNumber(rowIndicatorRowNumber); + invalidRowCounts = 0; + } else { + invalidRowCounts += 1; } - invalidRowCounts - } else { - invalidRowCounts } + invalidRowCounts + // } else { + // invalidRowCounts + // } // if (codeword == null) { // return invalidRowCounts; // } @@ -548,6 +595,13 @@ impl DetectionRXingResult { ) -> &Option> { &self.detectionRXingResultColumns[barcodeColumn] } + + pub fn getDetectionRXingResultColumnMut( + &mut self, + barcodeColumn: usize, + ) -> &mut Option> { + &mut self.detectionRXingResultColumns[barcodeColumn] + } } impl Display for DetectionRXingResult { diff --git a/src/pdf417/decoder/detection_result_column.rs b/src/pdf417/decoder/detection_result_column.rs index dd4a8fb..f21f81c 100644 --- a/src/pdf417/decoder/detection_result_column.rs +++ b/src/pdf417/decoder/detection_result_column.rs @@ -73,16 +73,16 @@ impl DetectionRXingResultColumnTrait for DetectionRXingResultColumn { } for i in 1..MAX_NEARBY_DISTANCE as usize { // 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 { - codeword = &self.codewords[nearImageRow]; + codeword = &self.codewords[nearImageRow as usize]; if codeword.is_some() { return codeword; } } - nearImageRow = self.imageRowToCodewordIndex(imageRow) + i; - if nearImageRow < self.codewords.len() { - codeword = &self.codewords[nearImageRow]; + nearImageRow = self.imageRowToCodewordIndex(imageRow) as isize + i as isize; + if nearImageRow < self.codewords.len() as isize { + codeword = &self.codewords[nearImageRow as usize]; if codeword.is_some() { return codeword; } diff --git a/src/pdf417/decoder/pdf_417_codeword_decoder.rs b/src/pdf417/decoder/pdf_417_codeword_decoder.rs index 71442e9..e31bc84 100644 --- a/src/pdf417/decoder/pdf_417_codeword_decoder.rs +++ b/src/pdf417/decoder/pdf_417_codeword_decoder.rs @@ -24,7 +24,7 @@ use crate::pdf417::pdf_417_common; // const RATIOS_TABLE :[[f32]] = // [[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 = [[0.0; pdf_417_common::BARS_IN_MODULE as usize]; pdf_417_common::SYMBOL_TABLE.len()]; // 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; 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; } @@ -70,8 +70,8 @@ fn sampleBitCounts(moduleBitCount: &[u32]) -> [u32; 8] { for i in 0..pdf_417_common::MODULES_IN_CODEWORD { // for (int i = 0; i < PDF417Common.MODULES_IN_CODEWORD; i++) { let sampleIndex: f32 = bitCountSum as f32 - / (2 * pdf_417_common::MODULES_IN_CODEWORD) as f32 - + (i * bitCountSum) as f32 / pdf_417_common::MODULES_IN_CODEWORD as f32; + / (2.0 * 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 { sumPreviousBits += moduleBitCount[bitCountIndex]; bitCountIndex += 1; @@ -108,15 +108,15 @@ fn getClosestDecodedValue(moduleBitCount: &[u32]) -> i32 { if bitCountSum > 1 { for i in 0..bitCountRatios.len() { // 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; for j in 0..RATIOS_TABLE.len() { // for (int j = 0; j < RATIOS_TABLE.length; j++) { 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 (int k = 0; k < PDF417Common.BARS_IN_MODULE; k++) { let diff = ratioTableRow[k] - bitCountRatios[k]; @@ -132,3 +132,57 @@ fn getClosestDecodedValue(moduleBitCount: &[u32]) -> i32 { } 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)); + } +} diff --git a/src/pdf417/decoder/pdf_417_scanning_decoder.rs b/src/pdf417/decoder/pdf_417_scanning_decoder.rs index 342f880..6103ef7 100644 --- a/src/pdf417/decoder/pdf_417_scanning_decoder.rs +++ b/src/pdf417/decoder/pdf_417_scanning_decoder.rs @@ -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. continue; } - let mut detectionRXingResultColumn = if barcodeColumn == 0 - || barcodeColumn == maxBarcodeColumn + let detectionRXingResultColumn = if barcodeColumn == 0 || barcodeColumn == maxBarcodeColumn { DetectionRXingResultColumn::new_with_is_left(boundingBox.clone(), barcodeColumn == 0) } else { DetectionRXingResultColumn::new(boundingBox.clone()) }; + detectionRXingResult - .setDetectionRXingResultColumn(barcodeColumn, Some(detectionRXingResultColumn.clone())); + .setDetectionRXingResultColumn(barcodeColumn, Some(detectionRXingResultColumn)); + let mut startColumn: i32 = -1; let mut previousStartColumn = startColumn; // 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() { let codeword = codeword.unwrap(); - detectionRXingResultColumn.setCodeword(imageRow, codeword); + //detectionRXingResultColumn.setCodeword(imageRow, codeword); + detectionRXingResult + .getDetectionRXingResultColumnMut(barcodeColumn) + .as_mut() + .unwrap() + .setCodeword(imageRow, codeword); previousStartColumn = startColumn; minCodewordWidth = minCodewordWidth.min(codeword.getWidth()); - maxCodewordWidth = maxCodewordWidth.min(codeword.getWidth()); + maxCodewordWidth = maxCodewordWidth.max(codeword.getWidth()); } } } @@ -416,7 +422,7 @@ fn createDecoderRXingResult( detectionRXingResult: &mut DetectionRXingResult, ) -> Result { let mut barcodeMatrix = createBarcodeMatrix(detectionRXingResult); - adjustCodewordCount(detectionRXingResult, &mut barcodeMatrix); + adjustCodewordCount(detectionRXingResult, &mut barcodeMatrix)?; let mut erasures = Vec::new(); //new ArrayList<>(); let mut codewords = vec![ 0; @@ -521,8 +527,8 @@ fn createDecoderRXingResultFromAmbiguousValues( fn createBarcodeMatrix(detectionRXingResult: &mut DetectionRXingResult) -> Vec> { let mut barcodeMatrix = vec![ - vec![BarcodeValue::new(); detectionRXingResult.getBarcodeRowCount() as usize]; - detectionRXingResult.getBarcodeColumnCount() + 2 + vec![BarcodeValue::new(); detectionRXingResult.getBarcodeColumnCount() + 2]; + detectionRXingResult.getBarcodeRowCount() as usize ]; // BarcodeValue[][] barcodeMatrix = // new BarcodeValue[detectionRXingResult.getBarcodeRowCount()][detectionRXingResult.getBarcodeColumnCount() + 2]; @@ -559,7 +565,8 @@ fn createBarcodeMatrix(detectionRXingResult: &mut DetectionRXingResult) -> Vec bool { - barcodeColumn >= 0 && barcodeColumn <= detectionRXingResult.getBarcodeColumnCount() + 1 + /*barcodeColumn >= 0 &&*/ + barcodeColumn <= detectionRXingResult.getBarcodeColumnCount() + 1 } fn getStartColumn( @@ -585,11 +592,17 @@ fn getStartColumn( codeword.getStartX() }; } - codeword = detectionRXingResult + + if detectionRXingResult .getDetectionRXingResultColumn(barcodeColumn as usize) - .as_ref() - .unwrap() - .getCodewordNearby(imageRow); + .is_some() + { + codeword = detectionRXingResult + .getDetectionRXingResultColumn(barcodeColumn as usize) + .as_ref() + .unwrap() + .getCodewordNearby(imageRow); + } if let Some(codeword) = codeword { return if leftToRight { @@ -827,7 +840,7 @@ fn decodeCodewords( let numECCodewords = 1 << (ecLevel + 1); let correctedErrorsCount = correctErrors(codewords, erasures, numECCodewords)?; - verifyCodewordCount(codewords, numECCodewords); + verifyCodewordCount(codewords, numECCodewords)?; // Decode the codewords let mut decoderRXingResult = @@ -853,7 +866,7 @@ fn correctErrors( numECCodewords: u32, ) -> Result { if !erasures.is_empty() && erasures.len() as u32 > numECCodewords / 2 + MAX_ERRORS - || numECCodewords < 0 + /*|| numECCodewords < 0*/ || numECCodewords > MAX_EC_CODEWORDS { // Too many errors or EC Codewords is corrupted @@ -902,7 +915,7 @@ fn getBitCountForCodeword(codeword: u32) -> [u32; 8] { break; } } - result[i as usize ] += 1; + result[i as usize] += 1; codeword >>= 1; } @@ -914,7 +927,10 @@ fn getCodewordBucketNumber(codeword: 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>) -> String{ diff --git a/src/pdf417/detector/detector.rs b/src/pdf417/detector/detector.rs index 2f7baed..41bac2e 100644 --- a/src/pdf417/detector/detector.rs +++ b/src/pdf417/detector/detector.rs @@ -299,6 +299,12 @@ fn findRowsWithPattern( skippedRowCount += 1; } } + } else { + if skippedRowCount > SKIPPED_ROW_COUNT_MAX { + break; + } else { + skippedRowCount += 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. // Scale up patternLength so that intermediate values below like scaledCounter will have // 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 mut totalVariance = 0.0; diff --git a/tests/common/abstract_black_box_test_case.rs b/tests/common/abstract_black_box_test_case.rs index a267795..60c2897 100644 --- a/tests/common/abstract_black_box_test_case.rs +++ b/tests/common/abstract_black_box_test_case.rs @@ -16,14 +16,17 @@ use std::{ collections::HashMap, - fs::{read_dir, read_to_string}, + fs::{read_dir, read_to_string, File}, + io::Read, path::{Path, PathBuf}, rc::Rc, }; +use encoding::Encoding; use rxing::{ - common::HybridBinarizer, BarcodeFormat, BinaryBitmap, BufferedImageLuminanceSource, - DecodeHintType, DecodeHintValue, RXingResultMetadataType, RXingResultMetadataValue, Reader, pdf417::PDF417RXingResultMetadata, + common::HybridBinarizer, pdf417::PDF417RXingResultMetadata, BarcodeFormat, BinaryBitmap, + BufferedImageLuminanceSource, DecodeHintType, DecodeHintValue, RXingResultMetadataType, + RXingResultMetadataValue, Reader, }; use super::TestRXingResult; @@ -208,7 +211,9 @@ impl AbstractBlackBoxTestCase { RXingResultMetadataValue::UpcEanExtension(v) } RXingResultMetadataType::PDF417_EXTRA_METADATA => { - RXingResultMetadataValue::Pdf417ExtraMetadata(Rc::new(PDF417RXingResultMetadata::default())) + RXingResultMetadataValue::Pdf417ExtraMetadata(Rc::new( + PDF417RXingResultMetadata::default(), + )) } RXingResultMetadataType::STRUCTURED_APPEND_SEQUENCE => { RXingResultMetadataValue::StructuredAppendSequence( @@ -222,7 +227,7 @@ impl AbstractBlackBoxTestCase { } RXingResultMetadataType::SYMBOLOGY_IDENTIFIER => { RXingResultMetadataValue::SymbologyIdentifier(v) - }, + } }; } @@ -474,7 +479,20 @@ impl AbstractBlackBoxTestCase { } fn read_file_as_string(file: PathBuf) -> Result { - 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 = 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') { 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())); }