mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 12:22:34 +00:00
aztec decoder passes
This commit is contained in:
@@ -41,16 +41,16 @@ use super::{decoder, AztecDetectorResult::AztecDetectorRXingResult};
|
||||
const NO_POINTS: &[RXingResultPoint] = &[RXingResultPoint { x: 0.0, y: 0.0 }; 0];
|
||||
|
||||
#[test]
|
||||
fn testHighLevelDecode() {
|
||||
fn test_high_level_decode() {
|
||||
// no ECI codes
|
||||
testHighLevelDecodeString(
|
||||
test_high_level_decode_string(
|
||||
"A. b.",
|
||||
// 'A' P/S '. ' L/L b D/L '.'
|
||||
"...X. ..... ...XX XXX.. ...XX XXXX. XX.X",
|
||||
);
|
||||
|
||||
// initial ECI code 26 (switch to UTF-8)
|
||||
testHighLevelDecodeString(
|
||||
test_high_level_decode_string(
|
||||
"Ça",
|
||||
// P/S FLG(n) 2 '2' '6' B/S 2 0xc3 0x87 L/L 'a'
|
||||
"..... ..... .X. .X.. X... XXXXX ...X. XX....XX X....XXX XXX.. ...X.",
|
||||
@@ -58,21 +58,21 @@ fn testHighLevelDecode() {
|
||||
|
||||
// initial character without ECI (must be interpreted as ISO_8859_1)
|
||||
// followed by ECI code 26 (= UTF-8) and UTF-8 text
|
||||
testHighLevelDecodeString(
|
||||
test_high_level_decode_string(
|
||||
"±Ça",
|
||||
// B/S 1 0xb1 P/S FLG(n) 2 '2' '6' B/S 2 0xc3 0x87 L/L 'a'
|
||||
"XXXXX ....X X.XX...X ..... ..... .X. .X.. X... XXXXX ...X. XX....XX X....XXX XXX.. ...X.",
|
||||
);
|
||||
|
||||
// GS1 data
|
||||
testHighLevelDecodeString(
|
||||
test_high_level_decode_string(
|
||||
"101233742",
|
||||
// P/S FLG(n) 0 D/L 1 0 1 2 3 P/S FLG(n) 0 3 7 4 2
|
||||
"..... ..... ... XXXX. ..XX ..X. ..XX .X.. .X.X .... ..... ... .X.X X..X .XX. .X..",
|
||||
);
|
||||
}
|
||||
|
||||
fn testHighLevelDecodeString(expectedString: &str, b: &str) {
|
||||
fn test_high_level_decode_string(expectedString: &str, b: &str) {
|
||||
let bits = toBitArray(&stripSpace(b));
|
||||
assert_eq!(
|
||||
expectedString,
|
||||
@@ -83,7 +83,7 @@ fn testHighLevelDecodeString(expectedString: &str, b: &str) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testAztecRXingResult() {
|
||||
fn test_aztec_rxing_result() {
|
||||
let matrix = BitMatrix::parse_strings(
|
||||
r"X X X X X X X X X X X X X X
|
||||
X X X X X X X X X X X X X X X
|
||||
@@ -148,7 +148,7 @@ X X X X X X X X X X X X X X
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testAztecRXingResultECI() {
|
||||
fn test_aztec_rxing_result_eci() {
|
||||
let matrix = BitMatrix::parse_strings(
|
||||
r" X X X X X X
|
||||
X X X X X X X X X X X X
|
||||
@@ -180,86 +180,86 @@ X X X X X X X X ",
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn testDecodeTooManyErrors() {
|
||||
fn test_decode_too_many_errors() {
|
||||
let matrix = BitMatrix::parse_strings(
|
||||
r"
|
||||
X X . X . . . X X . . . X . . X X X . X . X X X X X .
|
||||
X X . . X X . . . . . X X . . . X X . . . X . X . . X
|
||||
X . . . X X . . X X X . X X . X X X X . X X . . X . .
|
||||
. . . . X . X X . . X X . X X . X . X X X X . X . . X
|
||||
X X X . . X X X X X . . . . . X X . . . X . X . X . X
|
||||
X X . . . . . . . . X . . . X . X X X . X . . X . . .
|
||||
X X . . X . . . . . X X . . . . . X . . . . X . . X X \
|
||||
. . . X . X . X . . . . . X X X X X X . . . . . . X X
|
||||
X . . . X . X X X X X X . . X X X . X . X X X X X X .
|
||||
X . . X X X . X X X X X X X X X X X X X . . . X . X X
|
||||
. . . . X X . . . X . . . . . . . X X . . . X X . X .
|
||||
. . . X X X . . X X . X X X X X . X . . X . . . . . .
|
||||
X . . . . X . X . X . X . . . X . X . X X . X X . X X
|
||||
X . X . . X . X . X . X . X . X . X . . . . . X . X X
|
||||
X . X X X . . X . X . X . . . X . X . X X X . . . X X
|
||||
X X X X X X X X . X . X X X X X . X . X . X . X X X .
|
||||
. . . . . . . X . X . . . . . . . X X X X . . . X X X
|
||||
X X . . X . . X . X X X X X X X X X X X X X . . X . X
|
||||
X X X . X X X X . . X X X X . . X . . . . X . . X X X
|
||||
. . . . X . X X X . . . . X X X X . . X X X X . . . .
|
||||
. . X . . X . X . . . X . X X . X X . X . . . X . X .
|
||||
X X . . X . . X X X X X X X . . X . X X X X X X X . .
|
||||
X . X X . . X X . . . . . X . . . . . . X X . X X X .
|
||||
X . . X X . . X X . X . X . . . . X . X . . X . . X .
|
||||
X . X . X . . X . X X X X X X X X . X X X X . . X X .
|
||||
X X X X . . . X . . X X X . X X . . X . . . . X X X .
|
||||
X X . X . X . . . X . X . . . . X X . X . . X X . . . ",
|
||||
X X . X . . . X X . . . X . . X X X . X . X X X X X .
|
||||
X X . . X X . . . . . X X . . . X X . . . X . X . . X
|
||||
X . . . X X . . X X X . X X . X X X X . X X . . X . .
|
||||
. . . . X . X X . . X X . X X . X . X X X X . X . . X
|
||||
X X X . . X X X X X . . . . . X X . . . X . X . X . X
|
||||
X X . . . . . . . . X . . . X . X X X . X . . X . . .
|
||||
X X . . X . . . . . X X . . . . . X . . . . X . . X X
|
||||
. . . X . X . X . . . . . X X X X X X . . . . . . X X
|
||||
X . . . X . X X X X X X . . X X X . X . X X X X X X .
|
||||
X . . X X X . X X X X X X X X X X X X X . . . X . X X
|
||||
. . . . X X . . . X . . . . . . . X X . . . X X . X .
|
||||
. . . X X X . . X X . X X X X X . X . . X . . . . . .
|
||||
X . . . . X . X . X . X . . . X . X . X X . X X . X X
|
||||
X . X . . X . X . X . X . X . X . X . . . . . X . X X
|
||||
X . X X X . . X . X . X . . . X . X . X X X . . . X X
|
||||
X X X X X X X X . X . X X X X X . X . X . X . X X X .
|
||||
. . . . . . . X . X . . . . . . . X X X X . . . X X X
|
||||
X X . . X . . X . X X X X X X X X X X X X X . . X . X
|
||||
X X X . X X X X . . X X X X . . X . . . . X . . X X X
|
||||
. . . . X . X X X . . . . X X X X . . X X X X . . . .
|
||||
. . X . . X . X . . . X . X X . X X . X . . . X . X .
|
||||
X X . . X . . X X X X X X X . . X . X X X X X X X . .
|
||||
X . X X . . X X . . . . . X . . . . . . X X . X X X .
|
||||
X . . X X . . X X . X . X . . . . X . X . . X . . X .
|
||||
X . X . X . . X . X X X X X X X X . X X X X . . X X .
|
||||
X X X X . . . X . . X X X . X X . . X . . . . X X X .
|
||||
X X . X . X . . . X . X . . . . X X . X . . X X . . . ",
|
||||
"X ",
|
||||
". ",
|
||||
)
|
||||
.expect("parse string success");
|
||||
.expect("parse string failed");
|
||||
let r = AztecDetectorRXingResult::new(matrix, NO_POINTS.to_vec(), true, 16, 4);
|
||||
decoder::decode(&r);
|
||||
assert!(decoder::decode(&r).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn testDecodeTooManyErrors2() {
|
||||
fn test_decode_too_many_errors2() {
|
||||
let matrix = BitMatrix::parse_strings(
|
||||
r"
|
||||
. X X . . X . X X . . . X . . X X X . . . X X . X X .
|
||||
X X . X X . . X . . . X X . . . X X . X X X . X . X X
|
||||
. . . . X . . . X X X . X X . X X X X . X X . . X . .
|
||||
X . X X . . X . . . X X . X X . X . X X . . . . . X .
|
||||
X X . X . . X . X X . . . . . X X . . . . . X . . . X
|
||||
X . . X . . . . . . X . . . X . X X X X X X X . . . X
|
||||
X . . X X . . X . . X X . . . . . X . . . . . X X X .
|
||||
. . X X X X . X . . . . . X X X X X X . . . . . . X X
|
||||
X . . . X . X X X X X X . . X X X . X . X X X X X X .
|
||||
X . . X X X . X X X X X X X X X X X X X . . . X . X X
|
||||
. . . . X X . . . X . . . . . . . X X . . . X X . X .
|
||||
. . . X X X . . X X . X X X X X . X . . X . . . . . .
|
||||
X . . . . X . X . X . X . . . X . X . X X . X X . X X
|
||||
X . X . . X . X . X . X . X . X . X . . . . . X . X X
|
||||
X . X X X . . X . X . X . . . X . X . X X X . . . X X
|
||||
X X X X X X X X . X . X X X X X . X . X . X . X X X .
|
||||
. . . . . . . X . X . . . . . . . X X X X . . . X X X
|
||||
X X . . X . . X . X X X X X X X X X X X X X . . X . X
|
||||
X X X . X X X X . . X X X X . . X . . . . X . . X X X
|
||||
. . X X X X X . X . . . . X X X X . . X X X . X . X .
|
||||
. . X X . X . X . . . X . X X . X X . . . . X X . . .
|
||||
X . . . X . X . X X X X X X . . X . X X X X X . X . .
|
||||
. X . . . X X X . . . . . X . . . . . X X X X X . X .
|
||||
X . . X . X X X X . X . X . . . . X . X X . X . . X .
|
||||
X . . . X X . X . X X X X X X X X . X X X X . . X X .
|
||||
. X X X X . . X . . X X X . X X . . X . . . . X X X .
|
||||
X X . . . X X . . X . X . . . . X X . X . . X . X . X ",
|
||||
. X X . . X . X X . . . X . . X X X . . . X X . X X .
|
||||
X X . X X . . X . . . X X . . . X X . X X X . X . X X
|
||||
. . . . X . . . X X X . X X . X X X X . X X . . X . .
|
||||
X . X X . . X . . . X X . X X . X . X X . . . . . X .
|
||||
X X . X . . X . X X . . . . . X X . . . . . X . . . X
|
||||
X . . X . . . . . . X . . . X . X X X X X X X . . . X
|
||||
X . . X X . . X . . X X . . . . . X . . . . . X X X .
|
||||
. . X X X X . X . . . . . X X X X X X . . . . . . X X
|
||||
X . . . X . X X X X X X . . X X X . X . X X X X X X .
|
||||
X . . X X X . X X X X X X X X X X X X X . . . X . X X
|
||||
. . . . X X . . . X . . . . . . . X X . . . X X . X .
|
||||
. . . X X X . . X X . X X X X X . X . . X . . . . . .
|
||||
X . . . . X . X . X . X . . . X . X . X X . X X . X X
|
||||
X . X . . X . X . X . X . X . X . X . . . . . X . X X
|
||||
X . X X X . . X . X . X . . . X . X . X X X . . . X X
|
||||
X X X X X X X X . X . X X X X X . X . X . X . X X X .
|
||||
. . . . . . . X . X . . . . . . . X X X X . . . X X X
|
||||
X X . . X . . X . X X X X X X X X X X X X X . . X . X
|
||||
X X X . X X X X . . X X X X . . X . . . . X . . X X X
|
||||
. . X X X X X . X . . . . X X X X . . X X X . X . X .
|
||||
. . X X . X . X . . . X . X X . X X . . . . X X . . .
|
||||
X . . . X . X . X X X X X X . . X . X X X X X . X . .
|
||||
. X . . . X X X . . . . . X . . . . . X X X X X . X .
|
||||
X . . X . X X X X . X . X . . . . X . X X . X . . X .
|
||||
X . . . X X . X . X X X X X X X X . X X X X . . X X .
|
||||
. X X X X . . X . . X X X . X X . . X . . . . X X X .
|
||||
X X . . . X X . . X . X . . . . X X . X . . X . X . X ",
|
||||
"X ",
|
||||
". ",
|
||||
)
|
||||
.expect("String Parse OK");
|
||||
.expect("String Parse failed");
|
||||
let r = AztecDetectorRXingResult::new(matrix, NO_POINTS.to_vec(), true, 16, 4);
|
||||
decoder::decode(&r);
|
||||
assert!(decoder::decode(&r).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testRawBytes() {
|
||||
fn test_raw_bytes() {
|
||||
let bool0 = vec![false; 0];
|
||||
let bool1 = vec![true];
|
||||
let bool7 = vec![true, false, true, false, true, false, true];
|
||||
|
||||
@@ -123,33 +123,34 @@ pub fn highLevelDecode(correctedBits: &[bool]) -> Result<String, Exceptions> {
|
||||
*
|
||||
* @return the decoded string
|
||||
*/
|
||||
fn getEncodedData(correctedBits: &[bool]) -> Result<String, Exceptions> {
|
||||
let endIndex = correctedBits.len();
|
||||
let mut latchTable = Table::UPPER; // table most recently latched to
|
||||
let mut shiftTable = Table::UPPER; // table to use for the next read
|
||||
fn getEncodedData(corrected_bits: &[bool]) -> Result<String, Exceptions> {
|
||||
let endIndex = corrected_bits.len();
|
||||
let mut latch_table = Table::UPPER; // table most recently latched to
|
||||
let mut shift_table = Table::UPPER; // table to use for the next read
|
||||
|
||||
// Final decoded string result
|
||||
// (correctedBits-5) / 4 is an upper bound on the size (all-digit result)
|
||||
let mut result = String::with_capacity((correctedBits.len() - 5) / 4);
|
||||
let mut result = String::with_capacity((corrected_bits.len() - 5) / 4);
|
||||
|
||||
// Intermediary buffer of decoded bytes, which is decoded into a string and flushed
|
||||
// when character encoding changes (ECI) or input ends.
|
||||
let mut decodedBytes: Vec<u8> = Vec::new();
|
||||
let mut encdr: &'static dyn encoding::Encoding = encoding::all::UTF_8;
|
||||
let mut decoded_bytes: Vec<u8> = Vec::new();
|
||||
// let mut encdr: &'static dyn encoding::Encoding = encoding::all::UTF_8;
|
||||
let mut encdr: &'static dyn encoding::Encoding = encoding::all::ISO_8859_1;
|
||||
|
||||
let mut index = 0;
|
||||
while index < endIndex {
|
||||
if shiftTable == Table::BINARY {
|
||||
if shift_table == Table::BINARY {
|
||||
if endIndex - index < 5 {
|
||||
break;
|
||||
}
|
||||
let mut length = readCode(correctedBits, index, 5);
|
||||
let mut length = readCode(corrected_bits, index, 5);
|
||||
index += 5;
|
||||
if length == 0 {
|
||||
if endIndex - index < 11 {
|
||||
break;
|
||||
}
|
||||
length = readCode(correctedBits, index, 11) + 31;
|
||||
length = readCode(corrected_bits, index, 11) + 31;
|
||||
index += 11;
|
||||
}
|
||||
for _charCount in 0..length {
|
||||
@@ -158,34 +159,36 @@ fn getEncodedData(correctedBits: &[bool]) -> Result<String, Exceptions> {
|
||||
index = endIndex; // Force outer loop to exit
|
||||
break;
|
||||
}
|
||||
let code = readCode(correctedBits, index, 8);
|
||||
decodedBytes.push(code as u8);
|
||||
let code = readCode(corrected_bits, index, 8);
|
||||
decoded_bytes.push(code as u8);
|
||||
index += 8;
|
||||
}
|
||||
// Go back to whatever mode we had been in
|
||||
shiftTable = latchTable;
|
||||
shift_table = latch_table;
|
||||
} else {
|
||||
let size = if shiftTable == Table::DIGIT { 4 } else { 5 };
|
||||
let size = if shift_table == Table::DIGIT { 4 } else { 5 };
|
||||
if endIndex - index < size {
|
||||
break;
|
||||
}
|
||||
let code = readCode(correctedBits, index, size);
|
||||
let code = readCode(corrected_bits, index, size);
|
||||
index += size;
|
||||
let str = getCharacter(shiftTable, code)?;
|
||||
let str = getCharacter(shift_table, code)?;
|
||||
if "FLG(n)" == str {
|
||||
if endIndex - index < 3 {
|
||||
break;
|
||||
}
|
||||
let mut n = readCode(correctedBits, index, 3);
|
||||
let mut n = readCode(corrected_bits, index, 3);
|
||||
index += 3;
|
||||
// flush bytes, FLG changes state
|
||||
// try {
|
||||
result.push_str(&String::from_utf8(decodedBytes.clone()).unwrap());
|
||||
result.push_str(&encdr.decode(&decoded_bytes, encoding::DecoderTrap::Strict).unwrap());
|
||||
|
||||
// result.push_str(&String::from_utf8(decoded_bytes.clone()).unwrap());
|
||||
// result.append(decodedBytes.toString(encoding.name()));
|
||||
// } catch (UnsupportedEncodingException uee) {
|
||||
// throw new IllegalStateException(uee);
|
||||
// }
|
||||
decodedBytes.clear();
|
||||
decoded_bytes.clear();
|
||||
match n {
|
||||
0 => result.push(29 as char), // translate FNC1 as ASCII 29
|
||||
7 => {
|
||||
@@ -201,7 +204,7 @@ fn getEncodedData(correctedBits: &[bool]) -> Result<String, Exceptions> {
|
||||
}
|
||||
while n > 0 {
|
||||
//while (n-- > 0) {
|
||||
let nextDigit = readCode(correctedBits, index, 4);
|
||||
let nextDigit = readCode(corrected_bits, index, 4);
|
||||
index += 4;
|
||||
if nextDigit < 2 || nextDigit > 11 {
|
||||
return Err(Exceptions::FormatException(
|
||||
@@ -248,16 +251,16 @@ fn getEncodedData(correctedBits: &[bool]) -> Result<String, Exceptions> {
|
||||
// encoding = charsetECI.getCharset();
|
||||
// }
|
||||
// Go back to whatever mode we had been in
|
||||
shiftTable = latchTable;
|
||||
shift_table = latch_table;
|
||||
} else if str.starts_with("CTRL_") {
|
||||
// Table changes
|
||||
// ISO/IEC 24778:2008 prescribes ending a shift sequence in the mode from which it was invoked.
|
||||
// That's including when that mode is a shift.
|
||||
// Our test case dlusbs.png for issue #642 exercises that.
|
||||
latchTable = shiftTable; // Latch the current mode, so as to return to Upper after U/S B/S
|
||||
shiftTable = getTable(str.chars().nth(5).unwrap());
|
||||
latch_table = shift_table; // Latch the current mode, so as to return to Upper after U/S B/S
|
||||
shift_table = getTable(str.chars().nth(5).unwrap());
|
||||
if str.chars().nth(6).unwrap() == 'L' {
|
||||
latchTable = shiftTable;
|
||||
latch_table = shift_table;
|
||||
}
|
||||
} else {
|
||||
// Though stored as a table of strings for convenience, codes actually represent 1 or 2 *bytes*.
|
||||
@@ -265,15 +268,15 @@ fn getEncodedData(correctedBits: &[bool]) -> Result<String, Exceptions> {
|
||||
//let b = str.getBytes(StandardCharsets.US_ASCII);
|
||||
//decodedBytes.write(b, 0, b.length);
|
||||
for bt in b {
|
||||
decodedBytes.push(*bt);
|
||||
decoded_bytes.push(*bt);
|
||||
}
|
||||
// Go back to whatever mode we had been in
|
||||
shiftTable = latchTable;
|
||||
shift_table = latch_table;
|
||||
}
|
||||
}
|
||||
}
|
||||
//try {
|
||||
if let Ok(str) = encdr.decode(&decodedBytes, encoding::DecoderTrap::Strict) {
|
||||
if let Ok(str) = encdr.decode(&decoded_bytes, encoding::DecoderTrap::Strict) {
|
||||
result.push_str(&str);
|
||||
} else {
|
||||
return Err(Exceptions::IllegalStateException("bad encoding".to_owned()));
|
||||
@@ -404,11 +407,11 @@ fn correctBits(
|
||||
}
|
||||
|
||||
//try {
|
||||
let rsDecoder = ReedSolomonDecoder::new(gf);
|
||||
rsDecoder.decode(
|
||||
let rs_decoder = ReedSolomonDecoder::new(gf);
|
||||
rs_decoder.decode(
|
||||
&mut dataWords,
|
||||
(numCodewords - numDataCodewords as usize) as i32,
|
||||
);
|
||||
)?;
|
||||
//} catch (ReedSolomonException ex) {
|
||||
//throw FormatException.getFormatInstance(ex);
|
||||
//}
|
||||
@@ -531,9 +534,9 @@ fn extractBits(ddata: &AztecDetectorRXingResult, matrix: &BitMatrix) -> Vec<bool
|
||||
/**
|
||||
* Reads a code of given length and at given index in an array of bits
|
||||
*/
|
||||
fn readCode(rawbits: &[bool], startIndex: usize, length: usize) -> u32 {
|
||||
fn readCode(rawbits: &[bool], start_index: usize, length: usize) -> u32 {
|
||||
let mut res = 0;
|
||||
for i in startIndex..length {
|
||||
for i in start_index..start_index+length {
|
||||
// for (int i = startIndex; i < startIndex + length; i++) {
|
||||
res <<= 1;
|
||||
if rawbits[i] {
|
||||
@@ -546,24 +549,24 @@ fn readCode(rawbits: &[bool], startIndex: usize, length: usize) -> u32 {
|
||||
/**
|
||||
* Reads a code of length 8 in an array of bits, padding with zeros
|
||||
*/
|
||||
fn readByte(rawbits: &[bool], startIndex: usize) -> u8 {
|
||||
let n = rawbits.len() - startIndex;
|
||||
fn readByte(rawbits: &[bool], start_index: usize) -> u8 {
|
||||
let n = rawbits.len() - start_index;
|
||||
if n >= 8 {
|
||||
return readCode(rawbits, startIndex, 8) as u8;
|
||||
return readCode(rawbits, start_index, 8) as u8;
|
||||
}
|
||||
return (readCode(rawbits, startIndex, n) << (8 - n)) as u8;
|
||||
return (readCode(rawbits, start_index, n) << (8 - n)) as u8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a bit array into bytes, most significant bit first
|
||||
*/
|
||||
pub fn convertBoolArrayToByteArray(boolArr: &[bool]) -> Vec<u8> {
|
||||
let mut byteArr = vec![0u8; (boolArr.len() + 7) / 8];
|
||||
for i in 0..byteArr.len() {
|
||||
pub fn convertBoolArrayToByteArray(bool_arr: &[bool]) -> Vec<u8> {
|
||||
let mut byte_arr = vec![0u8; (bool_arr.len() + 7) / 8];
|
||||
for i in 0..byte_arr.len() {
|
||||
// for (int i = 0; i < byteArr.length; i++) {
|
||||
byteArr[i] = readByte(boolArr, 8 * i);
|
||||
byte_arr[i] = readByte(bool_arr, 8 * i);
|
||||
}
|
||||
return byteArr;
|
||||
return byte_arr;
|
||||
}
|
||||
|
||||
fn totalBitsInLayer(layers: usize, compact: bool) -> usize {
|
||||
|
||||
Reference in New Issue
Block a user