From d08f67feed056d4e7f5cdbc22cab092145c1d437 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Mon, 24 Apr 2023 17:42:40 -0500 Subject: [PATCH] partial test complete --- src/common/bit_source.rs | 4 +- .../cpp_essentials/concentric_finder.rs | 91 +++++++++++++++---- .../fast_edge_to_edge_counter.rs | 4 +- src/common/cpp_essentials/matrix.rs | 22 +++-- src/common/cpp_essentials/regression_line.rs | 5 + src/qrcode/cpp_port/decoder.rs | 25 ++--- src/qrcode/cpp_port/detector.rs | 4 +- src/rxing_result_point.rs | 7 ++ 8 files changed, 115 insertions(+), 47 deletions(-) diff --git a/src/common/bit_source.rs b/src/common/bit_source.rs index 22233df..cfb4174 100644 --- a/src/common/bit_source.rs +++ b/src/common/bit_source.rs @@ -147,7 +147,7 @@ impl BitSource { // Next read whole bytes if num_bits > 0 { while num_bits >= 8 { - result = (result << 8) | self.bytes[self.byte_offset] as u32; + result = (result << 8) | self.bytes[byte_offset] as u32; // result = ((result as u16) << 8) as u8 | (self.bytes[self.byte_offset]); byte_offset += 1; num_bits -= 8; @@ -158,7 +158,7 @@ impl BitSource { let bits_to_not_read = 8 - num_bits; let mask = (0xFF >> bits_to_not_read) << bits_to_not_read; result = (result << num_bits) - | ((self.bytes[self.byte_offset] & mask) as u32 >> bits_to_not_read); + | ((self.bytes[byte_offset] & mask) as u32 >> bits_to_not_read); bit_offset += num_bits; } } diff --git a/src/common/cpp_essentials/concentric_finder.rs b/src/common/cpp_essentials/concentric_finder.rs index 1fe34b6..0df0c69 100644 --- a/src/common/cpp_essentials/concentric_finder.rs +++ b/src/common/cpp_essentials/concentric_finder.rs @@ -305,7 +305,7 @@ pub fn CollectRingPoints( edgeIndex: i32, backup: bool, ) -> Vec { - let centerI = center.round(); + let centerI = center.floor(); let radius = range; let mut cur = EdgeTracer::new(image, centerI, point(0.0, 1.0)); if cur.stepToEdge(Some(edgeIndex), Some(radius), Some(backup)) == 0 { @@ -362,17 +362,20 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option Option Option Option Option) -> Option { +// let dist2center = |a, b| Point::distance(a, center) < Point::distance(b, center); + +// // Rotate points such that the first one is the furthest away from the center (hence, a corner) +// let mut points = points; +// points.rotate_left(points.iter().position(|p| dist2center(p, center)).unwrap()); + +// let mut corners = [&points[0]; 4]; +// corners[0] = &points[0]; + +// // Find the opposite corner by looking for the farthest point near the opposite point +// let opposite_corner = points.iter().take(points.len() / 2).max_by(|p| dist2center(p, corners[0])); +// corners[2] = opposite_corner; + +// // Find the two in between corners by looking for the points farthest from the long diagonal +// let dist2diagonal = |l: &RegressionLine, a| l.distance(a); +// corners[1] = points.iter().take(points.len() / 2).max_by(|p| dist2diagonal(&RegressionLine(*corners[0], *corners[2]), *p)); +// corners[3] = points.iter().skip(points.len() / 2).max_by(|p| dist2diagonal(&RegressionLine(*corners[0], *corners[2]), *p)); + +// let lines = [ +// RegressionLine::new(corners[0], corners[1]), +// RegressionLine::new(corners[1], corners[2]), +// RegressionLine::new(corners[2], corners[3]), +// RegressionLine::new(corners[3], corners[0]), +// ]; + +// if lines.iter().any(|l| !l.is_valid()) { +// return None; +// } + +// let mut res = QuadrilateralF::new(); +// for i in 0..4 { +// res[i] = intersect(lines[i], lines[(i + 1) % 4]); +// } + +// Some(res) +// } + pub fn QuadrilateralIsPlausibleSquare(q: &Quadrilateral, lineIndex: usize) -> bool { let mut m; diff --git a/src/common/cpp_essentials/fast_edge_to_edge_counter.rs b/src/common/cpp_essentials/fast_edge_to_edge_counter.rs index 3ac072f..dba41a6 100644 --- a/src/common/cpp_essentials/fast_edge_to_edge_counter.rs +++ b/src/common/cpp_essentials/fast_edge_to_edge_counter.rs @@ -56,7 +56,7 @@ impl<'a> FastEdgeToEdgeCounter<'a> { steps += 1; if steps > maxSteps { if maxSteps == self.stepsToBorder { - break false; + break; } else { return 0; } @@ -67,7 +67,7 @@ impl<'a> FastEdgeToEdgeCounter<'a> { // if !(self.under_arry[idx_pt] // == self.under_arry[self.p as usize]) if !(self.under_arry.get_index(idx_pt) == self.under_arry.get_index(self.p as usize)) { - break true; + break; } } // while (p[steps * stride] == p[0]); diff --git a/src/common/cpp_essentials/matrix.rs b/src/common/cpp_essentials/matrix.rs index d517b42..a1c1cfe 100644 --- a/src/common/cpp_essentials/matrix.rs +++ b/src/common/cpp_essentials/matrix.rs @@ -5,12 +5,12 @@ use crate::{Exceptions, Point}; pub struct Matrix { width: usize, height: usize, - data: Vec, + data: Vec>, } impl Matrix { - pub fn with_data(width: usize, height: usize, data: Vec) -> Result> { - if (width != 0 && data.len() / width as usize != height as usize) { + pub fn with_data(width: usize, height: usize, data: Vec>) -> Result> { + if width != 0 && data.len() / width as usize != height as usize { return Err(Exceptions::illegal_argument_with( "invalid size: width * height is too big", )); @@ -31,7 +31,7 @@ impl Matrix { Ok(Self { width, height, - data: vec![T::default(); width * height], + data: vec![None; width * height], }) } @@ -66,13 +66,15 @@ impl Matrix { pub fn get(&self, x: usize, y: usize) -> Option { if x >= self.width || y >= self.height { None - } else { - Some(self.data[Self::get_offset(x, y, self.width)]) + } else if let Some(Some(d)) = self.data.get(Self::get_offset(x, y, self.width)){ + Some(*d) + }else { + None } } pub fn set(&mut self, x: usize, y: usize, value: T) -> T { - self.data[Self::get_offset(x, y, self.width)] = value; + self.data[Self::get_offset(x, y, self.width)] = Some(value); self.get(x, y).unwrap() } @@ -84,7 +86,7 @@ impl Matrix { self.set(p.x as usize, p.y as usize, value) } - pub fn data(&self) -> &[T] { + pub fn data(&self) -> &[Option] { &self.data } @@ -97,10 +99,10 @@ impl Matrix { // } pub fn clear_with(&mut self, value: T) { - self.data.fill(value) + self.data.fill(Some(value)) } pub fn clear(&mut self) { - self.data.fill(T::default()) + self.data.fill(None) } } diff --git a/src/common/cpp_essentials/regression_line.rs b/src/common/cpp_essentials/regression_line.rs index 8847389..6e28d10 100644 --- a/src/common/cpp_essentials/regression_line.rs +++ b/src/common/cpp_essentials/regression_line.rs @@ -228,4 +228,9 @@ impl RegressionLine { new_rl.evaluate(&[point1, point2]); new_rl } + pub fn with_point_slice(points: &[Point]) -> Self { + let mut new_rl = RegressionLine::default(); + new_rl.evaluate(points); + new_rl + } } diff --git a/src/qrcode/cpp_port/decoder.rs b/src/qrcode/cpp_port/decoder.rs index 443e0ad..042a356 100644 --- a/src/qrcode/cpp_port/decoder.rs +++ b/src/qrcode/cpp_port/decoder.rs @@ -35,11 +35,14 @@ pub fn CorrectErrors(codewordBytes: &mut [u8], numDataCodewords: u32) -> Result< let rs = ReedSolomonDecoder::new(get_predefined_genericgf( PredefinedGenericGF::QrCodeField256, )); - if rs.decode(&mut codewordsInts, numECCodewords)? != 0 - // if (!ReedSolomonDecode(GenericGF::QRCodeField256(), codewordsInts, numECCodewords)) - { - return Ok(false); - } + + rs.decode(&mut codewordsInts, numECCodewords)?; + + // if rs.decode(&mut codewordsInts, numECCodewords)? != 0 + // // if (!ReedSolomonDecode(GenericGF::QRCodeField256(), codewordsInts, numECCodewords)) + // { + // return Ok(false); + // } // Copy back into array of bytes -- only need to worry about the bytes that were data // We don't care about errors in the error-correction codewords @@ -298,9 +301,9 @@ pub fn DecodeBitStream( let modeBitLength = Mode::get_codec_mode_bits_length(version); let res = (|| { - while (!IsEndOfStream(&mut bits, version)?) { + while !IsEndOfStream(&mut bits, version)? { let mode: Mode; - if (modeBitLength == 0) { + if modeBitLength == 0 { mode = Mode::NUMERIC; // MicroQRCode version 1 is always NUMERIC and modeBitLength is 0 } else { mode = Mode::CodecModeForBits( @@ -309,7 +312,7 @@ pub fn DecodeBitStream( )?; } - match (mode) { + match mode { Mode::FNC1_FIRST_POSITION => { // if (!result.empty()) // uncomment to enforce specification // throw FormatError("GS1 Indicator (FNC1 in first position) at illegal position"); @@ -317,14 +320,14 @@ pub fn DecodeBitStream( result.symbology.aiFlag = AIFlag::GS1; // In Alphanumeric mode undouble doubled '%' and treat single '%' as } Mode::FNC1_SECOND_POSITION => { - if (!result.is_empty()) { + if !result.is_empty() { return Err(Exceptions::format_with("AIM Application Indicator (FNC1 in second position) at illegal position")); // throw FormatError("AIM Application Indicator (FNC1 in second position) at illegal position"); } result.symbology.modifier = b'5'; // As above // ISO/IEC 18004:2015 7.4.8.3 AIM Application Indicator (FNC1 in second position), "00-99" or "A-Za-z" let appInd = bits.readBits(8)?; - if (appInd < 100) + if appInd < 100 // "00-09" { result += @@ -367,7 +370,7 @@ pub fn DecodeBitStream( // "Normal" QR code modes: // How many characters will follow, encoded in this mode? let count = bits.readBits(mode.CharacterCountBits(version) as usize)?; - match (mode) { + match mode { Mode::NUMERIC => DecodeNumericSegment(&mut bits, count, &mut result)?, Mode::ALPHANUMERIC => { DecodeAlphanumericSegment(&mut bits, count, &mut result)? diff --git a/src/qrcode/cpp_port/detector.rs b/src/qrcode/cpp_port/detector.rs index 6fcfea1..c5ffb52 100644 --- a/src/qrcode/cpp_port/detector.rs +++ b/src/qrcode/cpp_port/detector.rs @@ -714,8 +714,8 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result Self { + Self { + x: self.x.floor(), + y: self.y.floor() + } + } } impl From<&(f32, f32)> for Point {