From 4d703c4e51dfe66376c956bdf8ea0c5a3cb34875 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Fri, 28 Apr 2023 13:25:49 -0500 Subject: [PATCH] all tests but 7 (SA) and inverted pass --- .../cpp_essentials/concentric_finder.rs | 16 ++++----- src/common/eci_string_builder.rs | 36 +++++++++++-------- src/multi_use_multi_format_reader.rs | 6 ++-- src/qrcode/cpp_port/decoder.rs | 12 +++---- src/qrcode/cpp_port/detector.rs | 4 +-- src/qrcode/cpp_port/qr_cpp_reader.rs | 31 +++++++++++----- src/rxing_result_metadata.rs | 2 +- tests/cpp_qr_code_blackbox_tests.rs | 7 +++- 8 files changed, 72 insertions(+), 42 deletions(-) diff --git a/src/common/cpp_essentials/concentric_finder.rs b/src/common/cpp_essentials/concentric_finder.rs index d33fae5..29b21fd 100644 --- a/src/common/cpp_essentials/concentric_finder.rs +++ b/src/common/cpp_essentials/concentric_finder.rs @@ -5,7 +5,7 @@ use crate::{ }, BitMatrix, Quadrilateral, }, - point, Point, Exceptions, + point, Exceptions, Point, }; use crate::common::Result; @@ -402,19 +402,19 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option Option<&[Point]> { + let try_get_range = |a: usize, b: usize| -> Option<&[Point]> { if a > b { None - }else{ + } else { Some(&points[a + 1..b]) } }; -let lines = [ - RegressionLine::with_point_slice(try_get_range(corner_positions[0],corner_positions[1])?), - RegressionLine::with_point_slice(try_get_range(corner_positions[1],corner_positions[2])?), - RegressionLine::with_point_slice(try_get_range(corner_positions[2],corner_positions[3])?), - RegressionLine::with_point_slice(try_get_range(corner_positions[3],points.len())?), + let lines = [ + RegressionLine::with_point_slice(try_get_range(corner_positions[0], corner_positions[1])?), + RegressionLine::with_point_slice(try_get_range(corner_positions[1], corner_positions[2])?), + RegressionLine::with_point_slice(try_get_range(corner_positions[2], corner_positions[3])?), + RegressionLine::with_point_slice(try_get_range(corner_positions[3], points.len())?), ]; // let lines = [ diff --git a/src/common/eci_string_builder.rs b/src/common/eci_string_builder.rs index ea29d17..eb5637e 100644 --- a/src/common/eci_string_builder.rs +++ b/src/common/eci_string_builder.rs @@ -42,6 +42,7 @@ pub struct ECIStringBuilder { bytes: Vec, eci_positions: Vec<(Eci, usize, usize)>, // (Eci, start, end) pub symbology: SymbologyIdentifier, + eci_list: HashSet, } impl ECIStringBuilder { @@ -52,6 +53,7 @@ impl ECIStringBuilder { eci_positions: Vec::default(), has_eci: false, symbology: SymbologyIdentifier::default(), + eci_list: HashSet::default(), } } @@ -126,27 +128,33 @@ impl ECIStringBuilder { self.eci_positions.push((eci, self.bytes.len(), 0)); - let ecis = self.list_ecis(); + self.eci_list.insert(eci); - if ecis.len() == 1 && (ecis.contains(&Eci::Unknown)) { + if self.eci_list.len() == 1 && (self.eci_list.contains(&Eci::Unknown)) { self.has_eci = false; } } } /// Change the current encoding characterset, finding an eci to do so - pub fn switch_encoding(&mut self, charset: CharacterSet) { + pub fn switch_encoding(&mut self, charset: CharacterSet, is_eci: bool) { //self.append_eci(Eci::from(charset)) - if false && !self.has_eci { + if is_eci && !self.has_eci { self.eci_positions.clear(); } - if false || !self.has_eci + if is_eci || !self.has_eci //{self.eci_positions.push_back({eci, Size(bytes)});} { - self.append_eci(Eci::from(charset)) + // self.append_eci(Eci::from(charset)) + if let Some(last) = self.eci_positions.last_mut() { + last.2 = self.bytes.len() + } + + self.eci_positions + .push((Eci::from(charset), self.bytes.len(), 0)); } - self.has_eci |= false; + self.has_eci |= is_eci; } /// Finishes encoding anything in the buffer using the current ECI and resets. @@ -270,13 +278,13 @@ impl ECIStringBuilder { self } - pub fn list_ecis(&self) -> HashSet { - let mut hs = HashSet::new(); - self.eci_positions.iter().for_each(|pos| { - hs.insert(pos.0); - }); - hs - } + // pub fn list_ecis(&self) -> HashSet { + // let mut hs = HashSet::new(); + // self.eci_positions.iter().for_each(|pos| { + // hs.insert(pos.0); + // }); + // hs + // } } impl fmt::Display for ECIStringBuilder { diff --git a/src/multi_use_multi_format_reader.rs b/src/multi_use_multi_format_reader.rs index 17245f0..4e809e4 100644 --- a/src/multi_use_multi_format_reader.rs +++ b/src/multi_use_multi_format_reader.rs @@ -180,7 +180,7 @@ impl MultiUseMultiFormatReader { let a = self.qr_code_reader.decode_with_hints(image, &self.hints); if a.is_ok() { a - }else { + } else { self.cpp_qrcode_reader.decode_with_hints(image, &self.hints) } } @@ -214,10 +214,12 @@ impl MultiUseMultiFormatReader { return Ok(res); } } - if let Ok(res) = self.qr_code_reader.decode_with_hints(image, &self.hints) { return Ok(res); } + if let Ok(res) = self.cpp_qrcode_reader.decode_with_hints(image, &self.hints) { + return Ok(res); + } if let Ok(res) = self .data_matrix_reader .decode_with_hints(image, &self.hints) diff --git a/src/qrcode/cpp_port/decoder.rs b/src/qrcode/cpp_port/decoder.rs index 042a356..79fec91 100644 --- a/src/qrcode/cpp_port/decoder.rs +++ b/src/qrcode/cpp_port/decoder.rs @@ -70,7 +70,7 @@ pub fn DecodeHanziSegment( // Each character will require 2 bytes, decode as GB2312 // There is no ECI value for GB2312, use GB18030 which is a superset - result.switch_encoding(CharacterSet::GB18030); + result.switch_encoding(CharacterSet::GB18030, false); result.reserve(2 * count as usize); while (count > 0) { @@ -99,7 +99,7 @@ pub fn DecodeKanjiSegment( let mut count = count; // Each character will require 2 bytes. Read the characters as 2-byte pairs // and decode as Shift_JIS afterwards - result.switch_encoding(CharacterSet::Shift_JIS); + result.switch_encoding(CharacterSet::Shift_JIS, false); result.reserve(2 * count as usize); while (count > 0) { @@ -125,7 +125,7 @@ pub fn DecodeByteSegment( count: u32, result: &mut ECIStringBuilder, ) -> Result<()> { - result.switch_encoding(CharacterSet::Unknown); + result.switch_encoding(CharacterSet::Unknown, false); result.reserve(count as usize); for _i in 0..count { @@ -205,7 +205,7 @@ pub fn DecodeAlphanumericSegment( } } - result.switch_encoding(CharacterSet::ISO8859_1); + result.switch_encoding(CharacterSet::ISO8859_1, false); *result += buffer; Ok(()) @@ -218,7 +218,7 @@ pub fn DecodeNumericSegment( ) -> Result<()> { let mut count = count; - result.switch_encoding(CharacterSet::ISO8859_1); + result.switch_encoding(CharacterSet::ISO8859_1, false); result.reserve(count as usize); while (count > 0) { @@ -351,7 +351,7 @@ pub fn DecodeBitStream( } Mode::ECI => { // Count doesn't apply to ECI - result.switch_encoding(ParseECIValue(&mut bits)?.into()); + result.switch_encoding(ParseECIValue(&mut bits)?.into(), true); } Mode::HANZI => { // First handle Hanzi mode which does not start with character count diff --git a/src/qrcode/cpp_port/detector.rs b/src/qrcode/cpp_port/detector.rs index 850aaad..e05eba1 100644 --- a/src/qrcode/cpp_port/detector.rs +++ b/src/qrcode/cpp_port/detector.rs @@ -430,7 +430,7 @@ pub fn LocateAlignmentPattern( // #endif let cor = CenterOfRing( image, - estimate + moduleSize as f32 * 2.25 * d, + (estimate + moduleSize as f32 * 2.25 * d).floor(), moduleSize * 3, 1, false, @@ -441,7 +441,7 @@ pub fn LocateAlignmentPattern( continue; } - if let Some(cor1) = CenterOfRing(image, cor.unwrap(), moduleSize, 1, true) { + if let Some(cor1) = CenterOfRing(image, cor.unwrap().floor(), moduleSize, 1, true) { if let Some(cor2) = CenterOfRing(image, cor.unwrap().floor(), moduleSize * 3, -2, true) { if Point::distance(cor1, cor2) < moduleSize as f32 / 2.0 { diff --git a/src/qrcode/cpp_port/qr_cpp_reader.rs b/src/qrcode/cpp_port/qr_cpp_reader.rs index 1123feb..9976203 100644 --- a/src/qrcode/cpp_port/qr_cpp_reader.rs +++ b/src/qrcode/cpp_port/qr_cpp_reader.rs @@ -207,16 +207,26 @@ impl Reader for QrReader { let decoderResult = Decode(detectorResult.getBits())?; let position = detectorResult.getPoints(); - Ok(RXingResult::new( - &decoderResult.content().to_string(), - decoderResult.content().bytes().to_vec(), - position.to_vec(), + Ok(RXingResult::with_decoder_result( + decoderResult, + position, if detectorResult.getBits().width() < 21 { BarcodeFormat::MICRO_QR_CODE } else { BarcodeFormat::QR_CODE }, )) + + // Ok(RXingResult::new( + // &decoderResult.content().to_string(), + // decoderResult.content().bytes().to_vec(), + // position.to_vec(), + // if detectorResult.getBits().width() < 21 { + // BarcodeFormat::MICRO_QR_CODE + // } else { + // BarcodeFormat::QR_CODE + // }, + // )) // return Result(std::move(decoderResult), std::move(position), // detectorResult.bits().width() < 21 ? BarcodeFormat::MICRO_QR_CODE : BarcodeFormat::QR_CODE); } @@ -342,12 +352,17 @@ impl QrReader { let position = detectorResult.getPoints(); if let Ok(decoderResult) = decoderResult { if (decoderResult.isValid()) { - results.push(RXingResult::new( - &decoderResult.content().to_string(), - decoderResult.content().bytes().to_vec(), - position.to_vec(), + results.push(RXingResult::with_decoder_result( + decoderResult, + position, BarcodeFormat::MICRO_QR_CODE, )); + // results.push(RXingResult::new( + // &decoderResult.content().to_string(), + // decoderResult.content().bytes().to_vec(), + // position.to_vec(), + // BarcodeFormat::MICRO_QR_CODE, + // )); // results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MICRO_QR_CODE); if (maxSymbols != 0 && (results.len() as u32) == maxSymbols) { diff --git a/src/rxing_result_metadata.rs b/src/rxing_result_metadata.rs index 58ac8c9..3ffdbb2 100644 --- a/src/rxing_result_metadata.rs +++ b/src/rxing_result_metadata.rs @@ -120,7 +120,7 @@ impl From for RXingResultMetadataType { "OTHER" => RXingResultMetadataType::OTHER, "ORIENTATION" => RXingResultMetadataType::ORIENTATION, "BYTE_SEGMENTS" | "BYTESEGMENTS" => RXingResultMetadataType::BYTE_SEGMENTS, - "ERROR_CORRECTION_LEVEL" | "ERRORCORRECTIONLEVEL" => { + "ERROR_CORRECTION_LEVEL" | "ERRORCORRECTIONLEVEL" | "ECLEVEL" => { RXingResultMetadataType::ERROR_CORRECTION_LEVEL } "ISSUE_NUMBER" | "ISSUENUMBER" => RXingResultMetadataType::ISSUE_NUMBER, diff --git a/tests/cpp_qr_code_blackbox_tests.rs b/tests/cpp_qr_code_blackbox_tests.rs index 493cf4d..7d27531 100644 --- a/tests/cpp_qr_code_blackbox_tests.rs +++ b/tests/cpp_qr_code_blackbox_tests.rs @@ -160,6 +160,11 @@ fn mqr_black_box_test_case() { /** * @author Sean Owen + * + * 16.png seems to be an odd case where in both c++ and rs the result of a pure read + * is different than the result of a detect. there is an extra ' ' in the output of + * the pure read. I'm not sure how to fix this, as it occurs in both and seems to just + * be a function of the barcode. */ #[test] @@ -186,7 +191,7 @@ fn cpp_qrcode_black_box1_test_case() { fn cpp_qrcode_black_box2_test_case() { let mut tester = common::AbstractBlackBoxTestCase::new( "test_resources/blackbox/cpp/qrcode-2", - // MultiFormatReader::default(), + // MultiUseMultiFormatReader::default(), QrReader::default(), BarcodeFormat::QR_CODE, );