mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
feat: ported qr-model1 support from zxing-cpp
This commit is contained in:
@@ -2,6 +2,8 @@ use crate::qrcode::decoder::{
|
||||
ErrorCorrectionLevel, FormatInformation, FORMAT_INFO_DECODE_LOOKUP, FORMAT_INFO_MASK_QR,
|
||||
};
|
||||
|
||||
pub const FORMAT_INFO_MASK_QR_MODEL1: u32 = 0x2825;
|
||||
|
||||
pub const FORMAT_INFO_DECODE_LOOKUP_MICRO: [[u32; 2]; 32] = [
|
||||
[0x4445, 0x00],
|
||||
[0x4172, 0x01],
|
||||
@@ -50,7 +52,7 @@ impl FormatInformation {
|
||||
let formatInfoBits2 =
|
||||
((formatInfoBits2 >> 1) & 0b111111100000000) | (formatInfoBits2 & 0b11111111);
|
||||
let mut fi = Self::FindBestFormatInfo(
|
||||
FORMAT_INFO_MASK_QR,
|
||||
&[0, FORMAT_INFO_MASK_QR],
|
||||
FORMAT_INFO_DECODE_LOOKUP,
|
||||
&[
|
||||
formatInfoBits1,
|
||||
@@ -60,6 +62,22 @@ impl FormatInformation {
|
||||
],
|
||||
);
|
||||
|
||||
let mut fi_model1 = Self::FindBestFormatInfo(
|
||||
&[FORMAT_INFO_MASK_QR ^ FORMAT_INFO_MASK_QR_MODEL1],
|
||||
FORMAT_INFO_DECODE_LOOKUP,
|
||||
&[
|
||||
formatInfoBits1,
|
||||
formatInfoBits2,
|
||||
Self::MirrorBits(formatInfoBits1),
|
||||
mirroredFormatInfoBits2,
|
||||
],
|
||||
);
|
||||
|
||||
if fi_model1.hammingDistance < fi.hammingDistance {
|
||||
fi_model1.isModel1 = true;
|
||||
fi = fi_model1;
|
||||
}
|
||||
|
||||
// Use bits 3/4 for error correction, and 0-2 for mask.
|
||||
fi.error_correction_level =
|
||||
ErrorCorrectionLevel::ECLevelFromBits((fi.index >> 3) & 0x03, false);
|
||||
@@ -72,7 +90,7 @@ impl FormatInformation {
|
||||
pub fn DecodeMQR(formatInfoBits: u32) -> Self {
|
||||
// We don't use the additional masking (with 0x4445) to work around potentially non complying MicroQRCode encoders
|
||||
let mut fi = Self::FindBestFormatInfo(
|
||||
0,
|
||||
&[0],
|
||||
FORMAT_INFO_DECODE_LOOKUP_MICRO,
|
||||
&[formatInfoBits, Self::MirrorBits(formatInfoBits)],
|
||||
);
|
||||
@@ -94,11 +112,11 @@ impl FormatInformation {
|
||||
(bits.reverse_bits()) >> 17
|
||||
}
|
||||
|
||||
pub fn FindBestFormatInfo(mask: u32, lookup: [[u32; 2]; 32], bits: &[u32]) -> Self {
|
||||
pub fn FindBestFormatInfo(masks: &[u32], lookup: [[u32; 2]; 32], bits: &[u32]) -> Self {
|
||||
let mut fi = FormatInformation::default();
|
||||
|
||||
// Some QR codes apparently do not apply the XOR mask. Try without and with additional masking.
|
||||
for mask in [0, mask] {
|
||||
for mask in masks {
|
||||
// for (auto mask : {0, mask})
|
||||
for (bitsIndex, bit_set) in bits.iter().enumerate() {
|
||||
// for (int bitsIndex = 0; bitsIndex < Size(bits); ++bitsIndex)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::common::Result;
|
||||
use crate::qrcode::decoder::{Version, VersionRef, MICRO_VERSIONS, VERSIONS, VERSION_DECODE_INFO};
|
||||
use crate::qrcode::decoder::{
|
||||
Version, VersionRef, MICRO_VERSIONS, MODEL1_VERSIONS, VERSIONS, VERSION_DECODE_INFO,
|
||||
};
|
||||
use crate::Exceptions;
|
||||
|
||||
// const Version* Version::AllMicroVersions()
|
||||
@@ -16,7 +18,7 @@ use crate::Exceptions;
|
||||
// }
|
||||
|
||||
impl Version {
|
||||
pub fn FromDimension(dimension: u32) -> Result<VersionRef> {
|
||||
pub fn FromDimension(dimension: u32, is_model1: bool) -> Result<VersionRef> {
|
||||
let isMicro = dimension < 21;
|
||||
if dimension % Self::DimensionStep(isMicro) != 1 {
|
||||
//throw std::invalid_argument("Unexpected dimension");
|
||||
@@ -25,17 +27,31 @@ impl Version {
|
||||
Self::FromNumber(
|
||||
(dimension - Self::DimensionOffset(isMicro)) / Self::DimensionStep(isMicro),
|
||||
isMicro,
|
||||
is_model1,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn FromNumber(versionNumber: u32, is_micro: bool) -> Result<VersionRef> {
|
||||
if versionNumber < 1 || versionNumber > (if is_micro { 4 } else { 40 }) {
|
||||
pub fn FromNumber(versionNumber: u32, is_micro: bool, is_model1: bool) -> Result<VersionRef> {
|
||||
if versionNumber < 1
|
||||
|| versionNumber
|
||||
> (if is_micro {
|
||||
4
|
||||
} else {
|
||||
if is_model1 {
|
||||
14
|
||||
} else {
|
||||
40
|
||||
}
|
||||
})
|
||||
{
|
||||
//throw std::invalid_argument("Version should be in range [1-40].");
|
||||
return Err(Exceptions::ILLEGAL_ARGUMENT);
|
||||
}
|
||||
|
||||
Ok(if is_micro {
|
||||
&MICRO_VERSIONS[versionNumber as usize - 1]
|
||||
} else if is_model1 {
|
||||
&MODEL1_VERSIONS[versionNumber as usize - 1]
|
||||
} else {
|
||||
&VERSIONS[versionNumber as usize - 1]
|
||||
})
|
||||
@@ -92,4 +108,8 @@ impl Version {
|
||||
pub const fn isMicroQRCode(&self) -> bool {
|
||||
self.is_micro
|
||||
}
|
||||
|
||||
pub const fn isQRCodeModel1(&self) -> bool {
|
||||
self.is_model1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,13 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
pub fn withIsModel1(mut self, is_model_1: bool) -> DecoderResult<T> {
|
||||
if is_model_1 {
|
||||
self.content.symbology.modifier = 48
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
// pub fn build(self) -> DecoderResult<T> {
|
||||
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user