From 1a0f04736c0d7cc1ac4e5cb49d4e84fedadea671 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Tue, 20 Sep 2022 12:22:41 -0500 Subject: [PATCH] aztec decoder passes --- src/aztec/DecoderTest.rs | 138 +++++++++++++++++++-------------------- src/aztec/decoder.rs | 85 ++++++++++++------------ 2 files changed, 113 insertions(+), 110 deletions(-) diff --git a/src/aztec/DecoderTest.rs b/src/aztec/DecoderTest.rs index 1542099..14d3900 100644 --- a/src/aztec/DecoderTest.rs +++ b/src/aztec/DecoderTest.rs @@ -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]; diff --git a/src/aztec/decoder.rs b/src/aztec/decoder.rs index 95f1367..f19897e 100644 --- a/src/aztec/decoder.rs +++ b/src/aztec/decoder.rs @@ -123,33 +123,34 @@ pub fn highLevelDecode(correctedBits: &[bool]) -> Result { * * @return the decoded string */ -fn getEncodedData(correctedBits: &[bool]) -> Result { - 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 { + 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 = Vec::new(); - let mut encdr: &'static dyn encoding::Encoding = encoding::all::UTF_8; + let mut decoded_bytes: Vec = 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 { 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 { } 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 { // 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 { //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 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 { - let mut byteArr = vec![0u8; (boolArr.len() + 7) / 8]; - for i in 0..byteArr.len() { +pub fn convertBoolArrayToByteArray(bool_arr: &[bool]) -> Vec { + 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 {