all tests but 7 (SA) and inverted pass

This commit is contained in:
Henry Schimke
2023-04-28 13:25:49 -05:00
parent 6aee7a66b9
commit 4d703c4e51
8 changed files with 72 additions and 42 deletions

View File

@@ -5,7 +5,7 @@ use crate::{
}, },
BitMatrix, Quadrilateral, BitMatrix, Quadrilateral,
}, },
point, Point, Exceptions, point, Exceptions, Point,
}; };
use crate::common::Result; use crate::common::Result;
@@ -402,19 +402,19 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
points.iter().position(|p| *p == corners[3])?, points.iter().position(|p| *p == corners[3])?,
]; ];
let try_get_range = |a:usize, b:usize| -> Option<&[Point]> { let try_get_range = |a: usize, b: usize| -> Option<&[Point]> {
if a > b { if a > b {
None None
}else{ } else {
Some(&points[a + 1..b]) Some(&points[a + 1..b])
} }
}; };
let lines = [ let lines = [
RegressionLine::with_point_slice(try_get_range(corner_positions[0],corner_positions[1])?), 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[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[2], corner_positions[3])?),
RegressionLine::with_point_slice(try_get_range(corner_positions[3],points.len())?), RegressionLine::with_point_slice(try_get_range(corner_positions[3], points.len())?),
]; ];
// let lines = [ // let lines = [

View File

@@ -42,6 +42,7 @@ pub struct ECIStringBuilder {
bytes: Vec<u8>, bytes: Vec<u8>,
eci_positions: Vec<(Eci, usize, usize)>, // (Eci, start, end) eci_positions: Vec<(Eci, usize, usize)>, // (Eci, start, end)
pub symbology: SymbologyIdentifier, pub symbology: SymbologyIdentifier,
eci_list: HashSet<Eci>,
} }
impl ECIStringBuilder { impl ECIStringBuilder {
@@ -52,6 +53,7 @@ impl ECIStringBuilder {
eci_positions: Vec::default(), eci_positions: Vec::default(),
has_eci: false, has_eci: false,
symbology: SymbologyIdentifier::default(), symbology: SymbologyIdentifier::default(),
eci_list: HashSet::default(),
} }
} }
@@ -126,27 +128,33 @@ impl ECIStringBuilder {
self.eci_positions.push((eci, self.bytes.len(), 0)); 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; self.has_eci = false;
} }
} }
} }
/// Change the current encoding characterset, finding an eci to do so /// 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)) //self.append_eci(Eci::from(charset))
if false && !self.has_eci { if is_eci && !self.has_eci {
self.eci_positions.clear(); self.eci_positions.clear();
} }
if false || !self.has_eci if is_eci || !self.has_eci
//{self.eci_positions.push_back({eci, Size(bytes)});} //{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. /// Finishes encoding anything in the buffer using the current ECI and resets.
@@ -270,13 +278,13 @@ impl ECIStringBuilder {
self self
} }
pub fn list_ecis(&self) -> HashSet<Eci> { // pub fn list_ecis(&self) -> HashSet<Eci> {
let mut hs = HashSet::new(); // let mut hs = HashSet::new();
self.eci_positions.iter().for_each(|pos| { // self.eci_positions.iter().for_each(|pos| {
hs.insert(pos.0); // hs.insert(pos.0);
}); // });
hs // hs
} // }
} }
impl fmt::Display for ECIStringBuilder { impl fmt::Display for ECIStringBuilder {

View File

@@ -180,7 +180,7 @@ impl MultiUseMultiFormatReader {
let a = self.qr_code_reader.decode_with_hints(image, &self.hints); let a = self.qr_code_reader.decode_with_hints(image, &self.hints);
if a.is_ok() { if a.is_ok() {
a a
}else { } else {
self.cpp_qrcode_reader.decode_with_hints(image, &self.hints) self.cpp_qrcode_reader.decode_with_hints(image, &self.hints)
} }
} }
@@ -214,10 +214,12 @@ impl MultiUseMultiFormatReader {
return Ok(res); return Ok(res);
} }
} }
if let Ok(res) = self.qr_code_reader.decode_with_hints(image, &self.hints) { if let Ok(res) = self.qr_code_reader.decode_with_hints(image, &self.hints) {
return Ok(res); 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 if let Ok(res) = self
.data_matrix_reader .data_matrix_reader
.decode_with_hints(image, &self.hints) .decode_with_hints(image, &self.hints)

View File

@@ -70,7 +70,7 @@ pub fn DecodeHanziSegment(
// Each character will require 2 bytes, decode as GB2312 // Each character will require 2 bytes, decode as GB2312
// There is no ECI value for GB2312, use GB18030 which is a superset // 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); result.reserve(2 * count as usize);
while (count > 0) { while (count > 0) {
@@ -99,7 +99,7 @@ pub fn DecodeKanjiSegment(
let mut count = count; let mut count = count;
// Each character will require 2 bytes. Read the characters as 2-byte pairs // Each character will require 2 bytes. Read the characters as 2-byte pairs
// and decode as Shift_JIS afterwards // 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); result.reserve(2 * count as usize);
while (count > 0) { while (count > 0) {
@@ -125,7 +125,7 @@ pub fn DecodeByteSegment(
count: u32, count: u32,
result: &mut ECIStringBuilder, result: &mut ECIStringBuilder,
) -> Result<()> { ) -> Result<()> {
result.switch_encoding(CharacterSet::Unknown); result.switch_encoding(CharacterSet::Unknown, false);
result.reserve(count as usize); result.reserve(count as usize);
for _i in 0..count { 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; *result += buffer;
Ok(()) Ok(())
@@ -218,7 +218,7 @@ pub fn DecodeNumericSegment(
) -> Result<()> { ) -> Result<()> {
let mut count = count; let mut count = count;
result.switch_encoding(CharacterSet::ISO8859_1); result.switch_encoding(CharacterSet::ISO8859_1, false);
result.reserve(count as usize); result.reserve(count as usize);
while (count > 0) { while (count > 0) {
@@ -351,7 +351,7 @@ pub fn DecodeBitStream(
} }
Mode::ECI => { Mode::ECI => {
// Count doesn't apply to ECI // Count doesn't apply to ECI
result.switch_encoding(ParseECIValue(&mut bits)?.into()); result.switch_encoding(ParseECIValue(&mut bits)?.into(), true);
} }
Mode::HANZI => { Mode::HANZI => {
// First handle Hanzi mode which does not start with character count // First handle Hanzi mode which does not start with character count

View File

@@ -430,7 +430,7 @@ pub fn LocateAlignmentPattern(
// #endif // #endif
let cor = CenterOfRing( let cor = CenterOfRing(
image, image,
estimate + moduleSize as f32 * 2.25 * d, (estimate + moduleSize as f32 * 2.25 * d).floor(),
moduleSize * 3, moduleSize * 3,
1, 1,
false, false,
@@ -441,7 +441,7 @@ pub fn LocateAlignmentPattern(
continue; 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 let Some(cor2) = CenterOfRing(image, cor.unwrap().floor(), moduleSize * 3, -2, true)
{ {
if Point::distance(cor1, cor2) < moduleSize as f32 / 2.0 { if Point::distance(cor1, cor2) < moduleSize as f32 / 2.0 {

View File

@@ -207,16 +207,26 @@ impl Reader for QrReader {
let decoderResult = Decode(detectorResult.getBits())?; let decoderResult = Decode(detectorResult.getBits())?;
let position = detectorResult.getPoints(); let position = detectorResult.getPoints();
Ok(RXingResult::new( Ok(RXingResult::with_decoder_result(
&decoderResult.content().to_string(), decoderResult,
decoderResult.content().bytes().to_vec(), position,
position.to_vec(),
if detectorResult.getBits().width() < 21 { if detectorResult.getBits().width() < 21 {
BarcodeFormat::MICRO_QR_CODE BarcodeFormat::MICRO_QR_CODE
} else { } else {
BarcodeFormat::QR_CODE 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), // return Result(std::move(decoderResult), std::move(position),
// detectorResult.bits().width() < 21 ? BarcodeFormat::MICRO_QR_CODE : BarcodeFormat::QR_CODE); // detectorResult.bits().width() < 21 ? BarcodeFormat::MICRO_QR_CODE : BarcodeFormat::QR_CODE);
} }
@@ -342,12 +352,17 @@ impl QrReader {
let position = detectorResult.getPoints(); let position = detectorResult.getPoints();
if let Ok(decoderResult) = decoderResult { if let Ok(decoderResult) = decoderResult {
if (decoderResult.isValid()) { if (decoderResult.isValid()) {
results.push(RXingResult::new( results.push(RXingResult::with_decoder_result(
&decoderResult.content().to_string(), decoderResult,
decoderResult.content().bytes().to_vec(), position,
position.to_vec(),
BarcodeFormat::MICRO_QR_CODE, 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); // results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MICRO_QR_CODE);
if (maxSymbols != 0 && (results.len() as u32) == maxSymbols) { if (maxSymbols != 0 && (results.len() as u32) == maxSymbols) {

View File

@@ -120,7 +120,7 @@ impl From<String> for RXingResultMetadataType {
"OTHER" => RXingResultMetadataType::OTHER, "OTHER" => RXingResultMetadataType::OTHER,
"ORIENTATION" => RXingResultMetadataType::ORIENTATION, "ORIENTATION" => RXingResultMetadataType::ORIENTATION,
"BYTE_SEGMENTS" | "BYTESEGMENTS" => RXingResultMetadataType::BYTE_SEGMENTS, "BYTE_SEGMENTS" | "BYTESEGMENTS" => RXingResultMetadataType::BYTE_SEGMENTS,
"ERROR_CORRECTION_LEVEL" | "ERRORCORRECTIONLEVEL" => { "ERROR_CORRECTION_LEVEL" | "ERRORCORRECTIONLEVEL" | "ECLEVEL" => {
RXingResultMetadataType::ERROR_CORRECTION_LEVEL RXingResultMetadataType::ERROR_CORRECTION_LEVEL
} }
"ISSUE_NUMBER" | "ISSUENUMBER" => RXingResultMetadataType::ISSUE_NUMBER, "ISSUE_NUMBER" | "ISSUENUMBER" => RXingResultMetadataType::ISSUE_NUMBER,

View File

@@ -160,6 +160,11 @@ fn mqr_black_box_test_case() {
/** /**
* @author Sean Owen * @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] #[test]
@@ -186,7 +191,7 @@ fn cpp_qrcode_black_box1_test_case() {
fn cpp_qrcode_black_box2_test_case() { fn cpp_qrcode_black_box2_test_case() {
let mut tester = common::AbstractBlackBoxTestCase::new( let mut tester = common::AbstractBlackBoxTestCase::new(
"test_resources/blackbox/cpp/qrcode-2", "test_resources/blackbox/cpp/qrcode-2",
// MultiFormatReader::default(), // MultiUseMultiFormatReader::default(),
QrReader::default(), QrReader::default(),
BarcodeFormat::QR_CODE, BarcodeFormat::QR_CODE,
); );