mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 12:22:34 +00:00
cargo fmt
This commit is contained in:
@@ -28,21 +28,18 @@ type MaskCondition = fn(u32, u32) -> bool;
|
||||
fn testMask0() {
|
||||
testMaskAcrossDimensions(DataMask::DATA_MASK_000, |i, j| ((i + j) % 2 == 0));
|
||||
testMaskAcrossDimensionsU8(0, |i, j| ((i + j) % 2 == 0));
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testMask1() {
|
||||
testMaskAcrossDimensions(DataMask::DATA_MASK_001, |i, j| i % 2 == 0);
|
||||
testMaskAcrossDimensionsU8(1, |i, j| i % 2 == 0);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testMask2() {
|
||||
testMaskAcrossDimensions(DataMask::DATA_MASK_010, |i, j| j % 3 == 0);
|
||||
testMaskAcrossDimensionsU8(2, |i, j| j % 3 == 0);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -62,9 +59,7 @@ fn testMask5() {
|
||||
testMaskAcrossDimensions(DataMask::DATA_MASK_101, |i, j| {
|
||||
(i * j) % 2 + (i * j) % 3 == 0
|
||||
});
|
||||
testMaskAcrossDimensionsU8(5, |i, j| {
|
||||
(i * j) % 2 + (i * j) % 3 == 0
|
||||
});
|
||||
testMaskAcrossDimensionsU8(5, |i, j| (i * j) % 2 + (i * j) % 3 == 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -72,9 +67,7 @@ fn testMask6() {
|
||||
testMaskAcrossDimensions(DataMask::DATA_MASK_110, |i, j| {
|
||||
((i * j) % 2 + (i * j) % 3) % 2 == 0
|
||||
});
|
||||
testMaskAcrossDimensionsU8(6, |i, j| {
|
||||
((i * j) % 2 + (i * j) % 3) % 2 == 0
|
||||
});
|
||||
testMaskAcrossDimensionsU8(6, |i, j| ((i * j) % 2 + (i * j) % 3) % 2 == 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -82,9 +75,7 @@ fn testMask7() {
|
||||
testMaskAcrossDimensions(DataMask::DATA_MASK_111, |i, j| {
|
||||
((i + j) % 2 + (i * j) % 3) % 2 == 0
|
||||
});
|
||||
testMaskAcrossDimensionsU8(7, |i, j| {
|
||||
((i + j) % 2 + (i * j) % 3) % 2 == 0
|
||||
});
|
||||
testMaskAcrossDimensionsU8(7, |i, j| ((i + j) % 2 + (i * j) % 3) % 2 == 0);
|
||||
}
|
||||
|
||||
fn testMaskAcrossDimensionsU8(mask: u8, condition: MaskCondition) {
|
||||
|
||||
@@ -14,57 +14,97 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::qrcode::decoder::{FormatInformation, ErrorCorrectionLevel};
|
||||
use crate::qrcode::decoder::{ErrorCorrectionLevel, FormatInformation};
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
const MASKED_TEST_FORMAT_INFO: u32 = 0x2BED;
|
||||
const UNMASKED_TEST_FORMAT_INFO: u32 = MASKED_TEST_FORMAT_INFO ^ 0x5412;
|
||||
|
||||
const MASKED_TEST_FORMAT_INFO : u32 = 0x2BED;
|
||||
const UNMASKED_TEST_FORMAT_INFO : u32= MASKED_TEST_FORMAT_INFO ^ 0x5412;
|
||||
|
||||
#[test]
|
||||
fn testBitsDiffering() {
|
||||
#[test]
|
||||
fn testBitsDiffering() {
|
||||
assert_eq!(0, FormatInformation::numBitsDiffering(1, 1));
|
||||
assert_eq!(1, FormatInformation::numBitsDiffering(0, 2));
|
||||
assert_eq!(2, FormatInformation::numBitsDiffering(1, 2));
|
||||
assert_eq!(32, FormatInformation::numBitsDiffering(-1i32 as u32, 0));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testDecode() {
|
||||
#[test]
|
||||
fn testDecode() {
|
||||
// Normal case
|
||||
let expected =
|
||||
FormatInformation::decodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO);
|
||||
let expected = FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO,
|
||||
MASKED_TEST_FORMAT_INFO,
|
||||
);
|
||||
assert!(expected.is_some());
|
||||
let expected = expected.unwrap();
|
||||
assert_eq!( 0x07, expected.getDataMask());
|
||||
assert_eq!(0x07, expected.getDataMask());
|
||||
assert_eq!(ErrorCorrectionLevel::Q, expected.getErrorCorrectionLevel());
|
||||
// where the code forgot the mask!
|
||||
assert_eq!(expected,
|
||||
FormatInformation::decodeFormatInformation(UNMASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO).expect("return"));
|
||||
}
|
||||
assert_eq!(
|
||||
expected,
|
||||
FormatInformation::decodeFormatInformation(
|
||||
UNMASKED_TEST_FORMAT_INFO,
|
||||
MASKED_TEST_FORMAT_INFO
|
||||
)
|
||||
.expect("return")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testDecodeWithBitDifference() {
|
||||
let expected =
|
||||
FormatInformation::decodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO).unwrap();
|
||||
#[test]
|
||||
fn testDecodeWithBitDifference() {
|
||||
let expected = FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO,
|
||||
MASKED_TEST_FORMAT_INFO,
|
||||
)
|
||||
.unwrap();
|
||||
// 1,2,3,4 bits difference
|
||||
assert_eq!(expected, FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x01, MASKED_TEST_FORMAT_INFO ^ 0x01).expect("return"));
|
||||
assert_eq!(expected, FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x03, MASKED_TEST_FORMAT_INFO ^ 0x03).expect("return"));
|
||||
assert_eq!(expected, FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x07, MASKED_TEST_FORMAT_INFO ^ 0x07).expect("return"));
|
||||
assert_eq!(
|
||||
expected,
|
||||
FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x01,
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x01
|
||||
)
|
||||
.expect("return")
|
||||
);
|
||||
assert_eq!(
|
||||
expected,
|
||||
FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x03,
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x03
|
||||
)
|
||||
.expect("return")
|
||||
);
|
||||
assert_eq!(
|
||||
expected,
|
||||
FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x07,
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x07
|
||||
)
|
||||
.expect("return")
|
||||
);
|
||||
assert!(FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x0F, MASKED_TEST_FORMAT_INFO ^ 0x0F).is_none());
|
||||
}
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x0F,
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x0F
|
||||
)
|
||||
.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testDecodeWithMisread() {
|
||||
let expected =
|
||||
FormatInformation::decodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO).unwrap();
|
||||
assert_eq!(expected, FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x03, MASKED_TEST_FORMAT_INFO ^ 0x0F).unwrap());
|
||||
}
|
||||
#[test]
|
||||
fn testDecodeWithMisread() {
|
||||
let expected = FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO,
|
||||
MASKED_TEST_FORMAT_INFO,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
expected,
|
||||
FormatInformation::decodeFormatInformation(
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x03,
|
||||
MASKED_TEST_FORMAT_INFO ^ 0x0F
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,34 +18,50 @@ use crate::qrcode::decoder::Version;
|
||||
|
||||
use super::Mode;
|
||||
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn testForBits() {
|
||||
#[test]
|
||||
fn testForBits() {
|
||||
assert_eq!(Mode::TERMINATOR, Mode::forBits(0x00).unwrap());
|
||||
assert_eq!(Mode::NUMERIC, Mode::forBits(0x01).unwrap());
|
||||
assert_eq!(Mode::ALPHANUMERIC, Mode::forBits(0x02).unwrap());
|
||||
assert_eq!(Mode::BYTE, Mode::forBits(0x04).unwrap());
|
||||
assert_eq!(Mode::KANJI, Mode::forBits(0x08).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn testBadMode() {
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn testBadMode() {
|
||||
assert!(Mode::forBits(0x10).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testCharacterCount() {
|
||||
#[test]
|
||||
fn testCharacterCount() {
|
||||
// Spot check a few values
|
||||
assert_eq!(10, Mode::NUMERIC.getCharacterCountBits(Version::getVersionForNumber(5).unwrap()));
|
||||
assert_eq!(12, Mode::NUMERIC.getCharacterCountBits(Version::getVersionForNumber(26).unwrap()));
|
||||
assert_eq!(14, Mode::NUMERIC.getCharacterCountBits(Version::getVersionForNumber(40).unwrap()));
|
||||
assert_eq!(9, Mode::ALPHANUMERIC.getCharacterCountBits(Version::getVersionForNumber(6).unwrap()));
|
||||
assert_eq!(8, Mode::BYTE.getCharacterCountBits(Version::getVersionForNumber(7).unwrap()));
|
||||
assert_eq!(8, Mode::KANJI.getCharacterCountBits(Version::getVersionForNumber(8).unwrap()));
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
10,
|
||||
Mode::NUMERIC.getCharacterCountBits(Version::getVersionForNumber(5).unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
12,
|
||||
Mode::NUMERIC.getCharacterCountBits(Version::getVersionForNumber(26).unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
14,
|
||||
Mode::NUMERIC.getCharacterCountBits(Version::getVersionForNumber(40).unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
9,
|
||||
Mode::ALPHANUMERIC.getCharacterCountBits(Version::getVersionForNumber(6).unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
8,
|
||||
Mode::BYTE.getCharacterCountBits(Version::getVersionForNumber(7).unwrap())
|
||||
);
|
||||
assert_eq!(
|
||||
8,
|
||||
Mode::KANJI.getCharacterCountBits(Version::getVersionForNumber(8).unwrap())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,35 +14,36 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::{qrcode::decoder::{Version, ErrorCorrectionLevel}, Exceptions};
|
||||
|
||||
use crate::{
|
||||
qrcode::decoder::{ErrorCorrectionLevel, Version},
|
||||
Exceptions,
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Sean Owen
|
||||
*/
|
||||
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn testBadVersion() {
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn testBadVersion() {
|
||||
assert!(Version::getVersionForNumber(0).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testVersionForNumber() {
|
||||
#[test]
|
||||
fn testVersionForNumber() {
|
||||
for i in 1..=40 {
|
||||
// for (int i = 1; i <= 40; i++) {
|
||||
checkVersion(Version::getVersionForNumber(i), i, 4 * i + 17);
|
||||
// for (int i = 1; i <= 40; i++) {
|
||||
checkVersion(Version::getVersionForNumber(i), i, 4 * i + 17);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn checkVersion( version:Result<&Version,Exceptions>, number:u32, dimension:u32) {
|
||||
fn checkVersion(version: Result<&Version, Exceptions>, number: u32, dimension: u32) {
|
||||
assert!(version.is_ok());
|
||||
let version = version.unwrap();
|
||||
assert_eq!(number, version.getVersionNumber());
|
||||
// assertNotNull(version.getAlignmentPatternCenters());
|
||||
if number > 1 {
|
||||
assert!(version.getAlignmentPatternCenters().len() > 0);
|
||||
assert!(version.getAlignmentPatternCenters().len() > 0);
|
||||
}
|
||||
assert_eq!(dimension, version.getDimensionForVersion());
|
||||
let _tmp = version.getECBlocksForLevel(ErrorCorrectionLevel::H);
|
||||
@@ -56,18 +57,23 @@ use crate::{qrcode::decoder::{Version, ErrorCorrectionLevel}, Exceptions};
|
||||
// assertNotNull(version.getECBlocksForLevel(ErrorCorrectionLevel::M));
|
||||
// assertNotNull(version.getECBlocksForLevel(ErrorCorrectionLevel::Q));
|
||||
// assertNotNull(version.buildFunctionPattern());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testGetProvisionalVersionForDimension() {
|
||||
#[test]
|
||||
fn testGetProvisionalVersionForDimension() {
|
||||
for i in 1..=40 {
|
||||
// for (int i = 1; i <= 40; i++) {
|
||||
assert_eq!(i, Version::getProvisionalVersionForDimension(4 * i + 17).expect("must exist for supplied values").getVersionNumber());
|
||||
// for (int i = 1; i <= 40; i++) {
|
||||
assert_eq!(
|
||||
i,
|
||||
Version::getProvisionalVersionForDimension(4 * i + 17)
|
||||
.expect("must exist for supplied values")
|
||||
.getVersionNumber()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testDecodeVersionInformation() {
|
||||
#[test]
|
||||
fn testDecodeVersionInformation() {
|
||||
// Spot check
|
||||
doTestVersion(7, 0x07C94);
|
||||
doTestVersion(12, 0x0C762);
|
||||
@@ -75,11 +81,10 @@ use crate::{qrcode::decoder::{Version, ErrorCorrectionLevel}, Exceptions};
|
||||
doTestVersion(22, 0x168C9);
|
||||
doTestVersion(27, 0x1B08E);
|
||||
doTestVersion(32, 0x209D5);
|
||||
}
|
||||
|
||||
fn doTestVersion( expectedVersion:u32, mask:u32) {
|
||||
}
|
||||
|
||||
fn doTestVersion(expectedVersion: u32, mask: u32) {
|
||||
let version = Version::decodeVersionInformation(mask);
|
||||
assert!(version.is_ok());
|
||||
assert_eq!(expectedVersion, version.unwrap().getVersionNumber());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ impl BitMatrixParser {
|
||||
let dimension = self.bitMatrix.getHeight();
|
||||
let mut formatInfoBits2 = 0;
|
||||
let jMin = dimension - 7;
|
||||
for j in (jMin..=dimension-1).rev() {
|
||||
for j in (jMin..=dimension - 1).rev() {
|
||||
// for (int j = dimension - 1; j >= jMin; j--) {
|
||||
formatInfoBits2 = self.copyBit(8, j, formatInfoBits2);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
use crate::Exceptions;
|
||||
|
||||
use super::{VersionRef, ErrorCorrectionLevel};
|
||||
use super::{ErrorCorrectionLevel, VersionRef};
|
||||
|
||||
/**
|
||||
* <p>Encapsulates a block of data within a QR Code. QR Codes may split their data into
|
||||
@@ -26,118 +26,120 @@ use super::{VersionRef, ErrorCorrectionLevel};
|
||||
* @author Sean Owen
|
||||
*/
|
||||
pub struct DataBlock {
|
||||
|
||||
numDataCodewords:u32,
|
||||
codewords:Vec<u8>,
|
||||
numDataCodewords: u32,
|
||||
codewords: Vec<u8>,
|
||||
}
|
||||
|
||||
impl DataBlock {
|
||||
|
||||
fn new( numDataCodewords:u32, codewords:Vec<u8>) -> Self{
|
||||
Self{
|
||||
numDataCodewords,
|
||||
codewords,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>When QR Codes use multiple data blocks, they are actually interleaved.
|
||||
* That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
|
||||
* method will separate the data into original blocks.</p>
|
||||
*
|
||||
* @param rawCodewords bytes as read directly from the QR Code
|
||||
* @param version version of the QR Code
|
||||
* @param ecLevel error-correction level of the QR Code
|
||||
* @return DataBlocks containing original bytes, "de-interleaved" from representation in the
|
||||
* QR Code
|
||||
*/
|
||||
pub fn getDataBlocks( rawCodewords:&[u8],
|
||||
version:VersionRef,
|
||||
ecLevel:ErrorCorrectionLevel) -> Result<Vec<Self>,Exceptions> {
|
||||
|
||||
if rawCodewords.len() as u32 != version.getTotalCodewords() {
|
||||
return Err(Exceptions::IllegalArgumentException("".to_owned()))
|
||||
fn new(numDataCodewords: u32, codewords: Vec<u8>) -> Self {
|
||||
Self {
|
||||
numDataCodewords,
|
||||
codewords,
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out the number and size of data blocks used by this version and
|
||||
// error correction level
|
||||
let ecBlocks = version.getECBlocksForLevel(ecLevel);
|
||||
/**
|
||||
* <p>When QR Codes use multiple data blocks, they are actually interleaved.
|
||||
* That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
|
||||
* method will separate the data into original blocks.</p>
|
||||
*
|
||||
* @param rawCodewords bytes as read directly from the QR Code
|
||||
* @param version version of the QR Code
|
||||
* @param ecLevel error-correction level of the QR Code
|
||||
* @return DataBlocks containing original bytes, "de-interleaved" from representation in the
|
||||
* QR Code
|
||||
*/
|
||||
pub fn getDataBlocks(
|
||||
rawCodewords: &[u8],
|
||||
version: VersionRef,
|
||||
ecLevel: ErrorCorrectionLevel,
|
||||
) -> Result<Vec<Self>, Exceptions> {
|
||||
if rawCodewords.len() as u32 != version.getTotalCodewords() {
|
||||
return Err(Exceptions::IllegalArgumentException("".to_owned()));
|
||||
}
|
||||
|
||||
// First count the total number of data blocks
|
||||
let mut _totalBlocks = 0;
|
||||
let ecBlockArray = ecBlocks.getECBlocks();
|
||||
for ecBlock in ecBlockArray {
|
||||
// for (Version.ECB ecBlock : ecBlockArray) {
|
||||
_totalBlocks += ecBlock.getCount();
|
||||
// Figure out the number and size of data blocks used by this version and
|
||||
// error correction level
|
||||
let ecBlocks = version.getECBlocksForLevel(ecLevel);
|
||||
|
||||
// First count the total number of data blocks
|
||||
let mut _totalBlocks = 0;
|
||||
let ecBlockArray = ecBlocks.getECBlocks();
|
||||
for ecBlock in ecBlockArray {
|
||||
// for (Version.ECB ecBlock : ecBlockArray) {
|
||||
_totalBlocks += ecBlock.getCount();
|
||||
}
|
||||
|
||||
// Now establish DataBlocks of the appropriate size and number of data codewords
|
||||
let mut result = Vec::new();
|
||||
let mut numRXingResultBlocks = 0;
|
||||
for ecBlock in ecBlockArray {
|
||||
// for (Version.ECB ecBlock : ecBlockArray) {
|
||||
for _i in 0..ecBlock.getCount() {
|
||||
// for (int i = 0; i < ecBlock.getCount(); i++) {
|
||||
let numDataCodewords = ecBlock.getDataCodewords();
|
||||
let numBlockCodewords = ecBlocks.getECCodewordsPerBlock() + numDataCodewords;
|
||||
// result[numRXingResultBlocks] = DataBlock::new(numDataCodewords, vec![0u8;numBlockCodewords as usize]);
|
||||
result.push(DataBlock::new(
|
||||
numDataCodewords,
|
||||
vec![0u8; numBlockCodewords as usize],
|
||||
));
|
||||
numRXingResultBlocks += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// All blocks have the same amount of data, except that the last n
|
||||
// (where n may be 0) have 1 more byte. Figure out where these start.
|
||||
let shorterBlocksTotalCodewords = result[0].codewords.len();
|
||||
let mut longerBlocksStartAt = result.len() - 1;
|
||||
loop {
|
||||
//while longerBlocksStartAt >= 0 {
|
||||
let numCodewords = result[longerBlocksStartAt].codewords.len();
|
||||
if numCodewords == shorterBlocksTotalCodewords {
|
||||
break;
|
||||
}
|
||||
longerBlocksStartAt -= 1;
|
||||
}
|
||||
longerBlocksStartAt += 1;
|
||||
|
||||
let shorterBlocksNumDataCodewords =
|
||||
shorterBlocksTotalCodewords - ecBlocks.getECCodewordsPerBlock() as usize;
|
||||
// The last elements of result may be 1 element longer;
|
||||
// first fill out as many elements as all of them have
|
||||
let mut rawCodewordsOffset = 0;
|
||||
for i in 0..shorterBlocksNumDataCodewords {
|
||||
// for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {
|
||||
for j in 0..numRXingResultBlocks {
|
||||
// for (int j = 0; j < numRXingResultBlocks; j++) {
|
||||
result[j].codewords[i] = rawCodewords[rawCodewordsOffset];
|
||||
rawCodewordsOffset += 1;
|
||||
}
|
||||
}
|
||||
// Fill out the last data block in the longer ones
|
||||
for j in longerBlocksStartAt..numRXingResultBlocks {
|
||||
// for (int j = longerBlocksStartAt; j < numRXingResultBlocks; j++) {
|
||||
result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset];
|
||||
rawCodewordsOffset += 1;
|
||||
}
|
||||
// Now add in error correction blocks
|
||||
let max = result[0].codewords.len();
|
||||
for i in shorterBlocksNumDataCodewords..max {
|
||||
// for (int i = shorterBlocksNumDataCodewords; i < max; i++) {
|
||||
for j in 0..numRXingResultBlocks {
|
||||
// for (int j = 0; j < numRXingResultBlocks; j++) {
|
||||
let iOffset = if j < longerBlocksStartAt { i } else { i + 1 };
|
||||
result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset];
|
||||
rawCodewordsOffset += 1;
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// Now establish DataBlocks of the appropriate size and number of data codewords
|
||||
let mut result = Vec::new();
|
||||
let mut numRXingResultBlocks = 0;
|
||||
for ecBlock in ecBlockArray {
|
||||
// for (Version.ECB ecBlock : ecBlockArray) {
|
||||
for _i in 0..ecBlock.getCount() {
|
||||
// for (int i = 0; i < ecBlock.getCount(); i++) {
|
||||
let numDataCodewords = ecBlock.getDataCodewords();
|
||||
let numBlockCodewords = ecBlocks.getECCodewordsPerBlock() + numDataCodewords;
|
||||
// result[numRXingResultBlocks] = DataBlock::new(numDataCodewords, vec![0u8;numBlockCodewords as usize]);
|
||||
result.push( DataBlock::new(numDataCodewords, vec![0u8;numBlockCodewords as usize]));
|
||||
numRXingResultBlocks += 1;
|
||||
}
|
||||
pub fn getNumDataCodewords(&self) -> u32 {
|
||||
self.numDataCodewords
|
||||
}
|
||||
|
||||
// All blocks have the same amount of data, except that the last n
|
||||
// (where n may be 0) have 1 more byte. Figure out where these start.
|
||||
let shorterBlocksTotalCodewords = result[0].codewords.len();
|
||||
let mut longerBlocksStartAt = result.len() - 1;
|
||||
loop {
|
||||
//while longerBlocksStartAt >= 0 {
|
||||
let numCodewords = result[longerBlocksStartAt].codewords.len();
|
||||
if numCodewords == shorterBlocksTotalCodewords {
|
||||
break;
|
||||
}
|
||||
longerBlocksStartAt-=1;
|
||||
pub fn getCodewords(&self) -> &[u8] {
|
||||
&self.codewords
|
||||
}
|
||||
longerBlocksStartAt+=1;
|
||||
|
||||
let shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.getECCodewordsPerBlock() as usize;
|
||||
// The last elements of result may be 1 element longer;
|
||||
// first fill out as many elements as all of them have
|
||||
let mut rawCodewordsOffset = 0;
|
||||
for i in 0..shorterBlocksNumDataCodewords {
|
||||
// for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {
|
||||
for j in 0..numRXingResultBlocks {
|
||||
// for (int j = 0; j < numRXingResultBlocks; j++) {
|
||||
result[j].codewords[i] = rawCodewords[rawCodewordsOffset];
|
||||
rawCodewordsOffset += 1;
|
||||
}
|
||||
}
|
||||
// Fill out the last data block in the longer ones
|
||||
for j in longerBlocksStartAt..numRXingResultBlocks{
|
||||
// for (int j = longerBlocksStartAt; j < numRXingResultBlocks; j++) {
|
||||
result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset];
|
||||
rawCodewordsOffset += 1;
|
||||
}
|
||||
// Now add in error correction blocks
|
||||
let max = result[0].codewords.len();
|
||||
for i in shorterBlocksNumDataCodewords..max {
|
||||
// for (int i = shorterBlocksNumDataCodewords; i < max; i++) {
|
||||
for j in 0..numRXingResultBlocks {
|
||||
// for (int j = 0; j < numRXingResultBlocks; j++) {
|
||||
let iOffset = if j < longerBlocksStartAt {i} else {i + 1};
|
||||
result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset];
|
||||
rawCodewordsOffset += 1;
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn getNumDataCodewords(&self) -> u32{
|
||||
self. numDataCodewords
|
||||
}
|
||||
|
||||
pub fn getCodewords(&self) -> &[u8] {
|
||||
&self.codewords
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ use crate::{common::BitMatrix, Exceptions};
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
#[derive(Copy,Clone,Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum DataMask {
|
||||
// See ISO 18004:2006 6.8.1
|
||||
/**
|
||||
@@ -222,15 +222,18 @@ impl TryFrom<u8> for DataMask {
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
0=>Ok(DataMask::DATA_MASK_000),
|
||||
1=>Ok(DataMask::DATA_MASK_001),
|
||||
2=>Ok(DataMask::DATA_MASK_010),
|
||||
3=>Ok(DataMask::DATA_MASK_011),
|
||||
4=>Ok(DataMask::DATA_MASK_100),
|
||||
5=>Ok(DataMask::DATA_MASK_101),
|
||||
6=>Ok(DataMask::DATA_MASK_110),
|
||||
7=>Ok(DataMask::DATA_MASK_111),
|
||||
_=>Err(Exceptions::IllegalArgumentException(format!("{} is not between 0 and 7",value))),
|
||||
0 => Ok(DataMask::DATA_MASK_000),
|
||||
1 => Ok(DataMask::DATA_MASK_001),
|
||||
2 => Ok(DataMask::DATA_MASK_010),
|
||||
3 => Ok(DataMask::DATA_MASK_011),
|
||||
4 => Ok(DataMask::DATA_MASK_100),
|
||||
5 => Ok(DataMask::DATA_MASK_101),
|
||||
6 => Ok(DataMask::DATA_MASK_110),
|
||||
7 => Ok(DataMask::DATA_MASK_111),
|
||||
_ => Err(Exceptions::IllegalArgumentException(format!(
|
||||
"{} is not between 0 and 7",
|
||||
value
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,17 +286,19 @@ fn decodeByteSegment(
|
||||
encoding = CharacterSetECI::getCharset(currentCharacterSetECI.as_ref().unwrap());
|
||||
}
|
||||
|
||||
let encode_string = if currentCharacterSetECI.is_some() && currentCharacterSetECI.as_ref().unwrap() == &CharacterSetECI::Cp437 {
|
||||
{
|
||||
use codepage_437::BorrowFromCp437;
|
||||
use codepage_437::CP437_CONTROL;
|
||||
let encode_string = if currentCharacterSetECI.is_some()
|
||||
&& currentCharacterSetECI.as_ref().unwrap() == &CharacterSetECI::Cp437
|
||||
{
|
||||
{
|
||||
use codepage_437::BorrowFromCp437;
|
||||
use codepage_437::CP437_CONTROL;
|
||||
|
||||
String::borrow_from_cp437(&readBytes, &CP437_CONTROL)
|
||||
}
|
||||
}else {
|
||||
encoding
|
||||
.decode(&readBytes, encoding::DecoderTrap::Strict)
|
||||
.unwrap()
|
||||
String::borrow_from_cp437(&readBytes, &CP437_CONTROL)
|
||||
}
|
||||
} else {
|
||||
encoding
|
||||
.decode(&readBytes, encoding::DecoderTrap::Strict)
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
// let encode_string = encoding
|
||||
|
||||
@@ -198,7 +198,7 @@ fn correctErrors(codewordBytes: &mut [u8], numDataCodewords: usize) -> Result<()
|
||||
codewordsInts[i] = codewordBytes[i]; // & 0xFF;
|
||||
}
|
||||
|
||||
let mut sending_code_words : Vec<i32> = codewordsInts.iter().map(|x| *x as i32).collect();
|
||||
let mut sending_code_words: Vec<i32> = codewordsInts.iter().map(|x| *x as i32).collect();
|
||||
|
||||
if let Err(e) = RS_DECODER.decode(
|
||||
&mut sending_code_words,
|
||||
|
||||
@@ -88,15 +88,15 @@ impl From<ErrorCorrectionLevel> for u8 {
|
||||
}
|
||||
|
||||
impl FromStr for ErrorCorrectionLevel {
|
||||
type Err=Exceptions;
|
||||
type Err = Exceptions;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
// First try to see if the string is just the name of the value
|
||||
let as_str = match s.to_uppercase().as_str() {
|
||||
"L" => Some(ErrorCorrectionLevel::L),
|
||||
"M" => Some(ErrorCorrectionLevel::M),
|
||||
"Q" =>Some(ErrorCorrectionLevel::Q),
|
||||
"H" =>Some(ErrorCorrectionLevel::H),
|
||||
"Q" => Some(ErrorCorrectionLevel::Q),
|
||||
"H" => Some(ErrorCorrectionLevel::H),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@@ -110,7 +110,10 @@ impl FromStr for ErrorCorrectionLevel {
|
||||
return number_possible.unwrap().try_into();
|
||||
}
|
||||
|
||||
return Err(Exceptions::IllegalArgumentException(format!("could not parse {} into an ec level", s)))
|
||||
return Err(Exceptions::IllegalArgumentException(format!(
|
||||
"could not parse {} into an ec level",
|
||||
s
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,12 +101,12 @@ impl FormatInformation {
|
||||
) -> Option<FormatInformation> {
|
||||
let formatInfo = Self::doDecodeFormatInformation(masked_format_info1, masked_format_info2);
|
||||
if formatInfo.is_some() {
|
||||
return formatInfo
|
||||
return formatInfo;
|
||||
}
|
||||
// Should return null, but, some QR codes apparently
|
||||
// do not mask this info. Try again by actually masking the pattern
|
||||
// first
|
||||
Self::doDecodeFormatInformation(
|
||||
Self::doDecodeFormatInformation(
|
||||
masked_format_info1 ^ FORMAT_INFO_MASK_QR,
|
||||
masked_format_info2 ^ FORMAT_INFO_MASK_QR,
|
||||
)
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
mod version;
|
||||
mod mode;
|
||||
mod error_correction_level;
|
||||
mod format_information;
|
||||
mod data_block;
|
||||
mod qr_code_decoder_meta_data;
|
||||
mod data_mask;
|
||||
mod bit_matrix_parser;
|
||||
mod data_block;
|
||||
mod data_mask;
|
||||
pub mod decoded_bit_stream_parser;
|
||||
pub mod decoder;
|
||||
mod error_correction_level;
|
||||
mod format_information;
|
||||
mod mode;
|
||||
mod qr_code_decoder_meta_data;
|
||||
mod version;
|
||||
|
||||
#[cfg(test)]
|
||||
mod ErrorCorrectionLevelTestCase;
|
||||
#[cfg(test)]
|
||||
mod ModeTestCase;
|
||||
#[cfg(test)]
|
||||
mod VersionTestCase;
|
||||
#[cfg(test)]
|
||||
mod FormatInformationTestCase;
|
||||
#[cfg(test)]
|
||||
mod DataMaskTestCase;
|
||||
#[cfg(test)]
|
||||
mod DecodedBitStreamParserTestCase;
|
||||
#[cfg(test)]
|
||||
mod ErrorCorrectionLevelTestCase;
|
||||
#[cfg(test)]
|
||||
mod FormatInformationTestCase;
|
||||
#[cfg(test)]
|
||||
mod ModeTestCase;
|
||||
#[cfg(test)]
|
||||
mod VersionTestCase;
|
||||
|
||||
pub use version::*;
|
||||
pub use mode::*;
|
||||
pub use bit_matrix_parser::*;
|
||||
pub use data_block::*;
|
||||
pub use data_mask::*;
|
||||
pub use error_correction_level::*;
|
||||
pub use format_information::*;
|
||||
pub use data_block::*;
|
||||
pub use mode::*;
|
||||
pub use qr_code_decoder_meta_data::*;
|
||||
pub use data_mask::*;
|
||||
pub use bit_matrix_parser::*;
|
||||
pub use version::*;
|
||||
|
||||
@@ -24,31 +24,30 @@ use crate::RXingResultPoint;
|
||||
*/
|
||||
pub struct QRCodeDecoderMetaData(bool);
|
||||
|
||||
impl QRCodeDecoderMetaData {
|
||||
pub fn new( mirrored:bool) -> Self {
|
||||
Self(mirrored)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the QR Code was mirrored.
|
||||
*/
|
||||
pub fn isMirrored(&self) -> bool{
|
||||
self.0
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the result points' order correction due to mirroring.
|
||||
*
|
||||
* @param points Array of points to apply mirror correction to.
|
||||
*/
|
||||
pub fn applyMirroredCorrection(&self, points : &mut [RXingResultPoint]) {
|
||||
if !self.0 || points.is_empty() || points.len() < 3 {
|
||||
return
|
||||
impl QRCodeDecoderMetaData {
|
||||
pub fn new(mirrored: bool) -> Self {
|
||||
Self(mirrored)
|
||||
}
|
||||
let bottom_left = points[0];
|
||||
points[0] = points[2];
|
||||
points[2] = bottom_left;
|
||||
// No need to 'fix' top-left and alignment pattern.
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the QR Code was mirrored.
|
||||
*/
|
||||
pub fn isMirrored(&self) -> bool {
|
||||
self.0
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the result points' order correction due to mirroring.
|
||||
*
|
||||
* @param points Array of points to apply mirror correction to.
|
||||
*/
|
||||
pub fn applyMirroredCorrection(&self, points: &mut [RXingResultPoint]) {
|
||||
if !self.0 || points.is_empty() || points.len() < 3 {
|
||||
return;
|
||||
}
|
||||
let bottom_left = points[0];
|
||||
points[0] = points[2];
|
||||
points[2] = bottom_left;
|
||||
// No need to 'fix' top-left and alignment pattern.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ impl Version {
|
||||
/**
|
||||
* See ISO 18004:2006 Annex E
|
||||
*/
|
||||
pub fn buildFunctionPattern(&self) -> Result<BitMatrix,Exceptions> {
|
||||
pub fn buildFunctionPattern(&self) -> Result<BitMatrix, Exceptions> {
|
||||
let dimension = self.getDimensionForVersion();
|
||||
let mut bitMatrix = BitMatrix::with_single_dimension(dimension);
|
||||
|
||||
@@ -932,7 +932,7 @@ impl fmt::Display for Version {
|
||||
* will be the same across all blocks within one version.</p>
|
||||
*/
|
||||
#[derive(Debug)]
|
||||
pub struct ECBlocks {
|
||||
pub struct ECBlocks {
|
||||
ecCodewordsPerBlock: u32,
|
||||
ecBlocks: Vec<ECB>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user