mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
port finder pattern finder
This commit is contained in:
@@ -23,7 +23,7 @@ use crate::{
|
||||
BitMatrix, DefaultGridSampler, GridSampler,
|
||||
},
|
||||
exceptions::Exceptions,
|
||||
RXingResultPoint,
|
||||
RXingResultPoint, ResultPoint,
|
||||
};
|
||||
|
||||
use super::AztecDetectorResult::AztecDetectorRXingResult;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pub mod MathUtils;
|
||||
use crate::common::BitMatrix;
|
||||
use crate::{Exceptions, RXingResultPoint};
|
||||
use crate::{Exceptions, RXingResultPoint, ResultPoint};
|
||||
|
||||
/*
|
||||
* Copyright 2009 ZXing authors
|
||||
|
||||
226
src/lib.rs
226
src/lib.rs
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user