cargo fix

This commit is contained in:
Henry
2023-04-28 19:15:25 -05:00
parent 9a8df1931b
commit 2afc6be3dc
22 changed files with 157 additions and 158 deletions

View File

@@ -18,7 +18,7 @@
// import java.util.Arrays; // import java.util.Arrays;
use std::ops::Index;
use std::{cmp, fmt}; use std::{cmp, fmt};
use crate::common::Result; use crate::common::Result;

View File

@@ -63,9 +63,9 @@ impl BitMatrix {
let mut right = 0; let mut right = 0;
let mut bottom = 0; let mut bottom = 0;
if (!self.getTopLeftOnBitWithPosition(&mut left, &mut top) if !self.getTopLeftOnBitWithPosition(&mut left, &mut top)
|| !self.getBottomRightOnBitWithPosition(&mut right, &mut bottom) || !self.getBottomRightOnBitWithPosition(&mut right, &mut bottom)
|| bottom - top + 1 < minSize) || bottom - top + 1 < minSize
{ {
return (false, left, top, width, height); return (false, left, top, width, height);
} }
@@ -74,14 +74,14 @@ impl BitMatrix {
// for (int y = top; y <= bottom; y++ ) { // for (int y = top; y <= bottom; y++ ) {
for x in 0..left { for x in 0..left {
// for (int x = 0; x < left; ++x){ // for (int x = 0; x < left; ++x){
if (self.get(x, y)) { if self.get(x, y) {
left = x; left = x;
break; break;
} }
} }
for x in (right..(self.width() - 1)).rev() { for x in (right..(self.width() - 1)).rev() {
// for (int x = _width-1; x > right; x--){ // for (int x = _width-1; x > right; x--){
if (self.get(x, y)) { if self.get(x, y) {
right = x; right = x;
break; break;
} }

View File

@@ -1,9 +1,9 @@
use crate::common::Result;
use crate::qrcode::decoder::ErrorCorrectionLevel; use crate::qrcode::decoder::ErrorCorrectionLevel;
impl ErrorCorrectionLevel { impl ErrorCorrectionLevel {
pub fn ECLevelFromBitsSigned(bits: i8, isMicro: bool) -> Self { pub fn ECLevelFromBitsSigned(bits: i8, isMicro: bool) -> Self {
if (isMicro) { if isMicro {
let LEVEL_FOR_BITS: [ErrorCorrectionLevel; 8] = [ let LEVEL_FOR_BITS: [ErrorCorrectionLevel; 8] = [
ErrorCorrectionLevel::L, ErrorCorrectionLevel::L,
ErrorCorrectionLevel::L, ErrorCorrectionLevel::L,

View File

@@ -1,4 +1,4 @@
use crate::common::Result;
use crate::qrcode::decoder::{ use crate::qrcode::decoder::{
ErrorCorrectionLevel, FormatInformation, FORMAT_INFO_DECODE_LOOKUP, FORMAT_INFO_MASK_QR, ErrorCorrectionLevel, FormatInformation, FORMAT_INFO_DECODE_LOOKUP, FORMAT_INFO_MASK_QR,
@@ -84,7 +84,7 @@ impl FormatInformation {
// Bits 2/3/4 contain both error correction level and version, 0/1 contain mask. // Bits 2/3/4 contain both error correction level and version, 0/1 contain mask.
fi.error_correction_level = fi.error_correction_level =
ErrorCorrectionLevel::ECLevelFromBits((fi.index >> 2) & 0x07, true); ErrorCorrectionLevel::ECLevelFromBits((fi.index >> 2) & 0x07, true);
fi.data_mask = (fi.index & 0x03); fi.data_mask = fi.index & 0x03;
fi.microVersion = BITS_TO_VERSION[((fi.index >> 2) & 0x07) as usize] as u32; fi.microVersion = BITS_TO_VERSION[((fi.index >> 2) & 0x07) as usize] as u32;
fi.isMirrored = fi.bitsIndex == 1; fi.isMirrored = fi.bitsIndex == 1;

View File

@@ -18,7 +18,7 @@ use crate::Exceptions;
impl Version { impl Version {
pub fn FromDimension(dimension: u32) -> Result<VersionRef> { pub fn FromDimension(dimension: u32) -> Result<VersionRef> {
let isMicro = dimension < 21; let isMicro = dimension < 21;
if (dimension % Self::DimensionStep(isMicro) != 1) { if dimension % Self::DimensionStep(isMicro) != 1 {
//throw std::invalid_argument("Unexpected dimension"); //throw std::invalid_argument("Unexpected dimension");
return Err(Exceptions::ILLEGAL_ARGUMENT); return Err(Exceptions::ILLEGAL_ARGUMENT);
} }
@@ -29,7 +29,7 @@ impl Version {
} }
pub fn FromNumber(versionNumber: u32, is_micro: bool) -> Result<VersionRef> { pub fn FromNumber(versionNumber: u32, is_micro: bool) -> Result<VersionRef> {
if (versionNumber < 1 || versionNumber > (if is_micro { 4 } else { 40 })) { if versionNumber < 1 || versionNumber > (if is_micro { 4 } else { 40 }) {
//throw std::invalid_argument("Version should be in range [1-40]."); //throw std::invalid_argument("Version should be in range [1-40].");
return Err(Exceptions::ILLEGAL_ARGUMENT); return Err(Exceptions::ILLEGAL_ARGUMENT);
} }

View File

@@ -188,9 +188,9 @@ pub trait BitMatrixCursorTrait {
range: Option<i32>, range: Option<i32>,
) -> Option<[T; LEN]> { ) -> Option<[T; LEN]> {
let range = range.unwrap_or(0); let range = range.unwrap_or(0);
if (maxWhitePrefix != 0 if maxWhitePrefix != 0
&& self.isWhite() && self.isWhite()
&& !self.stepToEdge(Some(1), Some(maxWhitePrefix), None) > 0) && !self.stepToEdge(Some(1), Some(maxWhitePrefix), None) > 0
{ {
return None; return None;
} }

View File

@@ -5,10 +5,10 @@ use crate::{
}, },
BitMatrix, Quadrilateral, BitMatrix, Quadrilateral,
}, },
point, Exceptions, Point, point, Point,
}; };
use crate::common::Result;
use super::{ use super::{
BitMatrixCursorTrait, EdgeTracer, FastEdgeToEdgeCounter, Pattern, RegressionLine, BitMatrixCursorTrait, EdgeTracer, FastEdgeToEdgeCounter, Pattern, RegressionLine,
@@ -265,7 +265,7 @@ pub fn CenterOfRings(
// for (int i = 1; i < numOfRings; ++i) { // for (int i = 1; i < numOfRings; ++i) {
let c = CenterOfRing(image, center.floor(), range, i as i32, true)?; let c = CenterOfRing(image, center.floor(), range, i as i32, true)?;
if (c == Point::default()) { if c == Point::default() {
if n == 1 { if n == 1 {
return None; return None;
} else { } else {
@@ -342,7 +342,7 @@ pub fn CollectRingPoints(
} }
pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Quadrilateral> { pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Quadrilateral> {
let dist2Center = |a, b| Point::distance(a, center) < Point::distance(b, center); let _dist2Center = |a, b| Point::distance(a, center) < Point::distance(b, center);
// rotate points such that the first one is the furthest away from the center (hence, a corner) // rotate points such that the first one is the furthest away from the center (hence, a corner)
let max_by_pred = |a: &&Point, b: &&Point| { let max_by_pred = |a: &&Point, b: &&Point| {
@@ -372,7 +372,7 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
// corners[2] = std::max_element(&points[Size(points) * 3 / 8], &points[Size(points) * 5 / 8], dist2Center); // corners[2] = std::max_element(&points[Size(points) * 3 / 8], &points[Size(points) * 5 / 8], dist2Center);
// find the two in between corners by looking for the points farthest from the long diagonal // find the two in between corners by looking for the points farthest from the long diagonal
let l = RegressionLine::with_two_points(corners[0], corners[2]); let l = RegressionLine::with_two_points(corners[0], corners[2]);
let dist2Diagonal = /*[l = RegressionLine(*corners[0], *corners[2])]*/| a, b| { l.distance_single(a) < l.distance_single(b) }; let _dist2Diagonal = /*[l = RegressionLine(*corners[0], *corners[2])]*/| a, b| { l.distance_single(a) < l.distance_single(b) };
let diagonal_max_by_pred = |p1: &Point, p2: &Point| { let diagonal_max_by_pred = |p1: &Point, p2: &Point| {
let d1 = l.distance_single(*p1); let d1 = l.distance_single(*p1);
@@ -448,8 +448,8 @@ pub fn FitQadrilateralToPoints(center: Point, points: &mut [Point]) -> Option<Qu
for p in &points[beg[i]..end[i]] { for p in &points[beg[i]..end[i]] {
// for (const PointF* p = beg[i]; p != end[i]; ++p) { // for (const PointF* p = beg[i]; p != end[i]; ++p) {
let len = (end[i] - beg[i]) as f64; //std::distance(beg[i], end[i]); let len = (end[i] - beg[i]) as f64; //std::distance(beg[i], end[i]);
if (len > 3.0 if len > 3.0
&& (lines[i].distance_single(*p) as f64) > f64::max(1.0, f64::min(8.0, len / 8.0))) && (lines[i].distance_single(*p) as f64) > f64::max(1.0, f64::min(8.0, len / 8.0))
{ {
// #ifdef PRINT_DEBUG // #ifdef PRINT_DEBUG
// printf("%d: %.2f > %.2f @ %.fx%.f\n", i, lines[i].distance(*p), std::distance(beg[i], end[i]) / 1., p->x, p->y); // printf("%d: %.2f > %.2f @ %.fx%.f\n", i, lines[i].distance(*p), std::distance(beg[i], end[i]) / 1., p->x, p->y);
@@ -649,7 +649,7 @@ pub fn FinetuneConcentricPatternCenter(
return Some(res2); return Some(res2);
} }
// or the center can be approximated by a square // or the center can be approximated by a square
if (FitSquareToPoints(image, res1, range, 1, false).is_some()) { if FitSquareToPoints(image, res1, range, 1, false).is_some() {
return Some(res1); return Some(res1);
} }
// TODO: this is currently only keeping #258 alive, evaluate if still worth it // TODO: this is currently only keeping #258 alive, evaluate if still worth it

View File

@@ -1,6 +1,6 @@
use std::{any::Any, rc::Rc}; use std::{rc::Rc};
use crate::{common::ECIStringBuilder, Exceptions, RXingResult}; use crate::{common::ECIStringBuilder, Exceptions};
use super::StructuredAppendInfo; use super::StructuredAppendInfo;

View File

@@ -23,7 +23,7 @@ impl<T: Default + Clone + Copy> Matrix<T> {
} }
pub fn new(width: usize, height: usize) -> Result<Matrix<T>> { pub fn new(width: usize, height: usize) -> Result<Matrix<T>> {
if (width != 0 && (width * height) / width as usize != height as usize) { if width != 0 && (width * height) / width as usize != height as usize {
return Err(Exceptions::illegal_argument_with( return Err(Exceptions::illegal_argument_with(
"invalid size: width * height is too big", "invalid size: width * height is too big",
)); ));

View File

@@ -500,13 +500,13 @@ pub fn IsPattern<const E2E: bool, const LEN: usize, const SUM: usize, const SPAR
f64::min(modSize[0], modSize[1]), f64::min(modSize[0], modSize[1]),
f64::max(modSize[0], modSize[1]), f64::max(modSize[0], modSize[1]),
]; ];
if (M > 4.0 * m) { if M > 4.0 * m {
// make sure module sizes of bars and spaces are not too far away from each other // make sure module sizes of bars and spaces are not too far away from each other
return 0.0; return 0.0;
} }
if (min_quiet_zone != 0.0 if min_quiet_zone != 0.0
&& (space_in_pixel.unwrap_or_default()) < min_quiet_zone * modSize.space as f32) && (space_in_pixel.unwrap_or_default()) < min_quiet_zone * modSize.space as f32
{ {
return 0.0; return 0.0;
} }

View File

@@ -23,10 +23,10 @@
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fmt::{self, Display}, fmt::{self},
}; };
use crate::{pdf417::decoder::ec, BarcodeFormat};
use super::{CharacterSet, Eci, StringUtils}; use super::{CharacterSet, Eci, StringUtils};

View File

@@ -1,6 +1,6 @@
use crate::{point, Point}; use crate::{point, Point};
use super::PerspectiveTransform;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Quadrilateral(pub [Point; 4]); pub struct Quadrilateral(pub [Point; 4]);

View File

@@ -1,11 +1,11 @@
mod cpp_new_detector; mod cpp_new_detector;
pub(self) use crate::common::cpp_essentials::bitmatrix_cursor_trait::*; pub(self) use crate::common::cpp_essentials::bitmatrix_cursor_trait::*;
pub(self) use crate::common::cpp_essentials::direction::*;
pub(self) use crate::common::cpp_essentials::dm_regression_line::*; pub(self) use crate::common::cpp_essentials::dm_regression_line::*;
pub(self) use crate::common::cpp_essentials::edge_tracer::*; pub(self) use crate::common::cpp_essentials::edge_tracer::*;
pub(self) use crate::common::cpp_essentials::regression_line::*;
pub(self) use crate::common::cpp_essentials::step_result::*;
pub(self) use crate::common::cpp_essentials::util; pub(self) use crate::common::cpp_essentials::util;
pub(self) use crate::common::cpp_essentials::value::*;
pub use cpp_new_detector::detect; pub use cpp_new_detector::detect;

View File

@@ -249,7 +249,7 @@ impl CodaBarReader {
// Even j = bars, while odd j = spaces. Categories 2 and 3 are for // Even j = bars, while odd j = spaces. Categories 2 and 3 are for
// long stripes, while 0 and 1 are for short stripes. // long stripes, while 0 and 1 are for short stripes.
let category = (j & 1) + ((pattern as usize) & 1) * 2; let category = (j & 1) + ((pattern as usize) & 1) * 2;
sizes[category] += self.counters[(pos + j)]; sizes[category] += self.counters[pos + j];
counts[category] += 1; counts[category] += 1;
pattern >>= 1; pattern >>= 1;
} }
@@ -288,7 +288,7 @@ impl CodaBarReader {
// Even j = bars, while odd j = spaces. Categories 2 and 3 are for // Even j = bars, while odd j = spaces. Categories 2 and 3 are for
// long stripes, while 0 and 1 are for short stripes. // long stripes, while 0 and 1 are for short stripes.
let category = (j & 1) + ((pattern as usize) & 1) * 2; let category = (j & 1) + ((pattern as usize) & 1) * 2;
let size = self.counters[(pos + j)]; let size = self.counters[pos + j];
if (size as f32) < mins[category] || (size as f32) > maxes[category] { if (size as f32) < mins[category] || (size as f32) > maxes[category] {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }

View File

@@ -23,7 +23,7 @@ pub fn getBit(bitMatrix: &BitMatrix, x: u32, y: u32, mirrored: Option<bool>) ->
pub fn hasValidDimension(bitMatrix: &BitMatrix, isMicro: bool) -> bool { pub fn hasValidDimension(bitMatrix: &BitMatrix, isMicro: bool) -> bool {
let dimension = bitMatrix.height(); let dimension = bitMatrix.height();
if (isMicro) { if isMicro {
dimension >= 11 && dimension <= 17 && (dimension % 2) == 1 dimension >= 11 && dimension <= 17 && (dimension % 2) == 1
} else { } else {
dimension >= 21 && dimension <= 177 && (dimension % 4) == 1 dimension >= 21 && dimension <= 177 && (dimension % 4) == 1
@@ -35,7 +35,7 @@ pub fn ReadVersion(bitMatrix: &BitMatrix) -> Result<VersionRef> {
let mut version = Version::FromDimension(dimension)?; let mut version = Version::FromDimension(dimension)?;
if (version.getVersionNumber() < 7) { if version.getVersionNumber() < 7 {
return Ok(version); return Ok(version);
} }
@@ -52,7 +52,7 @@ pub fn ReadVersion(bitMatrix: &BitMatrix) -> Result<VersionRef> {
} }
version = Version::DecodeVersionInformation(versionBits, 0)?; // THIS MIGHT BE WRONG todo!() version = Version::DecodeVersionInformation(versionBits, 0)?; // THIS MIGHT BE WRONG todo!()
if (version.getDimensionForVersion() == dimension) { if version.getDimensionForVersion() == dimension {
return Ok(version); return Ok(version);
} }
} }
@@ -61,11 +61,11 @@ pub fn ReadVersion(bitMatrix: &BitMatrix) -> Result<VersionRef> {
} }
pub fn ReadFormatInformation(bitMatrix: &BitMatrix, isMicro: bool) -> Result<FormatInformation> { pub fn ReadFormatInformation(bitMatrix: &BitMatrix, isMicro: bool) -> Result<FormatInformation> {
if (!hasValidDimension(bitMatrix, isMicro)) { if !hasValidDimension(bitMatrix, isMicro) {
return Err(Exceptions::FORMAT); return Err(Exceptions::FORMAT);
} }
if (isMicro) { if isMicro {
// Read top-left format info bits // Read top-left format info bits
let mut formatInfoBits = 0; let mut formatInfoBits = 0;
for x in 1..9 { for x in 1..9 {
@@ -134,7 +134,7 @@ pub fn ReadQRCodewords(
while x > 0 { while x > 0 {
// for (int x = dimension - 1; x > 0; x -= 2) { // for (int x = dimension - 1; x > 0; x -= 2) {
// Skip whole column with vertical timing pattern. // Skip whole column with vertical timing pattern.
if (x == 6) { if x == 6 {
x -= 1; x -= 1;
} }
// Read alternatingly from bottom to top then top to bottom // Read alternatingly from bottom to top then top to bottom
@@ -145,7 +145,7 @@ pub fn ReadQRCodewords(
// for (int col = 0; col < 2; col++) { // for (int col = 0; col < 2; col++) {
let xx = (x - col) as u32; let xx = (x - col) as u32;
// Ignore bits covered by the function pattern // Ignore bits covered by the function pattern
if (!functionPattern.get(xx, y)) { if !functionPattern.get(xx, y) {
// Read a bit // Read a bit
AppendBit( AppendBit(
&mut currentByte, &mut currentByte,
@@ -154,7 +154,7 @@ pub fn ReadQRCodewords(
); );
// If we've made a whole byte, save it off // If we've made a whole byte, save it off
bitsRead += 1; bitsRead += 1;
if (bitsRead % 8 == 0) { if bitsRead % 8 == 0 {
result.push(std::mem::take(&mut currentByte)); result.push(std::mem::take(&mut currentByte));
} }
} }
@@ -164,7 +164,7 @@ pub fn ReadQRCodewords(
x -= 2; x -= 2;
} }
if ((result.len()) != version.getTotalCodewords() as usize) { if (result.len()) != version.getTotalCodewords() as usize {
return Err(Exceptions::FORMAT); return Err(Exceptions::FORMAT);
} }
@@ -185,11 +185,11 @@ pub fn ReadMQRCodewords(
let d4mBlockIndex = if version.getVersionNumber() == 1 { let d4mBlockIndex = if version.getVersionNumber() == 1 {
3 3
} else { } else {
(if formatInfo.error_correction_level == ErrorCorrectionLevel::L { if formatInfo.error_correction_level == ErrorCorrectionLevel::L {
11 11
} else { } else {
9 9
}) }
}; };
let mut result = Vec::new(); let mut result = Vec::new();
@@ -210,7 +210,7 @@ pub fn ReadMQRCodewords(
// for (int col = 0; col < 2; col++) { // for (int col = 0; col < 2; col++) {
let xx = x - col; let xx = x - col;
// Ignore bits covered by the function pattern // Ignore bits covered by the function pattern
if (!functionPattern.get(xx, y)) { if !functionPattern.get(xx, y) {
// Read a bit // Read a bit
AppendBit( AppendBit(
&mut currentByte, &mut currentByte,
@@ -219,8 +219,8 @@ pub fn ReadMQRCodewords(
); );
bitsRead += 1; bitsRead += 1;
// If we've made a whole byte, save it off; save early if 2x2 data block. // If we've made a whole byte, save it off; save early if 2x2 data block.
if (bitsRead == 8 if bitsRead == 8
|| (bitsRead == 4 && hasD4mBlock && (result.len()) == d4mBlockIndex - 1)) || (bitsRead == 4 && hasD4mBlock && (result.len()) == d4mBlockIndex - 1)
{ {
result.push(std::mem::take(&mut currentByte)); result.push(std::mem::take(&mut currentByte));
bitsRead = 0; bitsRead = 0;
@@ -232,7 +232,7 @@ pub fn ReadMQRCodewords(
x -= 2; x -= 2;
} }
if ((result.len()) != version.getTotalCodewords() as usize) { if (result.len()) != version.getTotalCodewords() as usize {
return Err(Exceptions::FORMAT); return Err(Exceptions::FORMAT);
} }
@@ -244,7 +244,7 @@ pub fn ReadCodewords(
version: VersionRef, version: VersionRef,
formatInfo: &FormatInformation, formatInfo: &FormatInformation,
) -> Result<Vec<u8>> { ) -> Result<Vec<u8>> {
if (!hasValidDimension(bitMatrix, version.isMicroQRCode())) { if !hasValidDimension(bitMatrix, version.isMicroQRCode()) {
return Err(Exceptions::FORMAT); return Err(Exceptions::FORMAT);
} }

View File

@@ -18,8 +18,8 @@ use crate::Exceptions;
pub fn GetDataMaskBit(maskIndex: u32, x: u32, y: u32, isMicro: Option<bool>) -> Result<bool> { pub fn GetDataMaskBit(maskIndex: u32, x: u32, y: u32, isMicro: Option<bool>) -> Result<bool> {
let isMicro = isMicro.unwrap_or(false); let isMicro = isMicro.unwrap_or(false);
let mut maskIndex = maskIndex; let mut maskIndex = maskIndex;
if (isMicro) { if isMicro {
if (maskIndex < 0 || maskIndex >= 4) { if maskIndex < 0 || maskIndex >= 4 {
return Err(Exceptions::illegal_argument_with( return Err(Exceptions::illegal_argument_with(
"QRCode maskIndex out of range", "QRCode maskIndex out of range",
)); ));
@@ -27,7 +27,7 @@ pub fn GetDataMaskBit(maskIndex: u32, x: u32, y: u32, isMicro: Option<bool>) ->
maskIndex = [1, 4, 6, 7][maskIndex as usize]; // map from MQR to QR indices maskIndex = [1, 4, 6, 7][maskIndex as usize]; // map from MQR to QR indices
} }
match (maskIndex) { match maskIndex {
0 => return Ok((y + x) % 2 == 0), 0 => return Ok((y + x) % 2 == 0),
1 => return Ok(y % 2 == 0), 1 => return Ok(y % 2 == 0),
2 => return Ok(x % 3 == 0), 2 => return Ok(x % 3 == 0),

View File

@@ -9,7 +9,7 @@ use crate::common::reedsolomon::{
get_predefined_genericgf, PredefinedGenericGF, ReedSolomonDecoder, get_predefined_genericgf, PredefinedGenericGF, ReedSolomonDecoder,
}; };
use crate::common::{ use crate::common::{
AIFlag, BitMatrix, BitSource, CharacterSet, DecoderRXingResult, ECIStringBuilder, Eci, Result, AIFlag, BitMatrix, BitSource, CharacterSet, ECIStringBuilder, Eci, Result,
SymbologyIdentifier, SymbologyIdentifier,
}; };
use crate::qrcode::cpp_port::bitmatrix_parser::{ use crate::qrcode::cpp_port::bitmatrix_parser::{
@@ -73,11 +73,11 @@ pub fn DecodeHanziSegment(
result.switch_encoding(CharacterSet::GB18030, false); result.switch_encoding(CharacterSet::GB18030, false);
result.reserve(2 * count as usize); result.reserve(2 * count as usize);
while (count > 0) { while count > 0 {
// Each 13 bits encodes a 2-byte character // Each 13 bits encodes a 2-byte character
let twoBytes = bits.readBits(13)?; let twoBytes = bits.readBits(13)?;
let mut assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060); let mut assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
if (assembledTwoBytes < 0x00A00) { if assembledTwoBytes < 0x00A00 {
// In the 0xA1A1 to 0xAAFE range // In the 0xA1A1 to 0xAAFE range
assembledTwoBytes += 0x0A1A1; assembledTwoBytes += 0x0A1A1;
} else { } else {
@@ -102,11 +102,11 @@ pub fn DecodeKanjiSegment(
result.switch_encoding(CharacterSet::Shift_JIS, false); result.switch_encoding(CharacterSet::Shift_JIS, false);
result.reserve(2 * count as usize); result.reserve(2 * count as usize);
while (count > 0) { while count > 0 {
// Each 13 bits encodes a 2-byte character // Each 13 bits encodes a 2-byte character
let twoBytes = bits.readBits(13)?; let twoBytes = bits.readBits(13)?;
let mut assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0); let mut assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);
if (assembledTwoBytes < 0x01F00) { if assembledTwoBytes < 0x01F00 {
// In the 0x8140 to 0x9FFC range // In the 0x8140 to 0x9FFC range
assembledTwoBytes += 0x08140; assembledTwoBytes += 0x08140;
} else { } else {
@@ -146,7 +146,7 @@ pub fn ToAlphaNumericChar(value: u32) -> Result<char> {
' ', '$', '%', '*', '+', '-', '.', '/', ':', ' ', '$', '%', '*', '+', '-', '.', '/', ':',
]; ];
if (value < 0 || value >= (ALPHANUMERIC_CHARS.len())) { if value < 0 || value >= (ALPHANUMERIC_CHARS.len()) {
return Err(Exceptions::index_out_of_bounds_with( return Err(Exceptions::index_out_of_bounds_with(
"oAlphaNumericChar: out of range", "oAlphaNumericChar: out of range",
)); ));
@@ -171,27 +171,27 @@ pub fn DecodeAlphanumericSegment(
buffer.push(ToAlphaNumericChar(nextTwoCharsBits % 45)?); buffer.push(ToAlphaNumericChar(nextTwoCharsBits % 45)?);
count -= 2; count -= 2;
} }
if (count == 1) { if count == 1 {
// special case: one character left // special case: one character left
buffer.push(ToAlphaNumericChar(bits.readBits(6)?)?); buffer.push(ToAlphaNumericChar(bits.readBits(6)?)?);
} }
// See section 6.4.8.1, 6.4.8.2 // See section 6.4.8.1, 6.4.8.2
if (result.symbology.aiFlag != AIFlag::None) { if result.symbology.aiFlag != AIFlag::None {
// We need to massage the result a bit if in an FNC1 mode: // We need to massage the result a bit if in an FNC1 mode:
for i in 0..buffer.len() { for i in 0..buffer.len() {
// for (size_t i = 0; i < buffer.length(); i++) { // for (size_t i = 0; i < buffer.length(); i++) {
if (buffer if buffer
.chars() .chars()
.nth(i) .nth(i)
.ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)? .ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)?
== '%') == '%'
{ {
if (i < buffer.len() - 1 if i < buffer.len() - 1
&& buffer && buffer
.chars() .chars()
.nth(i + 1) .nth(i + 1)
.ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)? .ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)?
== '%') == '%'
{ {
// %% is rendered as % // %% is rendered as %
buffer.remove(i + 1); buffer.remove(i + 1);
@@ -221,7 +221,7 @@ pub fn DecodeNumericSegment(
result.switch_encoding(CharacterSet::ISO8859_1, false); result.switch_encoding(CharacterSet::ISO8859_1, false);
result.reserve(count as usize); result.reserve(count as usize);
while (count > 0) { while count > 0 {
let n = std::cmp::min(count, 3); let n = std::cmp::min(count, 3);
let nDigits = bits.readBits(1 + 3 * n as usize)?; // read 4, 7 or 10 bits into 1, 2 or 3 digits let nDigits = bits.readBits(1 + 3 * n as usize)?; // read 4, 7 or 10 bits into 1, 2 or 3 digits
result.append_string(&crate::common::cpp_essentials::util::ToString( result.append_string(&crate::common::cpp_essentials::util::ToString(
@@ -236,16 +236,16 @@ pub fn DecodeNumericSegment(
pub fn ParseECIValue(bits: &mut BitSource) -> Result<Eci> { pub fn ParseECIValue(bits: &mut BitSource) -> Result<Eci> {
let firstByte = bits.readBits(8)?; let firstByte = bits.readBits(8)?;
if ((firstByte & 0x80) == 0) { if (firstByte & 0x80) == 0 {
// just one byte // just one byte
return Ok(Eci::from(firstByte & 0x7F)); return Ok(Eci::from(firstByte & 0x7F));
} }
if ((firstByte & 0xC0) == 0x80) { if (firstByte & 0xC0) == 0x80 {
// two bytes // two bytes
let secondByte = bits.readBits(8)?; let secondByte = bits.readBits(8)?;
return Ok(Eci::from(((firstByte & 0x3F) << 8) | secondByte)); return Ok(Eci::from(((firstByte & 0x3F) << 8) | secondByte));
} }
if ((firstByte & 0xE0) == 0xC0) { if (firstByte & 0xE0) == 0xC0 {
// three bytes // three bytes
let secondThirdBytes = bits.readBits(16)?; let secondThirdBytes = bits.readBits(16)?;
return Ok(Eci::from(((firstByte & 0x1F) << 16) | secondThirdBytes)); return Ok(Eci::from(((firstByte & 0x1F) << 16) | secondThirdBytes));
@@ -332,7 +332,7 @@ pub fn DecodeBitStream(
{ {
result += result +=
crate::common::cpp_essentials::util::ToString(appInd as usize, 2)?; crate::common::cpp_essentials::util::ToString(appInd as usize, 2)?;
} else if ((appInd >= 165 && appInd <= 190) || (appInd >= 197 && appInd <= 222)) } else if (appInd >= 165 && appInd <= 190) || (appInd >= 197 && appInd <= 222)
// "A-Za-z" // "A-Za-z"
{ {
result += (appInd - 100) as u8; result += (appInd - 100) as u8;
@@ -357,7 +357,7 @@ pub fn DecodeBitStream(
// First handle Hanzi mode which does not start with character count // First handle Hanzi mode which does not start with character count
// chinese mode contains a sub set indicator right after mode indicator // chinese mode contains a sub set indicator right after mode indicator
let subset = bits.readBits(4)?; let subset = bits.readBits(4)?;
if (subset != 1) if subset != 1
// GB2312_SUBSET is the only supported one right now // GB2312_SUBSET is the only supported one right now
{ {
return Err(Exceptions::format_with("Unsupported HANZI subset")); return Err(Exceptions::format_with("Unsupported HANZI subset"));
@@ -404,14 +404,14 @@ pub fn Decode(bits: &BitMatrix) -> Result<DecoderResult<bool>> {
// Read codewords // Read codewords
let codewords = ReadCodewords(bits, &version, &formatInfo)?; let codewords = ReadCodewords(bits, &version, &formatInfo)?;
if (codewords.is_empty()) { if codewords.is_empty() {
return Err(Exceptions::format_with("Failed to read codewords")); return Err(Exceptions::format_with("Failed to read codewords"));
} }
// Separate into data blocks // Separate into data blocks
let dataBlocks: Vec<DataBlock> = let dataBlocks: Vec<DataBlock> =
DataBlock::getDataBlocks(&codewords, &version, formatInfo.error_correction_level)?; DataBlock::getDataBlocks(&codewords, &version, formatInfo.error_correction_level)?;
if (dataBlocks.is_empty()) { if dataBlocks.is_empty() {
return Err(Exceptions::format_with("Failed to get data blocks")); return Err(Exceptions::format_with("Failed to get data blocks"));
} }

View File

@@ -4,8 +4,7 @@ use crate::{
CenterOfRing, DMRegressionLine, FindConcentricPatternCorners, FindLeftGuardBy, Matrix, CenterOfRing, DMRegressionLine, FindConcentricPatternCorners, FindLeftGuardBy, Matrix,
}, },
DefaultGridSampler, GridSampler, Result, SamplerControl, DefaultGridSampler, GridSampler, Result, SamplerControl,
}, }, point_i,
dimension, point_g, point_i,
qrcode::{ qrcode::{
decoder::{FormatInformation, Version, VersionRef}, decoder::{FormatInformation, Version, VersionRef},
detector::QRCodeDetectorResult, detector::QRCodeDetectorResult,
@@ -17,8 +16,8 @@ use multimap::MultiMap;
use crate::{ use crate::{
common::{ common::{
cpp_essentials::{ cpp_essentials::{
BitMatrixCursorTrait, ConcentricPattern, Direction, EdgeTracer, FindLeftGuard, BitMatrixCursorTrait, ConcentricPattern, Direction, EdgeTracer,
FixedPattern, GetPatternRow, GetPatternRowTP, IsPattern, LocateConcentricPattern, FixedPattern, GetPatternRowTP, IsPattern, LocateConcentricPattern,
PatternRow, PatternType, PatternView, ReadSymmetricPattern, RegressionLine, PatternRow, PatternType, PatternView, ReadSymmetricPattern, RegressionLine,
RegressionLineTrait, RegressionLineTrait,
}, },
@@ -48,8 +47,8 @@ fn FindPattern<'a>(view: PatternView<'a>) -> Result<PatternView<'a>> {
LEN, LEN,
|view: &PatternView, spaceInPixel: Option<f32>| { |view: &PatternView, spaceInPixel: Option<f32>| {
// perform a fast plausability test for 1:1:3:1:1 pattern // perform a fast plausability test for 1:1:3:1:1 pattern
if (view[2] < 2 as PatternType * std::cmp::max(view[0], view[4]) if view[2] < 2 as PatternType * std::cmp::max(view[0], view[4])
|| view[2] < std::cmp::max(view[1], view[3])) || view[2] < std::cmp::max(view[1], view[3])
{ {
return false; return false;
} }
@@ -70,7 +69,7 @@ pub fn FindFinderPatterns(image: &BitMatrix, tryHarder: bool) -> FinderPatterns
// QR versions regardless of how dense they are. // QR versions regardless of how dense they are.
let height = image.height(); let height = image.height();
let mut skip = (3 * height) / (4 * MAX_MODULES_FAST); let mut skip = (3 * height) / (4 * MAX_MODULES_FAST);
if (skip < MIN_SKIP || tryHarder) { if skip < MIN_SKIP || tryHarder {
skip = MIN_SKIP; skip = MIN_SKIP;
} }
@@ -113,7 +112,7 @@ pub fn FindFinderPatterns(image: &BitMatrix, tryHarder: bool) -> FinderPatterns
next.iter().sum::<u16>() as i32 * 3, next.iter().sum::<u16>() as i32 * 3,
); // 3 for very skewed samples ); // 3 for very skewed samples
// Reduce(next) * 3); // 3 for very skewed samples // Reduce(next) * 3); // 3 for very skewed samples
if (pattern.is_some()) { if pattern.is_some() {
// log(*pattern, 3); // log(*pattern, 3);
// assert!(image.get_point(pattern.as_ref().unwrap().p)); // assert!(image.get_point(pattern.as_ref().unwrap().p));
res.push(pattern.unwrap()); res.push(pattern.unwrap());
@@ -146,7 +145,7 @@ pub fn GenerateFinderPatternSets(patterns: &mut FinderPatterns) -> FinderPattern
// the camera projection on slanted symbols. The fact that the size of the finder pattern is proportional to the // the camera projection on slanted symbols. The fact that the size of the finder pattern is proportional to the
// distance from the camera is used here. This approximation only works if a < b < 2*a (see below). // distance from the camera is used here. This approximation only works if a < b < 2*a (see below).
// Test image: fix-finderpattern-order.jpg // Test image: fix-finderpattern-order.jpg
ConcentricPattern::dot((a - b), (a - b)) as f64 ConcentricPattern::dot(a - b, a - b) as f64
* (((b).size as f64) / ((a).size as f64)).powi(2) //std::pow(double(b.size) / a.size, 2) * (((b).size as f64) / ((a).size as f64)).powi(2) //std::pow(double(b.size) / a.size, 2)
}; };
@@ -170,7 +169,7 @@ pub fn GenerateFinderPatternSets(patterns: &mut FinderPatterns) -> FinderPattern
let mut c = &patterns[k]; let mut c = &patterns[k];
// if the pattern sizes are too different to be part of the same symbol, skip this // if the pattern sizes are too different to be part of the same symbol, skip this
// and the rest of the innermost loop (sorted list) // and the rest of the innermost loop (sorted list)
if (c.size > a.size * 2) { if c.size > a.size * 2 {
break; break;
} }
@@ -181,20 +180,20 @@ pub fn GenerateFinderPatternSets(patterns: &mut FinderPatterns) -> FinderPattern
let mut distBC2 = squaredDistance(*b, *c); let mut distBC2 = squaredDistance(*b, *c);
let mut distAC2 = squaredDistance(*a, *c); let mut distAC2 = squaredDistance(*a, *c);
if (distBC2 >= distAB2 && distBC2 >= distAC2) { if distBC2 >= distAB2 && distBC2 >= distAC2 {
std::mem::swap(&mut a, &mut b); std::mem::swap(&mut a, &mut b);
std::mem::swap(&mut distBC2, &mut distAC2); std::mem::swap(&mut distBC2, &mut distAC2);
} else if (distAB2 >= distAC2 && distAB2 >= distBC2) { } else if distAB2 >= distAC2 && distAB2 >= distBC2 {
std::mem::swap(&mut b, &mut c); std::mem::swap(&mut b, &mut c);
std::mem::swap(&mut distAB2, &mut distAC2); std::mem::swap(&mut distAB2, &mut distAC2);
} }
let distAB = (distAB2.sqrt()); let distAB = distAB2.sqrt();
let distBC = (distBC2).sqrt(); let distBC = (distBC2).sqrt();
// Make sure distAB and distBC don't differ more than reasonable // Make sure distAB and distBC don't differ more than reasonable
// TODO: make sure the constant 2 is not to conservative for reasonably tilted symbols // TODO: make sure the constant 2 is not to conservative for reasonably tilted symbols
if (distAB > 2.0 * distBC || distBC > 2.0 * distAB) { if distAB > 2.0 * distBC || distBC > 2.0 * distAB {
continue; continue;
} }
@@ -202,7 +201,7 @@ pub fn GenerateFinderPatternSets(patterns: &mut FinderPatterns) -> FinderPattern
let moduleCount = (distAB + distBC) let moduleCount = (distAB + distBC)
/ (2.0 * (a.size + b.size + c.size) as f64 / (3.0 * 7.0)) / (2.0 * (a.size + b.size + c.size) as f64 / (3.0 * 7.0))
+ 7.0; + 7.0;
if (moduleCount < 21.0 * 0.9 || moduleCount > 177.0 * 1.5) if moduleCount < 21.0 * 0.9 || moduleCount > 177.0 * 1.5
// moduleCount may be overestimated, see above // moduleCount may be overestimated, see above
{ {
continue; continue;
@@ -210,7 +209,7 @@ pub fn GenerateFinderPatternSets(patterns: &mut FinderPatterns) -> FinderPattern
// Make sure the angle between AB and BC does not deviate from 90° by more than 45° // Make sure the angle between AB and BC does not deviate from 90° by more than 45°
let cosAB_BC = (distAB2 + distBC2 - distAC2) / (2.0 * distAB * distBC); let cosAB_BC = (distAB2 + distBC2 - distAC2) / (2.0 * distAB * distBC);
if ((cosAB_BC.is_nan()) || cosAB_BC > cosUpper || cosAB_BC < cosLower) { if (cosAB_BC.is_nan()) || cosAB_BC > cosUpper || cosAB_BC < cosLower {
continue; continue;
} }
@@ -219,12 +218,12 @@ pub fn GenerateFinderPatternSets(patterns: &mut FinderPatterns) -> FinderPattern
// we need to check both two equal sides separately. // we need to check both two equal sides separately.
// The value of |c^2 - 2 * b^2| + |c^2 - 2 * a^2| increases as dissimilarity // The value of |c^2 - 2 * b^2| + |c^2 - 2 * a^2| increases as dissimilarity
// from isosceles right triangle. // from isosceles right triangle.
let d: f64 = ((distAC2 - 2.0 * distAB2).abs() + (distAC2 - 2.0 * distBC2).abs()); let d: f64 = (distAC2 - 2.0 * distAB2).abs() + (distAC2 - 2.0 * distBC2).abs();
// Use cross product to figure out whether A and C are correct or flipped. // 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 // 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 swap A and C. // we want for A, B, C. If it's negative then swap A and C.
if (ConcentricPattern::cross(*c - *b, *a - *b) < 0.0) { if ConcentricPattern::cross(*c - *b, *a - *b) < 0.0 {
std::mem::swap(&mut a, &mut c); std::mem::swap(&mut a, &mut c);
} }
@@ -276,13 +275,13 @@ pub fn EstimateModuleSize(image: &BitMatrix, a: ConcentricPattern, b: Concentric
let pattern = pattern.unwrap(); let pattern = pattern.unwrap();
if (!(IsPattern::<E2E, 5, 7, false>( if !(IsPattern::<E2E, 5, 7, false>(
&PatternView::new(&PatternRow::new(pattern.to_vec())), &PatternView::new(&PatternRow::new(pattern.to_vec())),
&PATTERN, &PATTERN,
None, None,
0.0, 0.0,
0.0, 0.0,
) != 0.0)) ) != 0.0)
{ {
return -1.0; return -1.0;
} }
@@ -316,13 +315,13 @@ pub fn EstimateDimension(
let ms_a = EstimateModuleSize(image, a, b); let ms_a = EstimateModuleSize(image, a, b);
let ms_b = EstimateModuleSize(image, b, a); let ms_b = EstimateModuleSize(image, b, a);
if (ms_a < 0.0 || ms_b < 0.0) { if ms_a < 0.0 || ms_b < 0.0 {
return DimensionEstimate::default(); return DimensionEstimate::default();
} }
let moduleSize = (ms_a + ms_b) / 2.0; let moduleSize = (ms_a + ms_b) / 2.0;
let dimension = ((ConcentricPattern::distance(a, b) as f64 / moduleSize).round() as i32 + 7); let dimension = (ConcentricPattern::distance(a, b) as f64 / moduleSize).round() as i32 + 7;
let error = 1 - (dimension % 4); let error = 1 - (dimension % 4);
DimensionEstimate { DimensionEstimate {
@@ -340,17 +339,17 @@ pub fn TraceLine(image: &BitMatrix, p: Point, d: Point, edge: i32) -> impl Regre
// collect points inside the black line -> backup on 3rd edge // collect points inside the black line -> backup on 3rd edge
cur.stepToEdge(Some(edge), Some(0), Some(edge == 3)); cur.stepToEdge(Some(edge), Some(0), Some(edge == 3));
if (edge == 3) { if edge == 3 {
cur.turnBack(); cur.turnBack();
} }
let mut curI = EdgeTracer::new(image, (cur.p), (Point::mainDirection(cur.d()))); let mut curI = EdgeTracer::new(image, cur.p, Point::mainDirection(cur.d()));
// make sure curI positioned such that the white->black edge is directly behind // make sure curI positioned such that the white->black edge is directly behind
// Test image: fix-traceline.jpg // Test image: fix-traceline.jpg
while (!bool::from(curI.edgeAtBack())) { while !bool::from(curI.edgeAtBack()) {
if (curI.edgeAtLeft().into()) { if curI.edgeAtLeft().into() {
curI.turnRight(); curI.turnRight();
} else if (curI.edgeAtRight().into()) { } else if curI.edgeAtRight().into() {
curI.turnLeft(); curI.turnLeft();
} else { } else {
curI.step(Some(-1.0)); curI.step(Some(-1.0));
@@ -498,14 +497,14 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
let top = EstimateDimension(image, fp.tl, fp.tr); let top = EstimateDimension(image, fp.tl, fp.tr);
let left = EstimateDimension(image, fp.tl, fp.bl); let left = EstimateDimension(image, fp.tl, fp.bl);
if (!(top.dim != 0) && !(left.dim != 0)) { if !(top.dim != 0) && !(left.dim != 0) {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
let best = if top.err == left.err { let best = if top.err == left.err {
(if top.dim > left.dim { top } else { left }) if top.dim > left.dim { top } else { left }
} else { } else {
(if top.err < left.err { top } else { left }) if top.err < left.err { top } else { left }
}; };
let mut dimension = best.dim; let mut dimension = best.dim;
let moduleSize = (best.ms + 1.0) as i32; let moduleSize = (best.ms + 1.0) as i32;
@@ -527,14 +526,14 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
let tr2 = TraceLine(image, fp.tr.p, fp.tl.p, 2); let tr2 = TraceLine(image, fp.tr.p, fp.tl.p, 2);
let tr3 = TraceLine(image, fp.tr.p, fp.tl.p, 3); let tr3 = TraceLine(image, fp.tr.p, fp.tl.p, 3);
if (bl2.isValid() && tr2.isValid() && bl3.isValid() && tr3.isValid()) { if bl2.isValid() && tr2.isValid() && bl3.isValid() && tr3.isValid() {
// intersect both outer and inner line pairs and take the center point between the two intersection points // intersect both outer and inner line pairs and take the center point between the two intersection points
let brInter = (DMRegressionLine::intersect(&bl2, &tr2).ok_or(Exceptions::NOT_FOUND)? let brInter = (DMRegressionLine::intersect(&bl2, &tr2).ok_or(Exceptions::NOT_FOUND)?
+ DMRegressionLine::intersect(&bl3, &tr3).ok_or(Exceptions::NOT_FOUND)?) + DMRegressionLine::intersect(&bl3, &tr3).ok_or(Exceptions::NOT_FOUND)?)
/ 2.0; / 2.0;
// log(brInter, 3); // log(brInter, 3);
if (dimension > 21) { if dimension > 21 {
if let Some(brCP) = LocateAlignmentPattern(image, moduleSize, brInter) { if let Some(brCP) = LocateAlignmentPattern(image, moduleSize, brInter) {
br = brCP.into(); br = brCP.into();
} }
@@ -542,16 +541,16 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
// if the symbol is tilted or the resolution of the RegressionLines is sufficient, use their intersection // if the symbol is tilted or the resolution of the RegressionLines is sufficient, use their intersection
// as the best estimate (see discussion in #199 and test image estimate-tilt.jpg ) // as the best estimate (see discussion in #199 and test image estimate-tilt.jpg )
if (!image.is_in(br.p) if !image.is_in(br.p)
&& (EstimateTilt(fp) > 1.1 && (EstimateTilt(fp) > 1.1
|| (bl2.isHighRes() && bl3.isHighRes() && tr2.isHighRes() && tr3.isHighRes()))) || (bl2.isHighRes() && bl3.isHighRes() && tr2.isHighRes() && tr3.isHighRes()))
{ {
br = brInter.into(); br = brInter.into();
} }
} }
// otherwise the simple estimation used by upstream is used as a best guess fallback // otherwise the simple estimation used by upstream is used as a best guess fallback
if (!image.is_in(br.p)) { if !image.is_in(br.p) {
br = fp.tr - fp.tl + fp.bl; br = fp.tr - fp.tl + fp.bl;
brOffset = point_i(0, 0); brOffset = point_i(0, 0);
} }
@@ -563,17 +562,17 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
Quadrilateral::from([fp.tl.p, fp.tr.p, br.p, fp.bl.p]), Quadrilateral::from([fp.tl.p, fp.tr.p, br.p, fp.bl.p]),
)?; )?;
if (dimension >= Version::DimensionOfVersion(7, false) as i32) { if dimension >= Version::DimensionOfVersion(7, false) as i32 {
let version = ReadVersion(image, dimension as u32, mod2Pix.clone()); let version = ReadVersion(image, dimension as u32, mod2Pix.clone());
// if the version bits are garbage -> discard the detection // if the version bits are garbage -> discard the detection
if (!version.is_ok() if !version.is_ok()
|| (version.as_ref().unwrap().getDimensionForVersion() as i32 - dimension).abs() > 8) || (version.as_ref().unwrap().getDimensionForVersion() as i32 - dimension).abs() > 8
{ {
/*return DetectorResult();*/ /*return DetectorResult();*/
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
if (version.as_ref().unwrap().getDimensionForVersion() as i32 != dimension) { if version.as_ref().unwrap().getDimensionForVersion() as i32 != dimension {
// printf("update dimension: %d -> %d\n", dimension, version.dimension()); // printf("update dimension: %d -> %d\n", dimension, version.dimension());
dimension = version.as_ref().unwrap().getDimensionForVersion() as i32; dimension = version.as_ref().unwrap().getDimensionForVersion() as i32;
mod2Pix = Mod2Pix( mod2Pix = Mod2Pix(
@@ -617,7 +616,7 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
// for (int y = 0; y <= N; ++y) // for (int y = 0; y <= N; ++y)
for x in 0..=N { for x in 0..=N {
// for (int x = 0; x <= N; ++x) { // for (int x = 0; x <= N; ++x) {
if (apP.get(x, y).is_some()) { if apP.get(x, y).is_some() {
continue; continue;
} }
@@ -640,7 +639,7 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
// for (int y = 0; y <= N; ++y) { // for (int y = 0; y <= N; ++y) {
for x in 0..=N { for x in 0..=N {
// for (int x = 0; x <= N; ++x) { // for (int x = 0; x <= N; ++x) {
if (apP.get(x, y).is_some()) { if apP.get(x, y).is_some() {
continue; continue;
} }
@@ -650,7 +649,7 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
let mut i = 2; let mut i = 2;
while i < 2 * N + 2 && hori.len() < 2 { while i < 2 * N + 2 && hori.len() < 2 {
let xi = x as isize + i as isize / 2 * (if i % 2 != 0 { 1 } else { -1 }); let xi = x as isize + i as isize / 2 * (if i % 2 != 0 { 1 } else { -1 });
if (0 <= xi && xi <= N as isize && apP.get(xi as usize, y).is_some()) { if 0 <= xi && xi <= N as isize && apP.get(xi as usize, y).is_some() {
hori.push( hori.push(
apP.get(xi as usize, y) apP.get(xi as usize, y)
.ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)?, .ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)?,
@@ -666,7 +665,7 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
let mut i = 2; let mut i = 2;
while i < 2 * N + 2 && verti.len() < 2 { while i < 2 * N + 2 && verti.len() < 2 {
let yi = y as isize + i as isize / 2 * (if i % 2 != 0 { 1 } else { -1 }); let yi = y as isize + i as isize / 2 * (if i % 2 != 0 { 1 } else { -1 });
if (0 <= yi && yi <= N as isize && apP.get(x, yi as usize).is_some()) { if 0 <= yi && yi <= N as isize && apP.get(x, yi as usize).is_some() {
verti.push( verti.push(
apP.get(x, yi as usize) apP.get(x, yi as usize)
.ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)?, .ok_or(Exceptions::INDEX_OUT_OF_BOUNDS)?,
@@ -681,7 +680,7 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
// } // }
// if we found 2 each, intersect the two lines that are formed by connecting the point pairs // if we found 2 each, intersect the two lines that are formed by connecting the point pairs
if ((hori.len()) == 2 && (verti.len()) == 2) { if (hori.len()) == 2 && (verti.len()) == 2 {
let guessed = RegressionLine::intersect( let guessed = RegressionLine::intersect(
&DMRegressionLine::new(hori[0], hori[1]), &DMRegressionLine::new(hori[0], hori[1]),
&DMRegressionLine::new(verti[0], verti[1]), &DMRegressionLine::new(verti[0], verti[1]),
@@ -719,7 +718,7 @@ pub fn SampleQR(image: &BitMatrix, fp: &FinderPatternSet) -> Result<QRCodeDetect
// for (int y = 0; y <= N; ++y) { // for (int y = 0; y <= N; ++y) {
for x in 0..=N { for x in 0..=N {
// for (int x = 0; x <= N; ++x) { // for (int x = 0; x <= N; ++x) {
if (apP.get(x, y).is_some()) { if apP.get(x, y).is_some() {
continue; continue;
} }
@@ -802,7 +801,7 @@ pub fn DetectPureQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
let (found, left, top, width, height) = image.findBoundingBox(0, 0, 0, 0, MIN_MODULES); let (found, left, top, width, height) = image.findBoundingBox(0, 0, 0, 0, MIN_MODULES);
if (!found || (width as i32 - height as i32).abs() > 1) { if !found || (width as i32 - height as i32).abs() > 1 {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
let right = left + width - 1; let right = left + width - 1;
@@ -825,7 +824,7 @@ pub fn DetectPureQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
// diagonal = BitMatrixCursorI(image, p, d).readPatternFromBlack<Pattern>(1, width / 3 + 1); // diagonal = BitMatrixCursorI(image, p, d).readPatternFromBlack<Pattern>(1, width / 3 + 1);
let diag_hld = diagonal.to_vec().into(); let diag_hld = diagonal.to_vec().into();
let view = PatternView::new(&diag_hld); let view = PatternView::new(&diag_hld);
if (!(IsPattern::<E2E, 5, 7, false>(&view, &PATTERN, None, 0.0, 0.0) != 0.0)) { if !(IsPattern::<E2E, 5, 7, false>(&view, &PATTERN, None, 0.0, 0.0) != 0.0) {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
} }
@@ -845,12 +844,12 @@ pub fn DetectPureQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
.dim; .dim;
let moduleSize: f32 = ((width) as f32) / dimension as f32; let moduleSize: f32 = ((width) as f32) / dimension as f32;
if (dimension < MIN_MODULES as i32 if dimension < MIN_MODULES as i32
|| dimension > MAX_MODULES as i32 || dimension > MAX_MODULES as i32
|| !image.is_in(point( || !image.is_in(point(
left as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize as f32, left as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize as f32,
top as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize, top as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize,
))) ))
{ {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
@@ -893,7 +892,7 @@ pub fn DetectPureMQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
let (found, left, top, width, height) = image.findBoundingBox(0, 0, 0, 0, MIN_MODULES); let (found, left, top, width, height) = image.findBoundingBox(0, 0, 0, 0, MIN_MODULES);
// int left, top, width, height; // int left, top, width, height;
if (!found || (width as i32 - height as i32).abs() > 1) { if !found || (width as i32 - height as i32).abs() > 1 {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
let right = left + width - 1; let right = left + width - 1;
@@ -905,20 +904,20 @@ pub fn DetectPureMQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
.ok_or(Exceptions::ILLEGAL_STATE)?; .ok_or(Exceptions::ILLEGAL_STATE)?;
let diag_hld = diagonal.to_vec().into(); let diag_hld = diagonal.to_vec().into();
let view = PatternView::new(&diag_hld); let view = PatternView::new(&diag_hld);
if (!(IsPattern::<E2E, 5, 7, false>(&view, &PATTERN, None, 0.0, 0.0) != 0.0)) { if !(IsPattern::<E2E, 5, 7, false>(&view, &PATTERN, None, 0.0, 0.0) != 0.0) {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
let fpWidth = (diagonal.into_iter().sum::<u16>()); let fpWidth = diagonal.into_iter().sum::<u16>();
let moduleSize: f32 = (fpWidth as f32) / 7.0; let moduleSize: f32 = (fpWidth as f32) / 7.0;
let dimension = (width as f32 / moduleSize).floor() as u32; let dimension = (width as f32 / moduleSize).floor() as u32;
if (dimension < MIN_MODULES if dimension < MIN_MODULES
|| dimension > MAX_MODULES || dimension > MAX_MODULES
|| !image.is_in(point( || !image.is_in(point(
left as f32 + moduleSize as f32 / 2.0 + (dimension - 1) as f32 * moduleSize, left as f32 + moduleSize as f32 / 2.0 + (dimension - 1) as f32 * moduleSize,
top as f32 + moduleSize as f32 / 2.0 + (dimension - 1) as f32 * moduleSize, top as f32 + moduleSize as f32 / 2.0 + (dimension - 1) as f32 * moduleSize,
))) ))
{ {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
@@ -1002,7 +1001,7 @@ pub fn SampleMQR(image: &BitMatrix, fp: ConcentricPattern) -> Result<QRCodeDetec
}; };
// check that we see both innermost timing pattern modules // check that we see both innermost timing pattern modules
if (!check(0, true) || !check(8, false) || !check(16, true)) { if !check(0, true) || !check(8, false) || !check(16, true) {
continue; continue;
} }
@@ -1017,13 +1016,13 @@ pub fn SampleMQR(image: &BitMatrix, fp: ConcentricPattern) -> Result<QRCodeDetec
} }
let fi = FormatInformation::DecodeMQR(formatInfoBits as u32); let fi = FormatInformation::DecodeMQR(formatInfoBits as u32);
if (fi.hammingDistance < bestFI.hammingDistance) { if fi.hammingDistance < bestFI.hammingDistance {
bestFI = fi; bestFI = fi;
bestPT = mod2Pix; bestPT = mod2Pix;
} }
} }
if (!bestFI.isValid()) { if !bestFI.isValid() {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }
@@ -1036,10 +1035,10 @@ pub fn SampleMQR(image: &BitMatrix, fp: ConcentricPattern) -> Result<QRCodeDetec
// for (int i = 0; i < dim; ++i) { // for (int i = 0; i < dim; ++i) {
let px = bestPT.transform_point(Point::centered(point_i(i, dim))); let px = bestPT.transform_point(Point::centered(point_i(i, dim)));
let py = bestPT.transform_point(Point::centered(point_i(dim, i))); let py = bestPT.transform_point(Point::centered(point_i(dim, i)));
blackPixels += u32::from((image.is_in(px) && image.get_point(px))) blackPixels += u32::from(image.is_in(px) && image.get_point(px))
+ u32::from((image.is_in(py) && image.get_point(py))); + u32::from(image.is_in(py) && image.get_point(py));
} }
if (blackPixels > 2 * dim / 3) { if blackPixels > 2 * dim / 3 {
return Err(Exceptions::NOT_FOUND); return Err(Exceptions::NOT_FOUND);
} }

View File

@@ -118,9 +118,9 @@
// } // namespace ZXing::QRCode // } // namespace ZXing::QRCode
use crate::{ use crate::{
common::{cpp_essentials::ConcentricPattern, DetectorRXingResult, HybridBinarizer}, common::{cpp_essentials::ConcentricPattern, DetectorRXingResult},
multi::MultipleBarcodeReader, multi::MultipleBarcodeReader,
BarcodeFormat, BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary, BarcodeFormat, DecodeHintType, DecodeHintValue, DecodingHintDictionary,
Exceptions, RXingResult, Reader, Exceptions, RXingResult, Reader,
}; };
@@ -132,7 +132,7 @@ use super::{
}, },
}; };
use crate::qrcode::detector::QRCodeDetectorResult as DetectorResult;
#[derive(Default)] #[derive(Default)]
pub struct QrReader; pub struct QrReader;
@@ -294,9 +294,9 @@ impl QrReader {
let allFPSets = GenerateFinderPatternSets(&mut allFPs); let allFPSets = GenerateFinderPatternSets(&mut allFPs);
for fpSet in allFPSets { for fpSet in allFPSets {
// for (const auto& fpSet : allFPSets) { // for (const auto& fpSet : allFPSets) {
if (usedFPs.contains(&fpSet.bl) if usedFPs.contains(&fpSet.bl)
|| usedFPs.contains(&fpSet.tl) || usedFPs.contains(&fpSet.tl)
|| usedFPs.contains(&fpSet.tr)) || usedFPs.contains(&fpSet.tr)
{ {
continue; continue;
} }
@@ -309,13 +309,13 @@ impl QrReader {
let decoderResult = Decode(detectorResult.getBits()); let decoderResult = Decode(detectorResult.getBits());
let position = detectorResult.getPoints(); let position = detectorResult.getPoints();
if let Ok(decoderResult) = decoderResult { if let Ok(decoderResult) = decoderResult {
if (decoderResult.isValid()) { if decoderResult.isValid() {
usedFPs.push(fpSet.bl); usedFPs.push(fpSet.bl);
usedFPs.push(fpSet.tl); usedFPs.push(fpSet.tl);
usedFPs.push(fpSet.tr); usedFPs.push(fpSet.tr);
} }
if (decoderResult.isValid()) { if decoderResult.isValid() {
// results.push(RXingResult::new( // results.push(RXingResult::new(
// &decoderResult.content().to_string(), // &decoderResult.content().to_string(),
// decoderResult.content().bytes().to_vec(), // decoderResult.content().bytes().to_vec(),
@@ -329,7 +329,7 @@ impl QrReader {
)); ));
// results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QR_CODE); // results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QR_CODE);
if (maxSymbols != 0 && (results.len() as u32) == maxSymbols) { if maxSymbols != 0 && (results.len() as u32) == maxSymbols {
break; break;
} }
} }
@@ -337,11 +337,11 @@ impl QrReader {
} }
} }
} }
if (check_mqr && !(maxSymbols != 0 && (results.len() as u32) == maxSymbols)) { if check_mqr && !(maxSymbols != 0 && (results.len() as u32) == maxSymbols) {
// if (_hints.hasFormat(BarcodeFormat::MicroQRCode) && !(maxSymbols && Size(results) == maxSymbols)) { // if (_hints.hasFormat(BarcodeFormat::MicroQRCode) && !(maxSymbols && Size(results) == maxSymbols)) {
for fp in allFPs { for fp in allFPs {
// for (const auto& fp : allFPs) { // for (const auto& fp : allFPs) {
if (usedFPs.contains(&fp)) { if usedFPs.contains(&fp) {
continue; continue;
} }
@@ -351,7 +351,7 @@ impl QrReader {
let decoderResult = Decode(detectorResult.getBits()); let decoderResult = Decode(detectorResult.getBits());
let position = detectorResult.getPoints(); let position = detectorResult.getPoints();
if let Ok(decoderResult) = decoderResult { if let Ok(decoderResult) = decoderResult {
if (decoderResult.isValid()) { if decoderResult.isValid() {
results.push(RXingResult::with_decoder_result( results.push(RXingResult::with_decoder_result(
decoderResult, decoderResult,
position, position,
@@ -365,7 +365,7 @@ impl QrReader {
// )); // ));
// results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MICRO_QR_CODE); // results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MICRO_QR_CODE);
if (maxSymbols != 0 && (results.len() as u32) == maxSymbols) { if maxSymbols != 0 && (results.len() as u32) == maxSymbols {
break; break;
} }
} }

View File

@@ -23,10 +23,10 @@
// using namespace ZXing; // using namespace ZXing;
// using namespace ZXing::QRCode; // using namespace ZXing::QRCode;
use crate::common::Result;
use crate::{ use crate::{
common::{cpp_essentials::DecoderResult, BitArray}, common::{BitArray},
qrcode::{ qrcode::{
cpp_port::decoder::DecodeBitStream, cpp_port::decoder::DecodeBitStream,
decoder::{ErrorCorrectionLevel, Version}, decoder::{ErrorCorrectionLevel, Version},

View File

@@ -12,7 +12,7 @@ use crate::{
fn CheckVersion(version: VersionRef, number: u32, dimension: u32) { fn CheckVersion(version: VersionRef, number: u32, dimension: u32) {
// assert_ne!(version, nullptr); // assert_ne!(version, nullptr);
assert_eq!(number, version.getVersionNumber()); assert_eq!(number, version.getVersionNumber());
if (number > 1 && !version.isMicroQRCode()) { if number > 1 && !version.isMicroQRCode() {
assert!(!version.getAlignmentPatternCenters().is_empty()); assert!(!version.getAlignmentPatternCenters().is_empty());
} }
assert_eq!(dimension, version.getDimensionForVersion()); assert_eq!(dimension, version.getDimensionForVersion());

View File

@@ -146,14 +146,14 @@ impl Mode {
let isMicro = isMicro.unwrap_or(false); let isMicro = isMicro.unwrap_or(false);
const BITS_2_MODE_LEN: usize = 4; const BITS_2_MODE_LEN: usize = 4;
if (!isMicro) { if !isMicro {
if ((bits >= 0x00 && bits <= 0x05) || (bits >= 0x07 && bits <= 0x09) || bits == 0x0d) { if (bits >= 0x00 && bits <= 0x05) || (bits >= 0x07 && bits <= 0x09) || bits == 0x0d {
return Mode::try_from(bits); return Mode::try_from(bits);
} }
} else { } else {
const Bits2Mode: [Mode; BITS_2_MODE_LEN] = const Bits2Mode: [Mode; BITS_2_MODE_LEN] =
[Mode::NUMERIC, Mode::ALPHANUMERIC, Mode::BYTE, Mode::KANJI]; [Mode::NUMERIC, Mode::ALPHANUMERIC, Mode::BYTE, Mode::KANJI];
if ((bits as usize) < BITS_2_MODE_LEN) { if (bits as usize) < BITS_2_MODE_LEN {
return Ok(Bits2Mode[bits as usize]); return Ok(Bits2Mode[bits as usize]);
} }
} }
@@ -168,8 +168,8 @@ impl Mode {
*/ */
pub fn CharacterCountBits(&self, version: &Version) -> u32 { pub fn CharacterCountBits(&self, version: &Version) -> u32 {
let number = version.getVersionNumber() as usize; let number = version.getVersionNumber() as usize;
if (version.isMicroQRCode()) { if version.isMicroQRCode() {
match (self) { match self {
Mode::NUMERIC=> return [3, 4, 5, 6][number - 1], Mode::NUMERIC=> return [3, 4, 5, 6][number - 1],
Mode::ALPHANUMERIC=> return [3, 4, 5][number - 2], Mode::ALPHANUMERIC=> return [3, 4, 5][number - 2],
Mode::BYTE=> return [4, 5][number - 3], Mode::BYTE=> return [4, 5][number - 3],
@@ -179,15 +179,15 @@ impl Mode {
} }
} }
let i = if (number <= 9) { let i = if number <= 9 {
0 0
} else if (number <= 26) { } else if number <= 26 {
1 1
} else { } else {
2 2
}; };
match (self) { match self {
Mode::NUMERIC=> return [10, 12, 14][i], Mode::NUMERIC=> return [10, 12, 14][i],
Mode::ALPHANUMERIC=> return [9, 11, 13][i], Mode::ALPHANUMERIC=> return [9, 11, 13][i],
Mode::BYTE=> return [8, 16, 16][i], Mode::BYTE=> return [8, 16, 16][i],