port finder pattern finder

This commit is contained in:
Henry Schimke
2022-10-07 18:25:46 -05:00
parent 8f831b63e8
commit a205e1e08b
7 changed files with 895 additions and 771 deletions

View File

@@ -23,7 +23,7 @@ use crate::{
BitMatrix, DefaultGridSampler, GridSampler,
},
exceptions::Exceptions,
RXingResultPoint,
RXingResultPoint, ResultPoint,
};
use super::AztecDetectorResult::AztecDetectorRXingResult;

View File

@@ -1,6 +1,6 @@
pub mod MathUtils;
use crate::common::BitMatrix;
use crate::{Exceptions, RXingResultPoint};
use crate::{Exceptions, RXingResultPoint, ResultPoint};
/*
* Copyright 2009 ZXing authors

View File

@@ -1,8 +1,8 @@
pub mod aztec;
pub mod qrcode;
pub mod client;
pub mod common;
mod exceptions;
pub mod qrcode;
pub use exceptions::Exceptions;
@@ -26,10 +26,9 @@ mod PlanarYUVLuminanceSourceTestCase;
#[cfg(test)]
mod RGBLuminanceSourceTestCase;
pub type EncodingHintDictionary = HashMap<EncodeHintType,EncodeHintValue>;
pub type DecodingHintDictionary= HashMap<DecodeHintType,DecodeHintValue>;
pub type MetadataDictionary = HashMap<RXingResultMetadataType,RXingResultMetadataValue>;
pub type EncodingHintDictionary = HashMap<EncodeHintType, EncodeHintValue>;
pub type DecodingHintDictionary = HashMap<DecodeHintType, DecodeHintValue>;
pub type MetadataDictionary = HashMap<RXingResultMetadataType, RXingResultMetadataValue>;
/*
* Copyright 2007 ZXing authors
@@ -54,7 +53,7 @@ pub type MetadataDictionary = HashMap<RXingResultMetadataType,RXingResultMetadat
*
* @author Sean Owen
*/
#[derive(Debug, PartialEq, Eq, Hash,Clone, Copy)]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum BarcodeFormat {
/** Aztec 2D barcode format. */
AZTEC,
@@ -566,7 +565,7 @@ pub enum DecodeHintType {
*
* @see DecodeHintType#NEED_RESULT_POINT_CALLBACK
*/
pub type RXingResultPointCallback = fn(&RXingResultPoint);
pub type RXingResultPointCallback = fn(&dyn ResultPoint);
#[derive(Clone)]
pub enum DecodeHintValue {
/**
@@ -885,21 +884,21 @@ impl From<String> for RXingResultMetadataType {
"OTHER" => RXingResultMetadataType::OTHER,
"ORIENTATION" => RXingResultMetadataType::ORIENTATION,
"BYTE_SEGMENTS" => RXingResultMetadataType::BYTE_SEGMENTS,
"ERROR_CORRECTION_LEVEL"=> RXingResultMetadataType::ERROR_CORRECTION_LEVEL,
"ISSUE_NUMBER"=> RXingResultMetadataType::ISSUE_NUMBER,
"SUGGESTED_PRICE"=> RXingResultMetadataType::SUGGESTED_PRICE,
"POSSIBLE_COUNTRY"=> RXingResultMetadataType::POSSIBLE_COUNTRY,
"UPC_EAN_EXTENSION"=>RXingResultMetadataType::UPC_EAN_EXTENSION,
"PDF417_EXTRA_METADATA"=> RXingResultMetadataType::PDF417_EXTRA_METADATA,
"STRUCTURED_APPEND_SEQUENCE"=> RXingResultMetadataType::STRUCTURED_APPEND_SEQUENCE,
"STRUCTURED_APPEND_PARITY"=>RXingResultMetadataType::STRUCTURED_APPEND_PARITY,
"SYMBOLOGY_IDENTIFIER"=>RXingResultMetadataType::SYMBOLOGY_IDENTIFIER,
"ERROR_CORRECTION_LEVEL" => RXingResultMetadataType::ERROR_CORRECTION_LEVEL,
"ISSUE_NUMBER" => RXingResultMetadataType::ISSUE_NUMBER,
"SUGGESTED_PRICE" => RXingResultMetadataType::SUGGESTED_PRICE,
"POSSIBLE_COUNTRY" => RXingResultMetadataType::POSSIBLE_COUNTRY,
"UPC_EAN_EXTENSION" => RXingResultMetadataType::UPC_EAN_EXTENSION,
"PDF417_EXTRA_METADATA" => RXingResultMetadataType::PDF417_EXTRA_METADATA,
"STRUCTURED_APPEND_SEQUENCE" => RXingResultMetadataType::STRUCTURED_APPEND_SEQUENCE,
"STRUCTURED_APPEND_PARITY" => RXingResultMetadataType::STRUCTURED_APPEND_PARITY,
"SYMBOLOGY_IDENTIFIER" => RXingResultMetadataType::SYMBOLOGY_IDENTIFIER,
_ => RXingResultMetadataType::OTHER,
}
}
}
#[derive(Debug,PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)]
pub enum RXingResultMetadataValue {
/**
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
@@ -1174,6 +1173,107 @@ impl fmt::Display for RXingResult {
//package com.google.zxing;
use crate::common::detector::MathUtils;
pub trait ResultPoint {
fn getX(&self) -> f32;
fn getY(&self) -> f32;
}
pub mod result_point_utils {
use crate::{common::detector::MathUtils, ResultPoint};
/**
* Orders an array of three RXingResultPoints 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
*/
pub fn orderBestPatterns<T: ResultPoint+Copy+Clone>(patterns: &mut [T; 3]) {
// Find distances between pattern centers
let zeroOneDistance = MathUtils::distance_float(
patterns[0].getX(),
patterns[0].getY(),
patterns[1].getX(),
patterns[1].getY(),
);
let oneTwoDistance = MathUtils::distance_float(
patterns[1].getX(),
patterns[1].getY(),
patterns[2].getX(),
patterns[2].getY(),
);
let zeroTwoDistance = MathUtils::distance_float(
patterns[0].getX(),
patterns[0].getY(),
patterns[2].getX(),
patterns[2].getY(),
);
let mut pointA; //: &RXingResultPoint;
let mut pointB; //: &RXingResultPoint;
let mut pointC; //: &RXingResultPoint;
// 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];
}
// 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.0f32 {
let temp = pointA;
pointA = pointC;
pointC = temp;
}
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<T:ResultPoint>(pattern1: T, pattern2: T) -> f32 {
return MathUtils::distance_float(
pattern1.getX(),
pattern1.getY(),
pattern2.getX(),
pattern2.getY(),
);
}
/**
* Returns the z component of the cross product between vectors BC and BA.
*/
pub fn crossProductZ<T: ResultPoint>(
pointA: T,
pointB: T,
pointC: T,
) -> f32 {
let bX = pointB.getX();
let bY = pointB.getY();
return ((pointC.getX() - bX) * (pointA.getY() - bY))
- ((pointC.getY() - bY) * (pointA.getX() - bX));
}
}
/**
* <p>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.</p>
@@ -1201,100 +1301,16 @@ impl RXingResultPoint {
pub const fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
}
pub fn getX(&self) -> f32 {
impl ResultPoint for RXingResultPoint {
fn getX(&self) -> f32 {
return self.x;
}
pub fn getY(&self) -> f32 {
fn getY(&self) -> f32 {
return self.y;
}
/**
* Orders an array of three RXingResultPoints 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
*/
pub fn orderBestPatterns(patterns: &mut Vec<RXingResultPoint>) {
// Find distances between pattern centers
let zeroOneDistance = MathUtils::distance_float(
patterns[0].getX(),
patterns[0].getY(),
patterns[1].getX(),
patterns[1].getY(),
);
let oneTwoDistance = MathUtils::distance_float(
patterns[1].getX(),
patterns[1].getY(),
patterns[2].getX(),
patterns[2].getY(),
);
let zeroTwoDistance = MathUtils::distance_float(
patterns[0].getX(),
patterns[0].getY(),
patterns[2].getX(),
patterns[2].getY(),
);
let mut pointA: &RXingResultPoint;
let mut pointB: &RXingResultPoint;
let mut pointC: &RXingResultPoint;
// 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];
}
// 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 RXingResultPoint::crossProductZ(&pointA, &pointB, &pointC) < 0.0f32 {
let temp = pointA;
pointA = pointC;
pointC = temp;
}
let pa = (*pointA).clone();
let pb = (*pointB).clone();
let pc = (*pointC).clone();
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: &RXingResultPoint, pattern2: &RXingResultPoint) -> f32 {
return MathUtils::distance_float(pattern1.x, pattern1.y, pattern2.x, pattern2.y);
}
/**
* Returns the z component of the cross product between vectors BC and BA.
*/
pub fn crossProductZ(
pointA: &RXingResultPoint,
pointB: &RXingResultPoint,
pointC: &RXingResultPoint,
) -> f32 {
let bX = pointB.x;
let bY = pointB.y;
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
}
}
impl fmt::Display for RXingResultPoint {

View File

@@ -16,7 +16,7 @@
//RXingResultPoint
use crate::RXingResultPoint;
use crate::{RXingResultPoint, ResultPoint};
/**
* <p>Encapsulates an alignment pattern, which are the smaller square patterns found in
@@ -24,17 +24,27 @@ use crate::RXingResultPoint;
*
* @author Sean Owen
*/
#[derive(Clone)]
#[derive(Debug,Clone, Copy,PartialEq)]
pub struct AlignmentPattern {
estimatedModuleSize: f32,
internal_result_point: RXingResultPoint,
point: (f32, f32),
}
impl ResultPoint for AlignmentPattern {
fn getX(&self) -> f32 {
self.point.0
}
fn getY(&self) -> f32 {
self.point.1
}
}
impl AlignmentPattern {
pub fn new(posX: f32, posY: f32, estimatedModuleSize: f32) -> Self {
Self {
estimatedModuleSize,
internal_result_point: RXingResultPoint { x: posX, y: posY },
point: (posX, posY),
}
}
@@ -43,9 +53,7 @@ impl AlignmentPattern {
* position and size -- meaning, it is at nearly the same center with nearly the same size.</p>
*/
pub fn aboutEquals(&self, moduleSize: f32, i: f32, j: f32) -> bool {
if (i - self.internal_result_point.getY()).abs() <= moduleSize
&& (j - self.internal_result_point.getX()).abs() <= moduleSize
{
if (i - self.getY()).abs() <= moduleSize && (j - self.getX()).abs() <= moduleSize {
let moduleSizeDiff = (moduleSize - self.estimatedModuleSize).abs();
return moduleSizeDiff <= 1.0 || moduleSizeDiff <= self.estimatedModuleSize;
}
@@ -57,13 +65,9 @@ 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.internal_result_point.getX() + j) / 2.0;
let combinedY = (self.internal_result_point.getY() + i) / 2.0;
let combinedX = (self.getX() + j) / 2.0;
let combinedY = (self.getY() + i) / 2.0;
let combinedModuleSize = (self.estimatedModuleSize + newModuleSize) / 2.0;
AlignmentPattern::new(combinedX, combinedY, combinedModuleSize)
}
pub fn as_RXingResultPoint(&self) -> &RXingResultPoint {
&self.internal_result_point
}
}

View File

@@ -306,7 +306,7 @@ impl AlignmentPatternFinder {
// Hadn't found this before; save it
let point = AlignmentPattern::new(centerJ, centerI, estimatedModuleSize);
if self.resultPointCallback.is_some() {
self.resultPointCallback.as_ref().unwrap()(point.as_RXingResultPoint());
self.resultPointCallback.as_ref().unwrap()(&point);
}
self.possibleCenters.push(point);
// if self.resultPointCallback.is_some() {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
use crate::RXingResultPoint;
use crate::{RXingResultPoint, ResultPoint};
/**
* <p>Encapsulates a finder pattern, which are the three square patterns found in
@@ -23,10 +23,21 @@ use crate::RXingResultPoint;
*
* @author Sean Owen
*/
pub struct FinderPattern {
#[derive(Debug,Clone, Copy,PartialEq)]
pub struct FinderPattern {
estimatedModuleSize: f32,
count: usize,
internal_result_point: RXingResultPoint,
point: (f32, f32),
}
impl ResultPoint for FinderPattern {
fn getX(&self) -> f32 {
self.point.0
}
fn getY(&self) -> f32 {
self.point.1
}
}
impl FinderPattern {
@@ -38,7 +49,7 @@ impl FinderPattern {
Self {
estimatedModuleSize,
count,
internal_result_point: RXingResultPoint::new(posX, posY),
point: (posX, posY),
}
}
@@ -55,9 +66,7 @@ impl FinderPattern {
* position and size -- meaning, it is at nearly the same center with nearly the same size.</p>
*/
pub fn aboutEquals(&self, moduleSize: f32, i: f32, j: f32) -> bool {
if (i - self.internal_result_point.getY()).abs() <= moduleSize
&& (j - self.internal_result_point.getX()).abs() <= moduleSize
{
if (i - self.getY()).abs() <= moduleSize && (j - self.getX()).abs() <= moduleSize {
let moduleSizeDiff = (moduleSize - self.estimatedModuleSize).abs();
return moduleSizeDiff <= 1.0 || moduleSizeDiff <= self.estimatedModuleSize;
}
@@ -71,8 +80,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.internal_result_point.getX() + j) / combinedCount;
let combinedY = (self.count as f32 * self.internal_result_point.getY() + i) / combinedCount;
let combinedX = (self.count as f32 * self.getX() + j) / combinedCount;
let combinedY = (self.count as f32 * self.getY() + i) / combinedCount;
let combinedModuleSize =
(self.count as f32 * self.estimatedModuleSize + newModuleSize) / combinedCount;
FinderPattern::private_new(

File diff suppressed because it is too large Load Diff