diff --git a/src/datamatrix/data_matrix_reader.rs b/src/datamatrix/data_matrix_reader.rs index 15a92c0b..698c2563 100644 --- a/src/datamatrix/data_matrix_reader.rs +++ b/src/datamatrix/data_matrix_reader.rs @@ -87,9 +87,16 @@ impl Reader for DataMatrixReader { decoderRXingResult = if let Ok(fnd) = || -> Result { let detectorRXingResult = zxing_cpp_detector::detect(image.get_black_matrix(), try_harder, true)?; - let decoded = DECODER.decode(detectorRXingResult.getBits())?; - points = detectorRXingResult.getPoints().to_vec(); - Ok(decoded) + for symbol in detectorRXingResult { + let decoded = DECODER.decode(symbol.getBits()); + if decoded.is_ok() { + points = symbol.getPoints().to_vec(); + return Ok(decoded?); + } else { + continue; + } + } + Err(Exceptions::NOT_FOUND) }() { fnd } else if try_harder { diff --git a/src/datamatrix/detector/zxing_cpp_detector/cpp_new_detector.rs b/src/datamatrix/detector/zxing_cpp_detector/cpp_new_detector.rs index 729147ca..1dd90532 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/cpp_new_detector.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/cpp_new_detector.rs @@ -15,8 +15,8 @@ use std::{cell::RefCell, rc::Rc}; use crate::{ common::{ - cpp_essentials::RegressionLineTrait, BitMatrix, DefaultGridSampler, GridSampler, - Quadrilateral, Result, + cpp_essentials::RegressionLineTrait, BitMatrix, DefaultGridSampler, DetectorRXingResult, + GridSampler, Quadrilateral, Result, }, datamatrix::detector::{ zxing_cpp_detector::{util::intersect, BitMatrixCursorTrait}, @@ -246,7 +246,7 @@ pub fn detect( image: &BitMatrix, tryHarder: bool, tryRotate: bool, -) -> Result { +) -> Result> { // #ifdef PRINT_DEBUG // LogMatrixWriter lmw(log, image, 1, "dm-log.pnm"); // // tryRotate = tryHarder = false; @@ -257,6 +257,8 @@ pub fn detect( // tryHarder = false; // #endif + let mut found_symbols = Vec::new(); + // a history log to remember where the tracing already passed by to prevent a later trace from doing the same work twice let mut history = None; if tryHarder { @@ -323,7 +325,10 @@ pub fn detect( // #else if let Ok(res) = Scan(&mut tracer, &mut lines) { // if res.isValid(){ - return Ok(res); + //return Ok(res); + // i += res.getPoints()[2].distance( res.getPoints()[0] ) as i32; + i += MIN_SYMBOL_SIZE as i32; + found_symbols.push(res); // } } @@ -343,6 +348,10 @@ pub fn detect( } // #ifndef __cpp_impl_coroutine - Err(Exceptions::NOT_FOUND) + if found_symbols.is_empty() { + Err(Exceptions::NOT_FOUND) + } else { + Ok(found_symbols) + } // #endif } diff --git a/test_resources/blackbox/github_issue_cases/349949736-8e3b9d66-d114-41ca-a8e0-f1332d111827.jpeg b/test_resources/blackbox/github_issue_cases/349949736-8e3b9d66-d114-41ca-a8e0-f1332d111827.jpeg new file mode 100644 index 00000000..d9de264f Binary files /dev/null and b/test_resources/blackbox/github_issue_cases/349949736-8e3b9d66-d114-41ca-a8e0-f1332d111827.jpeg differ diff --git a/test_resources/blackbox/github_issue_cases/349949791-1e8b67a7-0994-46fb-bd86-a5f3cd79f0e5.jpeg b/test_resources/blackbox/github_issue_cases/349949791-1e8b67a7-0994-46fb-bd86-a5f3cd79f0e5.jpeg new file mode 100644 index 00000000..222067b3 Binary files /dev/null and b/test_resources/blackbox/github_issue_cases/349949791-1e8b67a7-0994-46fb-bd86-a5f3cd79f0e5.jpeg differ diff --git a/tests/github_issues.rs b/tests/github_issues.rs index c1032f21..b91f0486 100644 --- a/tests/github_issues.rs +++ b/tests/github_issues.rs @@ -397,6 +397,7 @@ fn test_issue_49() { assert_eq!(EXPECTED_ITF_TEXT, itf_result.getText()); } + #[cfg(feature = "image")] #[test] fn test_issue_50() { @@ -479,3 +480,79 @@ fn test_issue_50_2() { assert_eq!(EXPECTED_FORMAT, result.getBarcodeFormat()); } + + +#[cfg(feature = "image")] +#[test] +fn issue_51_multiple_detection() { + use image::DynamicImage; + use rxing::{ + common::HybridBinarizer, + multi::{GenericMultipleBarcodeReader, MultipleBarcodeReader}, + BarcodeFormat, BinaryBitmap, BufferedImageLuminanceSource, DecodeHintType, DecodeHintValue, + DecodingHintDictionary, Exceptions, MultiUseMultiFormatReader, + }; + + const FILE_NAME : &str = "test_resources/blackbox/github_issue_cases/349949736-8e3b9d66-d114-41ca-a8e0-f1332d111827.jpeg"; + + let mut hints = DecodingHintDictionary::default(); + + let img = DynamicImage::from( + image::open(FILE_NAME) + .map_err(|e| Exceptions::runtime_with(format!("couldn't read {FILE_NAME}: {e}"))) + .unwrap() + .to_luma8(), + ); + let multi_format_reader = MultiUseMultiFormatReader::default(); + let mut scanner = GenericMultipleBarcodeReader::new(multi_format_reader); + + hints + .entry(DecodeHintType::TRY_HARDER) + .or_insert(DecodeHintValue::TryHarder(true)); + + let results = scanner + .decode_multiple_with_hints( + &mut BinaryBitmap::new(HybridBinarizer::new(BufferedImageLuminanceSource::new(img))), + &hints, + ) + .expect("must not fault during read image 1"); + + assert_eq!( + results.len(), + 1, + "must detect 1 barcodes, found: {}", + results.len() + ); + + const FILE_NAME2 : &str = "test_resources/blackbox/github_issue_cases/349949791-1e8b67a7-0994-46fb-bd86-a5f3cd79f0e5.jpeg"; + + let mut hints = DecodingHintDictionary::default(); + + let img = DynamicImage::from( + image::open(FILE_NAME2) + .map_err(|e| Exceptions::runtime_with(format!("couldn't read {FILE_NAME2}: {e}"))) + .unwrap() + .to_luma8(), + ); + let multi_format_reader = MultiUseMultiFormatReader::default(); + let mut scanner = GenericMultipleBarcodeReader::new(multi_format_reader); + + hints + .entry(DecodeHintType::TRY_HARDER) + .or_insert(DecodeHintValue::TryHarder(true)); + + let results = scanner + .decode_multiple_with_hints( + &mut BinaryBitmap::new(HybridBinarizer::new(BufferedImageLuminanceSource::new(img))), + &hints, + ) + .expect("must not fault during read of image 2"); + + assert_eq!( + results.len(), + 1, + "must detect 1 barcodes, found: {}", + results.len() + ); +} +