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:
@@ -67,6 +67,8 @@ pub enum BarcodeFormat {
|
|||||||
|
|
||||||
MICRO_QR_CODE,
|
MICRO_QR_CODE,
|
||||||
|
|
||||||
|
RECTANGULAR_MICRO_QR_CODE,
|
||||||
|
|
||||||
/** RSS 14 */
|
/** RSS 14 */
|
||||||
RSS_14,
|
RSS_14,
|
||||||
|
|
||||||
@@ -108,6 +110,7 @@ impl Display for BarcodeFormat {
|
|||||||
BarcodeFormat::PDF_417 => "pdf 417",
|
BarcodeFormat::PDF_417 => "pdf 417",
|
||||||
BarcodeFormat::QR_CODE => "qrcode",
|
BarcodeFormat::QR_CODE => "qrcode",
|
||||||
BarcodeFormat::MICRO_QR_CODE => "mqr",
|
BarcodeFormat::MICRO_QR_CODE => "mqr",
|
||||||
|
BarcodeFormat::RECTANGULAR_MICRO_QR_CODE => "rmqr",
|
||||||
BarcodeFormat::RSS_14 => "rss 14",
|
BarcodeFormat::RSS_14 => "rss 14",
|
||||||
BarcodeFormat::RSS_EXPANDED => "rss expanded",
|
BarcodeFormat::RSS_EXPANDED => "rss expanded",
|
||||||
BarcodeFormat::TELEPEN => "telepen",
|
BarcodeFormat::TELEPEN => "telepen",
|
||||||
@@ -150,6 +153,9 @@ impl From<&str> for BarcodeFormat {
|
|||||||
"mqr" | "microqr" | "micro_qr" | "micro_qrcode" | "micro_qr_code" | "mqr_code" => {
|
"mqr" | "microqr" | "micro_qr" | "micro_qrcode" | "micro_qr_code" | "mqr_code" => {
|
||||||
BarcodeFormat::MICRO_QR_CODE
|
BarcodeFormat::MICRO_QR_CODE
|
||||||
}
|
}
|
||||||
|
"rmqr" | "rectangular_mqr" | "rectangular_micro_qr" | "rmqr_code" => {
|
||||||
|
BarcodeFormat::RECTANGULAR_MICRO_QR_CODE
|
||||||
|
}
|
||||||
"rss 14" | "rss_14" | "rss14" | "gs1 databar" | "gs1 databar coupon"
|
"rss 14" | "rss_14" | "rss14" | "gs1 databar" | "gs1 databar coupon"
|
||||||
| "gs1_databar_coupon" => BarcodeFormat::RSS_14,
|
| "gs1_databar_coupon" => BarcodeFormat::RSS_14,
|
||||||
"rss expanded" | "expanded rss" | "rss_expanded" => BarcodeFormat::RSS_EXPANDED,
|
"rss expanded" | "expanded rss" | "rss_expanded" => BarcodeFormat::RSS_EXPANDED,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ use crate::qrcode::decoder::{
|
|||||||
ErrorCorrectionLevel, FormatInformation, FORMAT_INFO_DECODE_LOOKUP, FORMAT_INFO_MASK_QR,
|
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] = [
|
pub const FORMAT_INFO_DECODE_LOOKUP_MICRO: [[u32; 2]; 32] = [
|
||||||
[0x4445, 0x00],
|
[0x4445, 0x00],
|
||||||
[0x4172, 0x01],
|
[0x4172, 0x01],
|
||||||
@@ -50,7 +52,7 @@ impl FormatInformation {
|
|||||||
let formatInfoBits2 =
|
let formatInfoBits2 =
|
||||||
((formatInfoBits2 >> 1) & 0b111111100000000) | (formatInfoBits2 & 0b11111111);
|
((formatInfoBits2 >> 1) & 0b111111100000000) | (formatInfoBits2 & 0b11111111);
|
||||||
let mut fi = Self::FindBestFormatInfo(
|
let mut fi = Self::FindBestFormatInfo(
|
||||||
FORMAT_INFO_MASK_QR,
|
&[0, FORMAT_INFO_MASK_QR],
|
||||||
FORMAT_INFO_DECODE_LOOKUP,
|
FORMAT_INFO_DECODE_LOOKUP,
|
||||||
&[
|
&[
|
||||||
formatInfoBits1,
|
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.
|
// Use bits 3/4 for error correction, and 0-2 for mask.
|
||||||
fi.error_correction_level =
|
fi.error_correction_level =
|
||||||
ErrorCorrectionLevel::ECLevelFromBits((fi.index >> 3) & 0x03, false);
|
ErrorCorrectionLevel::ECLevelFromBits((fi.index >> 3) & 0x03, false);
|
||||||
@@ -72,7 +90,7 @@ impl FormatInformation {
|
|||||||
pub fn DecodeMQR(formatInfoBits: u32) -> Self {
|
pub fn DecodeMQR(formatInfoBits: u32) -> Self {
|
||||||
// We don't use the additional masking (with 0x4445) to work around potentially non complying MicroQRCode encoders
|
// We don't use the additional masking (with 0x4445) to work around potentially non complying MicroQRCode encoders
|
||||||
let mut fi = Self::FindBestFormatInfo(
|
let mut fi = Self::FindBestFormatInfo(
|
||||||
0,
|
&[0],
|
||||||
FORMAT_INFO_DECODE_LOOKUP_MICRO,
|
FORMAT_INFO_DECODE_LOOKUP_MICRO,
|
||||||
&[formatInfoBits, Self::MirrorBits(formatInfoBits)],
|
&[formatInfoBits, Self::MirrorBits(formatInfoBits)],
|
||||||
);
|
);
|
||||||
@@ -94,11 +112,11 @@ impl FormatInformation {
|
|||||||
(bits.reverse_bits()) >> 17
|
(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();
|
let mut fi = FormatInformation::default();
|
||||||
|
|
||||||
// Some QR codes apparently do not apply the XOR mask. Try without and with additional masking.
|
// 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 (auto mask : {0, mask})
|
||||||
for (bitsIndex, bit_set) in bits.iter().enumerate() {
|
for (bitsIndex, bit_set) in bits.iter().enumerate() {
|
||||||
// for (int bitsIndex = 0; bitsIndex < Size(bits); ++bitsIndex)
|
// for (int bitsIndex = 0; bitsIndex < Size(bits); ++bitsIndex)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::common::Result;
|
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;
|
use crate::Exceptions;
|
||||||
|
|
||||||
// const Version* Version::AllMicroVersions()
|
// const Version* Version::AllMicroVersions()
|
||||||
@@ -16,7 +18,7 @@ use crate::Exceptions;
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
impl Version {
|
impl Version {
|
||||||
pub fn FromDimension(dimension: u32) -> Result<VersionRef> {
|
pub fn FromDimension(dimension: u32, is_model1: bool) -> 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");
|
||||||
@@ -25,17 +27,31 @@ impl Version {
|
|||||||
Self::FromNumber(
|
Self::FromNumber(
|
||||||
(dimension - Self::DimensionOffset(isMicro)) / Self::DimensionStep(isMicro),
|
(dimension - Self::DimensionOffset(isMicro)) / Self::DimensionStep(isMicro),
|
||||||
isMicro,
|
isMicro,
|
||||||
|
is_model1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn FromNumber(versionNumber: u32, is_micro: bool) -> Result<VersionRef> {
|
pub fn FromNumber(versionNumber: u32, is_micro: bool, is_model1: bool) -> Result<VersionRef> {
|
||||||
if versionNumber < 1 || versionNumber > (if is_micro { 4 } else { 40 }) {
|
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].");
|
//throw std::invalid_argument("Version should be in range [1-40].");
|
||||||
return Err(Exceptions::ILLEGAL_ARGUMENT);
|
return Err(Exceptions::ILLEGAL_ARGUMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(if is_micro {
|
Ok(if is_micro {
|
||||||
&MICRO_VERSIONS[versionNumber as usize - 1]
|
&MICRO_VERSIONS[versionNumber as usize - 1]
|
||||||
|
} else if is_model1 {
|
||||||
|
&MODEL1_VERSIONS[versionNumber as usize - 1]
|
||||||
} else {
|
} else {
|
||||||
&VERSIONS[versionNumber as usize - 1]
|
&VERSIONS[versionNumber as usize - 1]
|
||||||
})
|
})
|
||||||
@@ -92,4 +108,8 @@ impl Version {
|
|||||||
pub const fn isMicroQRCode(&self) -> bool {
|
pub const fn isMicroQRCode(&self) -> bool {
|
||||||
self.is_micro
|
self.is_micro
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn isQRCodeModel1(&self) -> bool {
|
||||||
|
self.is_model1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,13 @@ where
|
|||||||
self
|
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> {
|
// pub fn build(self) -> DecoderResult<T> {
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -183,6 +183,9 @@ impl MultiFormatReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
BarcodeFormat::MICRO_QR_CODE => QrReader.decode_with_hints(image, &self.hints),
|
BarcodeFormat::MICRO_QR_CODE => QrReader.decode_with_hints(image, &self.hints),
|
||||||
|
BarcodeFormat::RECTANGULAR_MICRO_QR_CODE => {
|
||||||
|
QrReader.decode_with_hints(image, &self.hints)
|
||||||
|
}
|
||||||
BarcodeFormat::DATA_MATRIX => {
|
BarcodeFormat::DATA_MATRIX => {
|
||||||
DataMatrixReader.decode_with_hints(image, &self.hints)
|
DataMatrixReader.decode_with_hints(image, &self.hints)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pub fn hasValidDimension(bitMatrix: &BitMatrix, isMicro: bool) -> bool {
|
|||||||
pub fn ReadVersion(bitMatrix: &BitMatrix) -> Result<VersionRef> {
|
pub fn ReadVersion(bitMatrix: &BitMatrix) -> Result<VersionRef> {
|
||||||
let dimension = bitMatrix.height();
|
let dimension = bitMatrix.height();
|
||||||
|
|
||||||
let mut version = Version::FromDimension(dimension)?;
|
let mut version = Version::FromDimension(dimension, false)?;
|
||||||
|
|
||||||
if version.getVersionNumber() < 7 {
|
if version.getVersionNumber() < 7 {
|
||||||
return Ok(version);
|
return Ok(version);
|
||||||
@@ -235,6 +235,111 @@ pub fn ReadMQRCodewords(
|
|||||||
Ok(result.iter().copied().map(|x| x as u8).collect())
|
Ok(result.iter().copied().map(|x| x as u8).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ReadQRCodewordsModel1(
|
||||||
|
bitMatrix: &BitMatrix,
|
||||||
|
version: VersionRef,
|
||||||
|
formatInfo: &FormatInformation,
|
||||||
|
) -> Result<Vec<u8>> {
|
||||||
|
let mut result = Vec::with_capacity(version.getTotalCodewords() as usize);
|
||||||
|
let dimension = bitMatrix.height();
|
||||||
|
let columns = dimension / 4 + 1 + 2;
|
||||||
|
for j in 0..columns {
|
||||||
|
// for (int j = 0; j < columns; j++) {
|
||||||
|
if j <= 1 {
|
||||||
|
// vertical symbols on the right side
|
||||||
|
let rows = (dimension - 8) / 4;
|
||||||
|
for i in 0..rows {
|
||||||
|
// for (int i = 0; i < rows; i++) {
|
||||||
|
if j == 0 && i % 2 == 0 && i > 0 && i < rows - 1
|
||||||
|
// extension
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let x = (dimension - 1) - (j * 2);
|
||||||
|
let y = (dimension - 1) - (i * 4);
|
||||||
|
let mut currentByte = 0;
|
||||||
|
for b in 0..8 {
|
||||||
|
// for (int b = 0; b < 8; b++) {
|
||||||
|
AppendBit(
|
||||||
|
&mut currentByte,
|
||||||
|
GetDataMaskBit(formatInfo.data_mask as u32, x - b % 2, y - (b / 2), None)?
|
||||||
|
!= getBit(
|
||||||
|
bitMatrix,
|
||||||
|
x - b % 2,
|
||||||
|
y - (b / 2),
|
||||||
|
Some(formatInfo.isMirrored),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
result.push(currentByte);
|
||||||
|
}
|
||||||
|
} else if columns - j <= 4 {
|
||||||
|
// vertical symbols on the left side
|
||||||
|
let rows = (dimension - 16) / 4;
|
||||||
|
for i in 0..rows {
|
||||||
|
// for (int i = 0; i < rows; i++) {
|
||||||
|
let x = (columns - j - 1) * 2 + 1 + (if columns - j == 4 { 1 } else { 0 }); // timing
|
||||||
|
let y = (dimension - 1) - 8 - (i * 4);
|
||||||
|
let mut currentByte = 0;
|
||||||
|
for b in 0..8 {
|
||||||
|
// for (int b = 0; b < 8; b++) {
|
||||||
|
AppendBit(
|
||||||
|
&mut currentByte,
|
||||||
|
GetDataMaskBit(formatInfo.data_mask as u32, x - b % 2, y - (b / 2), None)?
|
||||||
|
!= getBit(
|
||||||
|
bitMatrix,
|
||||||
|
x - b % 2,
|
||||||
|
y - (b / 2),
|
||||||
|
Some(formatInfo.isMirrored),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
result.push(currentByte);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// horizontal symbols
|
||||||
|
let rows = dimension / 2;
|
||||||
|
for i in 0..rows {
|
||||||
|
// for (int i = 0; i < rows; i++) {
|
||||||
|
if j == 2 && i >= rows - 4
|
||||||
|
// alignment & finder
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if i == 0 && j % 2 == 1 && j + 1 != columns - 4
|
||||||
|
// extension
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let x = (dimension - 1) - (2 * 2) - (j - 2) * 4;
|
||||||
|
let y = (dimension - 1) - (i * 2) - (if i >= rows - 3 { 1 } else { 0 }); // timing
|
||||||
|
let mut currentByte = 0;
|
||||||
|
for b in 0..8 {
|
||||||
|
// for (int b = 0; b < 8; b++) {
|
||||||
|
AppendBit(
|
||||||
|
&mut currentByte,
|
||||||
|
GetDataMaskBit(formatInfo.data_mask as u32, x - b % 4, y - (b / 4), None)?
|
||||||
|
!= getBit(
|
||||||
|
bitMatrix,
|
||||||
|
x - b % 4,
|
||||||
|
y - (b / 4),
|
||||||
|
Some(formatInfo.isMirrored),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
result.push(currentByte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result[0] &= 0xf; // ignore corner
|
||||||
|
if (result.len()) != version.getTotalCodewords() as usize {
|
||||||
|
return Err(Exceptions::FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result.iter().copied().map(|x| x as u8).collect())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ReadCodewords(
|
pub fn ReadCodewords(
|
||||||
bitMatrix: &BitMatrix,
|
bitMatrix: &BitMatrix,
|
||||||
version: VersionRef,
|
version: VersionRef,
|
||||||
@@ -246,6 +351,8 @@ pub fn ReadCodewords(
|
|||||||
|
|
||||||
if version.isMicroQRCode() {
|
if version.isMicroQRCode() {
|
||||||
ReadMQRCodewords(bitMatrix, version, formatInfo)
|
ReadMQRCodewords(bitMatrix, version, formatInfo)
|
||||||
|
} else if formatInfo.isModel1 {
|
||||||
|
ReadQRCodewordsModel1(bitMatrix, version, formatInfo)
|
||||||
} else {
|
} else {
|
||||||
ReadQRCodewords(bitMatrix, version, formatInfo)
|
ReadQRCodewords(bitMatrix, version, formatInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,6 +299,10 @@ pub fn DecodeBitStream(
|
|||||||
let mut structuredAppend = StructuredAppendInfo::default();
|
let mut structuredAppend = StructuredAppendInfo::default();
|
||||||
let modeBitLength = Mode::get_codec_mode_bits_length(version);
|
let modeBitLength = Mode::get_codec_mode_bits_length(version);
|
||||||
|
|
||||||
|
if version.isQRCodeModel1() {
|
||||||
|
bits.readBits(4)?; /* Model 1 is leading with 4 0-bits -> drop them */
|
||||||
|
}
|
||||||
|
|
||||||
let res = (|| {
|
let res = (|| {
|
||||||
while !IsEndOfStream(&mut bits, version)? {
|
while !IsEndOfStream(&mut bits, version)? {
|
||||||
let mode: Mode = if modeBitLength == 0 {
|
let mode: Mode = if modeBitLength == 0 {
|
||||||
@@ -387,11 +391,21 @@ pub fn DecodeBitStream(
|
|||||||
.withError(res.err())
|
.withError(res.err())
|
||||||
.withEcLevel(ecLevel.to_string())
|
.withEcLevel(ecLevel.to_string())
|
||||||
.withVersionNumber(version.getVersionNumber())
|
.withVersionNumber(version.getVersionNumber())
|
||||||
.withStructuredAppend(structuredAppend))
|
.withStructuredAppend(structuredAppend)
|
||||||
|
.withIsModel1(version.isQRCodeModel1()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Decode(bits: &BitMatrix) -> Result<DecoderResult<bool>> {
|
pub fn Decode(bits: &BitMatrix) -> Result<DecoderResult<bool>> {
|
||||||
let Ok(pversion) = ReadVersion(bits) else {
|
let isMicroQRCode = bits.height() < 21;
|
||||||
|
let Ok(formatInfo) = ReadFormatInformation(bits, isMicroQRCode) else {
|
||||||
|
return Err(Exceptions::format_with("Invalid format information"));
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(pversion) = (if formatInfo.isModel1 {
|
||||||
|
Version::FromDimension(bits.height(), true)
|
||||||
|
} else {
|
||||||
|
ReadVersion(bits)
|
||||||
|
}) else {
|
||||||
return Err(Exceptions::format_with("Invalid version"));
|
return Err(Exceptions::format_with("Invalid version"));
|
||||||
};
|
};
|
||||||
let version = pversion;
|
let version = pversion;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ fn SimpleByteMode() {
|
|||||||
let bytes: Vec<u8> = ba.into();
|
let bytes: Vec<u8> = ba.into();
|
||||||
let result = DecodeBitStream(
|
let result = DecodeBitStream(
|
||||||
&bytes,
|
&bytes,
|
||||||
Version::FromNumber(1, false).expect("find_version"),
|
Version::FromNumber(1, false, false).expect("find_version"),
|
||||||
ErrorCorrectionLevel::M,
|
ErrorCorrectionLevel::M,
|
||||||
)
|
)
|
||||||
.expect("Decode")
|
.expect("Decode")
|
||||||
@@ -64,7 +64,7 @@ fn SimpleSJIS() {
|
|||||||
let bytes: Vec<u8> = ba.into();
|
let bytes: Vec<u8> = ba.into();
|
||||||
let result = DecodeBitStream(
|
let result = DecodeBitStream(
|
||||||
&bytes,
|
&bytes,
|
||||||
Version::FromNumber(1, false).unwrap(),
|
Version::FromNumber(1, false, false).unwrap(),
|
||||||
ErrorCorrectionLevel::M,
|
ErrorCorrectionLevel::M,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -86,7 +86,7 @@ fn ECI() {
|
|||||||
let bytes: Vec<u8> = ba.into();
|
let bytes: Vec<u8> = ba.into();
|
||||||
let result = DecodeBitStream(
|
let result = DecodeBitStream(
|
||||||
&bytes,
|
&bytes,
|
||||||
Version::FromNumber(1, false).unwrap(),
|
Version::FromNumber(1, false, false).unwrap(),
|
||||||
ErrorCorrectionLevel::M,
|
ErrorCorrectionLevel::M,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -105,7 +105,7 @@ fn Hanzi() {
|
|||||||
let bytes: Vec<u8> = ba.into();
|
let bytes: Vec<u8> = ba.into();
|
||||||
let result = DecodeBitStream(
|
let result = DecodeBitStream(
|
||||||
&bytes,
|
&bytes,
|
||||||
Version::FromNumber(1, false).unwrap(),
|
Version::FromNumber(1, false, false).unwrap(),
|
||||||
ErrorCorrectionLevel::M,
|
ErrorCorrectionLevel::M,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -127,7 +127,7 @@ fn HanziLevel1() {
|
|||||||
|
|
||||||
let result = DecodeBitStream(
|
let result = DecodeBitStream(
|
||||||
&bytes,
|
&bytes,
|
||||||
Version::FromNumber(1, false).unwrap(),
|
Version::FromNumber(1, false, false).unwrap(),
|
||||||
ErrorCorrectionLevel::M,
|
ErrorCorrectionLevel::M,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -138,7 +138,7 @@ fn HanziLevel1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn SymbologyIdentifier() {
|
fn SymbologyIdentifier() {
|
||||||
let version = Version::FromNumber(1, false).unwrap();
|
let version = Version::FromNumber(1, false, false).unwrap();
|
||||||
let ecLevel = ErrorCorrectionLevel::M;
|
let ecLevel = ErrorCorrectionLevel::M;
|
||||||
|
|
||||||
// Plain "ANUM(1) A"
|
// Plain "ANUM(1) A"
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ fn DecodeWithBitDifference() {
|
|||||||
MASKED_TEST_FORMAT_INFO2 ^ 0x07,
|
MASKED_TEST_FORMAT_INFO2 ^ 0x07,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
assert!(!FormatInformation::DecodeQR(
|
assert!(FormatInformation::DecodeQR(
|
||||||
MASKED_TEST_FORMAT_INFO ^ 0x0F,
|
MASKED_TEST_FORMAT_INFO ^ 0x0F,
|
||||||
MASKED_TEST_FORMAT_INFO2 ^ 0x0F
|
MASKED_TEST_FORMAT_INFO2 ^ 0x0F
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -27,27 +27,39 @@ fn CharacterCount() {
|
|||||||
// Spot check a few values
|
// Spot check a few values
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
10,
|
10,
|
||||||
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(5, false).unwrap())
|
Mode::CharacterCountBits(
|
||||||
|
&Mode::NUMERIC,
|
||||||
|
Version::FromNumber(5, false, false).unwrap()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
12,
|
12,
|
||||||
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(26, false).unwrap())
|
Mode::CharacterCountBits(
|
||||||
|
&Mode::NUMERIC,
|
||||||
|
Version::FromNumber(26, false, false).unwrap()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
14,
|
14,
|
||||||
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(40, false).unwrap())
|
Mode::CharacterCountBits(
|
||||||
|
&Mode::NUMERIC,
|
||||||
|
Version::FromNumber(40, false, false).unwrap()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
9,
|
9,
|
||||||
Mode::CharacterCountBits(&Mode::ALPHANUMERIC, Version::FromNumber(6, false).unwrap())
|
Mode::CharacterCountBits(
|
||||||
|
&Mode::ALPHANUMERIC,
|
||||||
|
Version::FromNumber(6, false, false).unwrap()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
8,
|
8,
|
||||||
Mode::CharacterCountBits(&Mode::BYTE, Version::FromNumber(7, false).unwrap())
|
Mode::CharacterCountBits(&Mode::BYTE, Version::FromNumber(7, false, false).unwrap())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
8,
|
8,
|
||||||
Mode::CharacterCountBits(&Mode::KANJI, Version::FromNumber(8, false).unwrap())
|
Mode::CharacterCountBits(&Mode::KANJI, Version::FromNumber(8, false, false).unwrap())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,26 +122,29 @@ fn MicroCharacterCount() {
|
|||||||
// Spot check a few values
|
// Spot check a few values
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
3,
|
3,
|
||||||
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(1, true).unwrap())
|
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(1, true, false).unwrap())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
4,
|
4,
|
||||||
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(2, true).unwrap())
|
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(2, true, false).unwrap())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
6,
|
6,
|
||||||
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(4, true).unwrap())
|
Mode::CharacterCountBits(&Mode::NUMERIC, Version::FromNumber(4, true, false).unwrap())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
3,
|
3,
|
||||||
Mode::CharacterCountBits(&Mode::ALPHANUMERIC, Version::FromNumber(2, true).unwrap())
|
Mode::CharacterCountBits(
|
||||||
|
&Mode::ALPHANUMERIC,
|
||||||
|
Version::FromNumber(2, true, false).unwrap()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
4,
|
4,
|
||||||
Mode::CharacterCountBits(&Mode::BYTE, Version::FromNumber(3, true).unwrap())
|
Mode::CharacterCountBits(&Mode::BYTE, Version::FromNumber(3, true, false).unwrap())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
4,
|
4,
|
||||||
Mode::CharacterCountBits(&Mode::KANJI, Version::FromNumber(4, true).unwrap())
|
Mode::CharacterCountBits(&Mode::KANJI, Version::FromNumber(4, true, false).unwrap())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ fn DoTestVersion(expectedVersion: u32, mask: i32) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn VersionForNumber() {
|
fn VersionForNumber() {
|
||||||
let version = Version::FromNumber(0, false);
|
let version = Version::FromNumber(0, false, false);
|
||||||
assert!(version.is_err(), "There is version with number 0");
|
assert!(version.is_err(), "There is version with number 0");
|
||||||
|
|
||||||
for i in 1..=40 {
|
for i in 1..=40 {
|
||||||
// for (int i = 1; i <= 40; i++) {
|
// for (int i = 1; i <= 40; i++) {
|
||||||
CheckVersion(
|
CheckVersion(
|
||||||
Version::FromNumber(i, false).expect("version number found"),
|
Version::FromNumber(i, false, false).expect("version number found"),
|
||||||
i,
|
i,
|
||||||
4 * i + 17,
|
4 * i + 17,
|
||||||
);
|
);
|
||||||
@@ -43,7 +43,7 @@ fn VersionForNumber() {
|
|||||||
fn GetProvisionalVersionForDimension() {
|
fn GetProvisionalVersionForDimension() {
|
||||||
for i in 1..=40 {
|
for i in 1..=40 {
|
||||||
// for (int i = 1; i <= 40; i++) {
|
// for (int i = 1; i <= 40; i++) {
|
||||||
let prov = Version::FromDimension(4 * i + 17)
|
let prov = Version::FromDimension(4 * i + 17, false)
|
||||||
.unwrap_or_else(|_| panic!("version should exist for {i}"));
|
.unwrap_or_else(|_| panic!("version should exist for {i}"));
|
||||||
// assert_ne!(prov, nullptr);
|
// assert_ne!(prov, nullptr);
|
||||||
assert_eq!(i, prov.getVersionNumber());
|
assert_eq!(i, prov.getVersionNumber());
|
||||||
@@ -63,13 +63,14 @@ fn DecodeVersionInformation() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn MicroVersionForNumber() {
|
fn MicroVersionForNumber() {
|
||||||
let version = Version::FromNumber(0, true);
|
let version = Version::FromNumber(0, true, false);
|
||||||
assert!(version.is_err(), "There is version with number 0");
|
assert!(version.is_err(), "There is version with number 0");
|
||||||
|
|
||||||
for i in 1..=4 {
|
for i in 1..=4 {
|
||||||
// for (int i = 1; i <= 4; i++) {
|
// for (int i = 1; i <= 4; i++) {
|
||||||
CheckVersion(
|
CheckVersion(
|
||||||
Version::FromNumber(i, true).unwrap_or_else(|_| panic!("version for {i} should exist")),
|
Version::FromNumber(i, true, false)
|
||||||
|
.unwrap_or_else(|_| panic!("version for {i} should exist")),
|
||||||
i,
|
i,
|
||||||
2 * i + 9,
|
2 * i + 9,
|
||||||
);
|
);
|
||||||
@@ -80,7 +81,7 @@ fn MicroVersionForNumber() {
|
|||||||
fn GetProvisionalMicroVersionForDimension() {
|
fn GetProvisionalMicroVersionForDimension() {
|
||||||
for i in 1..=4 {
|
for i in 1..=4 {
|
||||||
// for (int i = 1; i <= 4; i++) {
|
// for (int i = 1; i <= 4; i++) {
|
||||||
let prov = Version::FromDimension(2 * i + 9)
|
let prov = Version::FromDimension(2 * i + 9, false)
|
||||||
.unwrap_or_else(|_| panic!("version for micro {i} should exist"));
|
.unwrap_or_else(|_| panic!("version for micro {i} should exist"));
|
||||||
// assert_ne!(prov, nullptr);
|
// assert_ne!(prov, nullptr);
|
||||||
assert_eq!(i, prov.getVersionNumber());
|
assert_eq!(i, prov.getVersionNumber());
|
||||||
@@ -100,7 +101,7 @@ fn FunctionPattern() {
|
|||||||
};
|
};
|
||||||
for i in 1..=4 {
|
for i in 1..=4 {
|
||||||
// for (int i = 1; i <= 4; i++) {
|
// for (int i = 1; i <= 4; i++) {
|
||||||
let version = Version::FromNumber(i, true).expect("version must be found");
|
let version = Version::FromNumber(i, true, false).expect("version must be found");
|
||||||
let functionPattern = version
|
let functionPattern = version
|
||||||
.buildFunctionPattern()
|
.buildFunctionPattern()
|
||||||
.expect("function pattern must be found");
|
.expect("function pattern must be found");
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ pub struct FormatInformation {
|
|||||||
pub data_mask: u8,
|
pub data_mask: u8,
|
||||||
pub microVersion: u32,
|
pub microVersion: u32,
|
||||||
pub isMirrored: bool,
|
pub isMirrored: bool,
|
||||||
|
pub isModel1: bool,
|
||||||
|
|
||||||
pub index: u8, // = 255;
|
pub index: u8, // = 255;
|
||||||
pub bitsIndex: u8, // = 255;
|
pub bitsIndex: u8, // = 255;
|
||||||
@@ -86,6 +87,7 @@ impl Default for FormatInformation {
|
|||||||
data_mask: Default::default(),
|
data_mask: Default::default(),
|
||||||
microVersion: 0,
|
microVersion: 0,
|
||||||
isMirrored: false,
|
isMirrored: false,
|
||||||
|
isModel1: false,
|
||||||
index: 255,
|
index: 255,
|
||||||
bitsIndex: 255,
|
bitsIndex: 255,
|
||||||
}
|
}
|
||||||
@@ -104,6 +106,7 @@ impl FormatInformation {
|
|||||||
error_correction_level: errorCorrectionLevel,
|
error_correction_level: errorCorrectionLevel,
|
||||||
data_mask: dataMask,
|
data_mask: dataMask,
|
||||||
isMirrored: false,
|
isMirrored: false,
|
||||||
|
isModel1: false,
|
||||||
index: 255,
|
index: 255,
|
||||||
bitsIndex: 255,
|
bitsIndex: 255,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ pub type VersionRef = &'static Version;
|
|||||||
|
|
||||||
pub static VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::buildVersions);
|
pub static VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::buildVersions);
|
||||||
pub static MICRO_VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::build_micro_versions);
|
pub static MICRO_VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::build_micro_versions);
|
||||||
|
pub static MODEL1_VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::build_model1_versions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 18004:2006 Annex D.
|
* See ISO 18004:2006 Annex D.
|
||||||
@@ -55,6 +56,7 @@ pub struct Version {
|
|||||||
ecBlocks: Vec<ECBlocks>,
|
ecBlocks: Vec<ECBlocks>,
|
||||||
totalCodewords: u32,
|
totalCodewords: u32,
|
||||||
pub(crate) is_micro: bool,
|
pub(crate) is_micro: bool,
|
||||||
|
pub(crate) is_model1: bool,
|
||||||
}
|
}
|
||||||
impl Version {
|
impl Version {
|
||||||
fn new(versionNumber: u32, alignmentPatternCenters: Vec<u32>, ecBlocks: [ECBlocks; 4]) -> Self {
|
fn new(versionNumber: u32, alignmentPatternCenters: Vec<u32>, ecBlocks: [ECBlocks; 4]) -> Self {
|
||||||
@@ -73,6 +75,7 @@ impl Version {
|
|||||||
ecBlocks: ecBlocks.to_vec(),
|
ecBlocks: ecBlocks.to_vec(),
|
||||||
totalCodewords: total,
|
totalCodewords: total,
|
||||||
is_micro: false,
|
is_micro: false,
|
||||||
|
is_model1: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +95,35 @@ impl Version {
|
|||||||
ecBlocks,
|
ecBlocks,
|
||||||
totalCodewords: total,
|
totalCodewords: total,
|
||||||
is_micro: true,
|
is_micro: true,
|
||||||
|
is_model1: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_model1(versionNumber: u32, ecBlocks: Vec<ECBlocks>) -> Self {
|
||||||
|
let mut total = 0;
|
||||||
|
let ecCodewords = ecBlocks[0].getECCodewordsPerBlock();
|
||||||
|
let ecbArray = ecBlocks[0].getECBlocks();
|
||||||
|
let mut i = 0;
|
||||||
|
while i < ecbArray.len() {
|
||||||
|
total += ecbArray[i].getCount() * (ecbArray[i].getDataCodewords() + ecCodewords);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
versionNumber,
|
||||||
|
alignmentPatternCenters: Vec::default(),
|
||||||
|
ecBlocks,
|
||||||
|
totalCodewords: total,
|
||||||
|
is_micro: false,
|
||||||
|
is_model1: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[inline(always)]
|
||||||
|
// pub(crate) const fn isMicro(ecBlocks: &[ECBlocks; 4]) -> bool {
|
||||||
|
// ecBlocks[0].ecCodewordsPerBlock < 7 || ecBlocks[0].ecCodewordsPerBlock == 8
|
||||||
|
// }
|
||||||
|
|
||||||
pub const fn getVersionNumber(&self) -> u32 {
|
pub const fn getVersionNumber(&self) -> u32 {
|
||||||
self.versionNumber
|
self.versionNumber
|
||||||
}
|
}
|
||||||
@@ -970,6 +999,224 @@ impl Version {
|
|||||||
new ECB::new(61, 16)))
|
new ECB::new(61, 16)))
|
||||||
]*/
|
]*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* {1, {
|
||||||
|
7 , 1, 19, 0, 0,
|
||||||
|
10, 1, 16, 0, 0,
|
||||||
|
13, 1, 13, 0, 0,
|
||||||
|
17, 1, 9 , 0, 0
|
||||||
|
}},
|
||||||
|
{2, {
|
||||||
|
10, 1, 36, 0, 0,
|
||||||
|
16, 1, 30, 0, 0,
|
||||||
|
22, 1, 24, 0, 0,
|
||||||
|
30, 1, 16, 0, 0,
|
||||||
|
}},
|
||||||
|
{3, {
|
||||||
|
15, 1, 57, 0, 0,
|
||||||
|
28, 1, 44, 0, 0,
|
||||||
|
36, 1, 36, 0, 0,
|
||||||
|
48, 1, 24, 0, 0,
|
||||||
|
}},
|
||||||
|
{4, {
|
||||||
|
20, 1, 80, 0, 0,
|
||||||
|
40, 1, 60, 0, 0,
|
||||||
|
50, 1, 50, 0, 0,
|
||||||
|
66, 1, 34, 0, 0,
|
||||||
|
}},
|
||||||
|
{5, {
|
||||||
|
26, 1, 108, 0, 0,
|
||||||
|
52, 1, 82 , 0, 0,
|
||||||
|
66, 1, 68 , 0, 0,
|
||||||
|
88, 2, 46 , 0, 0,
|
||||||
|
}},
|
||||||
|
{6, {
|
||||||
|
34 , 1, 136, 0, 0,
|
||||||
|
63 , 2, 106, 0, 0,
|
||||||
|
84 , 2, 86 , 0, 0,
|
||||||
|
112, 2, 58 , 0, 0,
|
||||||
|
}},
|
||||||
|
{7, {
|
||||||
|
42 , 1, 170, 0, 0,
|
||||||
|
80 , 2, 132, 0, 0,
|
||||||
|
104, 2, 108, 0, 0,
|
||||||
|
138, 3, 72 , 0, 0,
|
||||||
|
}},
|
||||||
|
{8, {
|
||||||
|
48 , 2, 208, 0, 0,
|
||||||
|
96 , 2, 160, 0, 0,
|
||||||
|
128, 2, 128, 0, 0,
|
||||||
|
168, 3, 87 , 0, 0,
|
||||||
|
}},
|
||||||
|
{9, {
|
||||||
|
60 , 2, 246, 0, 0,
|
||||||
|
120, 2, 186, 0, 0,
|
||||||
|
150, 3, 156, 0, 0,
|
||||||
|
204, 3, 102, 0, 0,
|
||||||
|
}},
|
||||||
|
{10, {
|
||||||
|
68 , 2, 290, 0, 0,
|
||||||
|
136, 2, 222, 0, 0,
|
||||||
|
174, 3, 183, 0, 0,
|
||||||
|
232, 4, 124, 0, 0,
|
||||||
|
}},
|
||||||
|
{11, {
|
||||||
|
80 , 2, 336, 0, 0,
|
||||||
|
160, 4, 256, 0, 0,
|
||||||
|
208, 4, 208, 0, 0,
|
||||||
|
270, 5, 145, 0, 0,
|
||||||
|
}},
|
||||||
|
{12, {
|
||||||
|
92 , 2, 384, 0, 0,
|
||||||
|
184, 4, 292, 0, 0,
|
||||||
|
232, 4, 244, 0, 0,
|
||||||
|
310, 5, 165, 0, 0,
|
||||||
|
}},
|
||||||
|
{13, {
|
||||||
|
108, 3, 432, 0, 0,
|
||||||
|
208, 4, 332, 0, 0,
|
||||||
|
264, 4, 276, 0, 0,
|
||||||
|
348, 6, 192, 0, 0,
|
||||||
|
}},
|
||||||
|
{14, {
|
||||||
|
120, 3, 489, 0, 0,
|
||||||
|
240, 4, 368, 0, 0,
|
||||||
|
300, 5, 310, 0, 0,
|
||||||
|
396, 6, 210, 0, 0,
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
pub fn build_model1_versions() -> Vec<Version> {
|
||||||
|
Vec::from([
|
||||||
|
Version::new_model1(
|
||||||
|
1,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(7, vec![ECB::new(1, 19)]),
|
||||||
|
ECBlocks::new(10, vec![ECB::new(1, 16)]),
|
||||||
|
ECBlocks::new(13, vec![ECB::new(1, 13)]),
|
||||||
|
ECBlocks::new(17, vec![ECB::new(1, 9)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
2,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(10, vec![ECB::new(1, 36)]),
|
||||||
|
ECBlocks::new(16, vec![ECB::new(1, 30)]),
|
||||||
|
ECBlocks::new(22, vec![ECB::new(1, 24)]),
|
||||||
|
ECBlocks::new(30, vec![ECB::new(1, 16)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
3,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(15, vec![ECB::new(1, 57)]),
|
||||||
|
ECBlocks::new(28, vec![ECB::new(1, 44)]),
|
||||||
|
ECBlocks::new(36, vec![ECB::new(1, 36)]),
|
||||||
|
ECBlocks::new(48, vec![ECB::new(1, 24)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
4,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(20, vec![ECB::new(1, 80)]),
|
||||||
|
ECBlocks::new(40, vec![ECB::new(1, 60)]),
|
||||||
|
ECBlocks::new(50, vec![ECB::new(1, 50)]),
|
||||||
|
ECBlocks::new(66, vec![ECB::new(1, 34)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
5,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(26, vec![ECB::new(1, 108)]),
|
||||||
|
ECBlocks::new(52, vec![ECB::new(1, 82)]),
|
||||||
|
ECBlocks::new(66, vec![ECB::new(1, 68)]),
|
||||||
|
ECBlocks::new(88, vec![ECB::new(2, 46)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
6,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(34, vec![ECB::new(1, 136)]),
|
||||||
|
ECBlocks::new(63, vec![ECB::new(2, 106)]),
|
||||||
|
ECBlocks::new(84, vec![ECB::new(2, 86)]),
|
||||||
|
ECBlocks::new(112, vec![ECB::new(2, 58)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
7,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(42, vec![ECB::new(1, 170)]),
|
||||||
|
ECBlocks::new(80, vec![ECB::new(2, 132)]),
|
||||||
|
ECBlocks::new(104, vec![ECB::new(2, 108)]),
|
||||||
|
ECBlocks::new(138, vec![ECB::new(3, 72)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
8,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(48, vec![ECB::new(2, 208)]),
|
||||||
|
ECBlocks::new(96, vec![ECB::new(2, 160)]),
|
||||||
|
ECBlocks::new(128, vec![ECB::new(2, 128)]),
|
||||||
|
ECBlocks::new(168, vec![ECB::new(3, 87)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
9,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(60, vec![ECB::new(2, 246)]),
|
||||||
|
ECBlocks::new(120, vec![ECB::new(2, 186)]),
|
||||||
|
ECBlocks::new(150, vec![ECB::new(3, 156)]),
|
||||||
|
ECBlocks::new(204, vec![ECB::new(3, 102)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
10,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(68, vec![ECB::new(2, 290)]),
|
||||||
|
ECBlocks::new(136, vec![ECB::new(2, 222)]),
|
||||||
|
ECBlocks::new(174, vec![ECB::new(3, 183)]),
|
||||||
|
ECBlocks::new(232, vec![ECB::new(4, 124)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
11,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(80, vec![ECB::new(2, 336)]),
|
||||||
|
ECBlocks::new(160, vec![ECB::new(4, 256)]),
|
||||||
|
ECBlocks::new(208, vec![ECB::new(4, 208)]),
|
||||||
|
ECBlocks::new(270, vec![ECB::new(5, 145)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
12,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(92, vec![ECB::new(2, 384)]),
|
||||||
|
ECBlocks::new(184, vec![ECB::new(4, 292)]),
|
||||||
|
ECBlocks::new(232, vec![ECB::new(4, 244)]),
|
||||||
|
ECBlocks::new(310, vec![ECB::new(5, 165)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
13,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(108, vec![ECB::new(3, 432)]),
|
||||||
|
ECBlocks::new(208, vec![ECB::new(4, 332)]),
|
||||||
|
ECBlocks::new(264, vec![ECB::new(4, 276)]),
|
||||||
|
ECBlocks::new(348, vec![ECB::new(6, 192)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Version::new_model1(
|
||||||
|
14,
|
||||||
|
vec![
|
||||||
|
ECBlocks::new(120, vec![ECB::new(3, 489)]),
|
||||||
|
ECBlocks::new(240, vec![ECB::new(4, 368)]),
|
||||||
|
ECBlocks::new(300, vec![ECB::new(5, 310)]),
|
||||||
|
ECBlocks::new(396, vec![ECB::new(6, 210)]),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Version {
|
impl fmt::Display for Version {
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
symbologyIdentifier=]Q0
|
||||||
|
ecLevel=M
|
||||||
BIN
test_resources/blackbox/cpp/qrcode-2/qr-model-1.png
Normal file
BIN
test_resources/blackbox/cpp/qrcode-2/qr-model-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 230 B |
1
test_resources/blackbox/cpp/qrcode-2/qr-model-1.txt
Normal file
1
test_resources/blackbox/cpp/qrcode-2/qr-model-1.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
QR Code Model 1
|
||||||
@@ -198,10 +198,10 @@ fn cpp_qrcode_black_box2_test_case() {
|
|||||||
BarcodeFormat::QR_CODE,
|
BarcodeFormat::QR_CODE,
|
||||||
);
|
);
|
||||||
|
|
||||||
tester.add_test(45, 47, 0.0);
|
tester.add_test(46, 48, 0.0);
|
||||||
tester.add_test(45, 47, 90.0);
|
tester.add_test(46, 48, 90.0);
|
||||||
tester.add_test(45, 47, 180.0);
|
tester.add_test(46, 48, 180.0);
|
||||||
tester.add_test(45, 46, 270.0);
|
tester.add_test(46, 48, 270.0);
|
||||||
|
|
||||||
tester.ignore_pure = true;
|
tester.ignore_pure = true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user