diff --git a/src/aztec/DecoderTest.rs b/src/aztec/DecoderTest.rs index c7deae2..0a68af8 100644 --- a/src/aztec/DecoderTest.rs +++ b/src/aztec/DecoderTest.rs @@ -18,7 +18,7 @@ // import com.google.zxing.aztec.encoder.EncoderTest; // import com.google.zxing.FormatException; -// import com.google.zxing.RXingResultPoint; +// import com.google.zxing.Point; // import com.google.zxing.aztec.AztecDetectorRXingResult; // import com.google.zxing.common.BitArray; // import com.google.zxing.common.BitMatrix; @@ -29,7 +29,7 @@ use crate::{ aztec::shared_test_methods::{stripSpace, toBitArray, toBooleanArray}, common::BitMatrix, - RXingResultPoint, + Point, }; use super::{aztec_detector_result::AztecDetectorRXingResult, decoder}; @@ -38,7 +38,7 @@ use super::{aztec_detector_result::AztecDetectorRXingResult, decoder}; * Tests {@link Decoder}. */ -const NO_POINTS: [RXingResultPoint; 4] = [RXingResultPoint { x: 0.0, y: 0.0 }; 4]; +const NO_POINTS: [Point; 4] = [Point { x: 0.0, y: 0.0 }; 4]; #[test] fn test_high_level_decode() { diff --git a/src/aztec/DetectorTest.rs b/src/aztec/DetectorTest.rs index 5c9cc50..0c054d8 100644 --- a/src/aztec/DetectorTest.rs +++ b/src/aztec/DetectorTest.rs @@ -39,7 +39,7 @@ use rand::Rng; use crate::{aztec::decoder, common::BitMatrix, exceptions::Exceptions}; use super::{ - detector::{self, Detector, Point}, + detector::{self, AztecPoint, Detector}, encoder::{self, AztecCode}, }; @@ -261,7 +261,7 @@ fn clone(input: &BitMatrix) -> BitMatrix { result } -fn get_orientation_points(code: &AztecCode) -> Vec { +fn get_orientation_points(code: &AztecCode) -> Vec { let center = code.getMatrix().getWidth() as i32 / 2; let offset = if code.isCompact() { 5 } else { 7 }; let mut result = Vec::new(); @@ -271,12 +271,15 @@ fn get_orientation_points(code: &AztecCode) -> Vec { let mut ySign: i32 = -1; while ySign <= 1 { // for (int ySign = -1; ySign <= 1; ySign += 2) { - result.push(Point::new(center + xSign * offset, center + ySign * offset)); - result.push(Point::new( + result.push(AztecPoint::new( + center + xSign * offset, + center + ySign * offset, + )); + result.push(AztecPoint::new( center + xSign * (offset - 1), center + ySign * offset, )); - result.push(Point::new( + result.push(AztecPoint::new( center + xSign * offset, center + ySign * (offset - 1), )); diff --git a/src/aztec/EncoderTest.rs b/src/aztec/EncoderTest.rs index af45797..bf7be82 100644 --- a/src/aztec/EncoderTest.rs +++ b/src/aztec/EncoderTest.rs @@ -25,7 +25,7 @@ use crate::{ encoder::HighLevelEncoder, shared_test_methods::{stripSpace, toBitArray, toBooleanArray}, }, - BarcodeFormat, EncodeHintType, EncodeHintValue, RXingResultPoint, + BarcodeFormat, EncodeHintType, EncodeHintValue, Point, }; use super::{encoder::aztec_encoder, AztecWriter}; @@ -50,7 +50,7 @@ const WINDOWS_1252: EncodingRef = encoding::all::WINDOWS_1252; //Charset.forName // const DOTX: &str = "[^.X]"; // const SPACES: &str = "\\s+"; -const NO_POINTS: [RXingResultPoint; 4] = [RXingResultPoint { x: 0.0, y: 0.0 }; 4]; +const NO_POINTS: [Point; 4] = [Point { x: 0.0, y: 0.0 }; 4]; // real life tests diff --git a/src/aztec/aztec_detector_result.rs b/src/aztec/aztec_detector_result.rs index 8579347..7a7ab6c 100644 --- a/src/aztec/aztec_detector_result.rs +++ b/src/aztec/aztec_detector_result.rs @@ -16,13 +16,13 @@ // package com.google.zxing.aztec; -// import com.google.zxing.RXingResultPoint; +// import com.google.zxing.Point; // import com.google.zxing.common.BitMatrix; // import com.google.zxing.common.DetectorRXingResult; use crate::{ common::{BitMatrix, DetectorRXingResult}, - RXingResultPoint, + Point, }; /** @@ -33,7 +33,7 @@ use crate::{ */ pub struct AztecDetectorRXingResult { bits: BitMatrix, - points: [RXingResultPoint; 4], + points: [Point; 4], compact: bool, nbDatablocks: u32, nbLayers: u32, @@ -44,7 +44,7 @@ impl DetectorRXingResult for AztecDetectorRXingResult { &self.bits } - fn getPoints(&self) -> &[RXingResultPoint] { + fn getPoints(&self) -> &[Point] { &self.points } } @@ -52,7 +52,7 @@ impl DetectorRXingResult for AztecDetectorRXingResult { impl AztecDetectorRXingResult { pub fn new( bits: BitMatrix, - points: [RXingResultPoint; 4], + points: [Point; 4], compact: bool, nbDatablocks: u32, nbLayers: u32, diff --git a/src/aztec/aztec_reader.rs b/src/aztec/aztec_reader.rs index 2633301..76e392c 100644 --- a/src/aztec/aztec_reader.rs +++ b/src/aztec/aztec_reader.rs @@ -92,7 +92,7 @@ impl Reader for AztecReader { { // if let DecodeHintValue::NeedResultPointCallback(cb) = rpcb { for point in points { - cb(point); + cb(*point); } // } } diff --git a/src/aztec/detector.rs b/src/aztec/detector.rs index da66e37..4cbae88 100644 --- a/src/aztec/detector.rs +++ b/src/aztec/detector.rs @@ -18,12 +18,12 @@ use std::fmt; use crate::{ common::{ - detector::{MathUtils, WhiteRectangleDetector}, + detector::WhiteRectangleDetector, reedsolomon::{self, ReedSolomonDecoder}, BitMatrix, DefaultGridSampler, GridSampler, Result, }, exceptions::Exceptions, - RXingResultPoint, ResultPoint, + point, Point, }; use super::aztec_detector_result::AztecDetectorRXingResult; @@ -94,10 +94,10 @@ impl<'a> Detector<'_> { // 4. Sample the grid let bits = self.sample_grid( self.image, - &bulls_eye_corners[self.shift as usize % 4], - &bulls_eye_corners[(self.shift as usize + 1) % 4], - &bulls_eye_corners[(self.shift as usize + 2) % 4], - &bulls_eye_corners[(self.shift as usize + 3) % 4], + bulls_eye_corners[self.shift as usize % 4], + bulls_eye_corners[(self.shift as usize + 1) % 4], + bulls_eye_corners[(self.shift as usize + 2) % 4], + bulls_eye_corners[(self.shift as usize + 3) % 4], )?; // 5. Get the corners of the matrix. @@ -118,21 +118,21 @@ impl<'a> Detector<'_> { * @param bullsEyeCorners the array of bull's eye corners * @throws NotFoundException in case of too many errors or invalid parameters */ - fn extractParameters(&mut self, bulls_eye_corners: &[RXingResultPoint]) -> Result<()> { - if !self.is_valid(&bulls_eye_corners[0]) - || !self.is_valid(&bulls_eye_corners[1]) - || !self.is_valid(&bulls_eye_corners[2]) - || !self.is_valid(&bulls_eye_corners[3]) + fn extractParameters(&mut self, bulls_eye_corners: &[Point]) -> Result<()> { + if !self.is_valid(bulls_eye_corners[0]) + || !self.is_valid(bulls_eye_corners[1]) + || !self.is_valid(bulls_eye_corners[2]) + || !self.is_valid(bulls_eye_corners[3]) { return Err(Exceptions::notFoundWith("no valid points")); } let length = 2 * self.nb_center_layers; // Get the bits around the bull's eye let sides = [ - self.sample_line(&bulls_eye_corners[0], &bulls_eye_corners[1], length), // Right side - self.sample_line(&bulls_eye_corners[1], &bulls_eye_corners[2], length), // Bottom - self.sample_line(&bulls_eye_corners[2], &bulls_eye_corners[3], length), // Left side - self.sample_line(&bulls_eye_corners[3], &bulls_eye_corners[0], length), // Top + self.sample_line(bulls_eye_corners[0], bulls_eye_corners[1], length), // Right side + self.sample_line(bulls_eye_corners[1], bulls_eye_corners[2], length), // Bottom + self.sample_line(bulls_eye_corners[2], bulls_eye_corners[3], length), // Left side + self.sample_line(bulls_eye_corners[3], bulls_eye_corners[0], length), // Top ]; // bullsEyeCorners[shift] is the corner of the bulls'eye that has three @@ -262,7 +262,7 @@ impl<'a> Detector<'_> { * @return The corners of the bull-eye * @throws NotFoundException If no valid bull-eye can be found */ - fn get_bulls_eye_corners(&mut self, pCenter: Point) -> Result<[RXingResultPoint; 4]> { + fn get_bulls_eye_corners(&mut self, pCenter: AztecPoint) -> Result<[Point; 4]> { let mut pina = pCenter; let mut pinb = pCenter; let mut pinc = pCenter; @@ -285,8 +285,8 @@ impl<'a> Detector<'_> { //c b if self.nb_center_layers > 2 { - let q: f32 = Self::distance_points(&poutd, &pouta) * self.nb_center_layers as f32 - / (Self::distance_points(&pind, &pina) * (self.nb_center_layers + 2) as f32); + let q: f32 = Self::distance_points(poutd, pouta) * self.nb_center_layers as f32 + / (Self::distance_points(pind, pina) * (self.nb_center_layers + 2) as f32); // let q: f32 = Self::distance( // &poutd.to_rxing_result_point(), @@ -321,14 +321,10 @@ impl<'a> Detector<'_> { // Expand the square by .5 pixel in each direction so that we're on the border // between the white square and the black square - let pinax = - RXingResultPoint::new(pina.get_x() as f32 + 0.5f32, pina.get_y() as f32 - 0.5f32); - let pinbx = - RXingResultPoint::new(pinb.get_x() as f32 + 0.5f32, pinb.get_y() as f32 + 0.5f32); - let pincx = - RXingResultPoint::new(pinc.get_x() as f32 - 0.5f32, pinc.get_y() as f32 + 0.5f32); - let pindx = - RXingResultPoint::new(pind.get_x() as f32 - 0.5f32, pind.get_y() as f32 - 0.5f32); + let pinax = point(pina.get_x() as f32 + 0.5f32, pina.get_y() as f32 - 0.5f32); + let pinbx = point(pinb.get_x() as f32 + 0.5f32, pinb.get_y() as f32 + 0.5f32); + let pincx = point(pinc.get_x() as f32 - 0.5f32, pinc.get_y() as f32 + 0.5f32); + let pindx = point(pind.get_x() as f32 - 0.5f32, pind.get_y() as f32 - 0.5f32); // Expand the square so that its corners are the centers of the points // just outside the bull's eye. @@ -344,11 +340,11 @@ impl<'a> Detector<'_> { * * @return the center point */ - fn get_matrix_center(&self) -> Point { - let mut point_a = RXingResultPoint::default(); // { x: 0.0, y: 0.0 }; - let mut point_b = RXingResultPoint::default(); // { x: 0.0, y: 0.0 }; - let mut point_c = RXingResultPoint::default(); // { x: 0.0, y: 0.0 }; - let mut point_d = RXingResultPoint::default(); // { x: 0.0, y: 0.0 }; + fn get_matrix_center(&self) -> AztecPoint { + let mut point_a = Point::default(); + let mut point_b = Point::default(); + let mut point_c = Point::default(); + let mut point_d = Point::default(); let mut fnd = false; @@ -369,16 +365,16 @@ impl<'a> Detector<'_> { let cx: i32 = (self.image.getWidth() / 2) as i32; let cy: i32 = (self.image.getHeight() / 2) as i32; point_a = self - .get_first_different(&Point::new(cx + 7, cy - 7), false, 1, -1) + .get_first_different(&AztecPoint::new(cx + 7, cy - 7), false, 1, -1) .into(); point_b = self - .get_first_different(&Point::new(cx + 7, cy + 7), false, 1, 1) + .get_first_different(&AztecPoint::new(cx + 7, cy + 7), false, 1, 1) .into(); point_c = self - .get_first_different(&Point::new(cx - 7, cy + 7), false, -1, 1) + .get_first_different(&AztecPoint::new(cx - 7, cy + 7), false, -1, 1) .into(); point_d = self - .get_first_different(&Point::new(cx - 7, cy - 7), false, -1, -1) + .get_first_different(&AztecPoint::new(cx - 7, cy - 7), false, -1, -1) .into(); } // try { @@ -395,20 +391,16 @@ impl<'a> Detector<'_> { // // In that case, surely in the bull's eye, we try to expand the rectangle. // int cx = image.getWidth() / 2; // int cy = image.getHeight() / 2; - // pointA = getFirstDifferent(new Point(cx + 7, cy - 7), false, 1, -1).toRXingResultPoint(); - // pointB = getFirstDifferent(new Point(cx + 7, cy + 7), false, 1, 1).toRXingResultPoint(); - // pointC = getFirstDifferent(new Point(cx - 7, cy + 7), false, -1, 1).toRXingResultPoint(); - // pointD = getFirstDifferent(new Point(cx - 7, cy - 7), false, -1, -1).toRXingResultPoint(); + // pointA = getFirstDifferent(new Point(cx + 7, cy - 7), false, 1, -1).toPoint(); + // pointB = getFirstDifferent(new Point(cx + 7, cy + 7), false, 1, 1).toPoint(); + // pointC = getFirstDifferent(new Point(cx - 7, cy + 7), false, -1, 1).toPoint(); + // pointD = getFirstDifferent(new Point(cx - 7, cy - 7), false, -1, -1).toPoint(); // } //Compute the center of the rectangle - let mut cx = MathUtils::round( - (point_a.getX() + point_d.getX() + point_b.getX() + point_c.getX()) / 4.0f32, - ); - let mut cy = MathUtils::round( - (point_a.getY() + point_d.getY() + point_b.getY() + point_c.getY()) / 4.0f32, - ); + let mut cx = ((point_a.x + point_d.x + point_b.x + point_c.x) / 4.0).round() as i32; + let mut cy = ((point_a.y + point_d.y + point_b.y + point_c.y) / 4.0).round() as i32; // Redetermine the white rectangle starting from previously computed center. // This will ensure that we end up with a white rectangle in center bull's eye @@ -427,20 +419,20 @@ impl<'a> Detector<'_> { // In that case we try to expand the rectangle. if !fnd { point_a = self - .get_first_different(&Point::new(cx + 7, cy - 7), false, 1, -1) + .get_first_different(&AztecPoint::new(cx + 7, cy - 7), false, 1, -1) .into(); point_b = self - .get_first_different(&Point::new(cx + 7, cy + 7), false, 1, 1) + .get_first_different(&AztecPoint::new(cx + 7, cy + 7), false, 1, 1) .into(); point_c = self - .get_first_different(&Point::new(cx - 7, cy + 7), false, -1, 1) + .get_first_different(&AztecPoint::new(cx - 7, cy + 7), false, -1, 1) .into(); point_d = self - .get_first_different(&Point::new(cx - 7, cy - 7), false, -1, -1) + .get_first_different(&AztecPoint::new(cx - 7, cy - 7), false, -1, -1) .into(); } // try { - // RXingResultPoint[] cornerPoints = new WhiteRectangleDetector(image, 15, cx, cy).detect(); + // Point[] cornerPoints = new WhiteRectangleDetector(image, 15, cx, cy).detect(); // pointA = cornerPoints[0]; // pointB = cornerPoints[1]; // pointC = cornerPoints[2]; @@ -448,21 +440,17 @@ impl<'a> Detector<'_> { // } catch (NotFoundException e) { // // This exception can be in case the initial rectangle is white // // In that case we try to expand the rectangle. - // pointA = getFirstDifferent(new Point(cx + 7, cy - 7), false, 1, -1).toRXingResultPoint(); - // pointB = getFirstDifferent(new Point(cx + 7, cy + 7), false, 1, 1).toRXingResultPoint(); - // pointC = getFirstDifferent(new Point(cx - 7, cy + 7), false, -1, 1).toRXingResultPoint(); - // pointD = getFirstDifferent(new Point(cx - 7, cy - 7), false, -1, -1).toRXingResultPoint(); + // pointA = getFirstDifferent(new Point(cx + 7, cy - 7), false, 1, -1).toPoint(); + // pointB = getFirstDifferent(new Point(cx + 7, cy + 7), false, 1, 1).toPoint(); + // pointC = getFirstDifferent(new Point(cx - 7, cy + 7), false, -1, 1).toPoint(); + // pointD = getFirstDifferent(new Point(cx - 7, cy - 7), false, -1, -1).toPoint(); // } // Recompute the center of the rectangle - cx = MathUtils::round( - (point_a.getX() + point_d.getX() + point_b.getX() + point_c.getX()) / 4.0f32, - ); - cy = MathUtils::round( - (point_a.getY() + point_d.getY() + point_b.getY() + point_c.getY()) / 4.0f32, - ); + cx = ((point_a.x + point_d.x + point_b.x + point_c.x) / 4.0).round() as i32; + cy = ((point_a.y + point_d.y + point_b.y + point_c.y) / 4.0).round() as i32; - Point::new(cx, cy) + AztecPoint::new(cx, cy) } /** @@ -471,10 +459,7 @@ impl<'a> Detector<'_> { * @param bullsEyeCorners the array of bull's eye corners * @return the array of aztec code corners */ - fn get_matrix_corner_points( - &self, - bulls_eye_corners: &[RXingResultPoint], - ) -> [RXingResultPoint; 4] { + fn get_matrix_corner_points(&self, bulls_eye_corners: &[Point]) -> [Point; 4] { Self::expand_square( bulls_eye_corners, 2 * self.nb_center_layers, @@ -490,10 +475,10 @@ impl<'a> Detector<'_> { fn sample_grid( &self, image: &BitMatrix, - top_left: &RXingResultPoint, - top_right: &RXingResultPoint, - bottom_right: &RXingResultPoint, - bottom_left: &RXingResultPoint, + top_left: Point, + top_right: Point, + bottom_right: Point, + bottom_left: Point, ) -> Result { let sampler = DefaultGridSampler::default(); let dimension = self.get_dimension(); @@ -513,14 +498,14 @@ impl<'a> Detector<'_> { high, // bottomright low, high, // bottomleft - top_left.getX(), - top_left.getY(), - top_right.getX(), - top_right.getY(), - bottom_right.getX(), - bottom_right.getY(), - bottom_left.getX(), - bottom_left.getY(), + top_left.x, + top_left.y, + top_right.x, + top_right.y, + bottom_right.x, + bottom_right.y, + bottom_left.x, + bottom_left.y, ) } @@ -532,20 +517,20 @@ impl<'a> Detector<'_> { * @param size number of bits * @return the array of bits as an int (first bit is high-order bit of result) */ - fn sample_line(&self, p1: &RXingResultPoint, p2: &RXingResultPoint, size: u32) -> u32 { + fn sample_line(&self, p1: Point, p2: Point, size: u32) -> u32 { let mut result = 0; let d = Self::distance(p1, p2); let module_size = d / size as f32; - let px = p1.getX(); - let py = p1.getY(); - let dx = module_size * (p2.getX() - p1.getX()) / d; - let dy = module_size * (p2.getY() - p1.getY()) / d; + let px = p1.x; + let py = p1.y; + let dx = module_size * (p2.x - p1.x) / d; + let dy = module_size * (p2.y - p1.y) / d; for i in 0..size { // for (int i = 0; i < size; i++) { if self.image.get( - MathUtils::round(px + i as f32 * dx) as u32, - MathUtils::round(py + i as f32 * dy) as u32, + (px + i as f32 * dx).round() as u32, + (py + i as f32 * dy).round() as u32, ) { result |= 1 << (size - i - 1); } @@ -557,48 +542,54 @@ impl<'a> Detector<'_> { * @return true if the border of the rectangle passed in parameter is compound of white points only * or black points only */ - fn is_white_or_black_rectangle(&self, p1: &Point, p2: &Point, p3: &Point, p4: &Point) -> bool { + fn is_white_or_black_rectangle( + &self, + p1: &AztecPoint, + p2: &AztecPoint, + p3: &AztecPoint, + p4: &AztecPoint, + ) -> bool { let corr = 3; - let p1 = Point::new( + let p1 = AztecPoint::new( 0.max(p1.get_x() - corr), (self.image.getHeight() as i32 - 1).min(p1.get_y() + corr), ); - // let p1 = Point::new(Math.max(0, p1.getX() - corr), Math.min(image.getHeight() - 1, p1.getY() + corr)); - let p2 = Point::new(0.max(p2.get_x() - corr), 0.max(p2.get_y() - corr)); - // let p2 = Point::new(Math.max(0, p2.getX() - corr), Math.max(0, p2.getY() - corr)); - let p3 = Point::new( + // let p1 = point(Math.max(0, p1.getX() - corr), Math.min(image.getHeight() - 1, p1.getY() + corr)); + let p2 = AztecPoint::new(0.max(p2.get_x() - corr), 0.max(p2.get_y() - corr)); + // let p2 = point(Math.max(0, p2.getX() - corr), Math.max(0, p2.getY() - corr)); + let p3 = AztecPoint::new( (self.image.getWidth() as i32 - 1).min(p3.get_x() + corr), 0.max((self.image.getHeight() as i32 - 1).min(p3.get_y() - corr)), ); - // let p3 = Point::new(Math.min(image.getWidth() - 1, p3.getX() + corr), + // let p3 = point(Math.min(image.getWidth() - 1, p3.getX() + corr), // Math.max(0, Math.min(image.getHeight() - 1, p3.getY() - corr))); - let p4 = Point::new( + let p4 = AztecPoint::new( (self.image.getWidth() as i32 - 1).min(p4.get_x() + corr), (self.image.getHeight() as i32 - 1).min(p4.get_y() + corr), ); - // let p4 = Point::new(Math.min(image.getWidth() - 1, p4.getX() + corr), + // let p4 = point(Math.min(image.getWidth() - 1, p4.getX() + corr), // Math.min(image.getHeight() - 1, p4.getY() + corr)); - let c_init = self.get_color(&p4, &p1); + let c_init = self.get_color(p4, p1); if c_init == 0 { return false; } - let c = self.get_color(&p1, &p2); + let c = self.get_color(p1, p2); if c != c_init { return false; } - let c = self.get_color(&p2, &p3); + let c = self.get_color(p2, p3); if c != c_init { return false; } - let c = self.get_color(&p3, &p4); + let c = self.get_color(p3, p4); c == c_init } @@ -608,7 +599,7 @@ impl<'a> Detector<'_> { * * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else */ - fn get_color(&self, p1: &Point, p2: &Point) -> i32 { + fn get_color(&self, p1: AztecPoint, p2: AztecPoint) -> i32 { let d = Self::distance_points(p1, p2); if d == 0.0f32 { return 0; @@ -626,11 +617,7 @@ impl<'a> Detector<'_> { for _i in 0..i_max { // for (int i = 0; i < iMax; i++) { - if self - .image - .get(MathUtils::round(px) as u32, MathUtils::round(py) as u32) - != color_model - { + if self.image.get(px.round() as u32, py.round() as u32) != color_model { error += 1; } px += dx; @@ -653,7 +640,7 @@ impl<'a> Detector<'_> { /** * Gets the coordinate of the first point with a different color in the given direction */ - fn get_first_different(&self, init: &Point, color: bool, dx: i32, dy: i32) -> Point { + fn get_first_different(&self, init: &AztecPoint, color: bool, dx: i32, dy: i32) -> AztecPoint { let mut x = init.get_x() + dx; let mut y = init.get_y() + dy; @@ -675,7 +662,7 @@ impl<'a> Detector<'_> { } y -= dy; - Point::new(x, y) + AztecPoint::new(x, y) } /** @@ -686,26 +673,18 @@ impl<'a> Detector<'_> { * @param newSide the new length of the size of the square in the target bit matrix * @return the corners of the expanded square */ - fn expand_square( - corner_points: &[RXingResultPoint], - old_side: u32, - new_side: u32, - ) -> [RXingResultPoint; 4] { + fn expand_square(corner_points: &[Point], old_side: u32, new_side: u32) -> [Point; 4] { let ratio = new_side as f32 / (2.0f32 * old_side as f32); - let mut dx = corner_points[0].getX() - corner_points[2].getX(); - let mut dy = corner_points[0].getY() - corner_points[2].getY(); - let mut centerx = (corner_points[0].getX() + corner_points[2].getX()) / 2.0f32; - let mut centery = (corner_points[0].getY() + corner_points[2].getY()) / 2.0f32; - let result0 = RXingResultPoint::new(centerx + ratio * dx, centery + ratio * dy); - let result2 = RXingResultPoint::new(centerx - ratio * dx, centery - ratio * dy); + let d = corner_points[0] - corner_points[2]; + let middle = corner_points[0].middle(corner_points[2]); + let result0 = middle + ratio * d; + let result2 = middle - ratio * d; - dx = corner_points[1].getX() - corner_points[3].getX(); - dy = corner_points[1].getY() - corner_points[3].getY(); - centerx = (corner_points[1].getX() + corner_points[3].getX()) / 2.0f32; - centery = (corner_points[1].getY() + corner_points[3].getY()) / 2.0f32; - let result1 = RXingResultPoint::new(centerx + ratio * dx, centery + ratio * dy); - let result3 = RXingResultPoint::new(centerx - ratio * dx, centery - ratio * dy); + let d = corner_points[1] - corner_points[3]; + let middle = corner_points[1].middle(corner_points[3]); + let result1 = middle + ratio * d; + let result3 = middle - ratio * d; [result0, result1, result2, result3] } @@ -714,18 +693,18 @@ impl<'a> Detector<'_> { x >= 0 && x < self.image.getWidth() as i32 && y >= 0 && y < self.image.getHeight() as i32 } - fn is_valid(&self, point: &RXingResultPoint) -> bool { - let x = MathUtils::round(point.getX()); - let y = MathUtils::round(point.getY()); + fn is_valid(&self, point: Point) -> bool { + let x = point.x.round() as i32; + let y = point.y.round() as i32; self.is_valid_points(x, y) } - fn distance_points(a: &Point, b: &Point) -> f32 { - MathUtils::distance(a.get_x(), a.get_y(), b.get_x(), b.get_y()) + fn distance_points(a: AztecPoint, b: AztecPoint) -> f32 { + Point::from(a).distance(b.into()) } - fn distance(a: &RXingResultPoint, b: &RXingResultPoint) -> f32 { - MathUtils::distance(a.getX(), a.getY(), b.getX(), b.getY()) + fn distance(a: Point, b: Point) -> f32 { + a.distance(b) } fn get_dimension(&self) -> u32 { @@ -738,12 +717,12 @@ impl<'a> Detector<'_> { } #[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct Point { +pub struct AztecPoint { x: i32, y: i32, } -impl Point { +impl AztecPoint { pub fn new(x: i32, y: i32) -> Self { Self { x, y } } @@ -757,13 +736,13 @@ impl Point { } } -impl From for RXingResultPoint { - fn from(value: Point) -> Self { - RXingResultPoint::new(value.x as f32, value.y as f32) +impl From for Point { + fn from(value: AztecPoint) -> Self { + point(value.x as f32, value.y as f32) } } -impl fmt::Display for Point { +impl fmt::Display for AztecPoint { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "<{} {}>", &self.x, &self.y) } diff --git a/src/common/bit_matrix.rs b/src/common/bit_matrix.rs index 725c288..7f1e7a4 100644 --- a/src/common/bit_matrix.rs +++ b/src/common/bit_matrix.rs @@ -21,7 +21,7 @@ use std::fmt; use crate::common::Result; -use crate::{Exceptions, RXingResultPoint}; +use crate::{Exceptions, Point}; use super::BitArray; @@ -209,7 +209,7 @@ impl BitMatrix { ((self.bits[offset] >> (x & 0x1f)) & 1) != 0 } - pub fn get_point(&self, point: &RXingResultPoint) -> bool { + pub fn get_point(&self, point: Point) -> bool { self.get(point.x as u32, point.y as u32) // let offset = self.get_offset(point.y as u32, point.x as u32); // ((self.bits[offset] >> (x & 0x1f)) & 1) != 0 @@ -691,7 +691,7 @@ impl BitMatrix { new_bm } - pub fn isIn(&self, p: &RXingResultPoint, b: i32) -> bool { + pub fn isIn(&self, p: Point, b: i32) -> bool { b as f32 <= p.x && p.x < self.getWidth() as f32 - b as f32 && b as f32 <= p.y diff --git a/src/common/detector/MathUtils.rs b/src/common/detector/MathUtils.rs deleted file mode 100644 index 9123211..0000000 --- a/src/common/detector/MathUtils.rs +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2012 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -use std::{ - f32, i32, - ops::{Add, Sub}, -}; - -/** - * General math-related and numeric utility functions. - */ - -/** - * Ends up being a bit faster than {@link Math#round(float)}. This merely rounds its - * argument to the nearest int, where x.5 rounds up to x+1. Semantics of this shortcut - * differ slightly from {@link Math#round(float)} in that half rounds down for negative - * values. -2.5 rounds to -3, not -2. For purposes here it makes no difference. - * - * @param d real value to round - * @return nearest {@code int} - */ -#[inline(always)] -pub fn round(d: f32) -> i32 { - // (d + (if d < 0.0f32 { -0.5f32 } else { 0.5f32 })) as i32 - d.round() as i32 -} - -// /** -// * @param aX point A x coordinate -// * @param aY point A y coordinate -// * @param bX point B x coordinate -// * @param bY point B y coordinate -// * @return Euclidean distance between points A and B -// */ -// #[inline(always)] -// pub fn distance_float(aX: f32, aY: f32, bX: f32, bY: f32) -> f32 { -// let xDiff: f64 = (aX - bX).into(); -// let yDiff: f64 = (aY - bY).into(); -// (xDiff * xDiff + yDiff * yDiff).sqrt() as f32 -// } - -// /** -// * @param aX point A x coordinate -// * @param aY point A y coordinate -// * @param bX point B x coordinate -// * @param bY point B y coordinate -// * @return Euclidean distance between points A and B -// */ -// #[inline(always)] -// pub fn distance_int(aX: i32, aY: i32, bX: i32, bY: i32) -> f32 { -// let xDiff: f64 = (aX - bX).into(); -// let yDiff: f64 = (aY - bY).into(); -// (xDiff * xDiff + yDiff * yDiff).sqrt() as f32 -// } - -#[inline(always)] -pub fn distance(aX: T, aY: T, bX: T, bY: T) -> f32 -where - T: Sub + Into, -{ - let xDiff: f64 = (aX - bX).into(); - let yDiff: f64 = (aY - bY).into(); - (xDiff * xDiff + yDiff * yDiff).sqrt() as f32 -} - -/** - * @param array values to sum - * @return sum of values in array - */ -#[inline(always)] -pub fn sum<'a, T>(array: &'a [T]) -> T -where - T: Add + std::iter::Sum<&'a T>, -{ - array.iter().sum() -} - -#[cfg(test)] -mod tests { - use crate::common::detector::MathUtils; - - // static EPSILON: f32 = 1.0E-8f32; - - #[test] - fn testRound() { - assert_eq!(-1, MathUtils::round(-1.0f32)); - assert_eq!(0, MathUtils::round(0.0f32)); - assert_eq!(1, MathUtils::round(1.0f32)); - - assert_eq!(2, MathUtils::round(1.9f32)); - assert_eq!(2, MathUtils::round(2.1f32)); - - assert_eq!(3, MathUtils::round(2.5f32)); - - assert_eq!(-2, MathUtils::round(-1.9f32)); - assert_eq!(-2, MathUtils::round(-2.1f32)); - - assert_eq!(-3, MathUtils::round(-2.5f32)); // This differs from Math.round() - - assert_eq!(i32::MAX, MathUtils::round(i32::MAX as f32)); - assert_eq!(i32::MIN, MathUtils::round(i32::MIN as f32)); - - assert_eq!(i32::MAX, MathUtils::round(f32::MAX)); - assert_eq!(i32::MIN, MathUtils::round(f32::NEG_INFINITY)); - - assert_eq!(0, MathUtils::round(f32::NAN)); - } - - #[test] - fn testDistance() { - assert_eq!( - (8.0f32).sqrt(), - MathUtils::distance(1.0f32, 2.0f32, 3.0f32, 4.0f32) - ); - assert_eq!(0.0f32, MathUtils::distance(1.0f32, 2.0f32, 1.0f32, 2.0f32)); - - assert_eq!((8.0f32).sqrt(), MathUtils::distance(1, 2, 3, 4)); - assert_eq!(0.0f32, MathUtils::distance(1, 2, 1, 2)); - } - - #[test] - fn testSum() { - assert_eq!(0, MathUtils::sum(&[])); - assert_eq!(1, MathUtils::sum(&[1])); - assert_eq!(4, MathUtils::sum(&[1, 3])); - assert_eq!(0, MathUtils::sum(&[-1, 1])); - assert_eq!(0.0, MathUtils::sum(&[-1.0, 1.0])); - assert_eq!(4.0, MathUtils::sum(&[1.0, 3.0])); - } -} diff --git a/src/common/detector/mod.rs b/src/common/detector/mod.rs index fcd6de6..e403a70 100644 --- a/src/common/detector/mod.rs +++ b/src/common/detector/mod.rs @@ -1,5 +1,3 @@ -pub mod MathUtils; - mod monochrome_rectangle_detector; pub use monochrome_rectangle_detector::*; diff --git a/src/common/detector/monochrome_rectangle_detector.rs b/src/common/detector/monochrome_rectangle_detector.rs index af61a38..c7dfc86 100644 --- a/src/common/detector/monochrome_rectangle_detector.rs +++ b/src/common/detector/monochrome_rectangle_detector.rs @@ -19,7 +19,7 @@ use crate::{ common::{BitMatrix, Result}, - Exceptions, RXingResultPoint, ResultPoint, + point, Exceptions, Point, }; /** @@ -45,13 +45,13 @@ impl<'a> MonochromeRectangleDetector<'_> { *

Detects a rectangular region of black and white -- mostly black -- with a region of mostly * white, in an image.

* - * @return {@link RXingResultPoint}[] describing the corners of the rectangular region. The first and + * @return {@link Point}[] describing the corners of the rectangular region. The first and * last points are opposed on the diagonal, as are the second and third. The first point will be * the topmost point and the last, the bottommost. The second point will be leftmost and the * third, the rightmost * @throws NotFoundException if no Data Matrix Code can be found */ - pub fn detect(&self) -> Result<[RXingResultPoint; 4]> { + pub fn detect(&self) -> Result<[Point; 4]> { let height = self.image.getHeight() as i32; let width = self.image.getWidth() as i32; let halfHeight = height / 2; @@ -74,7 +74,7 @@ impl<'a> MonochromeRectangleDetector<'_> { bottom, halfWidth / 2, )?; - top = (pointA.getY() - 1f32) as i32; + top = (pointA.y - 1f32) as i32; let pointB = self.findCornerFromCenter( halfWidth, -deltaX, @@ -86,7 +86,7 @@ impl<'a> MonochromeRectangleDetector<'_> { bottom, halfHeight / 2, )?; - left = (pointB.getX() - 1f32) as i32; + left = (pointB.x - 1f32) as i32; let pointC = self.findCornerFromCenter( halfWidth, deltaX, @@ -98,7 +98,7 @@ impl<'a> MonochromeRectangleDetector<'_> { bottom, halfHeight / 2, )?; - right = (pointC.getX() + 1f32) as i32; + right = (pointC.x + 1f32) as i32; let pointD = self.findCornerFromCenter( halfWidth, 0, @@ -110,7 +110,7 @@ impl<'a> MonochromeRectangleDetector<'_> { bottom, halfWidth / 2, )?; - bottom = (pointD.getY() + 1f32) as i32; + bottom = (pointD.y + 1f32) as i32; // Go try to find point A again with better information -- might have been off at first. pointA = self.findCornerFromCenter( @@ -143,7 +143,7 @@ impl<'a> MonochromeRectangleDetector<'_> { * @param bottom maximum value of y * @param maxWhiteRun maximum run of white pixels that can still be considered to be within * the barcode - * @return a {@link RXingResultPoint} encapsulating the corner that was found + * @return a {@link Point} encapsulating the corner that was found * @throws NotFoundException if such a point cannot be found */ #[allow(clippy::too_many_arguments)] @@ -158,7 +158,7 @@ impl<'a> MonochromeRectangleDetector<'_> { top: i32, bottom: i32, maxWhiteRun: i32, - ) -> Result { + ) -> Result { let mut lastRange_z: Option<[i32; 2]> = None; let mut y: i32 = centerY; let mut x: i32 = centerX; @@ -178,27 +178,27 @@ impl<'a> MonochromeRectangleDetector<'_> { if lastRange[0] < centerX { if lastRange[1] > centerX { // straddle, choose one or the other based on direction - return Ok(RXingResultPoint::new( + return Ok(point( lastRange[usize::from(deltaY <= 0)] as f32, lastY as f32, )); } - return Ok(RXingResultPoint::new(lastRange[0] as f32, lastY as f32)); + return Ok(point(lastRange[0] as f32, lastY as f32)); } else { - return Ok(RXingResultPoint::new(lastRange[1] as f32, lastY as f32)); + return Ok(point(lastRange[1] as f32, lastY as f32)); } } else { let lastX = x - deltaX; if lastRange[0] < centerY { if lastRange[1] > centerY { - return Ok(RXingResultPoint::new( + return Ok(point( lastX as f32, lastRange[usize::from(deltaX >= 0)] as f32, )); } - return Ok(RXingResultPoint::new(lastX as f32, lastRange[0] as f32)); + return Ok(point(lastX as f32, lastRange[0] as f32)); } else { - return Ok(RXingResultPoint::new(lastX as f32, lastRange[1] as f32)); + return Ok(point(lastX as f32, lastRange[1] as f32)); } } } diff --git a/src/common/detector/white_rectangle_detector.rs b/src/common/detector/white_rectangle_detector.rs index 6cc1d6a..bb53065 100644 --- a/src/common/detector/white_rectangle_detector.rs +++ b/src/common/detector/white_rectangle_detector.rs @@ -18,11 +18,9 @@ use crate::{ common::{BitMatrix, Result}, - Exceptions, RXingResultPoint, ResultPoint, + point, Exceptions, Point, }; -use super::MathUtils; - /** *

* Detects a candidate barcode-like rectangular region within an image. It @@ -101,14 +99,14 @@ impl<'a> WhiteRectangleDetector<'_> { * region until it finds a white rectangular region. *

* - * @return {@link RXingResultPoint}[] describing the corners of the rectangular + * @return {@link Point}[] describing the corners of the rectangular * region. The first and last points are opposed on the diagonal, as * are the second and third. The first point will be the topmost * point and the last, the bottommost. The second point will be * leftmost and the third, the rightmost * @throws NotFoundException if no Data Matrix Code can be found */ - pub fn detect(&self) -> Result<[RXingResultPoint; 4]> { + pub fn detect(&self) -> Result<[Point; 4]> { let mut left: i32 = self.leftInit; let mut right: i32 = self.rightInit; let mut up: i32 = self.upInit; @@ -212,7 +210,7 @@ impl<'a> WhiteRectangleDetector<'_> { if !size_exceeded { let max_size = right - left; - let mut z: Option = None; + let mut z: Option = None; let mut i = 1; while z.is_none() && i < max_size { //for (int i = 1; z == null && i < maxSize; i++) { @@ -229,7 +227,7 @@ impl<'a> WhiteRectangleDetector<'_> { return Err(Exceptions::notFound); } - let mut t: Option = None; + let mut t: Option = None; //go down right let mut i = 1; while t.is_none() && i < max_size { @@ -247,7 +245,7 @@ impl<'a> WhiteRectangleDetector<'_> { return Err(Exceptions::notFound); } - let mut x: Option = None; + let mut x: Option = None; //go down left let mut i = 1; while x.is_none() && i < max_size { @@ -265,7 +263,7 @@ impl<'a> WhiteRectangleDetector<'_> { return Err(Exceptions::notFound); } - let mut y: Option = None; + let mut y: Option = None; //go up left let mut i = 1; while y.is_none() && i < max_size { @@ -283,28 +281,25 @@ impl<'a> WhiteRectangleDetector<'_> { return Err(Exceptions::notFound); } - Ok(self.center_edges(&y.unwrap(), &z.unwrap(), &x.unwrap(), &t.unwrap())) + Ok(self.center_edges(y.unwrap(), z.unwrap(), x.unwrap(), t.unwrap())) } else { Err(Exceptions::notFound) } } - fn get_black_point_on_segment( - &self, - a_x: f32, - a_y: f32, - b_x: f32, - b_y: f32, - ) -> Option { - let dist = MathUtils::round(MathUtils::distance(a_x, a_y, b_x, b_y)); + fn get_black_point_on_segment(&self, a_x: f32, a_y: f32, b_x: f32, b_y: f32) -> Option { + let a = point(a_x, a_y); + let b = point(b_x, b_y); + + let dist = a.distance(b).round() as i32; let x_step: f32 = (b_x - a_x) / dist as f32; let y_step: f32 = (b_y - a_y) / dist as f32; for i in 0..dist { - let x = MathUtils::round(a_x + i as f32 * x_step); - let y = MathUtils::round(a_y + i as f32 * y_step); + let x = (a_x + i as f32 * x_step).round() as i32; + let y = (a_y + i as f32 * y_step).round() as i32; if self.image.get(x as u32, y as u32) { - return Some(RXingResultPoint::new(x as f32, y as f32)); + return Some(point(x as f32, y as f32)); } } None @@ -317,19 +312,13 @@ impl<'a> WhiteRectangleDetector<'_> { * @param z left most point * @param x right most point * @param t top most point - * @return {@link RXingResultPoint}[] describing the corners of the rectangular + * @return {@link Point}[] describing the corners of the rectangular * region. The first and last points are opposed on the diagonal, as * are the second and third. The first point will be the topmost * point and the last, the bottommost. The second point will be * leftmost and the third, the rightmost */ - fn center_edges( - &self, - y: &RXingResultPoint, - z: &RXingResultPoint, - x: &RXingResultPoint, - t: &RXingResultPoint, - ) -> [RXingResultPoint; 4] { + fn center_edges(&self, y: Point, z: Point, x: Point, t: Point) -> [Point; 4] { // // t t // z x @@ -337,28 +326,28 @@ impl<'a> WhiteRectangleDetector<'_> { // y y // - let yi = y.getX(); - let yj = y.getY(); - let zi = z.getX(); - let zj = z.getY(); - let xi = x.getX(); - let xj = x.getY(); - let ti = t.getX(); - let tj = t.getY(); + let yi = y.x; + let yj = y.y; + let zi = z.x; + let zj = z.y; + let xi = x.x; + let xj = x.y; + let ti = t.x; + let tj = t.y; if yi < self.width as f32 / 2.0f32 { [ - RXingResultPoint::new(ti - CORR as f32, tj + CORR as f32), - RXingResultPoint::new(zi + CORR as f32, zj + CORR as f32), - RXingResultPoint::new(xi - CORR as f32, xj - CORR as f32), - RXingResultPoint::new(yi + CORR as f32, yj - CORR as f32), + point(ti - CORR as f32, tj + CORR as f32), + point(zi + CORR as f32, zj + CORR as f32), + point(xi - CORR as f32, xj - CORR as f32), + point(yi + CORR as f32, yj - CORR as f32), ] } else { [ - RXingResultPoint::new(ti + CORR as f32, tj + CORR as f32), - RXingResultPoint::new(zi + CORR as f32, zj - CORR as f32), - RXingResultPoint::new(xi - CORR as f32, xj + CORR as f32), - RXingResultPoint::new(yi - CORR as f32, yj - CORR as f32), + point(ti + CORR as f32, tj + CORR as f32), + point(zi + CORR as f32, zj - CORR as f32), + point(xi - CORR as f32, xj + CORR as f32), + point(yi - CORR as f32, yj - CORR as f32), ] } } diff --git a/src/common/mod.rs b/src/common/mod.rs index 4b3b080..257e8a6 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,7 +1,7 @@ pub mod detector; pub mod reedsolomon; -use crate::RXingResultPoint; +use crate::Point; #[cfg(test)] mod StringUtilsTestCase; @@ -44,7 +44,7 @@ pub type Result = std::result::Result; // package com.google.zxing.common; -// import com.google.zxing.RXingResultPoint; +// import com.google.zxing.Point; /** *

Encapsulates the result of detecting a barcode in an image. This includes the raw @@ -56,12 +56,12 @@ pub type Result = std::result::Result; pub trait DetectorRXingResult { fn getBits(&self) -> &BitMatrix; - fn getPoints(&self) -> &[RXingResultPoint]; + fn getPoints(&self) -> &[Point]; } // pub struct DetectorRXingResult { // bits: BitMatrix, -// points: Vec, +// points: Vec, // } mod bit_matrix; diff --git a/src/datamatrix/data_matrix_reader.rs b/src/datamatrix/data_matrix_reader.rs index bebeebd..ae16eed 100644 --- a/src/datamatrix/data_matrix_reader.rs +++ b/src/datamatrix/data_matrix_reader.rs @@ -39,7 +39,7 @@ static DECODER: Lazy = Lazy::new(Decoder::new); #[derive(Default)] pub struct DataMatrixReader; -// private static final RXingResultPoint[] NO_POINTS = new RXingResultPoint[0]; +// private static final Point[] NO_POINTS = new Point[0]; // private final Decoder decoder = new Decoder(); diff --git a/src/datamatrix/detector/datamatrix_detector.rs b/src/datamatrix/detector/datamatrix_detector.rs index c9db963..bf7dcd8 100644 --- a/src/datamatrix/detector/datamatrix_detector.rs +++ b/src/datamatrix/detector/datamatrix_detector.rs @@ -18,7 +18,7 @@ use crate::{ common::{ detector::WhiteRectangleDetector, BitMatrix, DefaultGridSampler, GridSampler, Result, }, - Exceptions, RXingResultPoint, ResultPoint, + point, Exceptions, Point, }; use super::DatamatrixDetectorResult; @@ -68,8 +68,8 @@ impl<'a> Detector<'_> { let bottomRight = points[2]; let topRight = points[3]; - let mut dimensionTop = self.transitionsBetween(&topLeft, &topRight) + 1; - let mut dimensionRight = self.transitionsBetween(&bottomRight, &topRight) + 1; + let mut dimensionTop = self.transitionsBetween(topLeft, topRight) + 1; + let mut dimensionRight = self.transitionsBetween(bottomRight, topRight) + 1; if (dimensionTop & 0x01) == 1 { dimensionTop += 1; } @@ -85,10 +85,10 @@ impl<'a> Detector<'_> { let bits = Self::sampleGrid( self.image, - &topLeft, - &bottomLeft, - &bottomRight, - &topRight, + topLeft, + bottomLeft, + bottomRight, + topRight, dimensionTop, dimensionRight, )?; @@ -99,15 +99,15 @@ impl<'a> Detector<'_> { )) } - fn shiftPoint(point: RXingResultPoint, to: RXingResultPoint, div: u32) -> RXingResultPoint { - let x = (to.getX() - point.getX()) / (div as f32 + 1.0); - let y = (to.getY() - point.getY()) / (div as f32 + 1.0); - RXingResultPoint::new(point.getX() + x, point.getY() + y) + fn shiftPoint(p: Point, to: Point, div: u32) -> Point { + let x = (to.x - p.x) / (div as f32 + 1.0); + let y = (to.y - p.y) / (div as f32 + 1.0); + point(p.x + x, p.y + y) } - fn moveAway(point: RXingResultPoint, fromX: f32, fromY: f32) -> RXingResultPoint { - let mut x = point.getX(); - let mut y = point.getY(); + fn moveAway(p: Point, fromX: f32, fromY: f32) -> Point { + let mut x = p.x; + let mut y = p.y; if x < fromX { x -= 1.0; @@ -121,13 +121,13 @@ impl<'a> Detector<'_> { y += 1.0; } - RXingResultPoint::new(x, y) + point(x, y) } /** * Detect a solid side which has minimum transition. */ - fn detectSolid1(&self, cornerPoints: [RXingResultPoint; 4]) -> [RXingResultPoint; 4] { + fn detectSolid1(&self, cornerPoints: [Point; 4]) -> [Point; 4] { // 0 2 // 1 3 let pointA = cornerPoints[0]; @@ -135,10 +135,10 @@ impl<'a> Detector<'_> { let pointC = cornerPoints[3]; let pointD = cornerPoints[2]; - let trAB = self.transitionsBetween(&pointA, &pointB); - let trBC = self.transitionsBetween(&pointB, &pointC); - let trCD = self.transitionsBetween(&pointC, &pointD); - let trDA = self.transitionsBetween(&pointD, &pointA); + let trAB = self.transitionsBetween(pointA, pointB); + let trBC = self.transitionsBetween(pointB, pointC); + let trCD = self.transitionsBetween(pointC, pointD); + let trDA = self.transitionsBetween(pointD, pointA); // 0..3 // : : @@ -172,7 +172,7 @@ impl<'a> Detector<'_> { /** * Detect a second solid side next to first solid side. */ - fn detectSolid2(&self, points: [RXingResultPoint; 4]) -> [RXingResultPoint; 4] { + fn detectSolid2(&self, points: [Point; 4]) -> [Point; 4] { // A..D // : : // B--C @@ -183,11 +183,11 @@ impl<'a> Detector<'_> { // Transition detection on the edge is not stable. // To safely detect, shift the points to the module center. - let tr = self.transitionsBetween(&pointA, &pointD); + let tr = self.transitionsBetween(pointA, pointD); let pointBs = Self::shiftPoint(pointB, pointC, (tr + 1) * 4); let pointCs = Self::shiftPoint(pointC, pointB, (tr + 1) * 4); - let trBA = self.transitionsBetween(&pointBs, &pointA); - let trCD = self.transitionsBetween(&pointCs, &pointD); + let trBA = self.transitionsBetween(pointBs, pointA); + let trCD = self.transitionsBetween(pointCs, pointD); // 0..3 // | : @@ -212,7 +212,7 @@ impl<'a> Detector<'_> { /** * Calculates the corner position of the white top right module. */ - fn correctTopRight(&self, points: &[RXingResultPoint; 4]) -> Option { + fn correctTopRight(&self, points: &[Point; 4]) -> Option { // A..D // | : // B--C @@ -222,37 +222,37 @@ impl<'a> Detector<'_> { let pointD = points[3]; // shift points for safe transition detection. - let mut trTop = self.transitionsBetween(&pointA, &pointD); - let mut trRight = self.transitionsBetween(&pointB, &pointD); + let mut trTop = self.transitionsBetween(pointA, pointD); + let mut trRight = self.transitionsBetween(pointB, pointD); let pointAs = Self::shiftPoint(pointA, pointB, (trRight + 1) * 4); let pointCs = Self::shiftPoint(pointC, pointB, (trTop + 1) * 4); - trTop = self.transitionsBetween(&pointAs, &pointD); - trRight = self.transitionsBetween(&pointCs, &pointD); + trTop = self.transitionsBetween(pointAs, pointD); + trRight = self.transitionsBetween(pointCs, pointD); - let candidate1 = RXingResultPoint::new( - pointD.getX() + (pointC.getX() - pointB.getX()) / (trTop as f32 + 1.0), - pointD.getY() + (pointC.getY() - pointB.getY()) / (trTop as f32 + 1.0), + let candidate1 = point( + pointD.x + (pointC.x - pointB.x) / (trTop as f32 + 1.0), + pointD.y + (pointC.y - pointB.y) / (trTop as f32 + 1.0), ); - let candidate2 = RXingResultPoint::new( - pointD.getX() + (pointA.getX() - pointB.getX()) / (trRight as f32 + 1.0), - pointD.getY() + (pointA.getY() - pointB.getY()) / (trRight as f32 + 1.0), + let candidate2 = point( + pointD.x + (pointA.x - pointB.x) / (trRight as f32 + 1.0), + pointD.y + (pointA.y - pointB.y) / (trRight as f32 + 1.0), ); - if !self.isValid(&candidate1) { - if self.isValid(&candidate2) { + if !self.isValid(candidate1) { + if self.isValid(candidate2) { return Some(candidate2); } return None; } - if !self.isValid(&candidate2) { + if !self.isValid(candidate2) { return Some(candidate1); } - let sumc1 = self.transitionsBetween(&pointAs, &candidate1) - + self.transitionsBetween(&pointCs, &candidate1); - let sumc2 = self.transitionsBetween(&pointAs, &candidate2) - + self.transitionsBetween(&pointCs, &candidate2); + let sumc1 = self.transitionsBetween(pointAs, candidate1) + + self.transitionsBetween(pointCs, candidate1); + let sumc2 = self.transitionsBetween(pointAs, candidate2) + + self.transitionsBetween(pointCs, candidate2); if sumc1 > sumc2 { Some(candidate1) @@ -264,7 +264,7 @@ impl<'a> Detector<'_> { /** * Shift the edge points to the module center. */ - fn shiftToModuleCenter(&self, points: [RXingResultPoint; 4]) -> [RXingResultPoint; 4] { + fn shiftToModuleCenter(&self, points: [Point; 4]) -> [Point; 4] { // A..D // | : // B--C @@ -274,16 +274,16 @@ impl<'a> Detector<'_> { let mut pointD = points[3]; // calculate pseudo dimensions - let mut dimH = self.transitionsBetween(&pointA, &pointD) + 1; - let mut dimV = self.transitionsBetween(&pointC, &pointD) + 1; + let mut dimH = self.transitionsBetween(pointA, pointD) + 1; + let mut dimV = self.transitionsBetween(pointC, pointD) + 1; // shift points for safe dimension detection let mut pointAs = Self::shiftPoint(pointA, pointB, dimV * 4); let mut pointCs = Self::shiftPoint(pointC, pointB, dimH * 4); // calculate more precise dimensions - dimH = self.transitionsBetween(&pointAs, &pointD) + 1; - dimV = self.transitionsBetween(&pointCs, &pointD) + 1; + dimH = self.transitionsBetween(pointAs, pointD) + 1; + dimV = self.transitionsBetween(pointCs, pointD) + 1; if (dimH & 0x01) == 1 { dimH += 1; } @@ -293,8 +293,8 @@ impl<'a> Detector<'_> { // WhiteRectangleDetector returns points inside of the rectangle. // I want points on the edges. - let centerX = (pointA.getX() + pointB.getX() + pointC.getX() + pointD.getX()) / 4.0; - let centerY = (pointA.getY() + pointB.getY() + pointC.getY() + pointD.getY()) / 4.0; + let centerX = (pointA.x + pointB.x + pointC.x + pointD.x) / 4.0; + let centerY = (pointA.y + pointB.y + pointC.y + pointD.y) / 4.0; pointA = Self::moveAway(pointA, centerX, centerY); pointB = Self::moveAway(pointB, centerX, centerY); pointC = Self::moveAway(pointC, centerX, centerY); @@ -316,19 +316,19 @@ impl<'a> Detector<'_> { [pointAs, pointBs, pointCs, pointDs] } - fn isValid(&self, p: &RXingResultPoint) -> bool { - p.getX() >= 0.0 - && p.getX() <= self.image.getWidth() as f32 - 1.0 - && p.getY() > 0.0 - && p.getY() <= self.image.getHeight() as f32 - 1.0 + fn isValid(&self, p: Point) -> bool { + p.x >= 0.0 + && p.x <= self.image.getWidth() as f32 - 1.0 + && p.y > 0.0 + && p.y <= self.image.getHeight() as f32 - 1.0 } fn sampleGrid( image: &BitMatrix, - topLeft: &RXingResultPoint, - bottomLeft: &RXingResultPoint, - bottomRight: &RXingResultPoint, - topRight: &RXingResultPoint, + topLeft: Point, + bottomLeft: Point, + bottomRight: Point, + topRight: Point, dimensionX: u32, dimensionY: u32, ) -> Result { @@ -346,26 +346,26 @@ impl<'a> Detector<'_> { dimensionY as f32 - 0.5, 0.5, dimensionY as f32 - 0.5, - topLeft.getX(), - topLeft.getY(), - topRight.getX(), - topRight.getY(), - bottomRight.getX(), - bottomRight.getY(), - bottomLeft.getX(), - bottomLeft.getY(), + topLeft.x, + topLeft.y, + topRight.x, + topRight.y, + bottomRight.x, + bottomRight.y, + bottomLeft.x, + bottomLeft.y, ) } /** * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm. */ - fn transitionsBetween(&self, from: &RXingResultPoint, to: &RXingResultPoint) -> u32 { + fn transitionsBetween(&self, from: Point, to: Point) -> u32 { // See QR Code Detector, sizeOfBlackWhiteBlackRun() - let mut fromX = from.getX().floor() as i32; - let mut fromY = from.getY().floor() as i32; - let mut toX = to.getX().floor() as i32; - let mut toY = (self.image.getHeight() - 1).min(to.getY().floor() as u32) as i32; + let mut fromX = from.x.floor() as i32; + let mut fromY = from.y.floor() as i32; + let mut toX = to.x.floor() as i32; + let mut toY = (self.image.getHeight() - 1).min(to.y.floor() as u32) as i32; let steep = (toY - fromY).abs() > (toX - fromX).abs(); if steep { diff --git a/src/datamatrix/detector/datamatrix_result.rs b/src/datamatrix/detector/datamatrix_result.rs index 40811e5..bd2634b 100644 --- a/src/datamatrix/detector/datamatrix_result.rs +++ b/src/datamatrix/detector/datamatrix_result.rs @@ -1,12 +1,12 @@ use crate::{ common::{BitMatrix, DetectorRXingResult}, - RXingResultPoint, + Point, }; -pub struct DatamatrixDetectorResult(BitMatrix, Vec); +pub struct DatamatrixDetectorResult(BitMatrix, Vec); impl DatamatrixDetectorResult { - pub fn new(bits: BitMatrix, points: Vec) -> Self { + pub fn new(bits: BitMatrix, points: Vec) -> Self { Self(bits, points) } } @@ -16,7 +16,7 @@ impl DetectorRXingResult for DatamatrixDetectorResult { &self.0 } - fn getPoints(&self) -> &[RXingResultPoint] { + fn getPoints(&self) -> &[Point] { &self.1 } } diff --git a/src/datamatrix/detector/zxing_cpp_detector/bitmatrix_cursor.rs b/src/datamatrix/detector/zxing_cpp_detector/bitmatrix_cursor.rs index 4c062d9..420eb2f 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/bitmatrix_cursor.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/bitmatrix_cursor.rs @@ -1,4 +1,4 @@ -use crate::RXingResultPoint; +use crate::Point; use super::{util::opposite, Direction, Value}; @@ -16,28 +16,28 @@ pub trait BitMatrixCursor { // BitMatrixCursor(const BitMatrix& image, POINT p, POINT d) : img(&image), p(p) { setDirection(d); } - fn testAt(&self, p: &RXingResultPoint) -> Value; //const - // { - // return img->isIn(p) ? Value{img->get(p)} : Value{}; - // } + fn testAt(&self, p: Point) -> Value; //const + // { + // return img->isIn(p) ? Value{img->get(p)} : Value{}; + // } - fn blackAt(&self, pos: &RXingResultPoint) -> bool { + fn blackAt(&self, pos: Point) -> bool { self.testAt(pos).isBlack() } - fn whiteAt(&self, pos: &RXingResultPoint) -> bool { + fn whiteAt(&self, pos: Point) -> bool { self.testAt(pos).isWhite() } - fn isIn(&self, p: &RXingResultPoint) -> bool; // { return img->isIn(p); } + fn isIn(&self, p: Point) -> bool; // { return img->isIn(p); } fn isInSelf(&self) -> bool; // { return self.isIn(p); } fn isBlack(&self) -> bool; // { return blackAt(p); } fn isWhite(&self) -> bool; // { return whiteAt(p); } - fn front(&self) -> &RXingResultPoint; //{ return d; } - fn back(&self) -> RXingResultPoint; // { return {-d.x, -d.y}; } - fn left(&self) -> RXingResultPoint; //{ return {d.y, -d.x}; } - fn right(&self) -> RXingResultPoint; //{ return {-d.y, d.x}; } - fn direction(&self, dir: Direction) -> RXingResultPoint { + fn front(&self) -> &Point; //{ return d; } + fn back(&self) -> Point; // { return {-d.x, -d.y}; } + fn left(&self) -> Point; //{ return {d.y, -d.x}; } + fn right(&self) -> Point; //{ return {-d.y, d.x}; } + fn direction(&self, dir: Direction) -> Point { self.right() * Into::::into(dir) } @@ -46,30 +46,30 @@ pub trait BitMatrixCursor { fn turnRight(&mut self); //noexcept { d = right(); } fn turn(&mut self, dir: Direction); //noexcept { d = direction(dir); } - fn edgeAt_point(&self, d: &RXingResultPoint) -> Value; + fn edgeAt_point(&self, d: Point) -> Value; // { // Value v = testAt(p); // return testAt(p + d) != v ? v : Value(); // } fn edgeAtFront(&self) -> Value { - return self.edgeAt_point(self.front()); + return self.edgeAt_point(*self.front()); } fn edgeAtBack(&self) -> Value { - self.edgeAt_point(&self.back()) + self.edgeAt_point(self.back()) } fn edgeAtLeft(&self) -> Value { - self.edgeAt_point(&self.left()) + self.edgeAt_point(self.left()) } fn edgeAtRight(&self) -> Value { - self.edgeAt_point(&self.right()) + self.edgeAt_point(self.right()) } fn edgeAt_direction(&self, dir: Direction) -> Value { - self.edgeAt_point(&self.direction(dir)) + self.edgeAt_point(self.direction(dir)) } - fn setDirection(&mut self, dir: &RXingResultPoint); // { d = bresenhamDirection(dir); } - // fn setDirection(&self, dir:&RXingResultPoint);// { d = dir; } + fn setDirection(&mut self, dir: Point); // { d = bresenhamDirection(dir); } + // fn setDirection(&self, dir: Point);// { d = dir; } fn step(&mut self, s: Option) -> bool; // DEF to 1 // { @@ -77,7 +77,7 @@ pub trait BitMatrixCursor { // return isIn(p); // } - fn movedBy(self, d: &RXingResultPoint) -> Self; + fn movedBy(self, d: Point) -> Self; // { // auto res = *this; // res.p += d; 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 045cddd..885a98a 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/cpp_new_detector.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/cpp_new_detector.rs @@ -20,8 +20,7 @@ use crate::{ DatamatrixDetectorResult, }, qrcode::encoder::ByteMatrix, - result_point_utils::distance, - Exceptions, RXingResultPoint, ResultPoint, + Exceptions, Point, }; use super::{DMRegressionLine, EdgeTracer}; @@ -46,10 +45,10 @@ fn Scan( continue; } - let mut tl = RXingResultPoint::default(); - let mut bl = RXingResultPoint::default(); - let mut br = RXingResultPoint::default(); - let mut tr = RXingResultPoint::default(); + let mut tl = Point::default(); + let mut bl = Point::default(); + let mut br = Point::default(); + let mut tr = Point::default(); for l in lines.iter_mut() { l.reset(); @@ -76,7 +75,7 @@ fn Scan( // follow left leg upwards t.turnRight(); t.state = 1; - CHECK!(t.traceLine(&t.right(), lineL)?); + CHECK!(t.traceLine(t.right(), lineL)?); CHECK!(t.traceCorner(&mut t.right(), &mut tl)?); lineL.reverse(); let mut tlTracer = t; @@ -84,34 +83,34 @@ fn Scan( // follow left leg downwards t = startTracer.clone(); t.state = 1; - t.setDirection(&tlTracer.right()); - CHECK!(t.traceLine(&t.left(), lineL)?); + t.setDirection(tlTracer.right()); + CHECK!(t.traceLine(t.left(), lineL)?); if !lineL.isValid() { - t.updateDirectionFromOrigin(&tl); + t.updateDirectionFromOrigin(tl); } let up = t.back(); CHECK!(t.traceCorner(&mut t.left(), &mut bl)?); // follow bottom leg right t.state = 2; - CHECK!(t.traceLine(&t.left(), lineB)?); + CHECK!(t.traceLine(t.left(), lineB)?); if !lineB.isValid() { - t.updateDirectionFromOrigin(&bl); + t.updateDirectionFromOrigin(bl); } let right = *t.front(); CHECK!(t.traceCorner(&mut t.left(), &mut br)?); - let lenL = distance(&tl, &bl) - 1.0; - let lenB = distance(&bl, &br) - 1.0; + let lenL = Point::distance(tl, bl) - 1.0; + let lenB = Point::distance(bl, br) - 1.0; CHECK!(lenL >= 8.0 && lenB >= 10.0 && lenB >= lenL / 4.0 && lenB <= lenL * 18.0); let mut maxStepSize: i32 = (lenB / 5.0 + 1.0) as i32; // datamatrix bottom dim is at least 10 // at this point we found a plausible L-shape and are now looking for the b/w pattern at the top and right: // follow top row right 'half way' (4 gaps), see traceGaps break condition with 'invalid' line - tlTracer.setDirection(&right); + tlTracer.setDirection(right); CHECK!(tlTracer.traceGaps( - &tlTracer.right(), + tlTracer.right(), lineT, maxStepSize, &mut DMRegressionLine::default() @@ -124,13 +123,13 @@ fn Scan( maxStepSize = std::cmp::min(lineT.length() as i32 / 3, (lenL / 5.0) as i32) * 2; // follow up until we reach the top line - t.setDirection(&up); + t.setDirection(up); t.state = 3; - CHECK!(t.traceGaps(&t.left(), lineR, maxStepSize, lineT)?); + CHECK!(t.traceGaps(t.left(), lineR, maxStepSize, lineT)?); CHECK!(t.traceCorner(&mut t.left(), &mut tr)?); - let lenT = distance(&tl, &tr) - 1.0; - let lenR = distance(&tr, &br) - 1.0; + let lenT = Point::distance(tl, tr) - 1.0; + let lenR = Point::distance(tr, br) - 1.0; CHECK!( (lenT - lenB).abs() / lenB < 0.5 @@ -140,7 +139,7 @@ fn Scan( ); // continue top row right until we cross the right line - CHECK!(tlTracer.traceGaps(&tlTracer.right(), lineT, maxStepSize, lineR)?); + CHECK!(tlTracer.traceGaps(tlTracer.right(), lineT, maxStepSize, lineR)?); // #ifdef PRINT_DEBUG // printf("L: %.1f, %.1f ^ %.1f, %.1f > %.1f, %.1f (%d : %d : %d : %d)\n", bl.x, bl.y, @@ -173,8 +172,8 @@ fn Scan( f64::INFINITY }; }; - splitDouble(lineT.modules(&tl, &tr)?, &mut dimT, &mut fracT); - splitDouble(lineR.modules(&br, &tr)?, &mut dimR, &mut fracR); + splitDouble(lineT.modules(tl, tr)?, &mut dimT, &mut fracT); + splitDouble(lineR.modules(br, tr)?, &mut dimR, &mut fracR); // #ifdef PRINT_DEBUG // printf("L: %.1f, %.1f ^ %.1f, %.1f > %.1f, %.1f ^> %.1f, %.1f\n", bl.x, bl.y, @@ -197,24 +196,18 @@ fn Scan( CHECK!((10..=144).contains(&dimT) && (8..=144).contains(&dimR)); - let movedTowardsBy = |a: &RXingResultPoint, - b1: &RXingResultPoint, - b2: &RXingResultPoint, - d: f32| - -> RXingResultPoint { - *a + d * RXingResultPoint::normalized( - RXingResultPoint::normalized(*b1 - *a) + RXingResultPoint::normalized(*b2 - *a), - ) + let movedTowardsBy = |a: Point, b1: Point, b2: Point, d: f32| -> Point { + a + d * Point::normalized(Point::normalized(b1 - a) + Point::normalized(b2 - a)) }; // shrink shape by half a pixel to go from center of white pixel outside of code to the edge between white and black let sourcePoints = Quadrilateral::with_points( - movedTowardsBy(&tl, &tr, &bl, 0.5), + movedTowardsBy(tl, tr, bl, 0.5), // move the tr point a little less because the jagged top and right line tend to be statistically slightly // inclined toward the center anyway. - movedTowardsBy(&tr, &br, &tl, 0.3), - movedTowardsBy(&br, &bl, &tr, 0.5), - movedTowardsBy(&bl, &tl, &br, 0.5), + movedTowardsBy(tr, br, tl, 0.3), + movedTowardsBy(br, bl, tr, 0.5), + movedTowardsBy(bl, tl, br, 0.5), ); let grid_sampler = DefaultGridSampler::default(); @@ -232,14 +225,14 @@ fn Scan( dimR as f32, 0.0, dimR as f32, - sourcePoints.topLeft().getX(), - sourcePoints.topLeft().getY(), - sourcePoints.topRight().getX(), - sourcePoints.topRight().getY(), - sourcePoints.bottomRight().getX(), - sourcePoints.bottomRight().getY(), - sourcePoints.bottomLeft().getX(), - sourcePoints.bottomLeft().getY(), + sourcePoints.topLeft().x, + sourcePoints.topLeft().y, + sourcePoints.topRight().x, + sourcePoints.topRight().y, + sourcePoints.bottomRight().x, + sourcePoints.bottomRight().y, + sourcePoints.bottomLeft().x, + sourcePoints.bottomLeft().y, ); // let res = grid_sampler.sample_grid(startTracer.img, dimT as u32, dimR as u32, &transform); @@ -292,18 +285,17 @@ pub fn detect( const MIN_SYMBOL_SIZE: u32 = 8 * 2; // minimum realistic size in pixel: 8 modules x 2 pixels per module for dir in [ - RXingResultPoint { x: -1.0, y: 0.0 }, - RXingResultPoint { x: 1.0, y: 0.0 }, - RXingResultPoint { x: 0.0, y: -1.0 }, - RXingResultPoint { x: 0.0, y: 1.0 }, + Point { x: -1.0, y: 0.0 }, + Point { x: 1.0, y: 0.0 }, + Point { x: 0.0, y: -1.0 }, + Point { x: 0.0, y: 1.0 }, ] { // for (auto dir : {PointF(-1, 0), PointF(1, 0), PointF(0, -1), PointF(0, 1)}) { - let center = RXingResultPoint { + let center = Point { x: (image.getWidth() / 2) as f32, y: (image.getHeight() / 2) as f32, }; //PointF(image.width() / 2, image.height() / 2); - let startPos = - RXingResultPoint::centered(&(center - center * dir + MIN_SYMBOL_SIZE as i32 / 2 * dir)); + let startPos = Point::centered(center - center * dir + MIN_SYMBOL_SIZE as i32 / 2 * dir); if let Some(history) = &mut history { history.borrow_mut().clear(0); diff --git a/src/datamatrix/detector/zxing_cpp_detector/dm_regression_line.rs b/src/datamatrix/detector/zxing_cpp_detector/dm_regression_line.rs index 1f6a9f3..0f0c375 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/dm_regression_line.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/dm_regression_line.rs @@ -1,5 +1,5 @@ use crate::common::Result; -use crate::{Exceptions, RXingResultPoint}; +use crate::{Exceptions, Point}; use super::{ util::{float_max, float_min}, @@ -8,8 +8,8 @@ use super::{ #[derive(Clone)] pub struct DMRegressionLine { - points: Vec, - direction_inward: RXingResultPoint, + points: Vec, + direction_inward: Point, pub(super) a: f32, pub(super) b: f32, pub(super) c: f32, @@ -31,14 +31,13 @@ impl Default for DMRegressionLine { } impl RegressionLine for DMRegressionLine { - fn points(&self) -> &[RXingResultPoint] { + fn points(&self) -> &[Point] { &self.points } fn length(&self) -> u32 { if self.points.len() >= 2 { - RXingResultPoint::distance(*self.points.first().unwrap(), *self.points.last().unwrap()) - as u32 + Point::distance(*self.points.first().unwrap(), *self.points.last().unwrap()) as u32 } else { 0 } @@ -48,9 +47,9 @@ impl RegressionLine for DMRegressionLine { !self.a.is_nan() } - fn normal(&self) -> RXingResultPoint { + fn normal(&self) -> Point { if self.isValid() { - RXingResultPoint { + Point { x: self.a, y: self.b, } @@ -59,29 +58,29 @@ impl RegressionLine for DMRegressionLine { } } - fn signedDistance(&self, p: &RXingResultPoint) -> f32 { - RXingResultPoint::dot(self.normal(), *p) - self.c + fn signedDistance(&self, p: Point) -> f32 { + Point::dot(self.normal(), p) - self.c } - fn distance_single(&self, p: &RXingResultPoint) -> f32 { + fn distance_single(&self, p: Point) -> f32 { (self.signedDistance(p)).abs() } fn reset(&mut self) { self.points.clear(); - self.direction_inward = RXingResultPoint { x: 0.0, y: 0.0 }; + self.direction_inward = Point { x: 0.0, y: 0.0 }; self.a = f32::NAN; self.b = f32::NAN; self.c = f32::NAN; } - fn add(&mut self, p: &RXingResultPoint) -> Result<()> { - if self.direction_inward == RXingResultPoint::default() { + fn add(&mut self, p: Point) -> Result<()> { + if self.direction_inward == Point::default() { return Err(Exceptions::illegalState); } - self.points.push(*p); + self.points.push(p); if self.points.len() == 1 { - self.c = RXingResultPoint::dot(self.normal(), *p); + self.c = Point::dot(self.normal(), p); } Ok(()) } @@ -90,8 +89,8 @@ impl RegressionLine for DMRegressionLine { self.points.pop(); } - fn setDirectionInward(&mut self, d: &RXingResultPoint) { - self.direction_inward = RXingResultPoint::normalized(*d); + fn setDirectionInward(&mut self, d: Point) { + self.direction_inward = Point::normalized(d); } fn evaluate_max_distance( @@ -113,7 +112,7 @@ impl RegressionLine for DMRegressionLine { // return sd > maxSignedDist || sd < -2 * maxSignedDist; // }); // points.erase(end, points.end()); - points.retain(|p| { + points.retain(|&p| { let sd = self.signedDistance(p) as f64; !(sd > maxSignedDist || sd < -2.0 * maxSignedDist) }); @@ -143,14 +142,14 @@ impl RegressionLine for DMRegressionLine { max.y = float_max(max.y, p.y); } let diff = max - min; - let len = RXingResultPoint::maxAbsComponent(&diff); - let steps = float_min((diff.x).abs(), (diff.y).abs()); + let len = diff.maxAbsComponent(); + let steps = float_min(diff.x.abs(), diff.y.abs()); // due to aliasing we get bad extrapolations if the line is short and too close to vertical/horizontal steps > 2.0 || len > 50.0 } - fn evaluate(&mut self, points: &[RXingResultPoint]) -> bool { - let mean = points.iter().sum::() / points.len() as f32; + fn evaluate(&mut self, points: &[Point]) -> bool { + let mean = points.iter().sum::() / points.len() as f32; let mut sumXX = 0.0; let mut sumYY = 0.0; @@ -171,18 +170,18 @@ impl RegressionLine for DMRegressionLine { self.a = sumXY / l; self.b = -sumXX / l; } - if RXingResultPoint::dot(self.direction_inward, self.normal()) < 0.0 { + if Point::dot(self.direction_inward, self.normal()) < 0.0 { // if (dot(_directionInward, normal()) < 0) { self.a = -self.a; self.b = -self.b; } - self.c = RXingResultPoint::dot(self.normal(), mean); // (a*mean.x + b*mean.y); - RXingResultPoint::dot(self.direction_inward, self.normal()) > 0.5 + self.c = Point::dot(self.normal(), mean); // (a*mean.x + b*mean.y); + Point::dot(self.direction_inward, self.normal()) > 0.5 // angle between original and new direction is at most 60 degree } fn evaluateSelf(&mut self) -> bool { - let mean = self.points.iter().sum::() / self.points.len() as f32; + let mean = self.points.iter().sum::() / self.points.len() as f32; let mut sumXX = 0.0; let mut sumYY = 0.0; @@ -203,13 +202,13 @@ impl RegressionLine for DMRegressionLine { self.a = sumXY / l; self.b = -sumXX / l; } - if RXingResultPoint::dot(self.direction_inward, self.normal()) < 0.0 { + if Point::dot(self.direction_inward, self.normal()) < 0.0 { // if (dot(_directionInward, normal()) < 0) { self.a = -self.a; self.b = -self.b; } - self.c = RXingResultPoint::dot(self.normal(), mean); // (a*mean.x + b*mean.y); - RXingResultPoint::dot(self.direction_inward, self.normal()) > 0.5 + self.c = Point::dot(self.normal(), mean); // (a*mean.x + b*mean.y); + Point::dot(self.direction_inward, self.normal()) > 0.5 // angle between original and new direction is at most 60 degree } } @@ -236,7 +235,7 @@ impl DMRegressionLine { self.points.reverse(); } - pub fn modules(&mut self, beg: &RXingResultPoint, end: &RXingResultPoint) -> Result { + pub fn modules(&mut self, beg: Point, end: Point) -> Result { if self.points.len() <= 3 { return Err(Exceptions::illegalState); } @@ -253,21 +252,28 @@ impl DMRegressionLine { // calculate the distance between the points projected onto the regression line for i in 1..self.points.len() { // for (size_t i = 1; i < _points.size(); ++i) - gapSizes.push(self.distance( - &self.project(&self.points[i]), - &self.project(&self.points[i - 1]), + gapSizes.push(Point::distance( + self.project(self.points[i]), + self.project(self.points[i - 1]), ) as f64); } // calculate the (expected average) distance of two adjacent pixels - let unitPixelDist = RXingResultPoint::length(RXingResultPoint::bresenhamDirection( - &(*self.points.last().ok_or(Exceptions::indexOutOfBounds)? - - *self.points.first().ok_or(Exceptions::indexOutOfBounds)?), + let unitPixelDist = Point::length(Point::bresenhamDirection( + self.points + .last() + .copied() + .ok_or(Exceptions::indexOutOfBounds)? + - self + .points + .first() + .copied() + .ok_or(Exceptions::indexOutOfBounds)?, )) as f64; // calculate the width of 2 modules (first black pixel to first black pixel) let mut sumFront: f64 = - self.distance(beg, &self.project(&self.points[0])) as f64 - unitPixelDist; + Point::distance(beg, self.project(self.points[0])) as f64 - unitPixelDist; let mut sumBack: f64 = 0.0; // (last black pixel to last black pixel) for dist in gapSizes { // for (auto dist : gapSizes) { @@ -283,13 +289,18 @@ impl DMRegressionLine { modSizes.push( sumFront - + self.distance( + + Point::distance( end, - &self.project(self.points.last().ok_or(Exceptions::indexOutOfBounds)?), + self.project( + self.points + .last() + .copied() + .ok_or(Exceptions::indexOutOfBounds)?, + ), ) as f64, ); modSizes[0] = 0.0; // the first element is an invalid sumBack value, would be pop_front() if vector supported this - let lineLength = self.distance(beg, end) as f64 - unitPixelDist; + let lineLength = Point::distance(beg, end) as f64 - unitPixelDist; let mut meanModSize = Self::average(&modSizes, |_: f64| true); // let meanModSize = average(modSizes, [](double){ return true; }); // #ifdef PRINT_DEBUG diff --git a/src/datamatrix/detector/zxing_cpp_detector/edge_tracer.rs b/src/datamatrix/detector/zxing_cpp_detector/edge_tracer.rs index ffbd1bd..f709e1a 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/edge_tracer.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/edge_tracer.rs @@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc}; use crate::{ common::{BitMatrix, Result}, qrcode::encoder::ByteMatrix, - Exceptions, RXingResultPoint, + Exceptions, Point, }; use super::{BitMatrixCursor, Direction, RegressionLine, StepResult, Value}; @@ -12,8 +12,8 @@ use super::{BitMatrixCursor, Direction, RegressionLine, StepResult, Value}; pub struct EdgeTracer<'a> { pub(super) img: &'a BitMatrix, - pub(super) p: RXingResultPoint, // current position - d: RXingResultPoint, // current direction + pub(super) p: Point, // current position + d: Point, // current direction // pub history: Option<&'a mut ByteMatrix>, // = nullptr; pub history: Option>>, @@ -35,7 +35,7 @@ pub struct EdgeTracer<'a> { // } impl BitMatrixCursor for EdgeTracer<'_> { - fn testAt(&self, p: &RXingResultPoint) -> Value { + fn testAt(&self, p: Point) -> Value { if self.img.isIn(p, 0) { Value::from(self.img.get_point(p)) } else { @@ -43,42 +43,42 @@ impl BitMatrixCursor for EdgeTracer<'_> { } } - fn isIn(&self, p: &RXingResultPoint) -> bool { + fn isIn(&self, p: Point) -> bool { self.img.isIn(p, 0) } fn isInSelf(&self) -> bool { - self.isIn(&self.p) + self.isIn(self.p) } fn isBlack(&self) -> bool { - self.blackAt(&self.p) + self.blackAt(self.p) } fn isWhite(&self) -> bool { - self.whiteAt(&self.p) + self.whiteAt(self.p) } - fn front(&self) -> &RXingResultPoint { + fn front(&self) -> &Point { &self.d } - fn back(&self) -> RXingResultPoint { - RXingResultPoint { + fn back(&self) -> Point { + Point { x: -self.d.x, y: -self.d.y, } } - fn left(&self) -> RXingResultPoint { - RXingResultPoint { + fn left(&self) -> Point { + Point { x: self.d.y, y: -self.d.x, } } - fn right(&self) -> RXingResultPoint { - RXingResultPoint { + fn right(&self) -> Point { + Point { x: -self.d.y, y: self.d.x, } @@ -100,28 +100,28 @@ impl BitMatrixCursor for EdgeTracer<'_> { self.d = self.direction(dir) } - fn edgeAt_point(&self, d: &RXingResultPoint) -> Value { - let v = self.testAt(&self.p); - if self.testAt(&(self.p + *d)) != v { + fn edgeAt_point(&self, d: Point) -> Value { + let v = self.testAt(self.p); + if self.testAt(self.p + d) != v { v } else { Value::Invalid } } - fn setDirection(&mut self, dir: &RXingResultPoint) { - self.d = RXingResultPoint::bresenhamDirection(dir) + fn setDirection(&mut self, dir: Point) { + self.d = dir.bresenhamDirection(); } fn step(&mut self, s: Option) -> bool { let s = if let Some(s) = s { s } else { 1.0 }; self.p += self.d * s; - self.isIn(&self.p) + self.isIn(self.p) } - fn movedBy(self, d: &RXingResultPoint) -> Self { + fn movedBy(self, d: Point) -> Self { let mut res = self; - res.p += *d; + res.p += d; res } @@ -139,11 +139,11 @@ impl BitMatrixCursor for EdgeTracer<'_> { let backup = if let Some(b) = backup { b } else { false }; // TODO: provide an alternative and faster out-of-bounds check than isIn() inside testAt() let mut steps = 0; - let mut lv = self.testAt(&self.p); + let mut lv = self.testAt(self.p); while nth > 0 && (range <= 0 || steps < range) && lv.isValid() { steps += 1; - let v = self.testAt(&(self.p + steps * self.d)); + let v = self.testAt(self.p + steps * self.d); if lv != v { lv = v; nth -= 1; @@ -158,7 +158,7 @@ impl BitMatrixCursor for EdgeTracer<'_> { } impl<'a> EdgeTracer<'_> { - pub fn new(image: &'a BitMatrix, p: RXingResultPoint, d: RXingResultPoint) -> EdgeTracer<'a> { + pub fn new(image: &'a BitMatrix, p: Point, d: Point) -> EdgeTracer<'a> { // : img(&image), p(p) { setDirection(d); } EdgeTracer { img: image, @@ -171,11 +171,11 @@ impl<'a> EdgeTracer<'_> { fn traceStep( &mut self, - dEdge: &RXingResultPoint, + dEdge: Point, maxStepSize: i32, goodDirection: bool, ) -> Result { - let dEdge = RXingResultPoint::mainDirection(*dEdge); + let dEdge = Point::mainDirection(dEdge); for breadth in 1..=(if maxStepSize == 1 { 2 } else if goodDirection { @@ -193,19 +193,19 @@ impl<'a> EdgeTracer<'_> { + (if i & 1 > 0 { (i + 1) / 2 } else { -i / 2 }) * dEdge; // dbg!(pEdge); - if !self.blackAt(&(pEdge + dEdge)) { + if !self.blackAt(pEdge + dEdge) { continue; } // found black pixel -> go 'outward' until we hit the b/w border for _j in 0..(std::cmp::max(maxStepSize, 3)) { // for (int j = 0; j < std::max(maxStepSize, 3) && isIn(pEdge); ++j) { - if self.whiteAt(&pEdge) { + if self.whiteAt(pEdge) { // if we are not making any progress, we still have another endless loop bug - if self.p == RXingResultPoint::centered(&pEdge) { + if self.p == pEdge.centered() { return Err(Exceptions::illegalState); } - self.p = RXingResultPoint::centered(&pEdge); + self.p = pEdge.centered(); // if (self.history && maxStepSize == 1) { if let Some(history) = &self.history { @@ -226,12 +226,12 @@ impl<'a> EdgeTracer<'_> { return Ok(StepResult::Found); } pEdge = pEdge - dEdge; - if self.blackAt(&(pEdge - self.d)) { + if self.blackAt(pEdge - self.d) { pEdge = pEdge - self.d; } // dbg!(pEdge); - if !self.isIn(&pEdge) { + if !self.isIn(pEdge) { break; } } @@ -243,45 +243,38 @@ impl<'a> EdgeTracer<'_> { Ok(StepResult::OpenEnd) } - pub fn updateDirectionFromOrigin(&mut self, origin: &RXingResultPoint) -> bool { + pub fn updateDirectionFromOrigin(&mut self, origin: Point) -> bool { let old_d = self.d; - self.setDirection(&(self.p - origin)); + self.setDirection(self.p - origin); // if the new direction is pointing "backward", i.e. angle(new, old) > 90 deg -> break - if RXingResultPoint::dot(self.d, old_d) < 0.0 { + if Point::dot(self.d, old_d) < 0.0 { return false; } // make sure d stays in the same quadrant to prevent an infinite loop if (self.d.x).abs() == (self.d.y).abs() { - self.d = RXingResultPoint::mainDirection(old_d) - + 0.99 * (self.d - RXingResultPoint::mainDirection(old_d)); - } else if RXingResultPoint::mainDirection(self.d) != RXingResultPoint::mainDirection(old_d) - { - self.d = RXingResultPoint::mainDirection(old_d) - + 0.99 * RXingResultPoint::mainDirection(self.d); + self.d = Point::mainDirection(old_d) + 0.99 * (self.d - Point::mainDirection(old_d)); + } else if Point::mainDirection(self.d) != Point::mainDirection(old_d) { + self.d = Point::mainDirection(old_d) + 0.99 * Point::mainDirection(self.d); } true } - pub fn traceLine( - &mut self, - dEdge: &RXingResultPoint, - line: &mut T, - ) -> Result { + pub fn traceLine(&mut self, dEdge: Point, line: &mut T) -> Result { line.setDirectionInward(dEdge); loop { // log(self.p); - line.add(&self.p)?; + line.add(self.p)?; if line.points().len() % 50 == 10 { if !line.evaluate_max_distance(None, None) { return Ok(false); } if !self.updateDirectionFromOrigin( - &(self.p - line.project(&self.p) + self.p - line.project(self.p) + **line .points() .first() .as_ref() - .ok_or(Exceptions::indexOutOfBounds)?), + .ok_or(Exceptions::indexOutOfBounds)?, ) { return Ok(false); } @@ -295,7 +288,7 @@ impl<'a> EdgeTracer<'_> { pub fn traceGaps( &mut self, - dEdge: &RXingResultPoint, + dEdge: Point, line: &mut T, maxStepSize: i32, finishLine: &mut T, @@ -329,21 +322,19 @@ impl<'a> EdgeTracer<'_> { // if we drifted too far outside of the code, break if line.isValid() - && line.signedDistance(&self.p) < -5.0 - && (!line.evaluate_max_distance(None, None) || line.signedDistance(&self.p) < -5.0) + && line.signedDistance(self.p) < -5.0 + && (!line.evaluate_max_distance(None, None) || line.signedDistance(self.p) < -5.0) { return Ok(false); } // if we are drifting towards the inside of the code, pull the current position back out onto the line - if line.isValid() && line.signedDistance(&self.p) > 3.0 { + if line.isValid() && line.signedDistance(self.p) > 3.0 { // The current direction d and the line we are tracing are supposed to be roughly parallel. // In case the 'go outward' step in traceStep lead us astray, we might end up with a line // that is almost perpendicular to d. Then the back-projection below can result in an // endless loop. Break if the angle between d and line is greater than 45 deg. - if (RXingResultPoint::dot(RXingResultPoint::normalized(self.d), line.normal())) - .abs() - > 0.7 + if (Point::dot(Point::normalized(self.d), line.normal())).abs() > 0.7 // thresh is approx. sin(45 deg) { return Ok(false); @@ -354,36 +345,41 @@ impl<'a> EdgeTracer<'_> { return Ok(false); } - let mut np = line.project(&self.p); + let mut np = line.project(self.p); // make sure we are making progress even when back-projecting: // consider a 90deg corner, rotated 45deg. we step away perpendicular from the line and get // back projected where we left off the line. // The 'while' instead of 'if' was introduced to fix the issue with #245. It turns out that // np can actually be behind the projection of the last line point and we need 2 steps in d // to prevent a dead lock. see #245.png - while RXingResultPoint::distance( + while Point::distance( np, line.project( line.points() .last() - .as_ref() + .copied() .ok_or(Exceptions::indexOutOfBounds)?, ), ) < 1.0 { np += self.d; } - self.p = RXingResultPoint::centered(&np); + self.p = Point::centered(np); } else { let stepLengthInMainDir = if line.points().is_empty() { 0.0 } else { - RXingResultPoint::dot( - RXingResultPoint::mainDirection(self.d), - self.p - line.points().last().ok_or(Exceptions::indexOutOfBounds)?, + Point::dot( + Point::mainDirection(self.d), + self.p + - line + .points() + .last() + .copied() + .ok_or(Exceptions::indexOutOfBounds)?, ) }; - line.add(&self.p)?; + line.add(self.p)?; if stepLengthInMainDir > 1.0 { gaps += 1; @@ -392,8 +388,12 @@ impl<'a> EdgeTracer<'_> { return Ok(false); } if !self.updateDirectionFromOrigin( - &(self.p - line.project(&self.p) - + *line.points().first().ok_or(Exceptions::indexOutOfBounds)?), + self.p - line.project(self.p) + + line + .points() + .first() + .copied() + .ok_or(Exceptions::indexOutOfBounds)?, ) { return Ok(false); } @@ -415,7 +415,7 @@ impl<'a> EdgeTracer<'_> { if finishLine.isValid() { maxStepSize = - std::cmp::min(maxStepSize, (finishLine.signedDistance(&self.p)) as i32); + std::cmp::min(maxStepSize, (finishLine.signedDistance(self.p)) as i32); } let stepResult = self.traceStep(dEdge, maxStepSize, line.isValid())?; @@ -425,24 +425,20 @@ impl<'a> EdgeTracer<'_> { { return Ok(stepResult == StepResult::OpenEnd && finishLine.isValid() - && (finishLine.signedDistance(&self.p)) as i32 <= maxStepSize + 1); + && (finishLine.signedDistance(self.p)) as i32 <= maxStepSize + 1); } } //while (true); } - pub fn traceCorner( - &mut self, - dir: &mut RXingResultPoint, - corner: &mut RXingResultPoint, - ) -> Result { + pub fn traceCorner(&mut self, dir: &mut Point, corner: &mut Point) -> Result { self.step(None); // log(p); *corner = self.p; std::mem::swap(&mut self.d, dir); - self.traceStep(&(-1.0 * dir), 2, false)?; + self.traceStep(-1.0 * (*dir), 2, false)?; // #ifdef PRINT_DEBUG // printf("turn: %.0f x %.0f -> %.2f, %.2f\n", p.x, p.y, d.x, d.y); // #endif - Ok(self.isIn(corner) && self.isIn(&self.p)) + Ok(self.isIn(*corner) && self.isIn(self.p)) } } diff --git a/src/datamatrix/detector/zxing_cpp_detector/quad.rs b/src/datamatrix/detector/zxing_cpp_detector/quad.rs index 99dcc2e..7e5578e 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/quad.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/quad.rs @@ -1,7 +1,7 @@ -use crate::RXingResultPoint; +use crate::Point; #[derive(Clone, Debug)] -pub struct Quadrilateral([RXingResultPoint; 4]); +pub struct Quadrilateral([Point; 4]); impl Quadrilateral { // using Base = std::array; @@ -11,31 +11,26 @@ impl Quadrilateral { #[allow(dead_code)] pub fn new() -> Self { - Self([RXingResultPoint { x: 0.0, y: 0.0 }; 4]) + Self([Point { x: 0.0, y: 0.0 }; 4]) } // pub fn with_f32( tl:f32, tr:f32, br:f32, bl:f32) -> Self { // Self([tl, tr,br, bl ]) // } - pub fn with_points( - tl: RXingResultPoint, - tr: RXingResultPoint, - br: RXingResultPoint, - bl: RXingResultPoint, - ) -> Self { + pub fn with_points(tl: Point, tr: Point, br: Point, bl: Point) -> Self { Self([tl, tr, br, bl]) } - pub fn topLeft(&self) -> &RXingResultPoint { + pub fn topLeft(&self) -> &Point { &self.0[0] } //const noexcept { return at(0); } - pub fn topRight(&self) -> &RXingResultPoint { + pub fn topRight(&self) -> &Point { &self.0[1] } //const noexcept { return at(1); } - pub fn bottomRight(&self) -> &RXingResultPoint { + pub fn bottomRight(&self) -> &Point { &self.0[2] } //const noexcept { return at(2); } - pub fn bottomLeft(&self) -> &RXingResultPoint { + pub fn bottomLeft(&self) -> &Point { &self.0[3] } //const noexcept { return at(3); } @@ -43,13 +38,13 @@ impl Quadrilateral { pub fn orientation(&self) -> f64 { let centerLine = (*self.topRight() + *self.bottomRight()) - (*self.topLeft() + *self.bottomLeft()); - if (centerLine == RXingResultPoint { x: 0.0, y: 0.0 }) { + if (centerLine == Point { x: 0.0, y: 0.0 }) { return 0.0; } - let centerLineF = RXingResultPoint::normalized(centerLine); + let centerLineF = Point::normalized(centerLine); f32::atan2(centerLineF.y, centerLineF.x).into() } - pub fn points(&self) -> &[RXingResultPoint] { + pub fn points(&self) -> &[Point] { &self.0 } } @@ -59,19 +54,19 @@ pub fn Rectangle(width: i32, height: i32, margin: Option) -> Quadrilateral let margin = if let Some(m) = margin { m } else { 0 }; Quadrilateral([ - RXingResultPoint { + Point { x: margin as f32, y: margin as f32, }, - RXingResultPoint { + Point { x: width as f32 - margin as f32, y: margin as f32, }, - RXingResultPoint { + Point { x: width as f32 - margin as f32, y: height as f32 - margin as f32, }, - RXingResultPoint { + Point { x: margin as f32, y: height as f32 - margin as f32, }, @@ -82,10 +77,10 @@ pub fn Rectangle(width: i32, height: i32, margin: Option) -> Quadrilateral pub fn CenteredSquare(size: i32) -> Quadrilateral { Scale( &Quadrilateral([ - RXingResultPoint { x: -1.0, y: -1.0 }, - RXingResultPoint { x: 1.0, y: -1.0 }, - RXingResultPoint { x: 1.0, y: 1.0 }, - RXingResultPoint { x: -1.0, y: 1.0 }, + Point { x: -1.0, y: -1.0 }, + Point { x: 1.0, y: -1.0 }, + Point { x: 1.0, y: 1.0 }, + Point { x: -1.0, y: 1.0 }, ]), size / 2, ) @@ -94,19 +89,19 @@ pub fn CenteredSquare(size: i32) -> Quadrilateral { #[allow(dead_code)] pub fn Line(y: i32, xStart: i32, xStop: i32) -> Quadrilateral { Quadrilateral([ - RXingResultPoint { + Point { x: xStart as f32, y: y as f32, }, - RXingResultPoint { + Point { x: xStop as f32, y: y as f32, }, - RXingResultPoint { + Point { x: xStop as f32, y: y as f32, }, - RXingResultPoint { + Point { x: xStart as f32, y: y as f32, }, @@ -126,7 +121,7 @@ pub fn IsConvex(poly: &Quadrilateral) -> bool { { let d1 = poly.0[(i + 2) % N] - poly.0[(i + 1) % N]; let d2 = poly.0[i] - poly.0[(i + 1) % N]; - let cp = RXingResultPoint::cross(&d1, &d2); + let cp = d1.cross(d2); m = if m.abs() > cp { cp } else { m.abs() }; @@ -162,8 +157,8 @@ pub fn Scale(q: &Quadrilateral, factor: i32) -> Quadrilateral { } #[allow(dead_code)] -pub fn Center(q: &Quadrilateral) -> RXingResultPoint { - let reduced: RXingResultPoint = q.0.iter().sum(); +pub fn Center(q: &Quadrilateral) -> Point { + let reduced: Point = q.0.iter().sum(); let size = q.0.len() as f32; reduced / size // return Reduce(q) / Size(q); @@ -186,14 +181,14 @@ pub fn RotatedCorners(q: &Quadrilateral, n: Option, mirror: Option) - } #[allow(dead_code)] -pub fn IsInside(p: &RXingResultPoint, q: &Quadrilateral) -> bool { +pub fn IsInside(p: Point, q: &Quadrilateral) -> bool { // Test if p is on the same side (right or left) of all polygon segments let mut pos = 0; let mut neg = 0; for i in 0..q.0.len() // for (int i = 0; i < Size(q); ++i) { - if RXingResultPoint::cross(&(*p - q.0[i]), &(q.0[(i + 1) % q.0.len()] - q.0[i])) < 0.0 { + if Point::cross(p - q.0[i], q.0[(i + 1) % q.0.len()] - q.0[i]) < 0.0 { neg += 1; } else { pos += 1; diff --git a/src/datamatrix/detector/zxing_cpp_detector/regression_line.rs b/src/datamatrix/detector/zxing_cpp_detector/regression_line.rs index f0f5ab5..a9ccd90 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/regression_line.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/regression_line.rs @@ -1,9 +1,9 @@ use crate::common::Result; -use crate::RXingResultPoint; +use crate::Point; pub trait RegressionLine { - // points: Vec, - // direction_inward: RXingResultPoint, + // points: Vec, + // direction_inward: Point, // } // impl RegressionLine { @@ -12,9 +12,9 @@ pub trait RegressionLine { // PointF::value_t a = NAN, b = NAN, c = NAN; // fn intersect(&self, l1: &T, l2: &T2) - // -> RXingResultPoint; + // -> Point; - // fn evaluate_begin_end(&self, begin:&RXingResultPoint, end:&RXingResultPoint) -> bool;// { + // fn evaluate_begin_end(&self, begin: Point, end: Point) -> bool;// { // { // let mean = std::accumulate(begin, end, PointF()) / std::distance(begin, end); // PointF::value_t sumXX = 0, sumYY = 0, sumXY = 0; @@ -41,13 +41,9 @@ pub trait RegressionLine { // return dot(_directionInward, normal()) > 0.5f; // angle between original and new direction is at most 60 degree // } - fn evaluate(&mut self, points: &[RXingResultPoint]) -> bool; // { return self.evaluate_begin_end(&points.front(), &points.back() + 1); } + fn evaluate(&mut self, points: &[Point]) -> bool; // { return self.evaluate_begin_end(&points.front(), &points.back() + 1); } fn evaluateSelf(&mut self) -> bool; - fn distance(&self, a: &RXingResultPoint, b: &RXingResultPoint) -> f32 { - crate::result_point_utils::distance(a, b) - } - // RegressionLine() { _points.reserve(16); } // arbitrary but plausible start size (tiny performance improvement) // template RegressionLine(PointT a, PointT b) @@ -60,14 +56,14 @@ pub trait RegressionLine { // evaluate(b, e); // } - fn points(&self) -> &[RXingResultPoint]; //const { return _points; } + fn points(&self) -> &[Point]; //const { return _points; } fn length(&self) -> u32; //const { return _points.size() >= 2 ? int(distance(_points.front(), _points.back())) : 0; } fn isValid(&self) -> bool; //const { return !std::isnan(a); } - fn normal(&self) -> RXingResultPoint; //const { return isValid() ? PointF(a, b) : _directionInward; } - fn signedDistance(&self, p: &RXingResultPoint) -> f32; //const { return dot(normal(), p) - c; } - fn distance_single(&self, p: &RXingResultPoint) -> f32; //const { return std::abs(signedDistance(PointF(p))); } - fn project(&self, p: &RXingResultPoint) -> RXingResultPoint { - *p - self.normal() * self.signedDistance(p) + fn normal(&self) -> Point; //const { return isValid() ? PointF(a, b) : _directionInward; } + fn signedDistance(&self, p: Point) -> f32; //const { return dot(normal(), p) - c; } + fn distance_single(&self, p: Point) -> f32; //const { return std::abs(signedDistance(PointF(p))); } + fn project(&self, p: Point) -> Point { + p - self.normal() * self.signedDistance(p) } fn reset(&mut self); @@ -77,16 +73,16 @@ pub trait RegressionLine { // a = b = c = NAN; // } - fn add(&mut self, p: &RXingResultPoint) -> Result<()>; //{ - // assert(_directionInward != PointF()); - // _points.push_back(p); - // if (_points.size() == 1) - // c = dot(normal(), p); - // } + fn add(&mut self, p: Point) -> Result<()>; //{ + // assert(_directionInward != PointF()); + // _points.push_back(p); + // if (_points.size() == 1) + // c = dot(normal(), p); + // } fn pop_back(&mut self); // { _points.pop_back(); } - fn setDirectionInward(&mut self, d: &RXingResultPoint); //{ _directionInward = normalized(d); } + fn setDirectionInward(&mut self, d: Point); //{ _directionInward = normalized(d); } // fn evaluate(&self, double maxSignedDist = -1, bool updatePoints = false) -> bool fn evaluate_max_distance( diff --git a/src/datamatrix/detector/zxing_cpp_detector/util.rs b/src/datamatrix/detector/zxing_cpp_detector/util.rs index 4f7be1b..28380cb 100644 --- a/src/datamatrix/detector/zxing_cpp_detector/util.rs +++ b/src/datamatrix/detector/zxing_cpp_detector/util.rs @@ -1,5 +1,5 @@ use crate::common::Result; -use crate::{Exceptions, RXingResultPoint}; +use crate::{Exceptions, Point}; use super::{DMRegressionLine, Direction, RegressionLine}; @@ -22,14 +22,14 @@ pub fn float_max(a: T, b: T) -> T { } #[inline(always)] -pub fn intersect(l1: &DMRegressionLine, l2: &DMRegressionLine) -> Result { +pub fn intersect(l1: &DMRegressionLine, l2: &DMRegressionLine) -> Result { if !(l1.isValid() && l2.isValid()) { return Err(Exceptions::illegalState); } let d = l1.a * l2.b - l1.b * l2.a; let x = (l1.c * l2.b - l1.b * l2.c) / d; let y = (l1.a * l2.c - l1.c * l2.a) / d; - Ok(RXingResultPoint { x, y }) + Ok(Point { x, y }) } #[allow(dead_code)] diff --git a/src/decode_hints.rs b/src/decode_hints.rs index 53649a4..dbc2885 100644 --- a/src/decode_hints.rs +++ b/src/decode_hints.rs @@ -18,7 +18,7 @@ use std::collections::HashSet; -use crate::{BarcodeFormat, RXingResultPointCallback}; +use crate::{BarcodeFormat, PointCallback}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -89,8 +89,8 @@ pub enum DecodeHintType { RETURN_CODABAR_START_END, /** - * The caller needs to be notified via callback when a possible {@link RXingResultPoint} - * is found. Maps to a {@link RXingResultPointCallback}. + * The caller needs to be notified via callback when a possible {@link Point} + * is found. Maps to a {@link PointCallback}. */ NEED_RESULT_POINT_CALLBACK, @@ -198,11 +198,11 @@ pub enum DecodeHintValue { ReturnCodabarStartEnd(bool), /** - * The caller needs to be notified via callback when a possible {@link RXingResultPoint} - * is found. Maps to a {@link RXingResultPointCallback}. + * The caller needs to be notified via callback when a possible {@link Point} + * is found. Maps to a {@link PointCallback}. */ #[cfg_attr(feature = "serde", serde(skip_serializing, skip_deserializing))] - NeedResultPointCallback(RXingResultPointCallback), + NeedResultPointCallback(PointCallback), /** * Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this. diff --git a/src/lib.rs b/src/lib.rs index c2b5cf4..dd88971 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,10 @@ pub use encode_hints::*; /// Callback which is invoked when a possible result point (significant /// point in the barcode image such as a corner) is found. -pub type RXingResultPointCallback = Rc; +pub type PointCallback = Rc; + +/** Temporary type to ease refactoring and keep backwards-compatibility */ +pub type RXingResultPointCallback = PointCallback; mod decode_hints; pub use decode_hints::*; diff --git a/src/maxicode/detector.rs b/src/maxicode/detector.rs index 75f3e4d..d0bfc0d 100644 --- a/src/maxicode/detector.rs +++ b/src/maxicode/detector.rs @@ -2,11 +2,8 @@ use num::integer::Roots; use crate::{ - common::{ - detector::MathUtils, BitMatrix, DefaultGridSampler, DetectorRXingResult, GridSampler, - Result, - }, - Exceptions, RXingResultPoint, + common::{BitMatrix, DefaultGridSampler, DetectorRXingResult, GridSampler, Result}, + point, Exceptions, Point, }; use super::MaxiCodeReader; @@ -16,7 +13,7 @@ const ROW_SCAN_SKIP: u32 = 2; #[derive(Debug)] pub struct MaxicodeDetectionResult { bits: BitMatrix, - points: Vec, + points: Vec, rotation: f32, } @@ -31,7 +28,7 @@ impl DetectorRXingResult for MaxicodeDetectionResult { &self.bits } - fn getPoints(&self) -> &[RXingResultPoint] { + fn getPoints(&self) -> &[Point] { &self.points } } @@ -349,8 +346,8 @@ pub fn detect(image: &BitMatrix, try_harder: bool) -> Result Result Result<([(f32, f32); 4] calculate_simple_boundary(circle, Some(image), None, false); let naive_box = [ - RXingResultPoint::new(left_boundary as f32, bottom_boundary as f32), - RXingResultPoint::new(left_boundary as f32, top_boundary as f32), - RXingResultPoint::new(right_boundary as f32, bottom_boundary as f32), - RXingResultPoint::new(right_boundary as f32, top_boundary as f32), + point(left_boundary as f32, bottom_boundary as f32), + point(left_boundary as f32, top_boundary as f32), + point(right_boundary as f32, bottom_boundary as f32), + point(right_boundary as f32, top_boundary as f32), ]; #[allow(unused_mut)] @@ -807,9 +804,9 @@ const BOTTOM_RIGHT_ORIENTATION_POS: ((u32, u32), (u32, u32), (u32, u32)) = fn attempt_rotation_box( image: &BitMatrix, circle: &mut Circle, - naive_box: &[RXingResultPoint; 4], + naive_box: &[Point; 4], center_scale: f64, -) -> Option<([RXingResultPoint; 4], f32)> { +) -> Option<([Point; 4], f32)> { // update our circle with a more accurate center point circle.calculate_high_accuracy_center(); @@ -955,10 +952,10 @@ fn attempt_rotation_box( Some(( [ - RXingResultPoint::new(new_1.0, new_1.1), - RXingResultPoint::new(new_2.0, new_2.1), - RXingResultPoint::new(new_3.0, new_3.1), - RXingResultPoint::new(new_4.0, new_4.1), + point(new_1.0, new_1.1), + point(new_2.0, new_2.1), + point(new_3.0, new_3.1), + point(new_4.0, new_4.1), ], final_rotation, )) diff --git a/src/multi/by_quadrant_reader.rs b/src/multi/by_quadrant_reader.rs index 571a79a..348124c 100644 --- a/src/multi/by_quadrant_reader.rs +++ b/src/multi/by_quadrant_reader.rs @@ -17,7 +17,7 @@ use std::collections::HashMap; use crate::common::Result; -use crate::{Exceptions, RXingResult, RXingResultPoint, Reader, ResultPoint}; +use crate::{point, Exceptions, Point, RXingResult, Reader}; /** * This class attempts to decode a barcode from an image, not by scanning the whole image, @@ -61,7 +61,7 @@ impl Reader for ByQuadrantReader { // This is a match because only NotFoundExceptions should be ignored match result { Ok(res) => { - let points = Self::makeAbsolute(res.getRXingResultPoints(), halfWidth as f32, 0.0); + let points = Self::makeAbsolute(res.getPoints(), halfWidth as f32, 0.0); return Ok(RXingResult::new_from_existing_result(res, points)); } Err(Exceptions::NotFoundException(_)) => {} @@ -74,7 +74,7 @@ impl Reader for ByQuadrantReader { // This is a match because only NotFoundExceptions should be ignored match result { Ok(res) => { - let points = Self::makeAbsolute(res.getRXingResultPoints(), 0.0, halfHeight as f32); + let points = Self::makeAbsolute(res.getPoints(), 0.0, halfHeight as f32); return Ok(RXingResult::new_from_existing_result(res, points)); } Err(Exceptions::NotFoundException(_)) => {} @@ -88,11 +88,8 @@ impl Reader for ByQuadrantReader { // This is a match because only NotFoundExceptions should be ignored match result { Ok(res) => { - let points = Self::makeAbsolute( - res.getRXingResultPoints(), - halfWidth as f32, - halfHeight as f32, - ); + let points = + Self::makeAbsolute(res.getPoints(), halfWidth as f32, halfHeight as f32); return Ok(RXingResult::new_from_existing_result(res, points)); } Err(Exceptions::NotFoundException(_)) => {} @@ -105,7 +102,7 @@ impl Reader for ByQuadrantReader { let result = self.0.decode_with_hints(&mut center, hints)?; let points = Self::makeAbsolute( - result.getRXingResultPoints(), + result.getPoints(), quarterWidth as f32, quarterHeight as f32, ); @@ -122,16 +119,12 @@ impl ByQuadrantReader { Self(delegate) } - fn makeAbsolute( - points: &[RXingResultPoint], - leftOffset: f32, - topOffset: f32, - ) -> Vec { + fn makeAbsolute(points: &[Point], leftOffset: f32, topOffset: f32) -> Vec { // let mut result = Vec::new(); // if !points.is_empty() { // // for relative in points { - // // result.push(RXingResultPoint::new( + // // result.push(point( // // relative.getX() + leftOffset, // // relative.getY() + topOffset, // // )); @@ -140,9 +133,7 @@ impl ByQuadrantReader { // result points .iter() - .map(|relative| { - RXingResultPoint::new(relative.getX() + leftOffset, relative.getY() + topOffset) - }) + .map(|relative| point(relative.x + leftOffset, relative.y + topOffset)) .collect() } } diff --git a/src/multi/generic_multiple_barcode_reader.rs b/src/multi/generic_multiple_barcode_reader.rs index a0ec5a6..a9b2910 100644 --- a/src/multi/generic_multiple_barcode_reader.rs +++ b/src/multi/generic_multiple_barcode_reader.rs @@ -17,8 +17,8 @@ use std::collections::HashMap; use crate::{ - common::Result, BinaryBitmap, DecodingHintDictionary, Exceptions, RXingResult, - RXingResultPoint, Reader, ResultPoint, + common::Result, point, BinaryBitmap, DecodingHintDictionary, Exceptions, Point, RXingResult, + Reader, }; use super::MultipleBarcodeReader; @@ -26,7 +26,7 @@ use super::MultipleBarcodeReader; /** *

Attempts to locate multiple barcodes in an image by repeatedly decoding portion of the image. * After one barcode is found, the areas left, above, right and below the barcode's - * {@link RXingResultPoint}s are scanned, recursively.

+ * {@link Point}s are scanned, recursively.

* *

A caller may want to also employ {@link ByQuadrantReader} when attempting to find multiple * 2D barcodes, like QR Codes, in an image, where the presence of multiple barcodes might prevent @@ -95,10 +95,10 @@ impl GenericMultipleBarcodeReader { } } - let resultPoints = result.getRXingResultPoints().clone(); + let resultPoints = result.getPoints().clone(); if !alreadyFound { - results.push(Self::translateRXingResultPoints(result, xOffset, yOffset)); + results.push(Self::translatePoints(result, xOffset, yOffset)); } if resultPoints.is_empty() { @@ -115,8 +115,8 @@ impl GenericMultipleBarcodeReader { // if (point == null) { // continue; // } - let x = point.getX(); - let y = point.getY(); + let x = point.x; + let y = point.y; if x < minX { minX = x; } @@ -177,25 +177,20 @@ impl GenericMultipleBarcodeReader { } } - fn translateRXingResultPoints(result: RXingResult, xOffset: u32, yOffset: u32) -> RXingResult { - let oldRXingResultPoints = result.getRXingResultPoints(); - if oldRXingResultPoints.is_empty() { + fn translatePoints(result: RXingResult, xOffset: u32, yOffset: u32) -> RXingResult { + let oldPoints = result.getPoints(); + if oldPoints.is_empty() { return result; } - let newRXingResultPoints: Vec = oldRXingResultPoints + let newPoints: Vec = oldPoints .iter() - .map(|oldPoint| { - RXingResultPoint::new( - oldPoint.getX() + xOffset as f32, - oldPoint.getY() + yOffset as f32, - ) - }) + .map(|oldPoint| point(oldPoint.x + xOffset as f32, oldPoint.y + yOffset as f32)) .collect(); - // let mut newRXingResultPoints = Vec::with_capacity(oldRXingResultPoints.len()); - // for oldPoint in oldRXingResultPoints { - // newRXingResultPoints.push(RXingResultPoint::new( + // let mut newPoints = Vec::with_capacity(oldPoints.len()); + // for oldPoint in oldPoints { + // newPoints.push(point( // oldPoint.getX() + xOffset as f32, // oldPoint.getY() + yOffset as f32, // )); @@ -204,7 +199,7 @@ impl GenericMultipleBarcodeReader { result.getText(), result.getRawBytes().clone(), result.getNumBits(), - newRXingResultPoints, + newPoints, *result.getBarcodeFormat(), result.getTimestamp(), ); diff --git a/src/multi/qrcode/detector/multi_finder_pattern_finder.rs b/src/multi/qrcode/detector/multi_finder_pattern_finder.rs index d8fb708..8065bac 100644 --- a/src/multi/qrcode/detector/multi_finder_pattern_finder.rs +++ b/src/multi/qrcode/detector/multi_finder_pattern_finder.rs @@ -19,8 +19,7 @@ use std::cmp::Ordering; use crate::{ common::{BitMatrix, Result}, qrcode::detector::{FinderPattern, FinderPatternFinder, FinderPatternInfo}, - result_point_utils, DecodeHintType, DecodingHintDictionary, Exceptions, - RXingResultPointCallback, + result_point_utils, DecodeHintType, DecodingHintDictionary, Exceptions, Point, PointCallback, }; // max. legal count of modules per QR code edge (177) @@ -68,7 +67,7 @@ impl<'a> MultiFinderPatternFinder<'_> { pub fn new( image: &'a BitMatrix, - resultPointCallback: Option, + resultPointCallback: Option, ) -> MultiFinderPatternFinder<'a> { MultiFinderPatternFinder(FinderPatternFinder::with_callback( image, @@ -175,9 +174,10 @@ impl<'a> MultiFinderPatternFinder<'_> { // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal let info = FinderPatternInfo::new(test); - let dA = result_point_utils::distance(info.getTopLeft(), info.getBottomLeft()); - let dC = result_point_utils::distance(info.getTopRight(), info.getBottomLeft()); - let dB = result_point_utils::distance(info.getTopLeft(), info.getTopRight()); + let dA = Point::distance(info.getTopLeft().into(), info.getBottomLeft().into()); + let dC = + Point::distance(info.getTopRight().into(), info.getBottomLeft().into()); + let dB = Point::distance(info.getTopLeft().into(), info.getTopRight().into()); // Check the sizes let estimatedModuleCount = (dA + dB) / (p1.getEstimatedModuleSize() * 2.0); diff --git a/src/oned/coda_bar_reader.rs b/src/oned/coda_bar_reader.rs index fa98222..c16a0d1 100644 --- a/src/oned/coda_bar_reader.rs +++ b/src/oned/coda_bar_reader.rs @@ -17,10 +17,10 @@ use rxing_one_d_proc_derive::OneDReader; use crate::common::{BitArray, Result}; -use crate::BarcodeFormat; use crate::DecodeHintValue; use crate::Exceptions; use crate::RXingResult; +use crate::{point, BarcodeFormat}; use super::OneDReader; @@ -170,8 +170,8 @@ impl OneDReader for CodaBarReader { &self.decodeRowRXingResult, Vec::new(), vec![ - RXingResultPoint::new(left, rowNumber as f32), - RXingResultPoint::new(right, rowNumber as f32), + point(left, rowNumber as f32), + point(right, rowNumber as f32), ], BarcodeFormat::CODABAR, ); diff --git a/src/oned/code_128_reader.rs b/src/oned/code_128_reader.rs index 052af5c..ed6d8b8 100644 --- a/src/oned/code_128_reader.rs +++ b/src/oned/code_128_reader.rs @@ -18,7 +18,7 @@ use rxing_one_d_proc_derive::OneDReader; use crate::{ common::{BitArray, Result}, - BarcodeFormat, Exceptions, RXingResult, + point, BarcodeFormat, Exceptions, RXingResult, }; use super::{one_d_reader, OneDReader}; @@ -338,8 +338,8 @@ impl OneDReader for Code128Reader { &result, rawBytes, vec![ - RXingResultPoint::new(left, rowNumber as f32), - RXingResultPoint::new(right, rowNumber as f32), + point(left, rowNumber as f32), + point(right, rowNumber as f32), ], BarcodeFormat::CODE_128, ); diff --git a/src/oned/code_39_reader.rs b/src/oned/code_39_reader.rs index ded6496..92ec57b 100644 --- a/src/oned/code_39_reader.rs +++ b/src/oned/code_39_reader.rs @@ -17,7 +17,7 @@ use rxing_one_d_proc_derive::OneDReader; use crate::common::{BitArray, Result}; -use crate::{BarcodeFormat, Exceptions, RXingResult}; +use crate::{point, BarcodeFormat, Exceptions, RXingResult}; use super::{one_d_reader, OneDReader}; @@ -134,8 +134,8 @@ impl OneDReader for Code39Reader { &resultString, Vec::new(), vec![ - RXingResultPoint::new(left, rowNumber as f32), - RXingResultPoint::new(right, rowNumber as f32), + point(left, rowNumber as f32), + point(right, rowNumber as f32), ], BarcodeFormat::CODE_39, ); diff --git a/src/oned/code_93_reader.rs b/src/oned/code_93_reader.rs index e3d01f4..4961a4d 100644 --- a/src/oned/code_93_reader.rs +++ b/src/oned/code_93_reader.rs @@ -18,7 +18,7 @@ use rxing_one_d_proc_derive::OneDReader; use crate::{ common::{BitArray, Result}, - BarcodeFormat, Exceptions, RXingResult, + point, BarcodeFormat, Exceptions, RXingResult, }; use super::{one_d_reader, OneDReader}; @@ -117,8 +117,8 @@ impl OneDReader for Code93Reader { &resultString, Vec::new(), vec![ - RXingResultPoint::new(left, rowNumber as f32), - RXingResultPoint::new(right, rowNumber as f32), + point(left, rowNumber as f32), + point(right, rowNumber as f32), ], BarcodeFormat::CODE_93, ); diff --git a/src/oned/itf_reader.rs b/src/oned/itf_reader.rs index 88ca208..8b36565 100644 --- a/src/oned/itf_reader.rs +++ b/src/oned/itf_reader.rs @@ -18,7 +18,7 @@ use rxing_one_d_proc_derive::OneDReader; use crate::{ common::{BitArray, Result}, - BarcodeFormat, DecodeHintValue, Exceptions, RXingResult, + point, BarcodeFormat, DecodeHintValue, Exceptions, RXingResult, }; use super::{one_d_reader, OneDReader}; @@ -150,8 +150,8 @@ impl OneDReader for ITFReader { &resultString, Vec::new(), // no natural byte representation for these barcodes vec![ - RXingResultPoint::new(startRange[1] as f32, rowNumber as f32), - RXingResultPoint::new(endRange[0] as f32, rowNumber as f32), + point(startRange[1] as f32, rowNumber as f32), + point(endRange[0] as f32, rowNumber as f32), ], BarcodeFormat::ITF, ); diff --git a/src/oned/multi_format_one_d_reader.rs b/src/oned/multi_format_one_d_reader.rs index b0177c0..2400e6b 100644 --- a/src/oned/multi_format_one_d_reader.rs +++ b/src/oned/multi_format_one_d_reader.rs @@ -157,8 +157,8 @@ impl Reader for MultiFormatOneDReader { ); // Update result points let height = rotatedImage.getHeight(); - let total_points = result.getRXingResultPoints().len(); - let points = result.getRXingResultPointsMut(); + let total_points = result.getPoints().len(); + let points = result.getPointsMut(); for point in points.iter_mut().take(total_points) { std::mem::swap(&mut point.x, &mut point.y); point.x = height as f32 - point.x - 1.0; diff --git a/src/oned/multi_format_upc_ean_reader.rs b/src/oned/multi_format_upc_ean_reader.rs index 3ef1c25..2284695 100644 --- a/src/oned/multi_format_upc_ean_reader.rs +++ b/src/oned/multi_format_upc_ean_reader.rs @@ -105,7 +105,7 @@ impl MultiFormatUPCEANReader { let mut resultUPCA = RXingResult::new( &result.getText()[1..], result.getRawBytes().clone(), - result.getRXingResultPoints().clone(), + result.getPoints().clone(), BarcodeFormat::UPC_A, ); resultUPCA.putAllMetadata(result.getRXingResultMetadata().clone()); @@ -189,8 +189,8 @@ impl Reader for MultiFormatUPCEANReader { ); // Update result points let height = rotatedImage.getHeight(); - let total_points = result.getRXingResultPoints().len(); - let points = result.getRXingResultPointsMut(); + let total_points = result.getPoints().len(); + let points = result.getPointsMut(); for point in points.iter_mut().take(total_points) { std::mem::swap(&mut point.x, &mut point.y); point.x = height as f32 - point.x - 1.0; diff --git a/src/oned/one_d_reader.rs b/src/oned/one_d_reader.rs index b1bd9e8..53880e0 100644 --- a/src/oned/one_d_reader.rs +++ b/src/oned/one_d_reader.rs @@ -16,8 +16,8 @@ use crate::{ common::{BitArray, Result}, - BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, RXingResult, - RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint, Reader, ResultPoint, + point, BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, + RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader, }; /** @@ -115,16 +115,10 @@ pub trait OneDReader: Reader { RXingResultMetadataValue::Orientation(180), ); // And remember to flip the result points horizontally. - let points = result.getRXingResultPointsMut(); + let points = result.getPointsMut(); if !points.is_empty() && points.len() >= 2 { - points[0] = RXingResultPoint::new( - width as f32 - points[0].getX() - 1.0, - points[0].getY(), - ); - points[1] = RXingResultPoint::new( - width as f32 - points[1].getX() - 1.0, - points[1].getY(), - ); + points[0] = point(width as f32 - points[0].x - 1.0, points[0].y); + points[1] = point(width as f32 - points[1].x - 1.0, points[1].y); } } return Ok(result); diff --git a/src/oned/rss/expanded/rss_expanded_reader.rs b/src/oned/rss/expanded/rss_expanded_reader.rs index 8ebd5e2..e31c1f2 100644 --- a/src/oned/rss/expanded/rss_expanded_reader.rs +++ b/src/oned/rss/expanded/rss_expanded_reader.rs @@ -215,8 +215,8 @@ impl Reader for RSSExpandedReader { // Update result points let height = rotatedImage.getHeight(); - let total_points = result.getRXingResultPoints().len(); - let points = result.getRXingResultPointsMut(); + let total_points = result.getPoints().len(); + let points = result.getPointsMut(); for point in points.iter_mut().take(total_points) { std::mem::swap(&mut point.x, &mut point.y); point.x = height as f32 - point.x - 1.0; @@ -540,14 +540,14 @@ impl RSSExpandedReader { .getFinderPattern() .as_ref() .ok_or(Exceptions::illegalState)? - .getRXingResultPoints(); + .getPoints(); let lastPoints = pairs .last() .ok_or(Exceptions::indexOutOfBounds)? .getFinderPattern() .as_ref() .ok_or(Exceptions::illegalState)? - .getRXingResultPoints(); + .getPoints(); let mut result = RXingResult::new( &resultingString, diff --git a/src/oned/rss/finder_pattern.rs b/src/oned/rss/finder_pattern.rs index 6578e95..775e38f 100644 --- a/src/oned/rss/finder_pattern.rs +++ b/src/oned/rss/finder_pattern.rs @@ -16,7 +16,7 @@ use std::hash::Hash; -use crate::RXingResultPoint; +use crate::{point, Point}; /** * Encapsulates an RSS barcode finder pattern, including its start/end position and row. @@ -25,7 +25,7 @@ use crate::RXingResultPoint; pub struct FinderPattern { value: u32, startEnd: [usize; 2], - resultPoints: Vec, + resultPoints: Vec, } impl FinderPattern { @@ -34,8 +34,8 @@ impl FinderPattern { value, startEnd, resultPoints: vec![ - RXingResultPoint::new(start as f32, rowNumber as f32), - RXingResultPoint::new(end as f32, rowNumber as f32), + point(start as f32, rowNumber as f32), + point(end as f32, rowNumber as f32), ], } } @@ -53,7 +53,7 @@ impl FinderPattern { &mut self.startEnd } - pub fn getRXingResultPoints(&self) -> &[RXingResultPoint] { + pub fn getPoints(&self) -> &[Point] { &self.resultPoints } } diff --git a/src/oned/rss/rss_14_reader.rs b/src/oned/rss/rss_14_reader.rs index ee2fb93..289023e 100644 --- a/src/oned/rss/rss_14_reader.rs +++ b/src/oned/rss/rss_14_reader.rs @@ -19,8 +19,8 @@ use std::collections::HashMap; use crate::{ common::{BitArray, Result}, oned::{one_d_reader, OneDReader}, - BarcodeFormat, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, - RXingResult, RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint, Reader, + point, BarcodeFormat, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, + RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader, }; use super::{ @@ -114,8 +114,8 @@ impl Reader for RSS14Reader { ); // Update result points let height = rotatedImage.getHeight(); - let total_points = result.getRXingResultPoints().len(); - let points = result.getRXingResultPointsMut(); + let total_points = result.getPoints().len(); + let points = result.getPointsMut(); for point in points.iter_mut().take(total_points) { std::mem::swap(&mut point.x, &mut point.y); point.x = height as f32 - point.x - 1.0 @@ -209,8 +209,8 @@ impl RSS14Reader { } buffer.push_str(&checkDigit.to_string()); - let leftPoints = leftPair.getFinderPattern().getRXingResultPoints(); - let rightPoints = rightPair.getFinderPattern().getRXingResultPoints(); + let leftPoints = leftPair.getFinderPattern().getPoints(); + let rightPoints = rightPair.getFinderPattern().getPoints(); let mut result = RXingResult::new( &buffer, Vec::new(), @@ -259,7 +259,7 @@ impl RSS14Reader { // row is actually reversed center = row.getSize() as f32 - 1.0 - center; } - cb(&RXingResultPoint::new(center, rowNumber as f32)); + cb(point(center, rowNumber as f32)); } let outside = self.decodeDataCharacter(row, &pattern, true)?; diff --git a/src/oned/upc_a_reader.rs b/src/oned/upc_a_reader.rs index 7eec6b8..2222438 100644 --- a/src/oned/upc_a_reader.rs +++ b/src/oned/upc_a_reader.rs @@ -94,7 +94,7 @@ impl UPCAReader { let mut upcaRXingResult = RXingResult::new( stripped_text, Vec::new(), - result.getRXingResultPoints().to_vec(), + result.getPoints().to_vec(), BarcodeFormat::UPC_A, ); upcaRXingResult.putAllMetadata(result.getRXingResultMetadata().clone()); diff --git a/src/oned/upc_ean_extension_2_support.rs b/src/oned/upc_ean_extension_2_support.rs index 76835f5..13f7ce6 100644 --- a/src/oned/upc_ean_extension_2_support.rs +++ b/src/oned/upc_ean_extension_2_support.rs @@ -18,8 +18,8 @@ use std::collections::HashMap; use crate::{ common::{BitArray, Result}, - BarcodeFormat, Exceptions, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, - RXingResultPoint, + point, BarcodeFormat, Exceptions, RXingResult, RXingResultMetadataType, + RXingResultMetadataValue, }; use super::{upc_ean_reader, UPCEANReader, STAND_IN}; @@ -49,11 +49,11 @@ impl UPCEANExtension2Support { &resultString, Vec::new(), vec![ - RXingResultPoint::new( + point( (extensionStartRange[0] + extensionStartRange[1]) as f32 / 2.0, rowNumber as f32, ), - RXingResultPoint::new(end as f32, rowNumber as f32), + point(end as f32, rowNumber as f32), ], BarcodeFormat::UPC_EAN_EXTENSION, ); diff --git a/src/oned/upc_ean_extension_5_support.rs b/src/oned/upc_ean_extension_5_support.rs index 32ffd8b..7748af1 100644 --- a/src/oned/upc_ean_extension_5_support.rs +++ b/src/oned/upc_ean_extension_5_support.rs @@ -18,8 +18,8 @@ use std::collections::HashMap; use crate::{ common::{BitArray, Result}, - BarcodeFormat, Exceptions, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, - RXingResultPoint, + point, BarcodeFormat, Exceptions, RXingResult, RXingResultMetadataType, + RXingResultMetadataValue, }; use super::{upc_ean_reader, UPCEANReader, STAND_IN}; @@ -51,11 +51,11 @@ impl UPCEANExtension5Support { &resultString, Vec::new(), vec![ - RXingResultPoint::new( + point( (extensionStartRange[0] + extensionStartRange[1]) as f32 / 2.0, rowNumber as f32, ), - RXingResultPoint::new(end as f32, rowNumber as f32), + point(end as f32, rowNumber as f32), ], BarcodeFormat::UPC_EAN_EXTENSION, ); diff --git a/src/oned/upc_ean_reader.rs b/src/oned/upc_ean_reader.rs index baa8147..021f61e 100644 --- a/src/oned/upc_ean_reader.rs +++ b/src/oned/upc_ean_reader.rs @@ -16,8 +16,8 @@ use crate::{ common::{BitArray, Result}, - BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, RXingResult, - RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint, Reader, + point, BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, RXingResult, + RXingResultMetadataType, RXingResultMetadataValue, Reader, }; use super::{one_d_reader, EANManufacturerOrgSupport, OneDReader, UPCEANExtensionSupport}; @@ -156,7 +156,7 @@ pub trait UPCEANReader: OneDReader { let mut symbologyIdentifier = 0; if let Some(DecodeHintValue::NeedResultPointCallback(cb)) = resultPointCallback { - cb(&RXingResultPoint::new( + cb(point( (startGuardRange[0] + startGuardRange[1]) as f32 / 2.0, rowNumber as f32, )); @@ -166,13 +166,13 @@ pub trait UPCEANReader: OneDReader { let endStart = self.decodeMiddle(row, startGuardRange, &mut result)?; if let Some(DecodeHintValue::NeedResultPointCallback(cb)) = resultPointCallback { - cb(&RXingResultPoint::new(endStart as f32, rowNumber as f32)); + cb(point(endStart as f32, rowNumber as f32)); } let endRange = self.decodeEnd(row, endStart)?; if let Some(DecodeHintValue::NeedResultPointCallback(cb)) = resultPointCallback { - cb(&RXingResultPoint::new( + cb(point( (endRange[0] + endRange[1]) as f32 / 2.0, rowNumber as f32, )); @@ -204,8 +204,8 @@ pub trait UPCEANReader: OneDReader { &resultString, Vec::new(), // no natural byte representation for these barcodes vec![ - RXingResultPoint::new(left, rowNumber as f32), - RXingResultPoint::new(right, rowNumber as f32), + point(left, rowNumber as f32), + point(right, rowNumber as f32), ], format, ); @@ -223,8 +223,7 @@ pub trait UPCEANReader: OneDReader { ), ); decodeRXingResult.putAllMetadata(extensionRXingResult.getRXingResultMetadata().clone()); - decodeRXingResult - .addRXingResultPoints(&mut extensionRXingResult.getRXingResultPoints().clone()); + decodeRXingResult.addPoints(&mut extensionRXingResult.getPoints().clone()); extensionLength = extensionRXingResult.getText().chars().count(); Ok(()) }; diff --git a/src/pdf417/decoder/bounding_box.rs b/src/pdf417/decoder/bounding_box.rs index d585065..c42f713 100644 --- a/src/pdf417/decoder/bounding_box.rs +++ b/src/pdf417/decoder/bounding_box.rs @@ -18,7 +18,7 @@ use std::rc::Rc; use crate::{ common::{BitMatrix, Result}, - Exceptions, RXingResultPoint, ResultPoint, + point, Exceptions, Point, }; /** @@ -27,10 +27,10 @@ use crate::{ #[derive(Clone)] pub struct BoundingBox { image: Rc, - topLeft: RXingResultPoint, - bottomLeft: RXingResultPoint, - topRight: RXingResultPoint, - bottomRight: RXingResultPoint, + topLeft: Point, + bottomLeft: Point, + topRight: Point, + bottomRight: Point, minX: u32, maxX: u32, minY: u32, @@ -39,10 +39,10 @@ pub struct BoundingBox { impl BoundingBox { pub fn new( image: Rc, - topLeft: Option, - bottomLeft: Option, - topRight: Option, - bottomRight: Option, + topLeft: Option, + bottomLeft: Option, + topRight: Option, + bottomRight: Option, ) -> Result { let leftUnspecified = topLeft.is_none() || bottomLeft.is_none(); let rightUnspecified = topRight.is_none() || bottomRight.is_none(); @@ -58,14 +58,13 @@ impl BoundingBox { if leftUnspecified { newTopRight = topRight.ok_or(Exceptions::illegalState)?; newBottomRight = bottomRight.ok_or(Exceptions::illegalState)?; - newTopLeft = RXingResultPoint::new(0.0, newTopRight.getY()); - newBottomLeft = RXingResultPoint::new(0.0, newBottomRight.getY()); + newTopLeft = point(0.0, newTopRight.y); + newBottomLeft = point(0.0, newBottomRight.y); } else if rightUnspecified { newTopLeft = topLeft.ok_or(Exceptions::illegalState)?; newBottomLeft = bottomLeft.ok_or(Exceptions::illegalState)?; - newTopRight = RXingResultPoint::new(image.getWidth() as f32 - 1.0, newTopLeft.getY()); - newBottomRight = - RXingResultPoint::new(image.getWidth() as f32 - 1.0, newBottomLeft.getY()); + newTopRight = point(image.getWidth() as f32 - 1.0, newTopLeft.y); + newBottomRight = point(image.getWidth() as f32 - 1.0, newBottomLeft.y); } else { newTopLeft = topLeft.ok_or(Exceptions::illegalState)?; newTopRight = topRight.ok_or(Exceptions::illegalState)?; @@ -75,10 +74,10 @@ impl BoundingBox { Ok(BoundingBox { image, - minX: newTopLeft.getX().min(newBottomLeft.getX()) as u32, - maxX: newTopRight.getX().max(newBottomRight.getX()) as u32, - minY: newTopLeft.getY().min(newTopRight.getY()) as u32, - maxY: newBottomLeft.getY().max(newBottomRight.getY()) as u32, + minX: newTopLeft.x.min(newBottomLeft.x) as u32, + maxX: newTopRight.x.max(newBottomRight.x) as u32, + minY: newTopLeft.y.min(newTopRight.y) as u32, + maxY: newBottomLeft.y.max(newBottomRight.y) as u32, topLeft: newTopLeft, bottomLeft: newBottomLeft, topRight: newTopRight, @@ -135,11 +134,11 @@ impl BoundingBox { if missingStartRows > 0 { let top = if isLeft { self.topLeft } else { self.topRight }; - let mut newMinY = top.getY() - missingStartRows as f32; + let mut newMinY = top.y - missingStartRows as f32; if newMinY < 0.0 { newMinY = 0.0; } - let newTop = RXingResultPoint::new(top.getX(), newMinY); + let newTop = point(top.x, newMinY); if isLeft { newTopLeft = newTop; } else { @@ -153,11 +152,11 @@ impl BoundingBox { } else { self.bottomRight }; - let mut newMaxY = bottom.getY() as u32 + missingEndRows; + let mut newMaxY = bottom.y as u32 + missingEndRows; if newMaxY >= self.image.getHeight() { newMaxY = self.image.getHeight() - 1; } - let newBottom = RXingResultPoint::new(bottom.getX(), newMaxY as f32); + let newBottom = point(bottom.x, newMaxY as f32); if isLeft { newBottomLeft = newBottom; } else { @@ -190,19 +189,19 @@ impl BoundingBox { self.maxY } - pub fn getTopLeft(&self) -> &RXingResultPoint { + pub fn getTopLeft(&self) -> &Point { &self.topLeft } - pub fn getTopRight(&self) -> &RXingResultPoint { + pub fn getTopRight(&self) -> &Point { &self.topRight } - pub fn getBottomLeft(&self) -> &RXingResultPoint { + pub fn getBottomLeft(&self) -> &Point { &self.bottomLeft } - pub fn getBottomRight(&self) -> &RXingResultPoint { + pub fn getBottomRight(&self) -> &Point { &self.bottomRight } } diff --git a/src/pdf417/decoder/detection_result_row_indicator_column.rs b/src/pdf417/decoder/detection_result_row_indicator_column.rs index 3653d5b..d714641 100644 --- a/src/pdf417/decoder/detection_result_row_indicator_column.rs +++ b/src/pdf417/decoder/detection_result_row_indicator_column.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use crate::{pdf417::pdf_417_common, ResultPoint}; +use crate::pdf417::pdf_417_common; use super::{ BarcodeMetadata, BarcodeValue, Codeword, DetectionRXingResultColumn, @@ -63,8 +63,8 @@ impl DetectionRXingResultRowIndicatorColumn for DetectionRXingResultColumn { boundingBox.getBottomRight() }; - let firstRow = self.imageRowToCodewordIndex(top.getY() as u32); - let lastRow = self.imageRowToCodewordIndex(bottom.getY() as u32); + let firstRow = self.imageRowToCodewordIndex(top.y as u32); + let lastRow = self.imageRowToCodewordIndex(bottom.y as u32); // We need to be careful using the average row height. Barcode could be skewed so that we have smaller and // taller rows let averageRowHeight: f64 = @@ -263,8 +263,8 @@ fn adjustIncompleteIndicatorColumnRowNumbers( } else { boundingBox.getBottomRight() }; - let firstRow = col.imageRowToCodewordIndex(top.getY() as u32); - let lastRow = col.imageRowToCodewordIndex(bottom.getY() as u32); + let firstRow = col.imageRowToCodewordIndex(top.y as u32); + let lastRow = col.imageRowToCodewordIndex(bottom.y as u32); let averageRowHeight: f64 = (lastRow as f64 - firstRow as f64) / barcodeMetadata.getRowCount() as f64; let codewords = col.getCodewordsMut(); diff --git a/src/pdf417/decoder/pdf_417_scanning_decoder.rs b/src/pdf417/decoder/pdf_417_scanning_decoder.rs index e0e825a..6977d8f 100644 --- a/src/pdf417/decoder/pdf_417_scanning_decoder.rs +++ b/src/pdf417/decoder/pdf_417_scanning_decoder.rs @@ -19,7 +19,7 @@ use std::rc::Rc; use crate::{ common::{BitMatrix, DecoderRXingResult, Result}, pdf417::pdf_417_common, - Exceptions, RXingResultPoint, ResultPoint, + Exceptions, Point, }; use super::{ @@ -44,10 +44,10 @@ const MAX_EC_CODEWORDS: u32 = 512; // than it should be. This can happen if the scanner used a bad blackpoint. pub fn decode( image: &BitMatrix, - imageTopLeft: Option, - imageBottomLeft: Option, - imageTopRight: Option, - imageBottomRight: Option, + imageTopLeft: Option, + imageBottomLeft: Option, + imageTopRight: Option, + imageBottomRight: Option, minCodewordWidth: u32, maxCodewordWidth: u32, ) -> Result { @@ -68,7 +68,7 @@ pub fn decode( leftRowIndicatorColumn = Some(getRowIndicatorColumn( image, boundingBox.clone(), - imageTopLeft.as_ref().unwrap(), + imageTopLeft.unwrap(), true, minCodewordWidth, maxCodewordWidth, @@ -78,7 +78,7 @@ pub fn decode( rightRowIndicatorColumn = Some(getRowIndicatorColumn( image, boundingBox.clone(), - imageTopRight.as_ref().unwrap(), + imageTopRight.unwrap(), false, minCodewordWidth, maxCodewordWidth, @@ -358,7 +358,7 @@ fn getBarcodeMetadata( fn getRowIndicatorColumn<'a>( image: &BitMatrix, boundingBox: Rc, - startPoint: &RXingResultPoint, + startPoint: Point, leftToRight: bool, minCodewordWidth: u32, maxCodewordWidth: u32, @@ -368,8 +368,8 @@ fn getRowIndicatorColumn<'a>( for i in 0..2 { // for (int i = 0; i < 2; i++) { let increment: i32 = if i == 0 { 1 } else { -1 }; - let mut startColumn: u32 = startPoint.getX() as u32; - let mut imageRow: i32 = startPoint.getY() as i32; + let mut startColumn: u32 = startPoint.x as u32; + let mut imageRow: i32 = startPoint.y as i32; while imageRow <= boundingBox.getMaxY() as i32 && imageRow >= boundingBox.getMinY() as i32 { // for (int imageRow = (int) startPoint.getY(); imageRow <= boundingBox.getMaxY() && // imageRow >= boundingBox.getMinY(); imageRow += increment) { diff --git a/src/pdf417/detector/pdf_417_detector.rs b/src/pdf417/detector/pdf_417_detector.rs index 19b12ed..1bf1935 100644 --- a/src/pdf417/detector/pdf_417_detector.rs +++ b/src/pdf417/detector/pdf_417_detector.rs @@ -16,7 +16,7 @@ use crate::{ common::{BitMatrix, Result}, - BinaryBitmap, DecodingHintDictionary, Exceptions, RXingResultPoint, ResultPoint, + point, BinaryBitmap, DecodingHintDictionary, Exceptions, Point, }; use std::borrow::Cow; @@ -115,10 +115,10 @@ fn applyRotation(matrix: &BitMatrix, rotation: u32) -> Result> { * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will * be found and returned * @param bitMatrix bit matrix to detect barcodes in - * @return List of RXingResultPoint arrays containing the coordinates of found barcodes + * @return List of Point arrays containing the coordinates of found barcodes */ -pub fn detect(multiple: bool, bitMatrix: &BitMatrix) -> Option; 8]>> { - let mut barcodeCoordinates: Vec<[Option; 8]> = Vec::new(); +pub fn detect(multiple: bool, bitMatrix: &BitMatrix) -> Option; 8]>> { + let mut barcodeCoordinates: Vec<[Option; 8]> = Vec::new(); let mut row = 0; let mut column = 0; let mut foundBarcodeInRow = false; @@ -136,10 +136,10 @@ pub fn detect(multiple: bool, bitMatrix: &BitMatrix) -> Option Option Option Option<[Option; 8]> { +fn findVertices(matrix: &BitMatrix, startRow: u32, startColumn: u32) -> Option<[Option; 8]> { let height = matrix.getHeight(); let width = matrix.getWidth(); let mut startRow = startRow; let mut startColumn = startColumn; - let mut result = [None::; 8]; //RXingResultPoint[8]; + let mut result = [None::; 8]; //Point[8]; copyToRXingResult( &mut result, &findRowsWithPattern(matrix, height, width, startRow, startColumn, &START_PATTERN)?, @@ -196,8 +192,8 @@ fn findVertices( ); if let Some(result_4) = result[4] { - startColumn = result_4.getX() as u32; - startRow = result_4.getY() as u32; + startColumn = result_4.x as u32; + startRow = result_4.y as u32; } copyToRXingResult( &mut result, @@ -209,8 +205,8 @@ fn findVertices( } fn copyToRXingResult( - result: &mut [Option], - tmpRXingResult: &[Option], + result: &mut [Option], + tmpRXingResult: &[Option], destinationIndexes: &[u32], ) { for i in 0..destinationIndexes.len() { @@ -225,7 +221,7 @@ fn findRowsWithPattern( startRow: u32, startColumn: u32, pattern: &[u32], -) -> Option<[Option; 4]> { +) -> Option<[Option; 4]> { let mut startRow = startRow; let mut result = [None; 4]; let mut found = false; @@ -248,14 +244,8 @@ fn findRowsWithPattern( break; } } - result[0] = Some(RXingResultPoint::new( - loc_store.as_ref()?[0] as f32, - startRow as f32, - )); - result[1] = Some(RXingResultPoint::new( - loc_store.as_ref()?[1] as f32, - startRow as f32, - )); + result[0] = Some(point(loc_store.as_ref()?[0] as f32, startRow as f32)); + result[1] = Some(point(loc_store.as_ref()?[1] as f32, startRow as f32)); found = true; break; } @@ -267,10 +257,7 @@ fn findRowsWithPattern( // Last row of the current symbol that contains pattern if found { let mut skippedRowCount = 0; - let mut previousRowLoc = [ - result[0].as_ref()?.getX() as u32, - result[1].as_ref()?.getX() as u32, - ]; + let mut previousRowLoc = [result[0].as_ref()?.x as u32, result[1].as_ref()?.x as u32]; while stopRow < height { if let Some(loc) = findGuardPattern( matrix, @@ -303,14 +290,8 @@ fn findRowsWithPattern( stopRow += 1; } stopRow -= skippedRowCount + 1; - result[2] = Some(RXingResultPoint::new( - previousRowLoc[0] as f32, - stopRow as f32, - )); - result[3] = Some(RXingResultPoint::new( - previousRowLoc[1] as f32, - stopRow as f32, - )); + result[2] = Some(point(previousRowLoc[0] as f32, stopRow as f32)); + result[3] = Some(point(previousRowLoc[1] as f32, stopRow as f32)); } if stopRow - startRow < BARCODE_MIN_HEIGHT { result.fill(None); diff --git a/src/pdf417/detector/pdf_417_detector_result.rs b/src/pdf417/detector/pdf_417_detector_result.rs index b3f67ad..0c9aea1 100644 --- a/src/pdf417/detector/pdf_417_detector_result.rs +++ b/src/pdf417/detector/pdf_417_detector_result.rs @@ -14,23 +14,19 @@ * limitations under the License. */ -use crate::{common::BitMatrix, RXingResultPoint}; +use crate::{common::BitMatrix, Point}; /** * @author Guenther Grau */ pub struct PDF417DetectorRXingResult { bits: BitMatrix, - points: Vec<[Option; 8]>, + points: Vec<[Option; 8]>, rotation: u32, } impl PDF417DetectorRXingResult { - pub fn with_rotation( - bits: BitMatrix, - points: Vec<[Option; 8]>, - rotation: u32, - ) -> Self { + pub fn with_rotation(bits: BitMatrix, points: Vec<[Option; 8]>, rotation: u32) -> Self { Self { bits, points, @@ -38,7 +34,7 @@ impl PDF417DetectorRXingResult { } } - pub fn new(bits: BitMatrix, points: Vec<[Option; 8]>) -> Self { + pub fn new(bits: BitMatrix, points: Vec<[Option; 8]>) -> Self { Self::with_rotation(bits, points, 0) } @@ -46,7 +42,7 @@ impl PDF417DetectorRXingResult { &self.bits } - pub fn getPoints(&self) -> &Vec<[Option; 8]> { + pub fn getPoints(&self) -> &Vec<[Option; 8]> { &self.points } diff --git a/src/pdf417/pdf_417_reader.rs b/src/pdf417/pdf_417_reader.rs index 6aa52f2..c37d833 100644 --- a/src/pdf417/pdf_417_reader.rs +++ b/src/pdf417/pdf_417_reader.rs @@ -18,8 +18,8 @@ use std::collections::HashMap; use crate::{ common::Result, multi::MultipleBarcodeReader, BarcodeFormat, BinaryBitmap, - DecodingHintDictionary, Exceptions, RXingResult, RXingResultMetadataType, - RXingResultMetadataValue, RXingResultPoint, Reader, ResultPoint, + DecodingHintDictionary, Exceptions, Point, RXingResult, RXingResultMetadataType, + RXingResultMetadataValue, Reader, }; use super::{ @@ -151,23 +151,23 @@ impl PDF417Reader { Ok(results) } - fn getMaxWidth(p1: &Option, p2: &Option) -> u64 { + fn getMaxWidth(p1: &Option, p2: &Option) -> u64 { if let (Some(p1), Some(p2)) = (p1, p2) { - (p1.getX() - p2.getX()).abs() as u64 + (p1.x - p2.x).abs() as u64 } else { 0 } } - fn getMinWidth(p1: &Option, p2: &Option) -> u64 { + fn getMinWidth(p1: &Option, p2: &Option) -> u64 { if let (Some(p1), Some(p2)) = (p1, p2) { - (p1.getX() - p2.getX()).abs() as u64 + (p1.x - p2.x).abs() as u64 } else { u32::MAX as u64 } } - fn getMaxCodewordWidth(p: &[Option]) -> u32 { + fn getMaxCodewordWidth(p: &[Option]) -> u32 { Self::getMaxWidth(&p[0], &p[4]) .max( Self::getMaxWidth(&p[6], &p[2]) * pdf_417_common::MODULES_IN_CODEWORD as u64 @@ -179,7 +179,7 @@ impl PDF417Reader { )) as u32 } - fn getMinCodewordWidth(p: &[Option]) -> u32 { + fn getMinCodewordWidth(p: &[Option]) -> u32 { Self::getMinWidth(&p[0], &p[4]) .min( Self::getMinWidth(&p[6], &p[2]) * pdf_417_common::MODULES_IN_CODEWORD as u64 diff --git a/src/qrcode/decoder/qr_code_decoder_meta_data.rs b/src/qrcode/decoder/qr_code_decoder_meta_data.rs index 503fd84..1bc853d 100644 --- a/src/qrcode/decoder/qr_code_decoder_meta_data.rs +++ b/src/qrcode/decoder/qr_code_decoder_meta_data.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use crate::RXingResultPoint; +use crate::Point; /** * Meta-data container for QR Code decoding. Instances of this class may be used to convey information back to the @@ -41,7 +41,7 @@ impl QRCodeDecoderMetaData { * * @param points Array of points to apply mirror correction to. */ - pub fn applyMirroredCorrection(&self, points: &mut [RXingResultPoint]) { + pub fn applyMirroredCorrection(&self, points: &mut [Point]) { if !self.0 || points.is_empty() || points.len() < 3 { return; } diff --git a/src/qrcode/detector/alignment_pattern.rs b/src/qrcode/detector/alignment_pattern.rs index 91934a5..e429600 100644 --- a/src/qrcode/detector/alignment_pattern.rs +++ b/src/qrcode/detector/alignment_pattern.rs @@ -14,9 +14,9 @@ * limitations under the License. */ -//RXingResultPoint +//Point -use crate::{RXingResultPoint, ResultPoint}; +use crate::{point, Point}; /** *

Encapsulates an alignment pattern, which are the smaller square patterns found in @@ -27,23 +27,18 @@ use crate::{RXingResultPoint, ResultPoint}; #[derive(Debug, Clone, Copy, PartialEq)] pub struct AlignmentPattern { estimatedModuleSize: f32, - point: (f32, f32), + point: Point, } -impl ResultPoint for AlignmentPattern { - fn getX(&self) -> f32 { - self.point.0 +impl From<&AlignmentPattern> for Point { + fn from(value: &AlignmentPattern) -> Self { + value.point } +} - fn getY(&self) -> f32 { - self.point.1 - } - - fn into_rxing_result_point(self) -> RXingResultPoint { - RXingResultPoint { - x: self.point.0, - y: self.point.1, - } +impl From for Point { + fn from(value: AlignmentPattern) -> Self { + value.point } } @@ -51,7 +46,7 @@ impl AlignmentPattern { pub fn new(posX: f32, posY: f32, estimatedModuleSize: f32) -> Self { Self { estimatedModuleSize, - point: (posX, posY), + point: point(posX, posY), } } @@ -60,7 +55,7 @@ impl AlignmentPattern { * position and size -- meaning, it is at nearly the same center with nearly the same size.

*/ pub fn aboutEquals(&self, moduleSize: f32, i: f32, j: f32) -> bool { - if (i - self.getY()).abs() <= moduleSize && (j - self.getX()).abs() <= moduleSize { + if (i - self.point.y).abs() <= moduleSize && (j - self.point.x).abs() <= moduleSize { let moduleSizeDiff = (moduleSize - self.estimatedModuleSize).abs(); return moduleSizeDiff <= 1.0 || moduleSizeDiff <= self.estimatedModuleSize; } @@ -72,8 +67,8 @@ impl AlignmentPattern { * with a new estimate. It returns a new {@code FinderPattern} containing an average of the two. */ pub fn combineEstimate(&self, i: f32, j: f32, newModuleSize: f32) -> AlignmentPattern { - let combinedX = (self.getX() + j) / 2.0; - let combinedY = (self.getY() + i) / 2.0; + let combinedX = (self.point.x + j) / 2.0; + let combinedY = (self.point.y + i) / 2.0; let combinedModuleSize = (self.estimatedModuleSize + newModuleSize) / 2.0; AlignmentPattern::new(combinedX, combinedY, combinedModuleSize) } diff --git a/src/qrcode/detector/alignment_pattern_finder.rs b/src/qrcode/detector/alignment_pattern_finder.rs index 266cb75..1197f8d 100644 --- a/src/qrcode/detector/alignment_pattern_finder.rs +++ b/src/qrcode/detector/alignment_pattern_finder.rs @@ -16,7 +16,7 @@ use crate::{ common::{BitMatrix, Result}, - Exceptions, RXingResultPointCallback, + Exceptions, PointCallback, }; use super::AlignmentPattern; @@ -44,7 +44,7 @@ pub struct AlignmentPatternFinder { height: u32, moduleSize: f32, crossCheckStateCount: [u32; 3], - resultPointCallback: Option, + resultPointCallback: Option, } impl AlignmentPatternFinder { @@ -65,7 +65,7 @@ impl AlignmentPatternFinder { width: u32, height: u32, moduleSize: f32, - resultPointCallback: Option, + resultPointCallback: Option, ) -> Self { Self { image, @@ -311,7 +311,7 @@ impl AlignmentPatternFinder { // Hadn't found this before; save it let point = AlignmentPattern::new(centerJ, centerI, estimatedModuleSize); if let Some(rpc) = self.resultPointCallback.clone() { - rpc(&point); + rpc((&point).into()); } self.possibleCenters.push(point); diff --git a/src/qrcode/detector/finder_pattern.rs b/src/qrcode/detector/finder_pattern.rs index 3d931e9..025a138 100644 --- a/src/qrcode/detector/finder_pattern.rs +++ b/src/qrcode/detector/finder_pattern.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use crate::{RXingResultPoint, ResultPoint}; +use crate::{point, Point}; /** *

Encapsulates a finder pattern, which are the three square patterns found in @@ -27,23 +27,18 @@ use crate::{RXingResultPoint, ResultPoint}; pub struct FinderPattern { estimatedModuleSize: f32, count: usize, - point: (f32, f32), + pub(crate) point: Point, } -impl ResultPoint for FinderPattern { - fn getX(&self) -> f32 { - self.point.0 +impl From<&FinderPattern> for Point { + fn from(value: &FinderPattern) -> Self { + value.point } +} - fn getY(&self) -> f32 { - self.point.1 - } - - fn into_rxing_result_point(self) -> RXingResultPoint { - RXingResultPoint { - x: self.point.0, - y: self.point.1, - } +impl From for Point { + fn from(value: FinderPattern) -> Self { + value.point } } @@ -56,7 +51,7 @@ impl FinderPattern { Self { estimatedModuleSize, count, - point: (posX, posY), + point: point(posX, posY), } } @@ -73,7 +68,7 @@ impl FinderPattern { * position and size -- meaning, it is at nearly the same center with nearly the same size.

*/ pub fn aboutEquals(&self, moduleSize: f32, i: f32, j: f32) -> bool { - if (i - self.getY()).abs() <= moduleSize && (j - self.getX()).abs() <= moduleSize { + if (i - self.point.y).abs() <= moduleSize && (j - self.point.x).abs() <= moduleSize { let moduleSizeDiff = (moduleSize - self.estimatedModuleSize).abs(); moduleSizeDiff <= 1.0 || moduleSizeDiff <= self.estimatedModuleSize } else { @@ -88,8 +83,8 @@ impl FinderPattern { */ pub fn combineEstimate(&self, i: f32, j: f32, newModuleSize: f32) -> FinderPattern { let combinedCount = self.count as f32 + 1.0; - let combinedX = (self.count as f32 * self.getX() + j) / combinedCount; - let combinedY = (self.count as f32 * self.getY() + i) / combinedCount; + let combinedX = (self.count as f32 * self.point.x + j) / combinedCount; + let combinedY = (self.count as f32 * self.point.y + i) / combinedCount; let combinedModuleSize = (self.count as f32 * self.estimatedModuleSize + newModuleSize) / combinedCount; FinderPattern::private_new( diff --git a/src/qrcode/detector/finder_pattern_finder.rs b/src/qrcode/detector/finder_pattern_finder.rs index 7c27665..53df7d8 100755 --- a/src/qrcode/detector/finder_pattern_finder.rs +++ b/src/qrcode/detector/finder_pattern_finder.rs @@ -14,10 +14,12 @@ * limitations under the License. */ +use std::ops::Div; + use crate::{ common::{BitMatrix, Result}, - result_point_utils, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, - RXingResultPointCallback, ResultPoint, + result_point_utils, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, Point, + PointCallback, }; use super::{FinderPattern, FinderPatternInfo}; @@ -35,7 +37,7 @@ pub struct FinderPatternFinder<'a> { possibleCenters: Vec, hasSkipped: bool, crossCheckStateCount: [u32; 5], - resultPointCallback: Option, + resultPointCallback: Option, } impl<'a> FinderPatternFinder<'_> { pub const CENTER_QUORUM: usize = 2; @@ -53,7 +55,7 @@ impl<'a> FinderPatternFinder<'_> { pub fn with_callback( image: &'a BitMatrix, - resultPointCallback: Option, + resultPointCallback: Option, ) -> FinderPatternFinder<'a> { FinderPatternFinder { image, @@ -603,7 +605,7 @@ impl<'a> FinderPatternFinder<'_> { let point = FinderPattern::new(centerJ, centerI, estimatedModuleSize); self.possibleCenters.push(point); if let Some(rpc) = self.resultPointCallback.clone() { - rpc(&point); + rpc((&point).into()); } } return true; @@ -633,9 +635,11 @@ impl<'a> FinderPatternFinder<'_> { // difference in the x / y coordinates of the two centers. // This is the case where you find top left last. self.hasSkipped = true; - return (((fnp.getX() - center.getX()).abs() - - (fnp.getY() - center.getY()).abs()) - / 2.0) + + return (Point::from(fnp) - Point::from(center)) + .abs() + .fold(|x, y| x - y) + .div(2.0) .floor() as u32; } else { firstConfirmedCenter.replace(center); @@ -679,10 +683,7 @@ impl<'a> FinderPatternFinder<'_> { * Get square of distance between a and b. */ fn squaredDistance(a: &FinderPattern, b: &FinderPattern) -> f64 { - let x = a.getX() as f64 - b.getX() as f64; - let y = a.getY() as f64 - b.getY() as f64; - - x * x + y * y + Point::from(a).squaredDistance(Point::from(b)) as f64 } /** diff --git a/src/qrcode/detector/qrcode_detector.rs b/src/qrcode/detector/qrcode_detector.rs index 17b4d6f..af84bfc 100644 --- a/src/qrcode/detector/qrcode_detector.rs +++ b/src/qrcode/detector/qrcode_detector.rs @@ -17,13 +17,10 @@ use std::collections::HashMap; use crate::{ - common::{ - detector::MathUtils, BitMatrix, DefaultGridSampler, GridSampler, PerspectiveTransform, - Result, - }, + common::{BitMatrix, DefaultGridSampler, GridSampler, PerspectiveTransform, Result}, + point, qrcode::decoder::Version, - result_point_utils, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, - RXingResultPointCallback, ResultPoint, + DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, Point, PointCallback, }; use super::{ @@ -39,7 +36,7 @@ use super::{ */ pub struct Detector<'a> { image: &'a BitMatrix, - resultPointCallback: Option, + resultPointCallback: Option, } impl<'a> Detector<'_> { @@ -54,7 +51,7 @@ impl<'a> Detector<'_> { self.image } - pub fn getRXingResultPointCallback(&self) -> &Option { + pub fn getPointCallback(&self) -> &Option { &self.resultPointCallback } @@ -116,16 +113,16 @@ impl<'a> Detector<'_> { // Anything above version 1 has an alignment pattern if !provisionalVersion.getAlignmentPatternCenters().is_empty() { // Guess where a "bottom right" finder pattern would have been - let bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX(); - let bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY(); + let bottomRightX = topRight.point.x - topLeft.point.x + bottomLeft.point.x; + let bottomRightY = topRight.point.y - topLeft.point.y + bottomLeft.point.y; // Estimate that alignment pattern is closer by 3 modules // from "bottom right" to known top left location let correctionToTopLeft = 1.0 - (3.0 / modulesBetweenFPCenters as f32); let estAlignmentX = - (topLeft.getX() + correctionToTopLeft * (bottomRightX - topLeft.getX())) as u32; + (topLeft.point.x + correctionToTopLeft * (bottomRightX - topLeft.point.x)) as u32; let estAlignmentY = - (topLeft.getY() + correctionToTopLeft * (bottomRightY - topLeft.getY())) as u32; + (topLeft.point.y + correctionToTopLeft * (bottomRightY - topLeft.point.y)) as u32; // Kind of arbitrary -- expand search radius before giving up let mut i = 4; @@ -153,29 +150,30 @@ impl<'a> Detector<'_> { let bits = Detector::sampleGrid(self.image, &transform, dimension)?; let mut points = vec![ - bottomLeft.into_rxing_result_point(), - topLeft.into_rxing_result_point(), - topRight.into_rxing_result_point(), + Point::from(bottomLeft), + Point::from(topLeft), + Point::from(topRight), ]; if alignmentPattern.is_some() { - points.push( - alignmentPattern - .ok_or(Exceptions::notFound)? - .into_rxing_result_point(), - ) + points.push(alignmentPattern.ok_or(Exceptions::notFound)?.into()) } Ok(QRCodeDetectorResult::new(bits, points)) } - fn createTransform( - topLeft: &T, - topRight: &T, - bottomLeft: &T, - alignmentPattern: Option<&X>, + fn createTransform, X: Into>( + topLeft: T, + topRight: T, + bottomLeft: T, + alignmentPattern: Option, dimension: u32, ) -> Option { + let topLeft: Point = topLeft.into(); + let topRight: Point = topRight.into(); + let bottomLeft: Point = bottomLeft.into(); + let alignmentPattern: Option = alignmentPattern.map(Into::into); + let dimMinusThree = dimension as f32 - 3.5; let bottomRightX: f32; let bottomRightY: f32; @@ -183,14 +181,14 @@ impl<'a> Detector<'_> { let sourceBottomRightY: f32; if alignmentPattern.is_some() { let alignmentPattern = alignmentPattern?; - bottomRightX = alignmentPattern.getX(); - bottomRightY = alignmentPattern.getY(); + bottomRightX = alignmentPattern.x; + bottomRightY = alignmentPattern.y; sourceBottomRightX = dimMinusThree - 3.0; sourceBottomRightY = sourceBottomRightX; } else { // Don't have an alignment pattern, just make up the bottom-right point - bottomRightX = (topRight.getX() - topLeft.getX()) + bottomLeft.getX(); - bottomRightY = (topRight.getY() - topLeft.getY()) + bottomLeft.getY(); + bottomRightX = (topRight.x - topLeft.x) + bottomLeft.x; + bottomRightY = (topRight.y - topLeft.y) + bottomLeft.y; sourceBottomRightX = dimMinusThree; sourceBottomRightY = dimMinusThree; } @@ -204,14 +202,14 @@ impl<'a> Detector<'_> { sourceBottomRightY, 3.5, dimMinusThree, - topLeft.getX(), - topLeft.getY(), - topRight.getX(), - topRight.getY(), + topLeft.x, + topLeft.y, + topRight.x, + topRight.y, bottomRightX, bottomRightY, - bottomLeft.getX(), - bottomLeft.getY(), + bottomLeft.x, + bottomLeft.y, )) } @@ -228,16 +226,16 @@ impl<'a> Detector<'_> { *

Computes the dimension (number of modules on a size) of the QR Code based on the position * of the finder patterns and estimated module size.

*/ - fn computeDimension( - topLeft: &T, - topRight: &T, - bottomLeft: &T, + fn computeDimension + Copy>( + topLeft: T, + topRight: T, + bottomLeft: T, moduleSize: f32, ) -> Result { let tltrCentersDimension = - MathUtils::round(result_point_utils::distance(topLeft, topRight) / moduleSize); + (Point::distance(topLeft.into(), topRight.into()) / moduleSize).round() as i32; let tlblCentersDimension = - MathUtils::round(result_point_utils::distance(topLeft, bottomLeft) / moduleSize); + (Point::distance(topLeft.into(), bottomLeft.into()) / moduleSize).round() as i32; let mut dimension = ((tltrCentersDimension + tlblCentersDimension) / 2) + 7; match dimension & 0x03 { 0 => dimension += 1, @@ -257,11 +255,11 @@ impl<'a> Detector<'_> { * @param bottomLeft detected bottom-left finder pattern center * @return estimated module size */ - pub fn calculateModuleSize( + pub fn calculateModuleSize + Copy>( &self, - topLeft: &T, - topRight: &T, - bottomLeft: &T, + topLeft: T, + topRight: T, + bottomLeft: T, ) -> f32 { // Take the average (self.calculateModuleSizeOneWay(topLeft, topRight) @@ -274,18 +272,21 @@ impl<'a> Detector<'_> { * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the * width of each, measuring along the axis between their centers.

*/ - fn calculateModuleSizeOneWay(&self, pattern: &T, otherPattern: &T) -> f32 { + fn calculateModuleSizeOneWay>(&self, pattern: T, otherPattern: T) -> f32 { + let pattern: Point = pattern.into(); + let otherPattern: Point = otherPattern.into(); + let moduleSizeEst1 = self.sizeOfBlackWhiteBlackRunBothWays( - pattern.getX().floor() as u32, - pattern.getY().floor() as u32, - otherPattern.getX().floor() as u32, - otherPattern.getY().floor() as u32, + pattern.x.floor() as u32, + pattern.y.floor() as u32, + otherPattern.x.floor() as u32, + otherPattern.y.floor() as u32, ); let moduleSizeEst2 = self.sizeOfBlackWhiteBlackRunBothWays( - otherPattern.getX().floor() as u32, - otherPattern.getY().floor() as u32, - pattern.getX().floor() as u32, - pattern.getY().floor() as u32, + otherPattern.x.floor() as u32, + otherPattern.y.floor() as u32, + pattern.x.floor() as u32, + pattern.y.floor() as u32, ); if moduleSizeEst1.is_nan() { return moduleSizeEst2 / 7.0; @@ -379,7 +380,10 @@ impl<'a> Detector<'_> { // color, advance to next state or end if we are in state 2 already if (state == 1) == self.image.get(realX as u32, realY as u32) { if state == 2 { - return MathUtils::distance(x, y, fromX as i32, fromY as i32); + return Point::distance( + point(x as f32, y as f32), + point(fromX as f32, fromY as f32), + ); } state += 1; } @@ -399,7 +403,10 @@ impl<'a> Detector<'_> { // is "white" so this last point at (toX+xStep,toY) is the right ending. This is really a // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this. if state == 2 { - return MathUtils::distance(toX as i32 + xstep, toY as i32, fromX as i32, fromY as i32); + return Point::distance( + point((toX as i32 + xstep) as f32, toY as f32), + point(fromX as f32, fromY as f32), + ); } // else we didn't find even black-white-black; no estimate is really possible f32::NAN diff --git a/src/qrcode/detector/qrcode_detector_result.rs b/src/qrcode/detector/qrcode_detector_result.rs index fa9070f..f3c3f30 100644 --- a/src/qrcode/detector/qrcode_detector_result.rs +++ b/src/qrcode/detector/qrcode_detector_result.rs @@ -1,15 +1,15 @@ use crate::{ common::{BitMatrix, DetectorRXingResult}, - RXingResultPoint, + Point, }; pub struct QRCodeDetectorResult { bit_source: BitMatrix, - result_points: Vec, + result_points: Vec, } impl QRCodeDetectorResult { - pub fn new(bit_source: BitMatrix, result_points: Vec) -> Self { + pub fn new(bit_source: BitMatrix, result_points: Vec) -> Self { Self { bit_source, result_points, @@ -22,7 +22,7 @@ impl DetectorRXingResult for QRCodeDetectorResult { &self.bit_source } - fn getPoints(&self) -> &[crate::RXingResultPoint] { + fn getPoints(&self) -> &[crate::Point] { &self.result_points } } diff --git a/src/qrcode/qr_code_reader.rs b/src/qrcode/qr_code_reader.rs index 8d00e27..b268518 100644 --- a/src/qrcode/qr_code_reader.rs +++ b/src/qrcode/qr_code_reader.rs @@ -18,8 +18,8 @@ use std::collections::HashMap; use crate::{ common::{BitMatrix, DecoderRXingResult, DetectorRXingResult, Result}, - BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, RXingResult, - RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint, Reader, + BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, Point, RXingResult, + RXingResultMetadataType, RXingResultMetadataValue, Reader, }; use super::{ @@ -36,7 +36,7 @@ use super::{ pub struct QRCodeReader; // pub struct QRCodeReader; { -// // private static final RXingResultPoint[] NO_POINTS = new RXingResultPoint[0]; +// // private static final Point[] NO_POINTS = new Point[0]; // } impl Reader for QRCodeReader { @@ -58,7 +58,7 @@ impl Reader for QRCodeReader { hints: &crate::DecodingHintDictionary, ) -> Result { let decoderRXingResult: DecoderRXingResult; - let mut points: Vec; + let mut points: Vec; if matches!( hints.get(&DecodeHintType::PURE_BARCODE), Some(DecodeHintValue::PureBarcode(true)) diff --git a/src/result_point.rs b/src/result_point.rs index 256a6e5..8b1565d 100644 --- a/src/result_point.rs +++ b/src/result_point.rs @@ -16,10 +16,10 @@ //package com.google.zxing; -use crate::RXingResultPoint; +use crate::Point; pub trait ResultPoint { fn getX(&self) -> f32; fn getY(&self) -> f32; - fn into_rxing_result_point(self) -> RXingResultPoint; + fn to_rxing_result_point(&self) -> Point; } diff --git a/src/result_point_utils.rs b/src/result_point_utils.rs index 39d7755..c8a4a33 100644 --- a/src/result_point_utils.rs +++ b/src/result_point_utils.rs @@ -1,87 +1,43 @@ -use crate::{common::detector::MathUtils, ResultPoint}; +use crate::Point; /** - * Orders an array of three RXingResultPoints in an order [A,B,C] such that AB is less than AC + * Orders an array of three Points in an order [A,B,C] such that AB is less than AC * and BC is less than AC, and the angle between BC and BA is less than 180 degrees. * - * @param patterns array of three {@code RXingResultPoint} to order + * @param patterns array of three {@code Point} to order */ -pub fn orderBestPatterns(patterns: &mut [T; 3]) { +pub fn orderBestPatterns + Copy>(patterns: &mut [T; 3]) { // Find distances between pattern centers - let zeroOneDistance = MathUtils::distance( - patterns[0].getX(), - patterns[0].getY(), - patterns[1].getX(), - patterns[1].getY(), - ); - let oneTwoDistance = MathUtils::distance( - patterns[1].getX(), - patterns[1].getY(), - patterns[2].getX(), - patterns[2].getY(), - ); - let zeroTwoDistance = MathUtils::distance( - patterns[0].getX(), - patterns[0].getY(), - patterns[2].getX(), - patterns[2].getY(), - ); - - let mut pointA; - let pointB; - let mut pointC; + let zeroOneDistance = Point::distance(patterns[0].into(), patterns[1].into()); + let oneTwoDistance = Point::distance(patterns[1].into(), patterns[2].into()); + let zeroTwoDistance = Point::distance(patterns[0].into(), patterns[2].into()); // Assume one closest to other two is B; A and C will just be guesses at first - if oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance { - pointB = patterns[0]; - pointA = patterns[1]; - pointC = patterns[2]; - } else if zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance { - pointB = patterns[1]; - pointA = patterns[0]; - pointC = patterns[2]; - } else { - pointB = patterns[2]; - pointA = patterns[0]; - pointC = patterns[1]; - } + let (mut pointA, pointB, mut pointC) = + if oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance { + (patterns[1], patterns[0], patterns[2]) + } else if zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance { + (patterns[0], patterns[1], patterns[2]) + } else { + (patterns[0], patterns[2], patterns[1]) + }; // Use cross product to figure out whether A and C are correct or flipped. // This asks whether BC x BA has a positive z component, which is the arrangement // we want for A, B, C. If it's negative, then we've got it flipped around and // should swap A and C. - if crossProductZ(pointA, pointB, pointC) < 0.0 { + if crossProductZ(pointA.into(), pointB.into(), pointC.into()) < 0.0 { std::mem::swap(&mut pointA, &mut pointC); } - let pa = pointA; - let pb = pointB; - let pc = pointC; - - patterns[0] = pa; - patterns[1] = pb; - patterns[2] = pc; -} - -/** - * @param pattern1 first pattern - * @param pattern2 second pattern - * @return distance between two points - */ -pub fn distance(pattern1: &T, pattern2: &T) -> f32 { - MathUtils::distance( - pattern1.getX(), - pattern1.getY(), - pattern2.getX(), - pattern2.getY(), - ) + patterns[0] = pointA; + patterns[1] = pointB; + patterns[2] = pointC; } /** * Returns the z component of the cross product between vectors BC and BA. */ -pub fn crossProductZ(pointA: T, pointB: T, pointC: T) -> f32 { - let bX = pointB.getX(); - let bY = pointB.getY(); - ((pointC.getX() - bX) * (pointA.getY() - bY)) - ((pointC.getY() - bY) * (pointA.getX() - bX)) +fn crossProductZ(a: Point, b: Point, c: Point) -> f32 { + ((c.x - b.x) * (a.y - b.y)) - ((c.y - b.y) * (a.x - b.x)) } diff --git a/src/rxing_result.rs b/src/rxing_result.rs index 5a72a84..90c544d 100644 --- a/src/rxing_result.rs +++ b/src/rxing_result.rs @@ -16,7 +16,7 @@ use std::{collections::HashMap, fmt}; -use crate::{BarcodeFormat, RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint}; +use crate::{BarcodeFormat, Point, RXingResultMetadataType, RXingResultMetadataValue}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -32,7 +32,7 @@ pub struct RXingResult { text: String, rawBytes: Vec, numBits: usize, - resultPoints: Vec, + resultPoints: Vec, format: BarcodeFormat, resultMetadata: HashMap, timestamp: u128, @@ -41,7 +41,7 @@ impl RXingResult { pub fn new( text: &str, rawBytes: Vec, - resultPoints: Vec, + resultPoints: Vec, format: BarcodeFormat, ) -> Self { Self::new_timestamp( @@ -56,7 +56,7 @@ impl RXingResult { pub fn new_timestamp( text: &str, rawBytes: Vec, - resultPoints: Vec, + resultPoints: Vec, format: BarcodeFormat, timestamp: u128, ) -> Self { @@ -68,7 +68,7 @@ impl RXingResult { text: &str, rawBytes: Vec, numBits: usize, - resultPoints: Vec, + resultPoints: Vec, format: BarcodeFormat, timestamp: u128, ) -> Self { @@ -83,7 +83,7 @@ impl RXingResult { } } - pub fn new_from_existing_result(prev: Self, points: Vec) -> Self { + pub fn new_from_existing_result(prev: Self, points: Vec) -> Self { Self { text: prev.text, rawBytes: prev.rawBytes, @@ -122,11 +122,21 @@ impl RXingResult { * identifying finder patterns or the corners of the barcode. The exact meaning is * specific to the type of barcode that was decoded. */ - pub fn getRXingResultPoints(&self) -> &Vec { + pub fn getPoints(&self) -> &Vec { &self.resultPoints } - pub fn getRXingResultPointsMut(&mut self) -> &mut Vec { + pub fn getPointsMut(&mut self) -> &mut Vec { + &mut self.resultPoints + } + + /** Currently necessary because the external OneDReader proc macro uses it. */ + pub fn getRXingResultPoints(&self) -> &Vec { + &&self.resultPoints + } + + /** Currently necessary because the external OneDReader proc macro uses it. */ + pub fn getRXingResultPointsMut(&mut self) -> &mut Vec { &mut self.resultPoints } @@ -169,7 +179,7 @@ impl RXingResult { } } - pub fn addRXingResultPoints(&mut self, newPoints: &mut Vec) { + pub fn addPoints(&mut self, newPoints: &mut Vec) { if !newPoints.is_empty() { self.resultPoints.append(newPoints); } diff --git a/src/rxing_result_point.rs b/src/rxing_result_point.rs index fb3128f..534ea96 100644 --- a/src/rxing_result_point.rs +++ b/src/rxing_result_point.rs @@ -1,11 +1,12 @@ use std::{fmt, iter::Sum}; -use crate::ResultPoint; use std::hash::Hash; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; +use crate::ResultPoint; + /** *

Encapsulates a point of interest in an image containing a barcode. Typically, this * would be the location of a finder pattern or the corner of the barcode, for example.

@@ -14,49 +15,58 @@ use serde::{Deserialize, Serialize}; */ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Debug, Clone, Copy, Default)] -pub struct RXingResultPoint { +pub struct Point { pub(crate) x: f32, pub(crate) y: f32, } -impl Hash for RXingResultPoint { + +/** An alias for `Point::new`. */ +pub fn point(x: f32, y: f32) -> Point { + Point::new(x, y) +} + +/** Currently necessary because the external OneDReader proc macro uses it. */ +pub type RXingResultPoint = Point; + +impl Hash for Point { fn hash(&self, state: &mut H) { self.x.to_string().hash(state); self.y.to_string().hash(state); } } -impl PartialEq for RXingResultPoint { + +impl PartialEq for Point { fn eq(&self, other: &Self) -> bool { self.x == other.x && self.y == other.y } } -impl Eq for RXingResultPoint {} -impl RXingResultPoint { +impl Eq for Point {} + +impl Point { pub const fn new(x: f32, y: f32) -> Self { Self { x, y } } + pub const fn with_single(x: f32) -> Self { Self { x, y: x } } } -impl std::ops::AddAssign for RXingResultPoint { +impl std::ops::AddAssign for Point { fn add_assign(&mut self, rhs: Self) { self.x = self.x + rhs.x; self.y = self.y + rhs.y; } } -impl<'a> Sum<&'a RXingResultPoint> for RXingResultPoint { - fn sum>(iter: I) -> Self { - let mut add = RXingResultPoint { x: 0.0, y: 0.0 }; - for n in iter { - add += *n; - } - add +impl<'a> Sum<&'a Point> for Point { + fn sum>(iter: I) -> Self { + iter.fold(Self::default(), |acc, &p| acc + p) } } -impl ResultPoint for RXingResultPoint { +/** This impl is temporary and is there to ease refactoring. */ +impl ResultPoint for Point { fn getX(&self) -> f32 { self.x } @@ -65,210 +75,187 @@ impl ResultPoint for RXingResultPoint { self.y } - fn into_rxing_result_point(self) -> RXingResultPoint { - self + fn to_rxing_result_point(&self) -> Self { + *self } } -impl fmt::Display for RXingResultPoint { +impl fmt::Display for Point { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "({},{})", self.x, self.y) } } -impl std::ops::Sub for RXingResultPoint { - type Output = RXingResultPoint; +impl std::ops::Sub for Point { + type Output = Self; fn sub(self, rhs: Self) -> Self::Output { - Self { - x: self.x - rhs.x, - y: self.y - rhs.y, - } + Self::new(self.x - rhs.x, self.y - rhs.y) } } -impl std::ops::Sub<&RXingResultPoint> for RXingResultPoint { - type Output = RXingResultPoint; - - fn sub(self, rhs: &Self) -> Self::Output { - Self { - x: self.x - rhs.x, - y: self.y - rhs.y, - } - } -} - -impl std::ops::Neg for RXingResultPoint { - type Output = RXingResultPoint; +impl std::ops::Neg for Point { + type Output = Self; fn neg(self) -> Self::Output { - Self { - x: -self.x, - y: -self.y, - } + Self::new(-self.x, -self.y) } } -impl std::ops::Add for RXingResultPoint { - type Output = RXingResultPoint; +impl std::ops::Add for Point { + type Output = Self; - fn add(self, rhs: RXingResultPoint) -> Self::Output { - Self { - x: self.x + rhs.x, - y: self.y + rhs.y, - } + fn add(self, rhs: Self) -> Self::Output { + Self::new(self.x + rhs.x, self.y + rhs.y) } } -impl std::ops::Mul for RXingResultPoint { - type Output = RXingResultPoint; +impl std::ops::Mul for Point { + type Output = Self; - fn mul(self, rhs: RXingResultPoint) -> Self::Output { - Self { - x: self.x * rhs.x, - y: self.y * rhs.y, - } + fn mul(self, rhs: Self) -> Self::Output { + Self::new(self.x * rhs.x, self.y * rhs.y) } } -impl std::ops::Mul for RXingResultPoint { - type Output = RXingResultPoint; +impl std::ops::Mul for Point { + type Output = Self; fn mul(self, rhs: f32) -> Self::Output { - Self { - x: self.x * rhs, - y: self.y * rhs, - } + Self::new(self.x * rhs, self.y * rhs) } } -impl std::ops::Mul for RXingResultPoint { - type Output = RXingResultPoint; +impl std::ops::Mul for Point { + type Output = Self; fn mul(self, rhs: i32) -> Self::Output { - Self { - x: self.x * rhs as f32, - y: self.y * rhs as f32, - } + Self::new(self.x * rhs as f32, self.y * rhs as f32) } } -impl std::ops::Mul for i32 { - type Output = RXingResultPoint; +impl std::ops::Mul for i32 { + type Output = Point; - fn mul(self, rhs: RXingResultPoint) -> Self::Output { - RXingResultPoint { - x: rhs.x * self as f32, - y: rhs.y * self as f32, - } + fn mul(self, rhs: Point) -> Self::Output { + Self::Output::new(rhs.x * self as f32, rhs.y * self as f32) } } -impl std::ops::Mul for f32 { - type Output = RXingResultPoint; +impl std::ops::Mul for f32 { + type Output = Point; - fn mul(self, rhs: RXingResultPoint) -> Self::Output { - RXingResultPoint { - x: rhs.x * self, - y: rhs.y * self, - } + fn mul(self, rhs: Point) -> Self::Output { + Self::Output::new(rhs.x * self, rhs.y * self) } } -impl std::ops::Mul<&RXingResultPoint> for f32 { - type Output = RXingResultPoint; - - fn mul(self, rhs: &RXingResultPoint) -> Self::Output { - RXingResultPoint { - x: rhs.x * self, - y: rhs.y * self, - } - } -} - -impl std::ops::Mul<&mut RXingResultPoint> for f32 { - type Output = RXingResultPoint; - - fn mul(self, rhs: &mut RXingResultPoint) -> Self::Output { - RXingResultPoint { - x: rhs.x * self, - y: rhs.y * self, - } - } -} - -impl std::ops::Div for RXingResultPoint { - type Output = RXingResultPoint; +impl std::ops::Div for Point { + type Output = Point; fn div(self, rhs: f32) -> Self::Output { - Self { - x: self.x / rhs, - y: self.y / rhs, - } + Self::Output::new(self.x / rhs, self.y / rhs) } } -impl RXingResultPoint { - pub fn dot(a: RXingResultPoint, b: RXingResultPoint) -> f32 { - a.x * b.x + a.y * b.y +impl Point { + pub fn dot(self, p: Self) -> f32 { + self.x * p.x + self.y * p.y } - pub fn cross(a: &RXingResultPoint, b: &RXingResultPoint) -> f32 { - a.x * b.y - b.x * a.y + pub fn cross(self, p: Self) -> f32 { + self.x * p.y - p.x * self.y } /// L1 norm - pub fn sumAbsComponent(p: &RXingResultPoint) -> f32 { - (p.x).abs() + (p.y).abs() + pub fn sumAbsComponent(self) -> f32 { + self.x.abs() + self.y.abs() } /// L2 norm - pub fn length(p: RXingResultPoint) -> f32 { - (Self::dot(p, p)).sqrt() + pub fn length(self) -> f32 { + self.x.hypot(self.y) } /// L-inf norm - pub fn maxAbsComponent(p: &RXingResultPoint) -> f32 { - let a = (p.x).abs(); - let b = (p.y).abs(); - - if a > b { - a - } else { - b - } - - // return std::cmp::max((p.x).abs(), (p.y).abs()); + pub fn maxAbsComponent(self) -> f32 { + f32::max(self.x.abs(), self.y.abs()) } - pub fn distance(a: RXingResultPoint, b: RXingResultPoint) -> f32 { - Self::length(a - b) + pub fn squaredDistance(self, p: Self) -> f32 { + let diff = self - p; + diff.x * diff.x + diff.y * diff.y + } + + pub fn distance(self, p: Self) -> f32 { + (self - p).length() + } + + pub fn abs(self) -> Self { + Self::new(self.x.abs(), self.y.abs()) + } + + pub fn fold U>(self, f: F) -> U { + f(self.x, self.y) } /// Calculate a floating point pixel coordinate representing the 'center' of the pixel. /// This is sort of the inverse operation of the PointI(PointF) conversion constructor. /// See also the documentation of the GridSampler API. #[inline(always)] - pub fn centered(p: &RXingResultPoint) -> RXingResultPoint { - RXingResultPoint { - x: (p.x).floor() + 0.5, - y: (p.y).floor() + 0.5, - } + pub fn centered(self) -> Self { + Self::new(self.x.floor() + 0.5, self.y.floor() + 0.5) } - pub fn normalized(d: RXingResultPoint) -> RXingResultPoint { - d / Self::length(d) + pub fn middle(self, p: Self) -> Self { + (self + p) / 2.0 } - pub fn bresenhamDirection(d: &RXingResultPoint) -> RXingResultPoint { - *d / Self::maxAbsComponent(d) + pub fn normalized(self) -> Self { + self / Self::length(self) } - pub fn mainDirection(d: RXingResultPoint) -> RXingResultPoint { - if (d.x).abs() > (d.y).abs() { - Self::new(d.x, 0.0) + pub fn bresenhamDirection(self) -> Self { + self / Self::maxAbsComponent(self) + } + + pub fn mainDirection(self) -> Self { + if self.x.abs() > self.y.abs() { + Self::new(self.x, 0.0) } else { - Self::new(0.0, d.y) + Self::new(0.0, self.y) } } } + +impl From<&(f32, f32)> for Point { + fn from(&(x, y): &(f32, f32)) -> Self { + Self::new(x, y) + } +} + +impl From<(f32, f32)> for Point { + fn from((x, y): (f32, f32)) -> Self { + Self::new(x, y) + } +} + +#[cfg(test)] +mod tests { + use super::Point; + + #[test] + fn testDistance() { + assert_eq!( + (8.0f32).sqrt(), + Point::new(1.0, 2.0).distance(Point::new(3.0, 4.0)) + ); + assert_eq!(0.0, Point::new(1.0, 2.0).distance(Point::new(1.0, 2.0))); + + assert_eq!( + (8.0f32).sqrt(), + Point::new(1.0, 2.0).distance(Point::new(3.0, 4.0)) + ); + assert_eq!(0.0, Point::new(1.0, 2.0).distance(Point::new(1.0, 2.0))); + } +}