diff --git a/src/aztec.rs b/src/aztec.rs index 6ef96f8..7f29130 100644 --- a/src/aztec.rs +++ b/src/aztec.rs @@ -1,15 +1,19 @@ -pub mod decoder; +pub mod decoder; pub mod detector; pub mod encoder; -use crate::{ResultPoint,BarcodeFormat,EncodeHintType,Writer,Reader,ReaderException,WriterException}; -use crate::common::{BitMatrix,DetectorResult,DecoderResult}; -use crate::{BarcodeFormat,BinaryBitmap,DecodeHintType,FormatException,NotFoundException,Reader,Result,ResultMetadataType,ResultPoint,ResultPointCallback}; use crate::aztec::decoder::Decoder; use crate::aztec::detector::Detector; +use crate::common::{BitMatrix, DecoderResult, DetectorResult}; +use crate::{ + BarcodeFormat, BinaryBitmap, DecodeHintType, FormatException, NotFoundException, Reader, + Result, ResultMetadataType, ResultPoint, ResultPointCallback, +}; +use crate::{ + BarcodeFormat, EncodeHintType, Reader, ReaderException, ResultPoint, Writer, WriterException, +}; -use crate::aztec::encoder::{AztecCode,Encoder}; - +use crate::aztec::encoder::{AztecCode, Encoder}; // AztecDetectorResult.java /** @@ -20,43 +24,53 @@ use crate::aztec::encoder::{AztecCode,Encoder}; */ pub struct AztecDetectorResult { //super: DetectorResult; + compact: bool, - compact: bool, + nb_datablocks: i32, - nb_datablocks: i32, + nb_layers: i32, - nb_layers: i32, + bits: BitMatrix, - bits: BitMatrix, - - points: Vec, + points: Vec, } impl DetectorResult for AztecDetectorResult { - fn get_bits(&self) -> BitMatrix { + fn get_bits(&self) -> BitMatrix { return self.bits; } - fn get_points(&self) -> Vec { + fn get_points(&self) -> Vec { return self.points; } } impl AztecDetectorResult { - - pub fn new( bits: &BitMatrix, points: &Vec, compact: bool, nb_datablocks: i32, nb_layers: i32) -> Self { - Self { compact: compact, nb_datablocks: nd_datablocks, nb_layers: nb_layers, bits: bits, points: points } + pub fn new( + bits: &BitMatrix, + points: &Vec, + compact: bool, + nb_datablocks: i32, + nb_layers: i32, + ) -> Self { + Self { + compact: compact, + nb_datablocks: nd_datablocks, + nb_layers: nb_layers, + bits: bits, + points: points, + } } - pub fn get_nb_layers(&self) -> i32 { + pub fn get_nb_layers(&self) -> i32 { return self.nb_layers; } - pub fn get_nb_datablocks(&self) -> i32 { + pub fn get_nb_datablocks(&self) -> i32 { return self.nb_datablocks; } - pub fn is_compact(&self) -> bool { + pub fn is_compact(&self) -> bool { return self.compact; } } @@ -68,33 +82,35 @@ impl AztecDetectorResult { * * @author David Olivier */ -pub struct AztecReader { -} +pub struct AztecReader {} impl Reader for AztecReader { - /** - * Locates and decodes a Data Matrix code in an image. - * - * @return a String representing the content encoded by the Data Matrix code - * @throws NotFoundException if a Data Matrix code cannot be found - * @throws FormatException if a Data Matrix code cannot be decoded - */ - /*fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, FormatException */Result> { + * Locates and decodes a Data Matrix code in an image. + * + * @return a String representing the content encoded by the Data Matrix code + * @throws NotFoundException if a Data Matrix code cannot be found + * @throws FormatException if a Data Matrix code cannot be decoded + */ + /*fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, FormatException */Result> { return Ok(self.decode(image, null)); }*/ - fn decode(&self, image: &BinaryBitmap, hints: &Map) -> Result { - let not_found_exception: NotFoundException = null; - let format_exception: FormatException = null; - let detector: Detector = Detector::new(&image.get_black_matrix()); - let mut points: Vec = null; - let decoder_result: DecoderResult = null; + fn decode( + &self, + image: &BinaryBitmap, + hints: &Map, + ) -> Result { + let not_found_exception: NotFoundException = null; + let format_exception: FormatException = null; + let detector: Detector = Detector::new(&image.get_black_matrix()); + let mut points: Vec = null; + let decoder_result: DecoderResult = null; - let detector_result: AztecDetectorResult = detector.detect(Some(false))?; - points = detector_result.get_points()?; - decoder_result = Decoder::new().decode(detector_result); - /* + let detector_result: AztecDetectorResult = detector.detect(Some(false))?; + points = detector_result.get_points()?; + decoder_result = Decoder::new().decode(detector_result); + /* let tryResult1 = 0; 'try1: loop { { @@ -137,28 +153,39 @@ impl Reader for AztecReader { } */ if hints != null { - let rpcb: ResultPointCallback = hints.get(DecodeHintType::NEED_RESULT_POINT_CALLBACK) as ResultPointCallback; + let rpcb: ResultPointCallback = + hints.get(DecodeHintType::NEED_RESULT_POINT_CALLBACK) as ResultPointCallback; if rpcb != null { - for point in points { + for point in points { rpcb.found_possible_result_point(&point); } } } - let result: Result = Result::new(&decoder_result.get_text(), &decoder_result.get_raw_bytes(), &decoder_result.get_num_bits(), points, BarcodeFormat::AZTEC, &System::current_time_millis()); - let byte_segments: List> = decoder_result.get_byte_segments(); + let result: Result = Result::new( + &decoder_result.get_text(), + &decoder_result.get_raw_bytes(), + &decoder_result.get_num_bits(), + points, + BarcodeFormat::AZTEC, + &System::current_time_millis(), + ); + let byte_segments: List> = decoder_result.get_byte_segments(); if byte_segments != null { result.put_metadata(ResultMetadataType::BYTE_SEGMENTS, &byte_segments); } - let ec_level: String = decoder_result.get_e_c_level(); + let ec_level: String = decoder_result.get_e_c_level(); if ec_level != null { result.put_metadata(ResultMetadataType::ERROR_CORRECTION_LEVEL, &ec_level); } - result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]z{}", decoder_result.get_symbology_modifier())); + result.put_metadata( + ResultMetadataType::SYMBOLOGY_IDENTIFIER, + format!("]z{}", decoder_result.get_symbology_modifier()), + ); return Ok(result); } - fn reset(&self) { - // do nothing + fn reset(&self) { + // do nothing } } @@ -167,30 +194,44 @@ impl Reader for AztecReader { /** * Renders an Aztec code as a {@link BitMatrix}. */ -pub struct AztecWriter { -} +pub struct AztecWriter {} impl Writer for AztecWriter { - - fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32, hints: Option<&HashMap>) -> BitMatrix { + fn encode( + &self, + contents: &String, + format: &BarcodeFormat, + width: i32, + height: i32, + hints: Option<&HashMap>, + ) -> BitMatrix { // Do not add any ECI code by default - let mut charset: Charset = null; - let ecc_percent: i32 = Encoder::DEFAULT_EC_PERCENT; - let mut layers: i32 = Encoder::DEFAULT_AZTEC_LAYERS; + let mut charset: Charset = null; + let ecc_percent: i32 = Encoder::DEFAULT_EC_PERCENT; + let mut layers: i32 = Encoder::DEFAULT_AZTEC_LAYERS; if hints != null { if hints.contains_key(EncodeHintType::CHARACTER_SET) { charset = Charset::for_name(&hints.get(EncodeHintType::CHARACTER_SET).to_string()); } if hints.contains_key(EncodeHintType::ERROR_CORRECTION) { - ecc_percent = Integer::parse_int(&hints.get(EncodeHintType::ERROR_CORRECTION).to_string()); + ecc_percent = + Integer::parse_int(&hints.get(EncodeHintType::ERROR_CORRECTION).to_string()); } if hints.contains_key(EncodeHintType::AZTEC_LAYERS) { layers = Integer::parse_int(&hints.get(EncodeHintType::AZTEC_LAYERS).to_string()); } } - return ::encode(&contents, format, width, height, &charset, ecc_percent, layers); + return ::encode( + &contents, + format, + width, + height, + &charset, + ecc_percent, + layers, + ); } -/* + /* fn encode( contents: &String, format: &BarcodeFormat, width: i32, height: i32, charset: &Charset, ecc_percent: i32, layers: i32) -> BitMatrix { if format != BarcodeFormat::AZTEC { return Err( IllegalArgumentException::new(format!("Can only encode AZTEC, but got {}", format))); @@ -198,16 +239,14 @@ impl Writer for AztecWriter { let aztec: AztecCode = Encoder::encode(&contents, ecc_percent, layers, &charset); return ::render_result(aztec, width, height); }*/ - - } impl AztecWriter { - fn render_result( code: &AztecCode, width: i32, height: i32) -> BitMatrix { + fn render_result(code: &AztecCode, width: i32, height: i32) -> BitMatrix { let input: BitMatrix = code.get_matrix(); - if input == null { - return Err( IllegalStateException::new()); - } + if input == null { + return Err(IllegalStateException::new()); + } let input_width: i32 = input.get_width(); let input_height: i32 = input.get_height(); let output_width: i32 = Math::max(width, input_width); @@ -218,30 +257,29 @@ impl AztecWriter { let output: BitMatrix = BitMatrix::new(output_width, output_height); { let input_y: i32 = 0; - let output_y: i32 = top_padding; - while input_y < input_height { - { - // Write the contents of this row of the barcode + let output_y: i32 = top_padding; + while input_y < input_height { + { + // Write the contents of this row of the barcode { let input_x: i32 = 0; - let output_x: i32 = left_padding; - while input_x < input_width { - { - if input.get(input_x, input_y) { - output.set_region(output_x, output_y, multiple, multiple); - } - } - input_x += 1; - output_x += multiple; + let output_x: i32 = left_padding; + while input_x < input_width { + { + if input.get(input_x, input_y) { + output.set_region(output_x, output_y, multiple, multiple); + } + } + input_x += 1; + output_x += multiple; } } - - } - input_y += 1; - output_y += multiple; + } + input_y += 1; + output_y += multiple; } } - return output; - } -} \ No newline at end of file + return output; + } +} diff --git a/src/aztec/decoder.rs b/src/aztec/decoder.rs index b12817d..6e2d158 100644 --- a/src/aztec/decoder.rs +++ b/src/aztec/decoder.rs @@ -1,7 +1,7 @@ -use create::FormatException; use crate::aztec::AztecDetectorResult; -use crate::common::{BitMatrix,CharacterSetECI,DecoderResult}; -use crate::common::reedsolomon::{GenericGF,ReedSolomonDecoder,ReedSolomonException}; +use crate::common::reedsolomon::{GenericGF, ReedSolomonDecoder, ReedSolomonException}; +use crate::common::{BitMatrix, CharacterSetECI, DecoderResult}; +use create::FormatException; /** *

The main class which implements Aztec Code decoding -- as opposed to locating and extracting @@ -10,78 +10,101 @@ use crate::common::reedsolomon::{GenericGF,ReedSolomonDecoder,ReedSolomonExcepti * @author David Olivier */ -const UPPER_TABLE: vec![Vec; 32] = vec!["CTRL_PS", " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "CTRL_LL", "CTRL_ML", "CTRL_DL", "CTRL_BS", ] -; +const UPPER_TABLE: vec![Vec; 32] = vec![ + "CTRL_PS", " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", + "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "CTRL_LL", "CTRL_ML", "CTRL_DL", "CTRL_BS", +]; - const LOWER_TABLE: vec![Vec; 32] = vec!["CTRL_PS", " ", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "CTRL_US", "CTRL_ML", "CTRL_DL", "CTRL_BS", ] -; +const LOWER_TABLE: vec![Vec; 32] = vec![ + "CTRL_PS", " ", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", + "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "CTRL_US", "CTRL_ML", "CTRL_DL", "CTRL_BS", +]; - const MIXED_TABLE: vec![Vec; 32] = vec!["CTRL_PS", " ", "\u{0001}", "\u{0002}", "\u{0003}", "\u{0004}", "\u{0005}", "\u{0006}", "\u{0007}", "\u{000b}", "\t", "\n", "\u{000d}", "\u{000f}", "\r", "\u{0021}", "\u{0022}", "\u{0023}", "\u{0024}", "\u{0025}", "@", "\\", "^", "_", "`", "|", "~", "\u{00b1}", "CTRL_LL", "CTRL_UL", "CTRL_PL", "CTRL_BS", ] -; +const MIXED_TABLE: vec![Vec; 32] = vec![ + "CTRL_PS", " ", "\u{0001}", "\u{0002}", "\u{0003}", "\u{0004}", "\u{0005}", "\u{0006}", + "\u{0007}", "\u{000b}", "\t", "\n", "\u{000d}", "\u{000f}", "\r", "\u{0021}", "\u{0022}", + "\u{0023}", "\u{0024}", "\u{0025}", "@", "\\", "^", "_", "`", "|", "~", "\u{00b1}", "CTRL_LL", + "CTRL_UL", "CTRL_PL", "CTRL_BS", +]; - const PUNCT_TABLE: vec![Vec; 32] = vec!["FLG(n)", "\r", "\r\n", ". ", ", ", ": ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "?", "[", "]", "{", "}", "CTRL_UL", ] -; +const PUNCT_TABLE: vec![Vec; 32] = vec![ + "FLG(n)", "\r", "\r\n", ". ", ", ", ": ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", + "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "?", "[", "]", "{", "}", "CTRL_UL", +]; - const DIGIT_TABLE: vec![Vec; 16] = vec!["CTRL_PS", " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ",", ".", "CTRL_UL", "CTRL_US", ] -; +const DIGIT_TABLE: vec![Vec; 16] = vec![ + "CTRL_PS", " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ",", ".", "CTRL_UL", + "CTRL_US", +]; - const DEFAULT_ENCODING: Charset = StandardCharsets::ISO_8859_1; +const DEFAULT_ENCODING: Charset = StandardCharsets::ISO_8859_1; pub struct Decoder { - - ddata: AztecDetectorResult + ddata: AztecDetectorResult, } enum Table { - - UPPER(), LOWER(), MIXED(), DIGIT(), PUNCT(), BINARY() + UPPER(), + LOWER(), + MIXED(), + DIGIT(), + PUNCT(), + BINARY(), } impl Decoder { - - - - pub fn decode(&self, detector_result: &AztecDetectorResult) -> Result { + pub fn decode( + &self, + detector_result: &AztecDetectorResult, + ) -> Result { self.ddata = detector_result; - let matrix: BitMatrix = detector_result.get_bits(); - let rawbits: Vec = self.extract_bits(&matrix); - let corrected_bits: CorrectedBitsResult = self.correct_bits(&rawbits); - let raw_bytes: Vec = ::convert_bool_array_to_byte_array(corrected_bits.correctBits); - let result: String = ::get_encoded_data(corrected_bits.correctBits); - let decoder_result: DecoderResult = DecoderResult::new(&raw_bytes, &result, null, &String::format("%d%%", corrected_bits.ecLevel), None, None, None); + let matrix: BitMatrix = detector_result.get_bits(); + let rawbits: Vec = self.extract_bits(&matrix); + let corrected_bits: CorrectedBitsResult = self.correct_bits(&rawbits); + let raw_bytes: Vec = ::convert_bool_array_to_byte_array(corrected_bits.correctBits); + let result: String = ::get_encoded_data(corrected_bits.correctBits); + let decoder_result: DecoderResult = DecoderResult::new( + &raw_bytes, + &result, + null, + &String::format("%d%%", corrected_bits.ecLevel), + None, + None, + None, + ); decoder_result.set_num_bits(corrected_bits.correctBits.len()); return Ok(decoder_result); } // This method is used for testing the high-level encoder - pub fn high_level_decode( corrected_bits: &Vec) -> /* throws FormatException */Result> { + pub fn high_level_decode(corrected_bits: &Vec) -> Result> { return Ok(::get_encoded_data(&corrected_bits)); } /** - * Gets the string encoded in the aztec code bits - * - * @return the decoded string - */ - fn get_encoded_data( corrected_bits: &Vec) -> /* throws FormatException */Result> { - let end_index: i32 = corrected_bits.len(); + * Gets the string encoded in the aztec code bits + * + * @return the decoded string + */ + fn get_encoded_data(corrected_bits: &Vec) -> Result> { + let end_index: i32 = corrected_bits.len(); // table most recently latched to - let latch_table: Table = Table::UPPER; + let latch_table: Table = Table::UPPER; // table to use for the next read - let shift_table: Table = Table::UPPER; + let shift_table: Table = Table::UPPER; // Final decoded string result // (correctedBits-5) / 4 is an upper bound on the size (all-digit result) - let result: StringBuilder = StringBuilder::new((corrected_bits.len() - 5) / 4); + let result: StringBuilder = StringBuilder::new((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 decoded_bytes: ByteArrayOutputStream = ByteArrayOutputStream::new(); - let mut encoding: Charset = DEFAULT_ENCODING; - let mut index: i32 = 0; + let decoded_bytes: ByteArrayOutputStream = ByteArrayOutputStream::new(); + let mut encoding: Charset = DEFAULT_ENCODING; + let mut index: i32 = 0; while index < end_index { if shift_table == Table::BINARY { if end_index - index < 5 { break; } - let mut length: i32 = ::read_code(&corrected_bits, index, 5); + let mut length: i32 = ::read_code(&corrected_bits, index, 5); index += 5; if length == 0 { if end_index - index < 11 { @@ -90,8 +113,8 @@ impl Decoder { length = ::read_code(&corrected_bits, index, 11) + 31; index += 11; } - { - let char_count: i32 = 0; + { + let char_count: i32 = 0; while char_count < length { { if end_index - index < 8 { @@ -99,71 +122,68 @@ impl Decoder { index = end_index; break; } - let code: i32 = ::read_code(&corrected_bits, index, 8); + let code: i32 = ::read_code(&corrected_bits, index, 8); decoded_bytes.write(code as i8); index += 8; } char_count += 1; - } - } + } + } // Go back to whatever mode we had been in shift_table = latch_table; } else { - let size: i32 = if shift_table == Table::DIGIT { 4 } else { 5 }; + let size: i32 = if shift_table == Table::DIGIT { 4 } else { 5 }; if end_index - index < size { break; } - let code: i32 = ::read_code(&corrected_bits, index, size); + let code: i32 = ::read_code(&corrected_bits, index, size); index += size; - let str: String = ::get_character(shift_table, code); + let str: String = ::get_character(shift_table, code); if "FLG(n)".equals(&str) { if end_index - index < 3 { break; } - let mut n: i32 = ::read_code(&corrected_bits, index, 3); + let mut n: i32 = ::read_code(&corrected_bits, index, 3); index += 3; // flush bytes, FLG changes state let tryResult1 = 0; - - result.append(&decoded_bytes.to_string(&encoding.name())); - + + result.append(&decoded_bytes.to_string(&encoding.name())); decoded_bytes.reset(); match n { - 0 => - { - // translate FNC1 as ASCII 29 - result.append(29 as char); + 0 => { + // translate FNC1 as ASCII 29 + result.append(29 as char); + break; + } + 7 => { + // FLG(7) is reserved and illegal + return Err(FormatException::get_format_instance()); + } + _ => { + // ECI is decimal integer encoded as 1-6 codes in DIGIT mode + let mut eci: i32 = 0; + if end_index - index < 4 * n { break; } - 7 => - { - // FLG(7) is reserved and illegal - return Err( FormatException::get_format_instance()); + while (n -= 1) > 0 { + let next_digit: i32 = ::read_code(&corrected_bits, index, 4); + index += 4; + if next_digit < 2 || next_digit > 11 { + // Not a decimal digit + return Err(FormatException::get_format_instance()); + } + eci = eci * 10 + (next_digit - 2); } - _ => - { - // ECI is decimal integer encoded as 1-6 codes in DIGIT mode - let mut eci: i32 = 0; - if end_index - index < 4 * n { - break; - } - while (n -= 1) > 0 { - let next_digit: i32 = ::read_code(&corrected_bits, index, 4); - index += 4; - if next_digit < 2 || next_digit > 11 { - // Not a decimal digit - return Err( FormatException::get_format_instance()); - } - eci = eci * 10 + (next_digit - 2); - } - let charset_e_c_i: CharacterSetECI = CharacterSetECI::get_character_set_e_c_i_by_value(eci); - if charset_e_c_i == null { - return Err( FormatException::get_format_instance()); - } - encoding = charset_e_c_i.get_charset(); + let charset_e_c_i: CharacterSetECI = + CharacterSetECI::get_character_set_e_c_i_by_value(eci); + if charset_e_c_i == null { + return Err(FormatException::get_format_instance()); } + encoding = charset_e_c_i.get_charset(); + } } // Go back to whatever mode we had been in shift_table = latch_table; @@ -180,101 +200,85 @@ impl Decoder { } } else { // Though stored as a table of strings for convenience, codes actually represent 1 or 2 *bytes*. - let b: Vec = str.get_bytes(StandardCharsets::US_ASCII); + let b: Vec = str.get_bytes(StandardCharsets::US_ASCII); decoded_bytes.write(&b, 0, b.len()); // Go back to whatever mode we had been in shift_table = latch_table; } } } - - result.append(&decoded_bytes.to_string(&encoding.name())); - + + result.append(&decoded_bytes.to_string(&encoding.name())); return Ok(result.to_string()); } /** - * gets the table corresponding to the char passed - */ - fn get_table( t: char) -> Table { + * gets the table corresponding to the char passed + */ + fn get_table(t: char) -> Table { match t { - 'L' => - { - return Table::LOWER; - } - 'P' => - { - return Table::PUNCT; - } - 'M' => - { - return Table::MIXED; - } - 'D' => - { - return Table::DIGIT; - } - 'B' => - { - return Table::BINARY; - } - 'U' => - { - } - _ => - { - return Table::UPPER; - } + 'L' => { + return Table::LOWER; + } + 'P' => { + return Table::PUNCT; + } + 'M' => { + return Table::MIXED; + } + 'D' => { + return Table::DIGIT; + } + 'B' => { + return Table::BINARY; + } + 'U' => {} + _ => { + return Table::UPPER; + } } } /** - * Gets the character (or string) corresponding to the passed code in the given table - * - * @param table the table used - * @param code the code of the character - */ - fn get_character( table: &Table, code: i32) -> String { + * Gets the character (or string) corresponding to the passed code in the given table + * + * @param table the table used + * @param code the code of the character + */ + fn get_character(table: &Table, code: i32) -> String { match table { - UPPER => - { - return UPPER_TABLE[code]; - } - LOWER => - { - return LOWER_TABLE[code]; - } - MIXED => - { - return MIXED_TABLE[code]; - } - PUNCT => - { - return PUNCT_TABLE[code]; - } - DIGIT => - { - return DIGIT_TABLE[code]; - } - _ => - { - // Should not reach here. - return Err( IllegalStateException::new("Bad table")); - } + UPPER => { + return UPPER_TABLE[code]; + } + LOWER => { + return LOWER_TABLE[code]; + } + MIXED => { + return MIXED_TABLE[code]; + } + PUNCT => { + return PUNCT_TABLE[code]; + } + DIGIT => { + return DIGIT_TABLE[code]; + } + _ => { + // Should not reach here. + return Err(IllegalStateException::new("Bad table")); + } } } - /** - *

Performs RS error correction on an array of bits.

- * - * @return the corrected array - * @throws FormatException if the input contains too many errors - */ - fn correct_bits(&self, rawbits: &Vec) -> Result { - let mut gf: GenericGF; - let codeword_size: i32; + *

Performs RS error correction on an array of bits.

+ * + * @return the corrected array + * @throws FormatException if the input contains too many errors + */ + fn correct_bits(&self, rawbits: &Vec) -> Result { + let mut gf: GenericGF; + let codeword_size: i32; if self.ddata.get_nb_layers() <= 2 { codeword_size = 6; gf = GenericGF::AZTEC_DATA_6; @@ -288,175 +292,198 @@ impl Decoder { codeword_size = 12; gf = GenericGF::AZTEC_DATA_12; } - let num_data_codewords: i32 = self.ddata.get_nb_datablocks(); - let num_codewords: i32 = rawbits.len() / codeword_size; + let num_data_codewords: i32 = self.ddata.get_nb_datablocks(); + let num_codewords: i32 = rawbits.len() / codeword_size; if num_codewords < num_data_codewords { - return Err( FormatException::get_format_instance()); + return Err(FormatException::get_format_instance()); } - let mut offset: i32 = rawbits.len() % codeword_size; - let data_words: [i32; num_codewords] = [0; num_codewords]; - { - let mut i: i32 = 0; + let mut offset: i32 = rawbits.len() % codeword_size; + let data_words: [i32; num_codewords] = [0; num_codewords]; + { + let mut i: i32 = 0; while i < num_codewords { { data_words[i] = ::read_code(&rawbits, offset, codeword_size); } i += 1; offset += codeword_size; - } - } + } + } let tryResult1 = 0; - - let rs_decoder: ReedSolomonDecoder = ReedSolomonDecoder::new(gf)?; - rs_decoder.decode(&data_words, num_codewords - num_data_codewords); - + + let rs_decoder: ReedSolomonDecoder = ReedSolomonDecoder::new(gf)?; + rs_decoder.decode(&data_words, num_codewords - num_data_codewords); // Now perform the unstuffing operation. // First, count how many bits are going to be thrown out as stuffing - let mask: i32 = (1 << codeword_size) - 1; - let stuffed_bits: i32 = 0; - { - let mut i: i32 = 0; + let mask: i32 = (1 << codeword_size) - 1; + let stuffed_bits: i32 = 0; + { + let mut i: i32 = 0; while i < num_data_codewords { { - let data_word: i32 = data_words[i]; + let data_word: i32 = data_words[i]; if data_word == 0 || data_word == mask { - return Err( FormatException::get_format_instance()); + return Err(FormatException::get_format_instance()); } else if data_word == 1 || data_word == mask - 1 { stuffed_bits += 1; } } i += 1; - } - } + } + } // Now, actually unpack the bits and remove the stuffing - let corrected_bits: [bool; num_data_codewords * codeword_size - stuffed_bits] = [false; num_data_codewords * codeword_size - stuffed_bits]; - let mut index: i32 = 0; - { - let mut i: i32 = 0; + let corrected_bits: [bool; num_data_codewords * codeword_size - stuffed_bits] = + [false; num_data_codewords * codeword_size - stuffed_bits]; + let mut index: i32 = 0; + { + let mut i: i32 = 0; while i < num_data_codewords { { - let data_word: i32 = data_words[i]; + let data_word: i32 = data_words[i]; if data_word == 1 || data_word == mask - 1 { // next codewordSize-1 bits are all zeros or all ones - Arrays::fill(&corrected_bits, index, index + codeword_size - 1, data_word > 1); + Arrays::fill( + &corrected_bits, + index, + index + codeword_size - 1, + data_word > 1, + ); index += codeword_size - 1; } else { - { - let mut bit: i32 = codeword_size - 1; + { + let mut bit: i32 = codeword_size - 1; while bit >= 0 { { - corrected_bits[index += 1 ] = (data_word & (1 << bit)) != 0; + corrected_bits[index += 1] = (data_word & (1 << bit)) != 0; } bit -= 1; - } - } - + } + } } } i += 1; - } - } + } + } - return Ok(CorrectedBitsResult::new(&corrected_bits, 100 * (num_codewords - num_data_codewords) / num_codewords)); + return Ok(CorrectedBitsResult::new( + &corrected_bits, + 100 * (num_codewords - num_data_codewords) / num_codewords, + )); } /** - * Gets the array of bits from an Aztec Code matrix - * - * @return the array of bits - */ - fn extract_bits(&self, matrix: &BitMatrix) -> Vec { - let compact: bool = self.ddata.is_compact(); - let layers: i32 = self.ddata.get_nb_layers(); + * Gets the array of bits from an Aztec Code matrix + * + * @return the array of bits + */ + fn extract_bits(&self, matrix: &BitMatrix) -> Vec { + let compact: bool = self.ddata.is_compact(); + let layers: i32 = self.ddata.get_nb_layers(); // not including alignment lines - let base_matrix_size: i32 = ( if compact { 11 } else { 14 }) + layers * 4; - let alignment_map: [i32; base_matrix_size] = [0; base_matrix_size]; - let mut rawbits: [bool; ::total_bits_in_layer(layers, compact)] = [false; ::total_bits_in_layer(layers, compact)]; + let base_matrix_size: i32 = (if compact { 11 } else { 14 }) + layers * 4; + let alignment_map: [i32; base_matrix_size] = [0; base_matrix_size]; + let mut rawbits: [bool; ::total_bits_in_layer(layers, compact)] = + [false; ::total_bits_in_layer(layers, compact)]; if compact { - { - let mut i: i32 = 0; + { + let mut i: i32 = 0; while i < alignment_map.len() { { alignment_map[i] = i; } i += 1; - } - } - + } + } } else { - let matrix_size: i32 = base_matrix_size + 1 + 2 * ((base_matrix_size / 2 - 1) / 15); - let orig_center: i32 = base_matrix_size / 2; - let center: i32 = matrix_size / 2; - { - let mut i: i32 = 0; + let matrix_size: i32 = base_matrix_size + 1 + 2 * ((base_matrix_size / 2 - 1) / 15); + let orig_center: i32 = base_matrix_size / 2; + let center: i32 = matrix_size / 2; + { + let mut i: i32 = 0; while i < orig_center { { - let new_offset: i32 = i + i / 15; + let new_offset: i32 = i + i / 15; alignment_map[orig_center - i - 1] = center - new_offset - 1; alignment_map[orig_center + i] = center + new_offset + 1; } i += 1; - } - } - + } + } } - { - let mut i: i32 = 0; - let row_offset: i32 = 0; + { + let mut i: i32 = 0; + let row_offset: i32 = 0; while i < layers { { - let row_size: i32 = (layers - i) * 4 + ( if compact { 9 } else { 12 }); + let row_size: i32 = (layers - i) * 4 + (if compact { 9 } else { 12 }); // The top-left most point of this layer is (not including alignment lines) - let low: i32 = i * 2; + let low: i32 = i * 2; // The bottom-right most point of this layer is (not including alignment lines) - let high: i32 = base_matrix_size - 1 - low; + let high: i32 = base_matrix_size - 1 - low; // We pull bits from the two 2 x rowSize columns and two rowSize x 2 rows - { - let mut j: i32 = 0; + { + let mut j: i32 = 0; while j < row_size { { - let column_offset: i32 = j * 2; - { - let mut k: i32 = 0; + let column_offset: i32 = j * 2; + { + let mut k: i32 = 0; while k < 2 { { // left column - rawbits[row_offset + column_offset + k] = matrix.get(alignment_map[low + k], alignment_map[low + j]); + rawbits[row_offset + column_offset + k] = matrix.get( + alignment_map[low + k], + alignment_map[low + j], + ); // bottom row - rawbits[row_offset + 2 * row_size + column_offset + k] = matrix.get(alignment_map[low + j], alignment_map[high - k]); + rawbits + [row_offset + 2 * row_size + column_offset + k] = + matrix.get( + alignment_map[low + j], + alignment_map[high - k], + ); // right column - rawbits[row_offset + 4 * row_size + column_offset + k] = matrix.get(alignment_map[high - k], alignment_map[high - j]); + rawbits + [row_offset + 4 * row_size + column_offset + k] = + matrix.get( + alignment_map[high - k], + alignment_map[high - j], + ); // top row - rawbits[row_offset + 6 * row_size + column_offset + k] = matrix.get(alignment_map[high - j], alignment_map[low + k]); + rawbits + [row_offset + 6 * row_size + column_offset + k] = + matrix.get( + alignment_map[high - j], + alignment_map[low + k], + ); } k += 1; - } - } - + } + } } j += 1; - } - } + } + } row_offset += row_size * 8; } i += 1; - } - } + } + } return rawbits; } /** - * Reads a code of given length and at given index in an array of bits - */ - fn read_code( rawbits: &Vec, start_index: i32, length: i32) -> i32 { - let mut res: i32 = 0; - { - let mut i: i32 = start_index; + * Reads a code of given length and at given index in an array of bits + */ + fn read_code(rawbits: &Vec, start_index: i32, length: i32) -> i32 { + let mut res: i32 = 0; + { + let mut i: i32 = start_index; while i < start_index + length { { res <<= 1; @@ -465,17 +492,17 @@ impl Decoder { } } i += 1; - } - } + } + } return res; } /** - * Reads a code of length 8 in an array of bits, padding with zeros - */ - fn read_byte( rawbits: &Vec, start_index: i32) -> i8 { - let n: i32 = rawbits.len() - start_index; + * Reads a code of length 8 in an array of bits, padding with zeros + */ + fn read_byte(rawbits: &Vec, start_index: i32) -> i8 { + let n: i32 = rawbits.len() - start_index; if n >= 8 { return ::read_code(&rawbits, start_index, 8) as i8; } @@ -483,38 +510,39 @@ impl Decoder { } /** - * Packs a bit array into bytes, most significant bit first - */ - fn convert_bool_array_to_byte_array( bool_arr: &Vec) -> Vec { - let byte_arr: [i8; (bool_arr.len() + 7) / 8] = [0; (bool_arr.len() + 7) / 8]; - { - let mut i: i32 = 0; + * Packs a bit array into bytes, most significant bit first + */ + fn convert_bool_array_to_byte_array(bool_arr: &Vec) -> Vec { + let byte_arr: [i8; (bool_arr.len() + 7) / 8] = [0; (bool_arr.len() + 7) / 8]; + { + let mut i: i32 = 0; while i < byte_arr.len() { { byte_arr[i] = ::read_byte(&bool_arr, 8 * i); } i += 1; - } - } + } + } return byte_arr; } - fn total_bits_in_layer( layers: i32, compact: bool) -> i32 { - return (( if compact { 88 } else { 112 }) + 16 * layers) * layers; + fn total_bits_in_layer(layers: i32, compact: bool) -> i32 { + return ((if compact { 88 } else { 112 }) + 16 * layers) * layers; } } struct CorrectedBitsResult { + correct_bits: Vec, - correct_bits: Vec, - - ec_level: i32 + ec_level: i32, } impl CorrectedBitsResult { - - fn new( correct_bits: &Vec, ec_level: i32) -> Self { - Self { correct_bits: correct_bits, ec_level: ec_level } - } -} \ No newline at end of file + fn new(correct_bits: &Vec, ec_level: i32) -> Self { + Self { + correct_bits: correct_bits, + ec_level: ec_level, + } + } +} diff --git a/src/aztec/detector.rs b/src/aztec/detector.rs index dac8169..c7347ca 100644 --- a/src/aztec/detector.rs +++ b/src/aztec/detector.rs @@ -1,9 +1,8 @@ -use crate::{NotFoundException,ResultPoint}; use crate::aztec::AztecDetectorResult; -use crate::common::{BitMatrix,GridSampler}; -use crate::common::detector::{MathUtils,WhiteRectangleDetector}; -use crate::common::reedsolomon::{GenericGF,ReedSolomonDecoder,ReedSolomonException}; - +use crate::common::detector::{MathUtils, WhiteRectangleDetector}; +use crate::common::reedsolomon::{GenericGF, ReedSolomonDecoder, ReedSolomonException}; +use crate::common::{BitMatrix, GridSampler}; +use crate::{NotFoundException, ResultPoint}; /** * Encapsulates logic that can detect an Aztec Code in an image, even if the Aztec Code @@ -13,93 +12,115 @@ use crate::common::reedsolomon::{GenericGF,ReedSolomonDecoder,ReedSolomonExcepti * @author Frank Yellin */ -const EXPECTED_CORNER_BITS: vec![Vec; 4] = vec![// 07340 XXX .XX X.. ... -0xee0, // 00734 ... XXX .XX X.. -0x1dc, // 04073 X.. ... XXX .XX -0x83b, // 03407 .XX X.. ... XXX -0x707, ] -; +const EXPECTED_CORNER_BITS: vec![Vec; 4] = vec![ + // 07340 XXX .XX X.. ... + 0xee0, // 00734 ... XXX .XX X.. + 0x1dc, // 04073 X.. ... XXX .XX + 0x83b, // 03407 .XX X.. ... XXX + 0x707, +]; pub struct Detector { + image: BitMatrix, - image: BitMatrix, + compact: bool, - compact: bool, + nb_layers: i32, - nb_layers: i32, + nb_data_blocks: i32, - nb_data_blocks: i32, + nb_center_layers: i32, - nb_center_layers: i32, - - shift: i32 + shift: i32, } impl Detector { - - pub fn new( image: &BitMatrix) -> Self { - let new_d : Self; + pub fn new(image: &BitMatrix) -> Self { + let new_d: Self; new_d.image = image; new_d } /** - * Detects an Aztec Code in an image. - * - * @param isMirror if true, image is a mirror-image of original - * @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code - * @throws NotFoundException if no Aztec Code can be found - */ - pub fn detect(&self, is_mirror: Option) -> Result { + * Detects an Aztec Code in an image. + * + * @param isMirror if true, image is a mirror-image of original + * @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code + * @throws NotFoundException if no Aztec Code can be found + */ + pub fn detect( + &self, + is_mirror: Option, + ) -> Result { // 1. Get the center of the aztec matrix - let p_center: Point = self.get_matrix_center(); + let p_center: Point = self.get_matrix_center(); // 2. Get the center points of the four diagonal points just outside the bull's eye // [topRight, bottomRight, bottomLeft, topLeft] - let bulls_eye_corners: Vec = self.get_bulls_eye_corners(&p_center); + let bulls_eye_corners: Vec = self.get_bulls_eye_corners(&p_center); if is_mirror.unwrap_or(false) { - let temp: ResultPoint = bulls_eye_corners[0]; + let temp: ResultPoint = bulls_eye_corners[0]; bulls_eye_corners[0] = bulls_eye_corners[2]; bulls_eye_corners[2] = temp; } // 3. Get the size of the matrix and other parameters from the bull's eye self.extract_parameters(&bulls_eye_corners); // 4. Sample the grid - let bits: BitMatrix = self.sample_grid(&self.image, bulls_eye_corners[self.shift % 4], bulls_eye_corners[(self.shift + 1) % 4], bulls_eye_corners[(self.shift + 2) % 4], bulls_eye_corners[(self.shift + 3) % 4]); + let bits: BitMatrix = self.sample_grid( + &self.image, + bulls_eye_corners[self.shift % 4], + bulls_eye_corners[(self.shift + 1) % 4], + bulls_eye_corners[(self.shift + 2) % 4], + bulls_eye_corners[(self.shift + 3) % 4], + ); // 5. Get the corners of the matrix. - let corners: Vec = self.get_matrix_corner_points(&bulls_eye_corners); - return Ok(AztecDetectorResult::new(&bits, &corners, self.compact, self.nb_data_blocks, self.nb_layers)); + let corners: Vec = self.get_matrix_corner_points(&bulls_eye_corners); + return Ok(AztecDetectorResult::new( + &bits, + &corners, + self.compact, + self.nb_data_blocks, + self.nb_layers, + )); } /** - * Extracts the number of data layers and data blocks from the layer around the bull's eye. - * - * @param bullsEyeCorners the array of bull's eye corners - * @throws NotFoundException in case of too many errors or invalid parameters - */ - fn extract_parameters(&self, bulls_eye_corners: &Vec) -> Result<(), NotFoundException> { - if !self.is_valid(bulls_eye_corners[0]) || !self.is_valid(bulls_eye_corners[1]) || !self.is_valid(bulls_eye_corners[2]) || !self.is_valid(bulls_eye_corners[3]) { - return Err( NotFoundException::get_not_found_instance()); + * Extracts the number of data layers and data blocks from the layer around the bull's eye. + * + * @param bullsEyeCorners the array of bull's eye corners + * @throws NotFoundException in case of too many errors or invalid parameters + */ + fn extract_parameters( + &self, + bulls_eye_corners: &Vec, + ) -> Result<(), NotFoundException> { + if !self.is_valid(bulls_eye_corners[0]) + || !self.is_valid(bulls_eye_corners[1]) + || !self.is_valid(bulls_eye_corners[2]) + || !self.is_valid(bulls_eye_corners[3]) + { + return Err(NotFoundException::get_not_found_instance()); } - let length: i32 = 2 * self.nb_center_layers; + let length: i32 = 2 * self.nb_center_layers; // Get the bits around the bull's eye - let sides: vec![Vec; 4] = vec![// Right side - self.sample_line(&bulls_eye_corners[0], &bulls_eye_corners[1], length), // Bottom - self.sample_line(&bulls_eye_corners[1], &bulls_eye_corners[2], length), // Left side - self.sample_line(&bulls_eye_corners[2], &bulls_eye_corners[3], length), // Top - self.sample_line(&bulls_eye_corners[3], &bulls_eye_corners[0], length), ] - ; + let sides: vec![Vec; 4] = vec![ + // Right side + self.sample_line(&bulls_eye_corners[0], &bulls_eye_corners[1], length), // Bottom + self.sample_line(&bulls_eye_corners[1], &bulls_eye_corners[2], length), // Left side + self.sample_line(&bulls_eye_corners[2], &bulls_eye_corners[3], length), // Top + self.sample_line(&bulls_eye_corners[3], &bulls_eye_corners[0], length), + ]; // bullsEyeCorners[shift] is the corner of the bulls'eye that has three // orientation marks. // sides[shift] is the row/column that goes from the corner with three // orientation marks to the corner with two. self.shift = ::get_rotation(&sides, length); // Flatten the parameter bits into a single 28- or 40-bit long - let parameter_data: i64 = 0; - { - let mut i: i32 = 0; + let parameter_data: i64 = 0; + { + let mut i: i32 = 0; while i < 4 { { - let side: i32 = sides[(self.shift + i) % 4]; + let side: i32 = sides[(self.shift + i) % 4]; if self.compact { // Each side of the form ..XXXXXXX. where Xs are parameter data parameter_data <<= 7; @@ -111,12 +132,12 @@ impl Detector { } } i += 1; - } - } + } + } // Corrects parameter data using RS. Returns just the data portion // without the error correction. - let corrected_data: i32 = ::get_corrected_parameter_data(parameter_data, self.compact); + let corrected_data: i32 = ::get_corrected_parameter_data(parameter_data, self.compact); if self.compact { // 8 bits: 2 bits layers and 6 bits data blocks self.nb_layers = (corrected_data >> 6) + 1; @@ -130,7 +151,7 @@ impl Detector { Ok(()) } - fn get_rotation( sides: &Vec, length: i32) -> Result { + fn get_rotation(sides: &Vec, length: i32) -> Result { // In a normal pattern, we expect to See // ** .* D A // * * @@ -140,10 +161,10 @@ impl Detector { // // Grab the 3 bits from each of the sides the form the locator pattern and concatenate // into a 12-bit integer. Start with the bit at A - let corner_bits: i32 = 0; - for side in sides { + let corner_bits: i32 = 0; + for side in sides { // XX......X where X's are orientation marks - let t: i32 = ((side >> (length - 2)) << 1) + (side & 1); + let t: i32 = ((side >> (length - 2)) << 1) + (side & 1); corner_bits = (corner_bits << 3) + t; } // Mov the bottom bit to the top, so that the three bits of the locator pattern at A are @@ -151,8 +172,8 @@ impl Detector { // 3 orientation bits at A || 3 orientation bits at B || ... || 3 orientation bits at D corner_bits = ((corner_bits & 1) << 11) + (corner_bits >> 1); // can easily tolerate two errors. - { - let mut shift: i32 = 0; + { + let mut shift: i32 = 0; while shift < 4 { { if Integer::bit_count(corner_bits ^ EXPECTED_CORNER_BITS[shift]) <= 2 { @@ -160,22 +181,25 @@ impl Detector { } } shift += 1; - } - } + } + } return Err(NotFoundException::get_not_found_instance()); } /** - * Corrects the parameter bits using Reed-Solomon algorithm. - * - * @param parameterData parameter bits - * @param compact true if this is a compact Aztec code - * @throws NotFoundException if the array contains too many errors - */ - fn get_corrected_parameter_data( parameter_data: i64, compact: bool) -> /* throws NotFoundException */Result> { - let num_codewords: i32; - let num_data_codewords: i32; + * Corrects the parameter bits using Reed-Solomon algorithm. + * + * @param parameterData parameter bits + * @param compact true if this is a compact Aztec code + * @throws NotFoundException if the array contains too many errors + */ + fn get_corrected_parameter_data( + parameter_data: i64, + compact: bool, + ) -> Result> { + let num_codewords: i32; + let num_data_codewords: i32; if compact { num_codewords = 7; num_data_codewords = 2; @@ -183,24 +207,24 @@ impl Detector { num_codewords = 10; num_data_codewords = 4; } - let num_e_c_codewords: i32 = num_codewords - num_data_codewords; - let parameter_words: [i32; num_codewords] = [0; num_codewords]; - { - let mut i: i32 = num_codewords - 1; + let num_e_c_codewords: i32 = num_codewords - num_data_codewords; + let parameter_words: [i32; num_codewords] = [0; num_codewords]; + { + let mut i: i32 = num_codewords - 1; while i >= 0 { { parameter_words[i] = parameter_data as i32 & 0xF; parameter_data >>= 4; } i -= 1; - } - } + } + } let tryResult1 = 0; /*'try1: loop { {*/ - let rs_decoder: ReedSolomonDecoder = ReedSolomonDecoder::new(GenericGF::AZTEC_PARAM); - rs_decoder.decode(¶meter_words, num_e_c_codewords); + let rs_decoder: ReedSolomonDecoder = ReedSolomonDecoder::new(GenericGF::AZTEC_PARAM); + rs_decoder.decode(¶meter_words, num_e_c_codewords); /*} break 'try1 } @@ -212,46 +236,50 @@ impl Detector { */ // Toss the error correction. Just return the data as an integer - let mut result: i32 = 0; - { - let mut i: i32 = 0; + let mut result: i32 = 0; + { + let mut i: i32 = 0; while i < num_data_codewords { { result = (result << 4) + parameter_words[i]; } i += 1; - } - } + } + } return Ok(result); } /** - * Finds the corners of a bull-eye centered on the passed point. - * This returns the centers of the diagonal points just outside the bull's eye - * Returns [topRight, bottomRight, bottomLeft, topLeft] - * - * @param pCenter Center point - * @return The corners of the bull-eye - * @throws NotFoundException If no valid bull-eye can be found - */ - fn get_bulls_eye_corners(&self, p_center: &Point) -> /* throws NotFoundException */Result, Rc> { - let mut pina: Point = p_center; - let mut pinb: Point = p_center; - let mut pinc: Point = p_center; - let mut pind: Point = p_center; - let mut color: bool = true; - { + * Finds the corners of a bull-eye centered on the passed point. + * This returns the centers of the diagonal points just outside the bull's eye + * Returns [topRight, bottomRight, bottomLeft, topLeft] + * + * @param pCenter Center point + * @return The corners of the bull-eye + * @throws NotFoundException If no valid bull-eye can be found + */ + fn get_bulls_eye_corners(&self, p_center: &Point) -> Result, Rc> { + let mut pina: Point = p_center; + let mut pinb: Point = p_center; + let mut pinc: Point = p_center; + let mut pind: Point = p_center; + let mut color: bool = true; + { self.nb_center_layers = 1; while self.nb_center_layers < 9 { { - let pouta: Point = self.get_first_different(&pina, color, 1, -1); - let poutb: Point = self.get_first_different(&pinb, color, 1, 1); - let poutc: Point = self.get_first_different(&pinc, color, -1, 1); - let poutd: Point = self.get_first_different(&pind, color, -1, -1); + let pouta: Point = self.get_first_different(&pina, color, 1, -1); + let poutb: Point = self.get_first_different(&pinb, color, 1, 1); + let poutc: Point = self.get_first_different(&pinc, color, -1, 1); + let poutd: Point = self.get_first_different(&pind, color, -1, -1); if self.nb_center_layers > 2 { - let q: f32 = ::distance(poutd, pouta) * self.nb_center_layers / (::distance(pind, pina) * (self.nb_center_layers + 2)); - if q < 0.75 || q > 1.25 || !self.is_white_or_black_rectangle(&pouta, &poutb, &poutc, &poutd) { + let q: f32 = ::distance(poutd, pouta) * self.nb_center_layers + / (::distance(pind, pina) * (self.nb_center_layers + 2)); + if q < 0.75 + || q > 1.25 + || !self.is_white_or_black_rectangle(&pouta, &poutb, &poutc, &poutd) + { break; } } @@ -262,62 +290,77 @@ impl Detector { color = !color; } self.nb_center_layers += 1; - } - } + } + } if self.nb_center_layers != 5 && self.nb_center_layers != 7 { - return Err( NotFoundException::get_not_found_instance()); + return Err(NotFoundException::get_not_found_instance()); } self.compact = self.nb_center_layers == 5; // Expand the square by .5 pixel in each direction so that we're on the border // between the white square and the black square - let pinax: ResultPoint = ResultPoint::new(pina.get_x() + 0.5f32, pina.get_y() - 0.5f32); - let pinbx: ResultPoint = ResultPoint::new(pinb.get_x() + 0.5f32, pinb.get_y() + 0.5f32); - let pincx: ResultPoint = ResultPoint::new(pinc.get_x() - 0.5f32, pinc.get_y() + 0.5f32); - let pindx: ResultPoint = ResultPoint::new(pind.get_x() - 0.5f32, pind.get_y() - 0.5f32); + let pinax: ResultPoint = ResultPoint::new(pina.get_x() + 0.5f32, pina.get_y() - 0.5f32); + let pinbx: ResultPoint = ResultPoint::new(pinb.get_x() + 0.5f32, pinb.get_y() + 0.5f32); + let pincx: ResultPoint = ResultPoint::new(pinc.get_x() - 0.5f32, pinc.get_y() + 0.5f32); + let pindx: ResultPoint = ResultPoint::new(pind.get_x() - 0.5f32, pind.get_y() - 0.5f32); // just outside the bull's eye. - return Ok(::expand_square( vec![pinax, pinbx, pincx, pindx, ] - , 2 * self.nb_center_layers - 3, 2 * self.nb_center_layers)); + return Ok(::expand_square( + vec![pinax, pinbx, pincx, pindx], + 2 * self.nb_center_layers - 3, + 2 * self.nb_center_layers, + )); } /** - * Finds a candidate center point of an Aztec code from an image - * - * @return the center point - */ - fn get_matrix_center(&self) -> Point { - let point_a: ResultPoint; - let point_b: ResultPoint; - let point_c: ResultPoint; - let point_d: ResultPoint; + * Finds a candidate center point of an Aztec code from an image + * + * @return the center point + */ + fn get_matrix_center(&self) -> Point { + let point_a: ResultPoint; + let point_b: ResultPoint; + let point_c: ResultPoint; + let point_d: ResultPoint; //Get a white rectangle that can be the border of the matrix in center bull's eye or let tryResult1 = 0; - + let corner_points_detector = WhiteRectangleDetector::new(&self.image, None, None, None); if corner_points_detector.is_ok() { + let corner_points: Vec = corner_points_detector.detect(); - let corner_points: Vec = corner_points_detector.detect(); - point_a = corner_points[0]; point_b = corner_points[1]; point_c = corner_points[2]; point_d = corner_points[3]; - }else { + } else { let cx: i32 = self.image.get_width() / 2; let cy: i32 = self.image.get_height() / 2; - point_a = self.get_first_different(&Point::new(cx + 7, cy - 7), false, 1, -1).to_result_point(); - point_b = self.get_first_different(&Point::new(cx + 7, cy + 7), false, 1, 1).to_result_point(); - point_c = self.get_first_different(&Point::new(cx - 7, cy + 7), false, -1, 1).to_result_point(); - point_d = self.get_first_different(&Point::new(cx - 7, cy - 7), false, -1, -1).to_result_point(); + point_a = self + .get_first_different(&Point::new(cx + 7, cy - 7), false, 1, -1) + .to_result_point(); + point_b = self + .get_first_different(&Point::new(cx + 7, cy + 7), false, 1, 1) + .to_result_point(); + point_c = self + .get_first_different(&Point::new(cx - 7, cy + 7), false, -1, 1) + .to_result_point(); + point_d = self + .get_first_different(&Point::new(cx - 7, cy - 7), false, -1, -1) + .to_result_point(); } //Compute the center of the rectangle - let mut cx: i32 = MathUtils::round((point_a.get_x() + point_d.get_x() + point_b.get_x() + point_c.get_x()) / 4.0f32); - let mut cy: i32 = MathUtils::round((point_a.get_y() + point_d.get_y() + point_b.get_y() + point_c.get_y()) / 4.0f32); + let mut cx: i32 = MathUtils::round( + (point_a.get_x() + point_d.get_x() + point_b.get_x() + point_c.get_x()) / 4.0f32, + ); + let mut cy: i32 = MathUtils::round( + (point_a.get_y() + point_d.get_y() + point_b.get_y() + point_c.get_y()) / 4.0f32, + ); // in order to compute a more accurate center. let tryResult1 = 0; - let corner_points_wrd = WhiteRectangleDetector::new(&self.image, Some(15), Some(cx), Some(cy)); + let corner_points_wrd = + WhiteRectangleDetector::new(&self.image, Some(15), Some(cx), Some(cy)); if corner_points_wrd.is_ok() { let corner_points: Vec = corner_points_wrd.detect(); point_a = corner_points[0]; @@ -325,95 +368,148 @@ impl Detector { point_c = corner_points[2]; point_d = corner_points[3]; } else { - point_a = self.get_first_different(&Point::new(cx + 7, cy - 7), false, 1, -1).to_result_point(); - point_b = self.get_first_different(&Point::new(cx + 7, cy + 7), false, 1, 1).to_result_point(); - point_c = self.get_first_different(&Point::new(cx - 7, cy + 7), false, -1, 1).to_result_point(); - point_d = self.get_first_different(&Point::new(cx - 7, cy - 7), false, -1, -1).to_result_point(); + point_a = self + .get_first_different(&Point::new(cx + 7, cy - 7), false, 1, -1) + .to_result_point(); + point_b = self + .get_first_different(&Point::new(cx + 7, cy + 7), false, 1, 1) + .to_result_point(); + point_c = self + .get_first_different(&Point::new(cx - 7, cy + 7), false, -1, 1) + .to_result_point(); + point_d = self + .get_first_different(&Point::new(cx - 7, cy - 7), false, -1, -1) + .to_result_point(); } // Recompute the center of the rectangle - cx = MathUtils::round((point_a.get_x() + point_d.get_x() + point_b.get_x() + point_c.get_x()) / 4.0f32); - cy = MathUtils::round((point_a.get_y() + point_d.get_y() + point_b.get_y() + point_c.get_y()) / 4.0f32); + cx = MathUtils::round( + (point_a.get_x() + point_d.get_x() + point_b.get_x() + point_c.get_x()) / 4.0f32, + ); + cy = MathUtils::round( + (point_a.get_y() + point_d.get_y() + point_b.get_y() + point_c.get_y()) / 4.0f32, + ); return Point::new(cx, cy); } /** - * Gets the Aztec code corners from the bull's eye corners and the parameters. - * - * @param bullsEyeCorners the array of bull's eye corners - * @return the array of aztec code corners - */ - fn get_matrix_corner_points(&self, bulls_eye_corners: &Vec) -> Vec { - return ::expand_square(bulls_eye_corners, 2 * self.nb_center_layers, &self.get_dimension()); + * Gets the Aztec code corners from the bull's eye corners and the parameters. + * + * @param bullsEyeCorners the array of bull's eye corners + * @return the array of aztec code corners + */ + fn get_matrix_corner_points(&self, bulls_eye_corners: &Vec) -> Vec { + return ::expand_square( + bulls_eye_corners, + 2 * self.nb_center_layers, + &self.get_dimension(), + ); } /** - * Creates a BitMatrix by sampling the provided image. - * topLeft, topRight, bottomRight, and bottomLeft are the centers of the squares on the - * diagonal just outside the bull's eye. - */ - fn sample_grid(&self, image: &BitMatrix, top_left: &ResultPoint, top_right: &ResultPoint, bottom_right: &ResultPoint, bottom_left: &ResultPoint) -> /* throws NotFoundException */Result> { - let sampler: GridSampler = GridSampler::get_instance(); - let dimension: i32 = self.get_dimension(); - let low: f32 = dimension / 2.0f32 - self.nb_center_layers; - let high: f32 = dimension / 2.0f32 + self.nb_center_layers; - return Ok(sampler.sample_grid(image, dimension, dimension, // topleft - low, // topleft - low, // topright - high, // topright - low, // bottomright - high, // bottomright - high, // bottomleft - low, // bottomleft - high, &top_left.get_x(), &top_left.get_y(), &top_right.get_x(), &top_right.get_y(), &bottom_right.get_x(), &bottom_right.get_y(), &bottom_left.get_x(), &bottom_left.get_y())); + * Creates a BitMatrix by sampling the provided image. + * topLeft, topRight, bottomRight, and bottomLeft are the centers of the squares on the + * diagonal just outside the bull's eye. + */ + fn sample_grid( + &self, + image: &BitMatrix, + top_left: &ResultPoint, + top_right: &ResultPoint, + bottom_right: &ResultPoint, + bottom_left: &ResultPoint, + ) -> Result> { + let sampler: GridSampler = GridSampler::get_instance(); + let dimension: i32 = self.get_dimension(); + let low: f32 = dimension / 2.0f32 - self.nb_center_layers; + let high: f32 = dimension / 2.0f32 + self.nb_center_layers; + return Ok(sampler.sample_grid( + image, + dimension, + dimension, // topleft + low, // topleft + low, // topright + high, // topright + low, // bottomright + high, // bottomright + high, // bottomleft + low, // bottomleft + high, + &top_left.get_x(), + &top_left.get_y(), + &top_right.get_x(), + &top_right.get_y(), + &bottom_right.get_x(), + &bottom_right.get_y(), + &bottom_left.get_x(), + &bottom_left.get_y(), + )); } /** - * Samples a line. - * - * @param p1 start point (inclusive) - * @param p2 end point (exclusive) - * @param size number of bits - * @return the array of bits as an int (first bit is high-order bit of result) - */ - fn sample_line(&self, p1: &ResultPoint, p2: &ResultPoint, size: i32) -> i32 { - let mut result: i32 = 0; - let d: f32 = ::distance(p1, p2); - let module_size: f32 = d / size; - let px: f32 = p1.get_x(); - let py: f32 = p1.get_y(); - let dx: f32 = module_size * (p2.get_x() - p1.get_x()) / d; - let dy: f32 = module_size * (p2.get_y() - p1.get_y()) / d; - { - let mut i: i32 = 0; + * Samples a line. + * + * @param p1 start point (inclusive) + * @param p2 end point (exclusive) + * @param size number of bits + * @return the array of bits as an int (first bit is high-order bit of result) + */ + fn sample_line(&self, p1: &ResultPoint, p2: &ResultPoint, size: i32) -> i32 { + let mut result: i32 = 0; + let d: f32 = ::distance(p1, p2); + let module_size: f32 = d / size; + let px: f32 = p1.get_x(); + let py: f32 = p1.get_y(); + let dx: f32 = module_size * (p2.get_x() - p1.get_x()) / d; + let dy: f32 = module_size * (p2.get_y() - p1.get_y()) / d; + { + let mut i: i32 = 0; while i < size { { - if self.image.get(&MathUtils::round(px + i * dx), &MathUtils::round(py + i * dy)) { + if self.image.get( + &MathUtils::round(px + i * dx), + &MathUtils::round(py + i * dy), + ) { result |= 1 << (size - i - 1); } } i += 1; - } - } + } + } return result; } /** - * @return true if the border of the rectangle passed in parameter is compound of white points only - * or black points only - */ - fn is_white_or_black_rectangle(&self, p1: &Point, p2: &Point, p3: &Point, p4: &Point) -> bool { - let corr: i32 = 3; - p1 = &Point::new(&Math::max(0, p1.get_x() - corr), &Math::min(self.image.get_height() - 1, p1.get_y() + corr)); - p2 = &Point::new(&Math::max(0, p2.get_x() - corr), &Math::max(0, p2.get_y() - corr)); - p3 = &Point::new(&Math::min(self.image.get_width() - 1, p3.get_x() + corr), &Math::max(0, &Math::min(self.image.get_height() - 1, p3.get_y() - corr))); - p4 = &Point::new(&Math::min(self.image.get_width() - 1, p4.get_x() + corr), &Math::min(self.image.get_height() - 1, p4.get_y() + corr)); - let c_init: i32 = self.get_color(p4, p1); + * @return true if the border of the rectangle passed in parameter is compound of white points only + * or black points only + */ + fn is_white_or_black_rectangle(&self, p1: &Point, p2: &Point, p3: &Point, p4: &Point) -> bool { + let corr: i32 = 3; + p1 = &Point::new( + &Math::max(0, p1.get_x() - corr), + &Math::min(self.image.get_height() - 1, p1.get_y() + corr), + ); + p2 = &Point::new( + &Math::max(0, p2.get_x() - corr), + &Math::max(0, p2.get_y() - corr), + ); + p3 = &Point::new( + &Math::min(self.image.get_width() - 1, p3.get_x() + corr), + &Math::max( + 0, + &Math::min(self.image.get_height() - 1, p3.get_y() - corr), + ), + ); + p4 = &Point::new( + &Math::min(self.image.get_width() - 1, p4.get_x() + corr), + &Math::min(self.image.get_height() - 1, p4.get_y() + corr), + ); + let c_init: i32 = self.get_color(p4, p1); if c_init == 0 { return false; } - let mut c: i32 = self.get_color(p1, p2); + let mut c: i32 = self.get_color(p1, p2); if c != c_init { return false; } @@ -426,24 +522,24 @@ impl Detector { } /** - * Gets the color of a segment - * - * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else - */ - fn get_color(&self, p1: &Point, p2: &Point) -> i32 { - let d: f32 = ::distance(p1, p2); + * Gets the color of a segment + * + * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else + */ + fn get_color(&self, p1: &Point, p2: &Point) -> i32 { + let d: f32 = ::distance(p1, p2); if d == 0.0f32 { return 0; } - let dx: f32 = (p2.get_x() - p1.get_x()) / d; - let dy: f32 = (p2.get_y() - p1.get_y()) / d; - let mut error: i32 = 0; - let mut px: f32 = p1.get_x(); - let mut py: f32 = p1.get_y(); - let color_model: bool = self.image.get(&p1.get_x(), &p1.get_y()); - let i_max: i32 = Math::floor(d) as i32; - { - let mut i: i32 = 0; + let dx: f32 = (p2.get_x() - p1.get_x()) / d; + let dy: f32 = (p2.get_y() - p1.get_y()) / d; + let mut error: i32 = 0; + let mut px: f32 = p1.get_x(); + let mut py: f32 = p1.get_y(); + let color_model: bool = self.image.get(&p1.get_x(), &p1.get_y()); + let i_max: i32 = Math::floor(d) as i32; + { + let mut i: i32 = 0; while i < i_max { { if self.image.get(&MathUtils::round(px), &MathUtils::round(py)) != color_model { @@ -453,22 +549,26 @@ impl Detector { py += dy; } i += 1; - } - } + } + } - let err_ratio: f32 = error / d; + let err_ratio: f32 = error / d; if err_ratio > 0.1f32 && err_ratio < 0.9f32 { return 0; } - return if (err_ratio <= 0.1f32) == color_model { 1 } else { -1 }; + return if (err_ratio <= 0.1f32) == color_model { + 1 + } else { + -1 + }; } /** - * Gets the coordinate of the first point with a different color in the given direction - */ - fn get_first_different(&self, init: &Point, color: bool, dx: i32, dy: i32) -> Point { - let mut x: i32 = init.get_x() + dx; - let mut y: i32 = init.get_y() + dy; + * Gets the coordinate of the first point with a different color in the given direction + */ + fn get_first_different(&self, init: &Point, color: bool, dx: i32, dy: i32) -> Point { + let mut x: i32 = init.get_x() + dx; + let mut y: i32 = init.get_y() + dy; while self.is_valid(x, y) && self.image.get(x, y) == color { x += dx; y += dy; @@ -487,86 +587,84 @@ impl Detector { } /** - * Expand the square represented by the corner points by pushing out equally in all directions - * - * @param cornerPoints the corners of the square, which has the bull's eye at its center - * @param oldSide the original length of the side of the square in the target bit matrix - * @param newSide the new length of the size of the square in the target bit matrix - * @return the corners of the expanded square - */ - fn expand_square( corner_points: &Vec, old_side: i32, new_side: i32) -> Vec { - let ratio: f32 = new_side / (2.0f32 * old_side); - let mut dx: f32 = corner_points[0].get_x() - corner_points[2].get_x(); - let mut dy: f32 = corner_points[0].get_y() - corner_points[2].get_y(); - let mut centerx: f32 = (corner_points[0].get_x() + corner_points[2].get_x()) / 2.0f32; - let mut centery: f32 = (corner_points[0].get_y() + corner_points[2].get_y()) / 2.0f32; - let result0: ResultPoint = ResultPoint::new(centerx + ratio * dx, centery + ratio * dy); - let result2: ResultPoint = ResultPoint::new(centerx - ratio * dx, centery - ratio * dy); + * Expand the square represented by the corner points by pushing out equally in all directions + * + * @param cornerPoints the corners of the square, which has the bull's eye at its center + * @param oldSide the original length of the side of the square in the target bit matrix + * @param newSide the new length of the size of the square in the target bit matrix + * @return the corners of the expanded square + */ + fn expand_square( + corner_points: &Vec, + old_side: i32, + new_side: i32, + ) -> Vec { + let ratio: f32 = new_side / (2.0f32 * old_side); + let mut dx: f32 = corner_points[0].get_x() - corner_points[2].get_x(); + let mut dy: f32 = corner_points[0].get_y() - corner_points[2].get_y(); + let mut centerx: f32 = (corner_points[0].get_x() + corner_points[2].get_x()) / 2.0f32; + let mut centery: f32 = (corner_points[0].get_y() + corner_points[2].get_y()) / 2.0f32; + let result0: ResultPoint = ResultPoint::new(centerx + ratio * dx, centery + ratio * dy); + let result2: ResultPoint = ResultPoint::new(centerx - ratio * dx, centery - ratio * dy); dx = corner_points[1].get_x() - corner_points[3].get_x(); dy = corner_points[1].get_y() - corner_points[3].get_y(); centerx = (corner_points[1].get_x() + corner_points[3].get_x()) / 2.0f32; centery = (corner_points[1].get_y() + corner_points[3].get_y()) / 2.0f32; - let result1: ResultPoint = ResultPoint::new(centerx + ratio * dx, centery + ratio * dy); - let result3: ResultPoint = ResultPoint::new(centerx - ratio * dx, centery - ratio * dy); - return vec![result0, result1, result2, result3, ] - ; + let result1: ResultPoint = ResultPoint::new(centerx + ratio * dx, centery + ratio * dy); + let result3: ResultPoint = ResultPoint::new(centerx - ratio * dx, centery - ratio * dy); + return vec![result0, result1, result2, result3]; } - fn is_valid_coords(&self, x: i32, y: i32) -> bool { + fn is_valid_coords(&self, x: i32, y: i32) -> bool { return x >= 0 && x < self.image.get_width() && y >= 0 && y < self.image.get_height(); } - fn is_valid_rp(&self, point: &ResultPoint) -> bool { - let x: i32 = MathUtils::round(&point.get_x()); - let y: i32 = MathUtils::round(&point.get_y()); + fn is_valid_rp(&self, point: &ResultPoint) -> bool { + let x: i32 = MathUtils::round(&point.get_x()); + let y: i32 = MathUtils::round(&point.get_y()); return self.is_valid(x, y); } - fn distance( a: &Point, b: &Point) -> f32 { + fn distance(a: &Point, b: &Point) -> f32 { return MathUtils::distance(&a.get_x(), &a.get_y(), &b.get_x(), &b.get_y()); } - fn distance( a: &ResultPoint, b: &ResultPoint) -> f32 { + fn distance(a: &ResultPoint, b: &ResultPoint) -> f32 { return MathUtils::distance(&a.get_x(), &a.get_y(), &b.get_x(), &b.get_y()); } - fn get_dimension(&self) -> i32 { + fn get_dimension(&self) -> i32 { if self.compact { return 4 * self.nb_layers + 11; } return 4 * self.nb_layers + 2 * ((2 * self.nb_layers + 6) / 15) + 15; } - - - } struct Point { + x: i32, - x: i32, - - y: i32 + y: i32, } impl Point { + fn to_result_point(&self) -> ResultPoint { + return ResultPoint::new(self.x, self.y); + } - fn to_result_point(&self) -> ResultPoint { - return ResultPoint::new(self.x, self.y); - } + fn new(x: i32, y: i32) -> Self { + Self { x: x, y: y } + } - fn new( x: i32, y: i32) -> Self { - Self { x: x, y: y } - } + fn get_x(&self) -> i32 { + return self.x; + } - fn get_x(&self) -> i32 { - return self.x; - } + fn get_y(&self) -> i32 { + return self.y; + } - fn get_y(&self) -> i32 { - return self.y; - } - - pub fn to_string(&self) -> String { - return format!("<{} {}>", self.x, self.y); - } -} \ No newline at end of file + pub fn to_string(&self) -> String { + return format!("<{} {}>", self.x, self.y); + } +} diff --git a/src/aztec/encoder.rs b/src/aztec/encoder.rs index f6590f7..0ba1e20 100644 --- a/src/aztec/encoder.rs +++ b/src/aztec/encoder.rs @@ -1,32 +1,31 @@ use std::cmp::Ordering; use std::fmt::format; -use crate::common::{BitArray,BitMatrix,CharacterSetECI}; -use crate::common::reedsolomon::{GenericGF,ReedSolomonEncoder}; +use crate::common::reedsolomon::{GenericGF, ReedSolomonEncoder}; +use crate::common::{BitArray, BitMatrix, CharacterSetECI}; // Token.java const EMPTY: Token = SimpleToken::new(null, 0, 0); pub trait Token { + fn new(previous: &Token) -> Token; /*{ + let .previous = previous; + }*/ - fn new( previous: &Token) -> Token ; /*{ - let .previous = previous; - }*/ + fn get_previous(&self) -> Token; /*{ + return self.previous; + }*/ - fn get_previous(&self) -> Token ; /*{ - return self.previous; - }*/ - - fn add(&self, value: i32, bit_count: i32) -> Token { + fn add(&self, value: i32, bit_count: i32) -> Token { return SimpleToken::new(self, value, bit_count); } - fn add_binary_shift(&self, start: i32, byte_count: i32) -> Token { + fn add_binary_shift(&self, start: i32, byte_count: i32) -> Token { //int bitCount = (byteCount * 8) + (byteCount <= 31 ? 10 : byteCount <= 62 ? 20 : 21); return BinaryShiftToken::new(self, start, byte_count); } - fn append_to(&self, bit_array: &BitArray, text: &Vec) ; + fn append_to(&self, bit_array: &BitArray, text: &Vec); } // AztecCode.java @@ -36,74 +35,72 @@ pub trait Token { * @author Rustam Abdullaev */ pub struct AztecCode { + compact: bool, - compact: bool, + size: i32, - size: i32, + layers: i32, - layers: i32, + code_words: i32, - code_words: i32, - - matrix: BitMatrix + matrix: BitMatrix, } impl AztecCode { + /** + * @return {@code true} if compact instead of full mode + */ + pub fn is_compact(&self) -> bool { + return self.compact; + } - /** - * @return {@code true} if compact instead of full mode - */ - pub fn is_compact(&self) -> bool { - return self.compact; - } + pub fn set_compact(&self, compact: bool) { + self.compact = compact; + } - pub fn set_compact(&self, compact: bool) { - self.compact = compact; - } + /** + * @return size in pixels (width and height) + */ + pub fn get_size(&self) -> i32 { + return self.size; + } - /** - * @return size in pixels (width and height) - */ - pub fn get_size(&self) -> i32 { - return self.size; - } + pub fn set_size(&self, size: i32) { + self.size = size; + } - pub fn set_size(&self, size: i32) { - self.size = size; - } + /** + * @return number of levels + */ + pub fn get_layers(&self) -> i32 { + return self.layers; + } - /** - * @return number of levels - */ - pub fn get_layers(&self) -> i32 { - return self.layers; - } + pub fn set_layers(&self, layers: i32) { + self.layers = layers; + } - pub fn set_layers(&self, layers: i32) { - self.layers = layers; - } + /** + * @return number of data codewords + */ + pub fn get_code_words(&self) -> i32 { + return self.code_words; + } - /** - * @return number of data codewords - */ - pub fn get_code_words(&self) -> i32 { - return self.code_words; - } + pub fn set_code_words(&self, code_words: i32) { + self.codeWords = code_words; + } - pub fn set_code_words(&self, code_words: i32) { - self.codeWords = code_words; - } + /** + * @return the symbol image + */ + pub fn get_matrix(&self) -> BitMatrix { + return self.matrix; + } - /** - * @return the symbol image - */ - pub fn get_matrix(&self) -> BitMatrix { - return self.matrix; - } - - pub fn set_matrix(&self, matrix: &BitMatrix) { - self.matrix = matrix; - } + pub fn set_matrix(&self, matrix: &BitMatrix) { + self.matrix = matrix; + } } // Encoder.java @@ -123,94 +120,112 @@ const MAX_NB_BITS: i32 = 32; const MAX_NB_BITS_COMPACT: i32 = 4; -const WORD_SIZE: vec![Vec; 33] = vec![4, 6, 6, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, ] -; -pub struct Encoder { -} +const WORD_SIZE: vec![Vec; 33] = vec![ + 4, 6, 6, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, +]; +pub struct Encoder {} impl Encoder { + fn new() -> Encoder {} - fn new() -> Encoder { - } + /** + * Encodes the given string content as an Aztec symbol (without ECI code) + * + * @param data input data string; must be encodable as ISO/IEC 8859-1 (Latin-1) + * @return Aztec symbol matrix with metadata + */ + pub fn encode(data: &String) -> AztecCode { + return ::encode(&data.get_bytes(StandardCharsets::ISO_8859_1)); + } - /** - * Encodes the given string content as an Aztec symbol (without ECI code) - * - * @param data input data string; must be encodable as ISO/IEC 8859-1 (Latin-1) - * @return Aztec symbol matrix with metadata - */ - pub fn encode( data: &String) -> AztecCode { - return ::encode(&data.get_bytes(StandardCharsets::ISO_8859_1)); - } + /** + * Encodes the given string content as an Aztec symbol (without ECI code) + * + * @param data input data string; must be encodable as ISO/IEC 8859-1 (Latin-1) + * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, + * a minimum of 23% + 3 words is recommended) + * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers + * @return Aztec symbol matrix with metadata + */ + pub fn encode(data: &String, min_e_c_c_percent: i32, user_specified_layers: i32) -> AztecCode { + return ::encode( + &data.get_bytes(StandardCharsets::ISO_8859_1), + min_e_c_c_percent, + user_specified_layers, + null, + ); + } - /** - * Encodes the given string content as an Aztec symbol (without ECI code) - * - * @param data input data string; must be encodable as ISO/IEC 8859-1 (Latin-1) - * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, - * a minimum of 23% + 3 words is recommended) - * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers - * @return Aztec symbol matrix with metadata - */ - pub fn encode( data: &String, min_e_c_c_percent: i32, user_specified_layers: i32) -> AztecCode { - return ::encode(&data.get_bytes(StandardCharsets::ISO_8859_1), min_e_c_c_percent, user_specified_layers, null); - } + /** + * Encodes the given string content as an Aztec symbol + * + * @param data input data string + * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, + * a minimum of 23% + 3 words is recommended) + * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers + * @param charset character set in which to encode string using ECI; if null, no ECI code + * will be inserted, and the string must be encodable as ISO/IEC 8859-1 + * (Latin-1), the default encoding of the symbol. + * @return Aztec symbol matrix with metadata + */ + pub fn encode( + data: &String, + min_e_c_c_percent: i32, + user_specified_layers: i32, + charset: &Charset, + ) -> AztecCode { + let bytes: Vec = data.get_bytes(if null != charset { + charset + } else { + StandardCharsets::ISO_8859_1 + }); + return ::encode(&bytes, min_e_c_c_percent, user_specified_layers, &charset); + } - /** - * Encodes the given string content as an Aztec symbol - * - * @param data input data string - * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, - * a minimum of 23% + 3 words is recommended) - * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers - * @param charset character set in which to encode string using ECI; if null, no ECI code - * will be inserted, and the string must be encodable as ISO/IEC 8859-1 - * (Latin-1), the default encoding of the symbol. - * @return Aztec symbol matrix with metadata - */ - pub fn encode( data: &String, min_e_c_c_percent: i32, user_specified_layers: i32, charset: &Charset) -> AztecCode { - let bytes: Vec = data.get_bytes( if null != charset { charset } else { StandardCharsets::ISO_8859_1 }); - return ::encode(&bytes, min_e_c_c_percent, user_specified_layers, &charset); - } + /** + * Encodes the given binary content as an Aztec symbol (without ECI code) + * + * @param data input data string + * @return Aztec symbol matrix with metadata + */ + pub fn encode(data: &Vec) -> AztecCode { + return ::encode(&data, DEFAULT_EC_PERCENT, DEFAULT_AZTEC_LAYERS, null); + } - /** - * Encodes the given binary content as an Aztec symbol (without ECI code) - * - * @param data input data string - * @return Aztec symbol matrix with metadata - */ - pub fn encode( data: &Vec) -> AztecCode { - return ::encode(&data, DEFAULT_EC_PERCENT, DEFAULT_AZTEC_LAYERS, null); - } + /** + * Encodes the given binary content as an Aztec symbol (without ECI code) + * + * @param data input data string + * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, + * a minimum of 23% + 3 words is recommended) + * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers + * @return Aztec symbol matrix with metadata + */ + pub fn encode(data: &Vec, min_e_c_c_percent: i32, user_specified_layers: i32) -> AztecCode { + return ::encode(&data, min_e_c_c_percent, user_specified_layers, null); + } - /** - * Encodes the given binary content as an Aztec symbol (without ECI code) - * - * @param data input data string - * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, - * a minimum of 23% + 3 words is recommended) - * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers - * @return Aztec symbol matrix with metadata - */ - pub fn encode( data: &Vec, min_e_c_c_percent: i32, user_specified_layers: i32) -> AztecCode { - return ::encode(&data, min_e_c_c_percent, user_specified_layers, null); - } - - /** - * Encodes the given binary content as an Aztec symbol - * - * @param data input data string - * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, - * a minimum of 23% + 3 words is recommended) - * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers - * @param charset character set to mark using ECI; if null, no ECI code will be inserted, and the - * default encoding of ISO/IEC 8859-1 will be assuming by readers. - * @return Aztec symbol matrix with metadata - */ - pub fn encode( data: &Vec, min_e_c_c_percent: i32, user_specified_layers: i32, charset: Option<&Charset>) -> AztecCode { - // High-level encode + /** + * Encodes the given binary content as an Aztec symbol + * + * @param data input data string + * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008, + * a minimum of 23% + 3 words is recommended) + * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers + * @param charset character set to mark using ECI; if null, no ECI code will be inserted, and the + * default encoding of ISO/IEC 8859-1 will be assuming by readers. + * @return Aztec symbol matrix with metadata + */ + pub fn encode( + data: &Vec, + min_e_c_c_percent: i32, + user_specified_layers: i32, + charset: Option<&Charset>, + ) -> AztecCode { + // High-level encode let bits: BitArray = HighLevelEncoder::new(&data, charset).encode(); - // stuff bits and choose symbol size + // stuff bits and choose symbol size let ecc_bits: i32 = bits.get_size() * min_e_c_c_percent / 100 + 11; let total_size_bits: i32 = bits.get_size() + ecc_bits; let mut compact: bool; @@ -218,395 +233,429 @@ impl Encoder { let total_bits_in_layer: i32; let word_size: i32; let stuffed_bits: BitArray; - if user_specified_layers != DEFAULT_AZTEC_LAYERS { - compact = user_specified_layers < 0; - layers = Math::abs(user_specified_layers); - if layers > ( if compact { MAX_NB_BITS_COMPACT } else { MAX_NB_BITS }) { - return Err( IllegalArgumentException::new(&String::format("Illegal value %s for layers", user_specified_layers))); - } - total_bits_in_layer = self.total_bits_in_layer(layers, compact); - word_size = WORD_SIZE[layers]; - let usable_bits_in_layers: i32 = total_bits_in_layer - (total_bits_in_layer % word_size); - stuffed_bits = ::stuff_bits(bits, word_size); - if stuffed_bits.get_size() + ecc_bits > usable_bits_in_layers { - return Err( IllegalArgumentException::new("Data to large for user specified layer")); - } - if compact && stuffed_bits.get_size() > word_size * 64 { - // Compact format only allows 64 data words, though C4 can hold more words than that - return Err( IllegalArgumentException::new("Data to large for user specified layer")); - } - } else { - word_size = 0; - stuffed_bits = null; - // is the same size, but has more data. + if user_specified_layers != DEFAULT_AZTEC_LAYERS { + compact = user_specified_layers < 0; + layers = Math::abs(user_specified_layers); + if layers + > (if compact { + MAX_NB_BITS_COMPACT + } else { + MAX_NB_BITS + }) + { + return Err(IllegalArgumentException::new(&String::format( + "Illegal value %s for layers", + user_specified_layers, + ))); + } + total_bits_in_layer = self.total_bits_in_layer(layers, compact); + word_size = WORD_SIZE[layers]; + let usable_bits_in_layers: i32 = + total_bits_in_layer - (total_bits_in_layer % word_size); + stuffed_bits = ::stuff_bits(bits, word_size); + if stuffed_bits.get_size() + ecc_bits > usable_bits_in_layers { + return Err(IllegalArgumentException::new( + "Data to large for user specified layer", + )); + } + if compact && stuffed_bits.get_size() > word_size * 64 { + // Compact format only allows 64 data words, though C4 can hold more words than that + return Err(IllegalArgumentException::new( + "Data to large for user specified layer", + )); + } + } else { + word_size = 0; + stuffed_bits = null; + // is the same size, but has more data. { let mut i: i32 = 0; - loop { - { - if i > MAX_NB_BITS { - return Err( IllegalArgumentException::new("Data too large for an Aztec code")); - } - compact = i <= 3; - layers = if compact { i + 1 } else { i }; - total_bits_in_layer = self.total_bits_in_layer(layers, compact); - if total_size_bits > total_bits_in_layer { - continue; - } - // wordSize has changed - if stuffed_bits == null || word_size != WORD_SIZE[layers] { - word_size = WORD_SIZE[layers]; - stuffed_bits = ::stuff_bits(bits, word_size); - } - let usable_bits_in_layers: i32 = total_bits_in_layer - (total_bits_in_layer % word_size); - if compact && stuffed_bits.get_size() > word_size * 64 { - // Compact format only allows 64 data words, though C4 can hold more words than that - continue; - } - if stuffed_bits.get_size() + ecc_bits <= usable_bits_in_layers { - break; - } - } - i += 1; + loop { + { + if i > MAX_NB_BITS { + return Err(IllegalArgumentException::new( + "Data too large for an Aztec code", + )); + } + compact = i <= 3; + layers = if compact { i + 1 } else { i }; + total_bits_in_layer = self.total_bits_in_layer(layers, compact); + if total_size_bits > total_bits_in_layer { + continue; + } + // wordSize has changed + if stuffed_bits == null || word_size != WORD_SIZE[layers] { + word_size = WORD_SIZE[layers]; + stuffed_bits = ::stuff_bits(bits, word_size); + } + let usable_bits_in_layers: i32 = + total_bits_in_layer - (total_bits_in_layer % word_size); + if compact && stuffed_bits.get_size() > word_size * 64 { + // Compact format only allows 64 data words, though C4 can hold more words than that + continue; + } + if stuffed_bits.get_size() + ecc_bits <= usable_bits_in_layers { + break; + } + } + i += 1; } } - - } - let message_bits: BitArray = ::generate_check_words(stuffed_bits, total_bits_in_layer, word_size); - // generate mode message + } + let message_bits: BitArray = + ::generate_check_words(stuffed_bits, total_bits_in_layer, word_size); + // generate mode message let message_size_in_words: i32 = stuffed_bits.get_size() / word_size; - let mode_message: BitArray = ::generate_mode_message(compact, layers, message_size_in_words); - // allocate symbol - // not including alignment lines - let base_matrix_size: i32 = ( if compact { 11 } else { 14 }) + layers * 4; + let mode_message: BitArray = + ::generate_mode_message(compact, layers, message_size_in_words); + // allocate symbol + // not including alignment lines + let base_matrix_size: i32 = (if compact { 11 } else { 14 }) + layers * 4; let alignment_map: [i32; base_matrix_size] = [0; base_matrix_size]; let matrix_size: i32; - if compact { - // no alignment marks in compact mode, alignmentMap is a no-op - matrix_size = base_matrix_size; + if compact { + // no alignment marks in compact mode, alignmentMap is a no-op + matrix_size = base_matrix_size; { let mut i: i32 = 0; - while i < alignment_map.len() { - { - alignment_map[i] = i; - } - i += 1; + while i < alignment_map.len() { + { + alignment_map[i] = i; + } + i += 1; } } - - } else { - matrix_size = base_matrix_size + 1 + 2 * ((base_matrix_size / 2 - 1) / 15); + } else { + matrix_size = base_matrix_size + 1 + 2 * ((base_matrix_size / 2 - 1) / 15); let orig_center: i32 = base_matrix_size / 2; let center: i32 = matrix_size / 2; { let mut i: i32 = 0; - while i < orig_center { - { + while i < orig_center { + { let new_offset: i32 = i + i / 15; - alignment_map[orig_center - i - 1] = center - new_offset - 1; - alignment_map[orig_center + i] = center + new_offset + 1; - } - i += 1; + alignment_map[orig_center - i - 1] = center - new_offset - 1; + alignment_map[orig_center + i] = center + new_offset + 1; + } + i += 1; } } - - } + } let matrix: BitMatrix = BitMatrix::new(matrix_size); - // draw data bits + // draw data bits { let mut i: i32 = 0; - let row_offset: i32 = 0; - while i < layers { - { - let row_size: i32 = (layers - i) * 4 + ( if compact { 9 } else { 12 }); + let row_offset: i32 = 0; + while i < layers { + { + let row_size: i32 = (layers - i) * 4 + (if compact { 9 } else { 12 }); { let mut j: i32 = 0; - while j < row_size { - { + while j < row_size { + { let column_offset: i32 = j * 2; { let mut k: i32 = 0; - while k < 2 { - { - if message_bits.get(row_offset + column_offset + k) { - matrix.set(alignment_map[i * 2 + k], alignment_map[i * 2 + j]); - } - if message_bits.get(row_offset + row_size * 2 + column_offset + k) { - matrix.set(alignment_map[i * 2 + j], alignment_map[base_matrix_size - 1 - i * 2 - k]); - } - if message_bits.get(row_offset + row_size * 4 + column_offset + k) { - matrix.set(alignment_map[base_matrix_size - 1 - i * 2 - k], alignment_map[base_matrix_size - 1 - i * 2 - j]); - } - if message_bits.get(row_offset + row_size * 6 + column_offset + k) { - matrix.set(alignment_map[base_matrix_size - 1 - i * 2 - j], alignment_map[i * 2 + k]); - } - } - k += 1; + while k < 2 { + { + if message_bits.get(row_offset + column_offset + k) { + matrix.set( + alignment_map[i * 2 + k], + alignment_map[i * 2 + j], + ); + } + if message_bits + .get(row_offset + row_size * 2 + column_offset + k) + { + matrix.set( + alignment_map[i * 2 + j], + alignment_map[base_matrix_size - 1 - i * 2 - k], + ); + } + if message_bits + .get(row_offset + row_size * 4 + column_offset + k) + { + matrix.set( + alignment_map[base_matrix_size - 1 - i * 2 - k], + alignment_map[base_matrix_size - 1 - i * 2 - j], + ); + } + if message_bits + .get(row_offset + row_size * 6 + column_offset + k) + { + matrix.set( + alignment_map[base_matrix_size - 1 - i * 2 - j], + alignment_map[i * 2 + k], + ); + } + } + k += 1; } } - - } - j += 1; + } + j += 1; } } - row_offset += row_size * 8; - } - i += 1; + row_offset += row_size * 8; + } + i += 1; } } - // draw mode message - ::draw_mode_message(matrix, compact, matrix_size, mode_message); - // draw alignment marks - if compact { - ::draw_bulls_eye(matrix, matrix_size / 2, 5); - } else { - ::draw_bulls_eye(matrix, matrix_size / 2, 7); + // draw mode message + ::draw_mode_message(matrix, compact, matrix_size, mode_message); + // draw alignment marks + if compact { + ::draw_bulls_eye(matrix, matrix_size / 2, 5); + } else { + ::draw_bulls_eye(matrix, matrix_size / 2, 7); { let mut i: i32 = 0; - let mut j: i32 = 0; - while i < base_matrix_size / 2 - 1 { - { + let mut j: i32 = 0; + while i < base_matrix_size / 2 - 1 { + { { let mut k: i32 = (matrix_size / 2) & 1; - while k < matrix_size { - { - matrix.set(matrix_size / 2 - j, k); - matrix.set(matrix_size / 2 + j, k); - matrix.set(k, matrix_size / 2 - j); - matrix.set(k, matrix_size / 2 + j); - } - k += 2; + while k < matrix_size { + { + matrix.set(matrix_size / 2 - j, k); + matrix.set(matrix_size / 2 + j, k); + matrix.set(k, matrix_size / 2 - j); + matrix.set(k, matrix_size / 2 + j); + } + k += 2; } } - - } - i += 15; - j += 16; + } + i += 15; + j += 16; } } - - } + } let aztec: AztecCode = AztecCode::new(); - aztec.set_compact(compact); - aztec.set_size(matrix_size); - aztec.set_layers(layers); - aztec.set_code_words(message_size_in_words); - aztec.set_matrix(&matrix); - return aztec; - } + aztec.set_compact(compact); + aztec.set_size(matrix_size); + aztec.set_layers(layers); + aztec.set_code_words(message_size_in_words); + aztec.set_matrix(&matrix); + return aztec; + } - fn draw_bulls_eye( matrix: &BitMatrix, center: i32, size: i32) { + fn draw_bulls_eye(matrix: &BitMatrix, center: i32, size: i32) { { let mut i: i32 = 0; - while i < size { - { + while i < size { + { { let mut j: i32 = center - i; - while j <= center + i { - { - matrix.set(j, center - i); - matrix.set(j, center + i); - matrix.set(center - i, j); - matrix.set(center + i, j); - } - j += 1; + while j <= center + i { + { + matrix.set(j, center - i); + matrix.set(j, center + i); + matrix.set(center - i, j); + matrix.set(center + i, j); + } + j += 1; } } - - } - i += 2; + } + i += 2; } } - matrix.set(center - size, center - size); - matrix.set(center - size + 1, center - size); - matrix.set(center - size, center - size + 1); - matrix.set(center + size, center - size); - matrix.set(center + size, center - size + 1); - matrix.set(center + size, center + size - 1); - } + matrix.set(center - size, center - size); + matrix.set(center - size + 1, center - size); + matrix.set(center - size, center - size + 1); + matrix.set(center + size, center - size); + matrix.set(center + size, center - size + 1); + matrix.set(center + size, center + size - 1); + } - fn generate_mode_message( compact: bool, layers: i32, message_size_in_words: i32) -> BitArray { + fn generate_mode_message(compact: bool, layers: i32, message_size_in_words: i32) -> BitArray { let mode_message: BitArray = BitArray::new(); - if compact { - mode_message.append_bits(layers - 1, 2); - mode_message.append_bits(message_size_in_words - 1, 6); - mode_message = ::generate_check_words(mode_message, 28, 4); - } else { - mode_message.append_bits(layers - 1, 5); - mode_message.append_bits(message_size_in_words - 1, 11); - mode_message = ::generate_check_words(mode_message, 40, 4); - } - return mode_message; - } + if compact { + mode_message.append_bits(layers - 1, 2); + mode_message.append_bits(message_size_in_words - 1, 6); + mode_message = ::generate_check_words(mode_message, 28, 4); + } else { + mode_message.append_bits(layers - 1, 5); + mode_message.append_bits(message_size_in_words - 1, 11); + mode_message = ::generate_check_words(mode_message, 40, 4); + } + return mode_message; + } - fn draw_mode_message( matrix: &BitMatrix, compact: bool, matrix_size: i32, mode_message: &BitArray) { + fn draw_mode_message( + matrix: &BitMatrix, + compact: bool, + matrix_size: i32, + mode_message: &BitArray, + ) { let center: i32 = matrix_size / 2; - if compact { + if compact { { let mut i: i32 = 0; - while i < 7 { - { + while i < 7 { + { let offset: i32 = center - 3 + i; - if mode_message.get(i) { - matrix.set(offset, center - 5); - } - if mode_message.get(i + 7) { - matrix.set(center + 5, offset); - } - if mode_message.get(20 - i) { - matrix.set(offset, center + 5); - } - if mode_message.get(27 - i) { - matrix.set(center - 5, offset); - } - } - i += 1; + if mode_message.get(i) { + matrix.set(offset, center - 5); + } + if mode_message.get(i + 7) { + matrix.set(center + 5, offset); + } + if mode_message.get(20 - i) { + matrix.set(offset, center + 5); + } + if mode_message.get(27 - i) { + matrix.set(center - 5, offset); + } + } + i += 1; } } - - } else { + } else { { let mut i: i32 = 0; - while i < 10 { - { + while i < 10 { + { let offset: i32 = center - 5 + i + i / 5; - if mode_message.get(i) { - matrix.set(offset, center - 7); - } - if mode_message.get(i + 10) { - matrix.set(center + 7, offset); - } - if mode_message.get(29 - i) { - matrix.set(offset, center + 7); - } - if mode_message.get(39 - i) { - matrix.set(center - 7, offset); - } - } - i += 1; + if mode_message.get(i) { + matrix.set(offset, center - 7); + } + if mode_message.get(i + 10) { + matrix.set(center + 7, offset); + } + if mode_message.get(29 - i) { + matrix.set(offset, center + 7); + } + if mode_message.get(39 - i) { + matrix.set(center - 7, offset); + } + } + i += 1; } } + } + } - } - } - - fn generate_check_words( bit_array: &BitArray, total_bits: i32, word_size: i32) -> BitArray { - // bitArray is guaranteed to be a multiple of the wordSize, so no padding needed + fn generate_check_words(bit_array: &BitArray, total_bits: i32, word_size: i32) -> BitArray { + // bitArray is guaranteed to be a multiple of the wordSize, so no padding needed let message_size_in_words: i32 = bit_array.get_size() / word_size; let rs: ReedSolomonEncoder = ReedSolomonEncoder::new(&::get_g_f(word_size)); let total_words: i32 = total_bits / word_size; let message_words: Vec = ::bits_to_words(bit_array, word_size, total_words); - rs.encode(&message_words, total_words - message_size_in_words); + rs.encode(&message_words, total_words - message_size_in_words); let start_pad: i32 = total_bits % word_size; let message_bits: BitArray = BitArray::new(); - message_bits.append_bits(0, start_pad); - for message_word in message_words { - message_bits.append_bits(message_word, word_size); - } - return message_bits; - } + message_bits.append_bits(0, start_pad); + for message_word in message_words { + message_bits.append_bits(message_word, word_size); + } + return message_bits; + } - fn bits_to_words( stuffed_bits: &BitArray, word_size: i32, total_words: i32) -> Vec { + fn bits_to_words(stuffed_bits: &BitArray, word_size: i32, total_words: i32) -> Vec { let mut message: [i32; total_words] = [0; total_words]; let mut i: i32; let mut n: i32; { - i = 0; - n = stuffed_bits.get_size() / word_size; - while i < n { - { + i = 0; + n = stuffed_bits.get_size() / word_size; + while i < n { + { let mut value: i32 = 0; { let mut j: i32 = 0; - while j < word_size { - { - value |= if stuffed_bits.get(i * word_size + j) { (1 << word_size - j - 1) } else { 0 }; - } - j += 1; + while j < word_size { + { + value |= if stuffed_bits.get(i * word_size + j) { + (1 << word_size - j - 1) + } else { + 0 + }; + } + j += 1; } } - message[i] = value; - } - i += 1; + message[i] = value; + } + i += 1; } } - return message; - } + return message; + } - fn get_g_f( word_size: i32) -> GenericGF { - match word_size { - 4 => - { - return GenericGF::AZTEC_PARAM; - } - 6 => - { - return GenericGF::AZTEC_DATA_6; - } - 8 => - { - return GenericGF::AZTEC_DATA_8; - } - 10 => - { - return GenericGF::AZTEC_DATA_10; - } - 12 => - { - return GenericGF::AZTEC_DATA_12; - } - _ => - { - return Err( IllegalArgumentException::new(format!("Unsupported word size {}", word_size))); - } - } - } + fn get_g_f(word_size: i32) -> GenericGF { + match word_size { + 4 => { + return GenericGF::AZTEC_PARAM; + } + 6 => { + return GenericGF::AZTEC_DATA_6; + } + 8 => { + return GenericGF::AZTEC_DATA_8; + } + 10 => { + return GenericGF::AZTEC_DATA_10; + } + 12 => { + return GenericGF::AZTEC_DATA_12; + } + _ => { + return Err(IllegalArgumentException::new(format!( + "Unsupported word size {}", + word_size + ))); + } + } + } - fn stuff_bits( bits: &BitArray, word_size: i32) -> BitArray { + fn stuff_bits(bits: &BitArray, word_size: i32) -> BitArray { let out: BitArray = BitArray::new(); let n: i32 = bits.get_size(); let mask: i32 = (1 << word_size) - 2; { let mut i: i32 = 0; - while i < n { - { + while i < n { + { let mut word: i32 = 0; { let mut j: i32 = 0; - while j < word_size { - { - if i + j >= n || bits.get(i + j) { - word |= 1 << (word_size - 1 - j); - } - } - j += 1; + while j < word_size { + { + if i + j >= n || bits.get(i + j) { + word |= 1 << (word_size - 1 - j); + } + } + j += 1; } } - if (word & mask) == mask { - out.append_bits(word & mask, word_size); - i -= 1; - } else if (word & mask) == 0 { - out.append_bits(word | 1, word_size); - i -= 1; - } else { - out.append_bits(word, word_size); - } - } - i += word_size; + if (word & mask) == mask { + out.append_bits(word & mask, word_size); + i -= 1; + } else if (word & mask) == 0 { + out.append_bits(word | 1, word_size); + i -= 1; + } else { + out.append_bits(word, word_size); + } + } + i += word_size; } } - return out; - } + return out; + } - fn total_bits_in_layer( layers: i32, compact: bool) -> i32 { - return (( if compact { 88 } else { 112 }) + 16 * layers) * layers; - } + fn total_bits_in_layer(layers: i32, compact: bool) -> i32 { + return ((if compact { 88 } else { 112 }) + 16 * layers) * layers; + } } // BinaryShiftToken.java @@ -614,53 +663,57 @@ struct BinaryShiftToken { //super: Token; previous: dyn Token, - binary_shift_start: i32, + binary_shift_start: i32, - binary_shift_byte_count: i32 + binary_shift_byte_count: i32, } impl Token for BinaryShiftToken { - fn append_to(&self, bit_array: &BitArray, text: &Vec) { + fn append_to(&self, bit_array: &BitArray, text: &Vec) { let bsbc: i32 = self.binary_shift_byte_count; { let mut i: i32 = 0; - while i < bsbc { - { - if i == 0 || (i == 31 && bsbc <= 62) { - // We need a header before the first character, and before - // character 31 when the total byte code is <= 62 - // BINARY_SHIFT - bit_array.append_bits(31, 5); - if bsbc > 62 { - bit_array.append_bits(bsbc - 31, 16); - } else if i == 0 { - // 1 <= binaryShiftByteCode <= 62 - bit_array.append_bits(&Math::min(bsbc, 31), 5); - } else { - // 32 <= binaryShiftCount <= 62 and i == 31 - bit_array.append_bits(bsbc - 31, 5); - } - } - bit_array.append_bits(text[self.binary_shift_start + i], 8); - } - i += 1; + while i < bsbc { + { + if i == 0 || (i == 31 && bsbc <= 62) { + // We need a header before the first character, and before + // character 31 when the total byte code is <= 62 + // BINARY_SHIFT + bit_array.append_bits(31, 5); + if bsbc > 62 { + bit_array.append_bits(bsbc - 31, 16); + } else if i == 0 { + // 1 <= binaryShiftByteCode <= 62 + bit_array.append_bits(&Math::min(bsbc, 31), 5); + } else { + // 32 <= binaryShiftCount <= 62 and i == 31 + bit_array.append_bits(bsbc - 31, 5); + } + } + bit_array.append_bits(text[self.binary_shift_start + i], 8); + } + i += 1; } } + } - } - - fn to_string(&self) -> String { - return format!("<{}::{}>", self.binary_shift_start, (self.binary_shift_start + self.binary_shift_byte_count - 1)); - } + fn to_string(&self) -> String { + return format!( + "<{}::{}>", + self.binary_shift_start, + (self.binary_shift_start + self.binary_shift_byte_count - 1) + ); + } } impl BinaryShiftToken { - - fn new( previous: &Token, binary_shift_start: i32, binary_shift_byte_count: i32) -> Self { - Self{ previous, binary_shift_start, binary_shift_byte_count} + fn new(previous: &Token, binary_shift_start: i32, binary_shift_byte_count: i32) -> Self { + Self { + previous, + binary_shift_start, + binary_shift_byte_count, + } } - - } // HighLevelEncoder.java @@ -677,136 +730,154 @@ impl BinaryShiftToken { * @author Rustam Abdullaev */ -const MODE_NAMES: vec![Vec; 5] = vec!["UPPER", "LOWER", "DIGIT", "MIXED", "PUNCT", ] -; +const MODE_NAMES: vec![Vec; 5] = vec!["UPPER", "LOWER", "DIGIT", "MIXED", "PUNCT"]; // 5 bits - const MODE_UPPER: i32 = 0; +const MODE_UPPER: i32 = 0; // 5 bits - const MODE_LOWER: i32 = 1; +const MODE_LOWER: i32 = 1; // 4 bits - const MODE_DIGIT: i32 = 2; +const MODE_DIGIT: i32 = 2; // 5 bits - const MODE_MIXED: i32 = 3; +const MODE_MIXED: i32 = 3; // 5 bits - const MODE_PUNCT: i32 = 4; +const MODE_PUNCT: i32 = 4; // The Latch Table shows, for each pair of Modes, the optimal method for // getting from one mode to another. In the worst possible case, this can // be up to 14 bits. In the best possible case, we are already there! // The high half-word of each entry gives the number of bits. // The low half-word of each entry are the actual bits necessary to change - const LATCH_TABLE: vec![vec![Vec>; 5]; 5] = vec![vec![0, // UPPER -> LOWER -(5 << 16) + 28, // UPPER -> DIGIT -(5 << 16) + 30, // UPPER -> MIXED -(5 << 16) + 29, // UPPER -> MIXED -> PUNCT -(10 << 16) + (29 << 5) + 30, ] -, vec![// LOWER -> DIGIT -> UPPER -(9 << 16) + (30 << 4) + 14, 0, // LOWER -> DIGIT -(5 << 16) + 30, // LOWER -> MIXED -(5 << 16) + 29, // LOWER -> MIXED -> PUNCT -(10 << 16) + (29 << 5) + 30, ] -, vec![// DIGIT -> UPPER -(4 << 16) + 14, // DIGIT -> UPPER -> LOWER -(9 << 16) + (14 << 5) + 28, 0, // DIGIT -> UPPER -> MIXED -(9 << 16) + (14 << 5) + 29, (14 << 16) + (14 << 10) + (29 << 5) + 30, ] -, vec![// MIXED -> UPPER -(5 << 16) + 29, // MIXED -> LOWER -(5 << 16) + 28, // MIXED -> UPPER -> DIGIT -(10 << 16) + (29 << 5) + 30, 0, // MIXED -> PUNCT -(5 << 16) + 30, ] -, vec![// PUNCT -> UPPER -(5 << 16) + 31, // PUNCT -> UPPER -> LOWER -(10 << 16) + (31 << 5) + 28, // PUNCT -> UPPER -> DIGIT -(10 << 16) + (31 << 5) + 30, // PUNCT -> UPPER -> MIXED -(10 << 16) + (31 << 5) + 29, 0, ] -, ] -; +const LATCH_TABLE: vec![vec![Vec>; 5]; 5] = vec![ + vec![ + 0, // UPPER -> LOWER + (5 << 16) + 28, // UPPER -> DIGIT + (5 << 16) + 30, // UPPER -> MIXED + (5 << 16) + 29, // UPPER -> MIXED -> PUNCT + (10 << 16) + (29 << 5) + 30, + ], + vec![ + // LOWER -> DIGIT -> UPPER + (9 << 16) + (30 << 4) + 14, + 0, // LOWER -> DIGIT + (5 << 16) + 30, // LOWER -> MIXED + (5 << 16) + 29, // LOWER -> MIXED -> PUNCT + (10 << 16) + (29 << 5) + 30, + ], + vec![ + // DIGIT -> UPPER + (4 << 16) + 14, // DIGIT -> UPPER -> LOWER + (9 << 16) + (14 << 5) + 28, + 0, // DIGIT -> UPPER -> MIXED + (9 << 16) + (14 << 5) + 29, + (14 << 16) + (14 << 10) + (29 << 5) + 30, + ], + vec![ + // MIXED -> UPPER + (5 << 16) + 29, // MIXED -> LOWER + (5 << 16) + 28, // MIXED -> UPPER -> DIGIT + (10 << 16) + (29 << 5) + 30, + 0, // MIXED -> PUNCT + (5 << 16) + 30, + ], + vec![ + // PUNCT -> UPPER + (5 << 16) + 31, // PUNCT -> UPPER -> LOWER + (10 << 16) + (31 << 5) + 28, // PUNCT -> UPPER -> DIGIT + (10 << 16) + (31 << 5) + 30, // PUNCT -> UPPER -> MIXED + (10 << 16) + (31 << 5) + 29, + 0, + ], +]; // A reverse mapping from [mode][char] to the encoding for that character // in that mode. An entry of 0 indicates no mapping exists. - const CHAR_MAP: [[i32; 256]; 5] = [[0; 256]; 5]; +const CHAR_MAP: [[i32; 256]; 5] = [[0; 256]; 5]; // A map showing the available shift codes. (The shifts to BINARY are not // shown // mode shift codes, per table - const SHIFT_TABLE: [[i32; 6]; 6] = [[0; 6]; 6]; +const SHIFT_TABLE: [[i32; 6]; 6] = [[0; 6]; 6]; pub struct HighLevelEncoder { + text: Vec, - text: Vec, - - charset: Charset + charset: Charset, } impl HighLevelEncoder { - - pub fn new( text: &Vec, charset: Option<&Charset>) -> Self { + pub fn new(text: &Vec, charset: Option<&Charset>) -> Self { CHAR_MAP[MODE_UPPER][' '] = 1; { let mut c: i32 = 'A'; - while c <= 'Z' { - { - CHAR_MAP[MODE_UPPER][c] = c - 'A' + 2; - } - c += 1; + while c <= 'Z' { + { + CHAR_MAP[MODE_UPPER][c] = c - 'A' + 2; + } + c += 1; } } - CHAR_MAP[MODE_LOWER][' '] = 1; + CHAR_MAP[MODE_LOWER][' '] = 1; { let mut c: i32 = 'a'; - while c <= 'z' { - { - CHAR_MAP[MODE_LOWER][c] = c - 'a' + 2; - } - c += 1; + while c <= 'z' { + { + CHAR_MAP[MODE_LOWER][c] = c - 'a' + 2; + } + c += 1; } } - CHAR_MAP[MODE_DIGIT][' '] = 1; + CHAR_MAP[MODE_DIGIT][' '] = 1; { let mut c: i32 = '0'; - while c <= '9' { - { - CHAR_MAP[MODE_DIGIT][c] = c - '0' + 2; - } - c += 1; + while c <= '9' { + { + CHAR_MAP[MODE_DIGIT][c] = c - '0' + 2; + } + c += 1; } } - CHAR_MAP[MODE_DIGIT][','] = 12; - CHAR_MAP[MODE_DIGIT]['.'] = 13; - let mixed_table: vec![Vec; 28] = vec!['\0', ' ', '\u{0001}', '\u{0002}', '\u{0003}', '\u{0004}', '\u{0005}', '\u{0006}', '\u{0007}', '\u{000b}', '\t', '\n', '\u{000D}', '\u{000f}', '\r', '\u{0021}', '\u{0022}', '\u{0023}', '\u{0024}', '\u{0025}', '@', '\\', '^', '_', '`', '|', '~', '\u{00b1}', ] - ; + CHAR_MAP[MODE_DIGIT][','] = 12; + CHAR_MAP[MODE_DIGIT]['.'] = 13; + let mixed_table: vec![Vec; 28] = vec![ + '\0', ' ', '\u{0001}', '\u{0002}', '\u{0003}', '\u{0004}', '\u{0005}', '\u{0006}', + '\u{0007}', '\u{000b}', '\t', '\n', '\u{000D}', '\u{000f}', '\r', '\u{0021}', + '\u{0022}', '\u{0023}', '\u{0024}', '\u{0025}', '@', '\\', '^', '_', '`', '|', '~', + '\u{00b1}', + ]; { let mut i: i32 = 0; - while i < mixed_table.len() { - { - CHAR_MAP[MODE_MIXED][mixed_table[i]] = i; - } - i += 1; + while i < mixed_table.len() { + { + CHAR_MAP[MODE_MIXED][mixed_table[i]] = i; + } + i += 1; } } - let punct_table: vec![Vec; 31] = vec!['\0', '\r', '\0', '\0', '\0', '\0', '!', '\'', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '[', ']', '{', '}', ] - ; + let punct_table: vec![Vec; 31] = vec![ + '\0', '\r', '\0', '\0', '\0', '\0', '!', '\'', '#', '$', '%', '&', '\'', '(', ')', '*', + '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '[', ']', '{', '}', + ]; { let mut i: i32 = 0; - while i < punct_table.len() { - { - if punct_table[i] > 0 { - CHAR_MAP[MODE_PUNCT][punct_table[i]] = i; - } - } - i += 1; + while i < punct_table.len() { + { + if punct_table[i] > 0 { + CHAR_MAP[MODE_PUNCT][punct_table[i]] = i; + } + } + i += 1; } } - for table in SHIFT_TABLE { + for table in SHIFT_TABLE { Arrays::fill(&table, -1); } SHIFT_TABLE[MODE_UPPER][MODE_PUNCT] = 0; @@ -816,53 +887,58 @@ impl HighLevelEncoder { SHIFT_TABLE[MODE_DIGIT][MODE_PUNCT] = 0; SHIFT_TABLE[MODE_DIGIT][MODE_UPPER] = 15; - Self { text: text, charset: charset } + Self { + text: text, + charset: charset, + } } /** - * @return text represented by this encoder encoded as a {@link BitArray} - */ - pub fn encode(&self) -> BitArray { - let initial_state: State = State::INITIAL_STATE; + * @return text represented by this encoder encoded as a {@link BitArray} + */ + pub fn encode(&self) -> BitArray { + let initial_state: State = State::INITIAL_STATE; if self.charset != null { - let eci: CharacterSetECI = CharacterSetECI::get_character_set_e_c_i(&self.charset); + let eci: CharacterSetECI = CharacterSetECI::get_character_set_e_c_i(&self.charset); if null == eci { - return Err( IllegalArgumentException::new(format!("No ECI code for character set {}", self.charset))); + return Err(IllegalArgumentException::new(format!( + "No ECI code for character set {}", + self.charset + ))); } initial_state = initial_state.append_f_l_gn(&eci.get_value()); } - let mut states: Collection = Collections::singleton_list(initial_state); - { - let mut index: i32 = 0; + let mut states: Collection = Collections::singleton_list(initial_state); + { + let mut index: i32 = 0; while index < self.text.len() { { - let pair_code: i32; - let next_char: i32 = if index + 1 < self.text.len() { self.text[index + 1] } else { 0 }; + let pair_code: i32; + let next_char: i32 = if index + 1 < self.text.len() { + self.text[index + 1] + } else { + 0 + }; match self.text[index] { - '\r' => - { - pair_code = if next_char == '\n' { 2 } else { 0 }; - break; - } - '.' => - { - pair_code = if next_char == ' ' { 3 } else { 0 }; - break; - } - ',' => - { - pair_code = if next_char == ' ' { 4 } else { 0 }; - break; - } - ':' => - { - pair_code = if next_char == ' ' { 5 } else { 0 }; - break; - } - _ => - { - pair_code = 0; - } + '\r' => { + pair_code = if next_char == '\n' { 2 } else { 0 }; + break; + } + '.' => { + pair_code = if next_char == ' ' { 3 } else { 0 }; + break; + } + ',' => { + pair_code = if next_char == ' ' { 4 } else { 0 }; + break; + } + ':' => { + pair_code = if next_char == ' ' { 5 } else { 0 }; + break; + } + _ => { + pair_code = 0; + } } if pair_code > 0 { // We have one of the four special PUNCT pairs. Treat them specially. @@ -875,21 +951,24 @@ impl HighLevelEncoder { } } index += 1; - } - } + } + } // We are left with a set of states. Find the shortest one. - let min_state = states.iter().min_by(|a,b| { - let c = a.get_bit_count() - b.get_bit_count(); - if c > 0 { - Ordering::Greater - } else if c < 0 { - Ordering::Less - }else { - Ordering::Equal - } - }).unwrap(); - /*let min_state: State = Collections::min(&states, Comparator::new() { + let min_state = states + .iter() + .min_by(|a, b| { + let c = a.get_bit_count() - b.get_bit_count(); + if c > 0 { + Ordering::Greater + } else if c < 0 { + Ordering::Less + } else { + Ordering::Equal + } + }) + .unwrap(); + /*let min_state: State = Collections::min(&states, Comparator::new() { pub fn compare(&self, a: &State, b: &State) -> i32 { return a.get_bit_count() - b.get_bit_count(); @@ -902,9 +981,9 @@ impl HighLevelEncoder { // We update a set of states for a new character by updating each state // for the new character, merging the results, and then removing the // non-optimal states. - fn update_state_list_for_char(&self, states: &Vec, index: i32) -> Vec { - let result: Vec = Vec::new(); - for state in states { + fn update_state_list_for_char(&self, states: &Vec, index: i32) -> Vec { + let result: Vec = Vec::new(); + for state in states { self.update_state_for_char(state, index, &result); } return ::simplify_states(&result); @@ -913,61 +992,68 @@ impl HighLevelEncoder { // Return a set of states that represent the possible ways of updating this // state for the next character. The resulting set of states are added to // the "result" list. - fn update_state_for_char(&self, state: &State, index: i32, result: &Vec) { - let ch: char = (self.text[index] & 0xFF) as char; - let char_in_current_table: bool = CHAR_MAP[state.get_mode()][ch] > 0; - let state_no_binary: State = null; - { - let mut mode: i32 = 0; + fn update_state_for_char(&self, state: &State, index: i32, result: &Vec) { + let ch: char = (self.text[index] & 0xFF) as char; + let char_in_current_table: bool = CHAR_MAP[state.get_mode()][ch] > 0; + let state_no_binary: State = null; + { + let mut mode: i32 = 0; while mode <= MODE_PUNCT { { - let char_in_mode: i32 = CHAR_MAP[mode][ch]; + let char_in_mode: i32 = CHAR_MAP[mode][ch]; if char_in_mode > 0 { if state_no_binary == null { // Only create stateNoBinary the first time it's required. state_no_binary = state.end_binary_shift(index); } // Try generating the character by latching to its mode - if !char_in_current_table || mode == state.get_mode() || mode == MODE_DIGIT { + if !char_in_current_table || mode == state.get_mode() || mode == MODE_DIGIT + { // If the character is in the current table, we don't want to latch to // any other mode except possibly digit (which uses only 4 bits). Any // other latch would be equally successful *after* this character, and // so wouldn't save any bits. - let latch_state: State = state_no_binary.latch_and_append(mode, char_in_mode); + let latch_state: State = + state_no_binary.latch_and_append(mode, char_in_mode); result.add(latch_state); } // Try generating the character by switching to its mode. if !char_in_current_table && SHIFT_TABLE[state.get_mode()][mode] >= 0 { // It never makes sense to temporarily shift to another mode if the // character exists in the current mode. That can never save bits. - let shift_state: State = state_no_binary.shift_and_append(mode, char_in_mode); + let shift_state: State = + state_no_binary.shift_and_append(mode, char_in_mode); result.add(shift_state); } } } mode += 1; - } - } + } + } if state.get_binary_shift_byte_count() > 0 || CHAR_MAP[state.get_mode()][ch] == 0 { // It's never worthwhile to go into binary shift mode if you're not already // in binary shift mode, and the character exists in your current mode. // That can never save bits over just outputting the char in the current mode. - let binary_state: State = state.add_binary_shift_char(index); + let binary_state: State = state.add_binary_shift_char(index); result.add(binary_state); } } - fn update_state_list_for_pair( states: &Iterable, index: i32, pair_code: i32) -> Vec { - let result: Collection = Vec::new(); - for state in states { + fn update_state_list_for_pair( + states: &Iterable, + index: i32, + pair_code: i32, + ) -> Vec { + let result: Collection = Vec::new(); + for state in states { ::update_state_for_pair(state, index, pair_code, &result); } return ::simplify_states(&result); } - fn update_state_for_pair( state: &State, index: i32, pair_code: i32, result: &Vec) { - let state_no_binary: State = state.end_binary_shift(index); + fn update_state_for_pair(state: &State, index: i32, pair_code: i32, result: &Vec) { + let state_no_binary: State = state.end_binary_shift(index); // Possibility 1. Latch to MODE_PUNCT, and then append this code result.add(&state_no_binary.latch_and_append(MODE_PUNCT, pair_code)); if state.get_mode() != MODE_PUNCT { @@ -977,27 +1063,35 @@ impl HighLevelEncoder { } if pair_code == 3 || pair_code == 4 { // both characters are in DIGITS. Sometimes better to just add two digits - let digit_state: State = state_no_binary.latch_and_append(MODE_DIGIT, // period or comma in DIGIT - 16 - pair_code).latch_and_append(MODE_DIGIT, // space in DIGIT - 1); + let digit_state: State = state_no_binary + .latch_and_append( + MODE_DIGIT, // period or comma in DIGIT + 16 - pair_code, + ) + .latch_and_append( + MODE_DIGIT, // space in DIGIT + 1, + ); result.add(digit_state); } if state.get_binary_shift_byte_count() > 0 { // It only makes sense to do the characters as binary if we're already // in binary mode. - let binary_state: State = state.add_binary_shift_char(index).add_binary_shift_char(index + 1); + let binary_state: State = state + .add_binary_shift_char(index) + .add_binary_shift_char(index + 1); result.add(binary_state); } } - fn simplify_states( states: &Iterable) -> Collection { - let result: Deque = Vec::new(); - for new_state in states { - let mut add: bool = true; - { - let iterator: Iterator = result.iterator(); - while iterator.has_next(){ - let old_state: State = iterator.next(); + fn simplify_states(states: &Iterable) -> Collection { + let result: Deque = Vec::new(); + for new_state in states { + let mut add: bool = true; + { + let iterator: Iterator = result.iterator(); + while iterator.has_next() { + let old_state: State = iterator.next(); if old_state.is_better_than_or_equal_to(new_state) { add = false; break; @@ -1006,7 +1100,7 @@ impl HighLevelEncoder { iterator.remove(); } } - } + } if add { result.add_first(new_state); @@ -1019,33 +1113,38 @@ impl HighLevelEncoder { // SimpleToken.java struct SimpleToken { //super: Token; - previous :dyn Token, + previous: dyn Token, // For normal words, indicates value and bitCount - value: i16, + value: i16, - bit_count: i16, + bit_count: i16, } impl Token for SimpleToken { - fn append_to(&self, bit_array: &BitArray, text: &Vec) { + fn append_to(&self, bit_array: &BitArray, text: &Vec) { bit_array.append_bits(self.value, self.bit_count); } - fn to_string(&self) -> String { - let mut value: i32 = self.value & ((1 << self.bit_count) - 1); + fn to_string(&self) -> String { + let mut value: i32 = self.value & ((1 << self.bit_count) - 1); value |= 1 << self.bit_count; - return format!("<{}>",format!("{}",value | (1 << self.bit_count)).as_bytes()[1..]); + return format!( + "<{}>", + format!("{}", value | (1 << self.bit_count)).as_bytes()[1..] + ); //return '<' + Integer::to_binary_string(value | (1 << self.bit_count))::substring(1) + '>'; } } impl SimpleToken { - - fn new( previous: &Token, value: i32, bit_count: i32) -> Self { - Self { previous, value, bit_count } + fn new(previous: &Token, value: i32, bit_count: i32) -> Self { + Self { + previous, + value, + bit_count, + } } - } // State.java @@ -1057,62 +1156,68 @@ impl SimpleToken { const INITIAL_STATE: State = State::new(Token::EMPTY, HighLevelEncoder::MODE_UPPER, 0, 0); struct State { - // The current mode of the encoding (or the mode to which we'll return if // we're in Binary Shift mode. - mode: i32, + mode: i32, // The list of tokens that we output. If we are in Binary Shift mode, this // token list does *not* yet included the token for those bytes - token: Token, + token: Token, // If non-zero, the number of most recent bytes that should be output // in Binary Shift mode. - binary_shift_byte_count: i32, + binary_shift_byte_count: i32, // The total number of bits generated (including Binary Shift). - bit_count: i32, + bit_count: i32, - binary_shift_cost: i32 + binary_shift_cost: i32, } impl State { - - fn new( token: &Token, mode: i32, binary_bytes: i32, bit_count: i32) -> Self { - Self{ mode: mode, token: token, binary_shift_byte_count: binary_bytes, bit_count: bit_count, binary_shift_cost: ::calculate_binary_shift_cost(binary_bytes) } + fn new(token: &Token, mode: i32, binary_bytes: i32, bit_count: i32) -> Self { + Self { + mode: mode, + token: token, + binary_shift_byte_count: binary_bytes, + bit_count: bit_count, + binary_shift_cost: ::calculate_binary_shift_cost(binary_bytes), + } } - fn get_mode(&self) -> i32 { + fn get_mode(&self) -> i32 { return self.mode; } - fn get_token(&self) -> Token { + fn get_token(&self) -> Token { return self.token; } - fn get_binary_shift_byte_count(&self) -> i32 { + fn get_binary_shift_byte_count(&self) -> i32 { return self.binary_shift_byte_count; } - fn get_bit_count(&self) -> i32 { + fn get_bit_count(&self) -> i32 { return self.bit_count; } - fn append_f_l_gn(&self, eci: i32) -> State { + fn append_f_l_gn(&self, eci: i32) -> State { // 0: FLG(n) - let result: State = self.shift_and_append(HighLevelEncoder::MODE_PUNCT, 0); - let mut token: Token = result.token; - let bits_added: i32 = 3; + let result: State = self.shift_and_append(HighLevelEncoder::MODE_PUNCT, 0); + let mut token: Token = result.token; + let bits_added: i32 = 3; if eci < 0 { // 0: FNC1 token = token.add(0, 3); } else if eci > 999999 { - return Err( IllegalArgumentException::new("ECI code must be between 0 and 999999")); + return Err(IllegalArgumentException::new( + "ECI code must be between 0 and 999999", + )); } else { - let eci_digits: Vec = eci.to_string().as_bytes();//Integer::to_string(eci)::get_bytes(StandardCharsets::ISO_8859_1); - // 1-6: number of ECI digits + let eci_digits: Vec = eci.to_string().as_bytes(); //Integer::to_string(eci)::get_bytes(StandardCharsets::ISO_8859_1); + // 1-6: number of ECI digits token = token.add(eci_digits.len(), 3); - for eci_digit in eci_digits { + for eci_digit in eci_digits { token = token.add(eci_digit - '0' + 2, 4); } bits_added += eci_digits.len() * 4; @@ -1122,44 +1227,74 @@ impl State { // Create a new state representing this state with a latch to a (not // necessary different) mode, and then a code. - fn latch_and_append(&self, mode: i32, value: i32) -> State { - let bit_count: i32 = self.bitCount; - let mut token: Token = self.token; + fn latch_and_append(&self, mode: i32, value: i32) -> State { + let bit_count: i32 = self.bitCount; + let mut token: Token = self.token; if mode != self.mode { - let latch: i32 = HighLevelEncoder::LATCH_TABLE[self.mode][mode]; + let latch: i32 = HighLevelEncoder::LATCH_TABLE[self.mode][mode]; token = token.add(latch & 0xFFFF, latch >> 16); bit_count += latch >> 16; } - let latch_mode_bit_count: i32 = if mode == HighLevelEncoder::MODE_DIGIT { 4 } else { 5 }; + let latch_mode_bit_count: i32 = if mode == HighLevelEncoder::MODE_DIGIT { + 4 + } else { + 5 + }; token = token.add(value, latch_mode_bit_count); return State::new(&token, mode, 0, bit_count + latch_mode_bit_count); } // Create a new state representing this state, with a temporary shift // to a different mode to output a single value. - fn shift_and_append(&self, mode: i32, value: i32) -> State { - let mut token: Token = self.token; - let this_mode_bit_count: i32 = if self.mode == HighLevelEncoder::MODE_DIGIT { 4 } else { 5 }; + fn shift_and_append(&self, mode: i32, value: i32) -> State { + let mut token: Token = self.token; + let this_mode_bit_count: i32 = if self.mode == HighLevelEncoder::MODE_DIGIT { + 4 + } else { + 5 + }; // Shifts exist only to UPPER and PUNCT, both with tokens size 5. - token = token.add(HighLevelEncoder::SHIFT_TABLE[self.mode][mode], this_mode_bit_count); + token = token.add( + HighLevelEncoder::SHIFT_TABLE[self.mode][mode], + this_mode_bit_count, + ); token = token.add(value, 5); - return State::new(&token, self.mode, 0, self.bitCount + this_mode_bit_count + 5); + return State::new( + &token, + self.mode, + 0, + self.bitCount + this_mode_bit_count + 5, + ); } // Create a new state representing this state, but an additional character // output in Binary Shift mode. - fn add_binary_shift_char(&self, index: i32) -> State { - let mut token: Token = self.token; - let mut mode: i32 = self.mode; - let bit_count: i32 = self.bitCount; + fn add_binary_shift_char(&self, index: i32) -> State { + let mut token: Token = self.token; + let mut mode: i32 = self.mode; + let bit_count: i32 = self.bitCount; if self.mode == HighLevelEncoder::MODE_PUNCT || self.mode == HighLevelEncoder::MODE_DIGIT { - let latch: i32 = HighLevelEncoder::LATCH_TABLE[mode][HighLevelEncoder::MODE_UPPER]; + let latch: i32 = HighLevelEncoder::LATCH_TABLE[mode][HighLevelEncoder::MODE_UPPER]; token = token.add(latch & 0xFFFF, latch >> 16); bit_count += latch >> 16; mode = HighLevelEncoder::MODE_UPPER; } - let delta_bit_count: i32 = if (self.binary_shift_byte_count == 0 || self.binary_shift_byte_count == 31) { 18 } else { if (self.binary_shift_byte_count == 62) { 9 } else { 8 } }; - let mut result: State = State::new(&token, mode, self.binary_shift_byte_count + 1, bit_count + delta_bit_count); + let delta_bit_count: i32 = + if (self.binary_shift_byte_count == 0 || self.binary_shift_byte_count == 31) { + 18 + } else { + if (self.binary_shift_byte_count == 62) { + 9 + } else { + 8 + } + }; + let mut result: State = State::new( + &token, + mode, + self.binary_shift_byte_count + 1, + bit_count + delta_bit_count, + ); if result.binaryShiftByteCount == 2047 + 31 { // The string is as long as it's allowed to be. We should end it. result = result.end_binary_shift(index + 1); @@ -1169,61 +1304,72 @@ impl State { // Create the state identical to this one, but we are no longer in // Binary Shift mode. - fn end_binary_shift(&self, index: i32) -> State { + fn end_binary_shift(&self, index: i32) -> State { if self.binary_shift_byte_count == 0 { return self; } - let mut token: Token = self.token; - token = token.add_binary_shift(index - self.binary_shift_byte_count, self.binary_shift_byte_count); + let mut token: Token = self.token; + token = token.add_binary_shift( + index - self.binary_shift_byte_count, + self.binary_shift_byte_count, + ); return State::new(&token, self.mode, 0, self.bitCount); } // Returns true if "this" state is better (or equal) to be in than "that" // state under all possible circumstances. - fn is_better_than_or_equal_to(&self, other: &State) -> bool { - let new_mode_bit_count: i32 = self.bitCount + (HighLevelEncoder::LATCH_TABLE[self.mode][other.mode] >> 16); + fn is_better_than_or_equal_to(&self, other: &State) -> bool { + let new_mode_bit_count: i32 = + self.bitCount + (HighLevelEncoder::LATCH_TABLE[self.mode][other.mode] >> 16); if self.binaryShiftByteCount < other.binaryShiftByteCount { // add additional B/S encoding cost of other, if any new_mode_bit_count += other.binaryShiftCost - self.binaryShiftCost; - } else if self.binaryShiftByteCount > other.binaryShiftByteCount && other.binaryShiftByteCount > 0 { + } else if self.binaryShiftByteCount > other.binaryShiftByteCount + && other.binaryShiftByteCount > 0 + { // maximum possible additional cost (we end up exceeding the 31 byte boundary and other state can stay beneath it) new_mode_bit_count += 10; } return new_mode_bit_count <= other.bitCount; } - fn to_bit_array(&self, text: &Vec) -> BitArray { - let symbols: List = Vec::new(); - { - let mut token: Token = self.end_binary_shift(text.len()).token; + fn to_bit_array(&self, text: &Vec) -> BitArray { + let symbols: List = Vec::new(); + { + let mut token: Token = self.end_binary_shift(text.len()).token; while token != null { { symbols.add(token); } token = token.get_previous(); - } - } + } + } - let bit_array: BitArray = BitArray::new(); + let bit_array: BitArray = BitArray::new(); // Add each token to the result in forward order - { - let mut i: i32 = symbols.size() - 1; + { + let mut i: i32 = symbols.size() - 1; while i >= 0 { { symbols.get(i).append_to(bit_array, &text); } i -= 1; - } - } + } + } return bit_array; } - pub fn to_string(&self) -> String { - return String::format("%s bits=%d bytes=%d", HighLevelEncoder::MODE_NAMES[self.mode], self.bit_count, self.binary_shift_byte_count); + pub fn to_string(&self) -> String { + return String::format( + "%s bits=%d bytes=%d", + HighLevelEncoder::MODE_NAMES[self.mode], + self.bit_count, + self.binary_shift_byte_count, + ); } - fn calculate_binary_shift_cost( binary_shift_byte_count: i32) -> i32 { + fn calculate_binary_shift_cost(binary_shift_byte_count: i32) -> i32 { if binary_shift_byte_count > 62 { // B/S with extended length return 21;