From 88fb66936b17acab3aef3ec984198014eb3e2525 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Sat, 13 Aug 2022 17:28:07 -0500 Subject: [PATCH] datamatrix copy --- .../datamatrix/DataMatrixReader.java | 0 .../datamatrix/DataMatrixWriter.java | 0 .../datamatrix/decoder/BitMatrixParser.java | 0 .../datamatrix/decoder/DataBlock.java | 0 .../decoder/DecodedBitStreamParser.java | 0 .../datamatrix/decoder/Decoder.java | 0 .../datamatrix/decoder/Version.java | 0 .../datamatrix/detector/Detector.java | 0 .../datamatrix/encoder/ASCIIEncoder.java | 0 .../datamatrix/encoder/Base256Encoder.java | 0 .../datamatrix/encoder/C40Encoder.java | 0 .../encoder/DataMatrixSymbolInfo144.java | 0 .../datamatrix/encoder/DefaultPlacement.java | 0 .../datamatrix/encoder/EdifactEncoder.java | 0 .../datamatrix/encoder/Encoder.java | 0 .../datamatrix/encoder/EncoderContext.java | 0 .../datamatrix/encoder/ErrorCorrection.java | 0 .../datamatrix/encoder/HighLevelEncoder.java | 0 .../datamatrix/encoder/MinimalEncoder.java | 0 .../datamatrix/encoder/SymbolInfo.java | 0 .../datamatrix/encoder/SymbolShapeHint.java | 0 .../datamatrix/encoder/TextEncoder.java | 0 .../datamatrix/encoder/X12Encoder.java | 0 .../zxing/datamatrix/data_matrix_reader.rs | 146 - .../zxing/datamatrix/data_matrix_writer.rs | 220 -- .../datamatrix/decoder/bit_matrix_parser.rs | 459 --- .../zxing/datamatrix/decoder/data_block.rs | 154 - .../decoder/decoded_bit_stream_parser.rs | 679 ---- .../zxing/datamatrix/decoder/decoder.rs | 149 - .../zxing/datamatrix/decoder/version.rs | 189 -- .../zxing/datamatrix/detector/detector.rs | 320 -- .../datamatrix/encoder/a_s_c_i_i_encoder.rs | 93 - .../datamatrix/encoder/base256_encoder.rs | 80 - .../zxing/datamatrix/encoder/c40_encoder.rs | 212 -- .../encoder/data_matrix_symbol_info144.rs | 36 - .../datamatrix/encoder/default_placement.rs | 198 -- .../datamatrix/encoder/edifact_encoder.rs | 149 - .../zxing/datamatrix/encoder/encoder.rs | 24 - .../datamatrix/encoder/encoder_context.rs | 149 - .../datamatrix/encoder/error_correction.rs | 227 -- .../datamatrix/encoder/high_level_encoder.rs | 491 --- .../datamatrix/encoder/minimal_encoder.rs | 947 ------ .../zxing/datamatrix/encoder/symbol_info.rs | 220 -- .../datamatrix/encoder/symbol_shape_hint.rs | 25 - .../zxing/datamatrix/encoder/text_encoder.rs | 91 - .../zxing/datamatrix/encoder/x12_encoder.rs | 99 - src/datamatrix.rs | 373 +++ src/datamatrix/decoder.rs | 1573 +++++++++ src/datamatrix/detector.rs | 311 ++ src/datamatrix/encoder.rs | 2820 +++++++++++++++++ 50 files changed, 5077 insertions(+), 5357 deletions(-) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/DataMatrixReader.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/DataMatrixWriter.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/decoder/BitMatrixParser.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/decoder/DataBlock.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/decoder/DecodedBitStreamParser.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/decoder/Decoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/decoder/Version.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/detector/Detector.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/ASCIIEncoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/Base256Encoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/C40Encoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/DataMatrixSymbolInfo144.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/DefaultPlacement.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/EdifactEncoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/Encoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/EncoderContext.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/ErrorCorrection.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/HighLevelEncoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/MinimalEncoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/SymbolInfo.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/SymbolShapeHint.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/TextEncoder.java (100%) rename port_src/core/{src/main/java/com/google/zxing => DONE}/datamatrix/encoder/X12Encoder.java (100%) delete mode 100644 port_src/output/zxing/datamatrix/data_matrix_reader.rs delete mode 100644 port_src/output/zxing/datamatrix/data_matrix_writer.rs delete mode 100644 port_src/output/zxing/datamatrix/decoder/bit_matrix_parser.rs delete mode 100644 port_src/output/zxing/datamatrix/decoder/data_block.rs delete mode 100644 port_src/output/zxing/datamatrix/decoder/decoded_bit_stream_parser.rs delete mode 100644 port_src/output/zxing/datamatrix/decoder/decoder.rs delete mode 100644 port_src/output/zxing/datamatrix/decoder/version.rs delete mode 100644 port_src/output/zxing/datamatrix/detector/detector.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/a_s_c_i_i_encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/base256_encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/c40_encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/data_matrix_symbol_info144.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/default_placement.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/edifact_encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/encoder_context.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/error_correction.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/high_level_encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/minimal_encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/symbol_info.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/symbol_shape_hint.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/text_encoder.rs delete mode 100644 port_src/output/zxing/datamatrix/encoder/x12_encoder.rs diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/DataMatrixReader.java b/port_src/core/DONE/datamatrix/DataMatrixReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/DataMatrixReader.java rename to port_src/core/DONE/datamatrix/DataMatrixReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/DataMatrixWriter.java b/port_src/core/DONE/datamatrix/DataMatrixWriter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/DataMatrixWriter.java rename to port_src/core/DONE/datamatrix/DataMatrixWriter.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/BitMatrixParser.java b/port_src/core/DONE/datamatrix/decoder/BitMatrixParser.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/BitMatrixParser.java rename to port_src/core/DONE/datamatrix/decoder/BitMatrixParser.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/DataBlock.java b/port_src/core/DONE/datamatrix/decoder/DataBlock.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/DataBlock.java rename to port_src/core/DONE/datamatrix/decoder/DataBlock.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/DecodedBitStreamParser.java b/port_src/core/DONE/datamatrix/decoder/DecodedBitStreamParser.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/DecodedBitStreamParser.java rename to port_src/core/DONE/datamatrix/decoder/DecodedBitStreamParser.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/Decoder.java b/port_src/core/DONE/datamatrix/decoder/Decoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/Decoder.java rename to port_src/core/DONE/datamatrix/decoder/Decoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/Version.java b/port_src/core/DONE/datamatrix/decoder/Version.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/decoder/Version.java rename to port_src/core/DONE/datamatrix/decoder/Version.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/detector/Detector.java b/port_src/core/DONE/datamatrix/detector/Detector.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/detector/Detector.java rename to port_src/core/DONE/datamatrix/detector/Detector.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/ASCIIEncoder.java b/port_src/core/DONE/datamatrix/encoder/ASCIIEncoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/ASCIIEncoder.java rename to port_src/core/DONE/datamatrix/encoder/ASCIIEncoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/Base256Encoder.java b/port_src/core/DONE/datamatrix/encoder/Base256Encoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/Base256Encoder.java rename to port_src/core/DONE/datamatrix/encoder/Base256Encoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/C40Encoder.java b/port_src/core/DONE/datamatrix/encoder/C40Encoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/C40Encoder.java rename to port_src/core/DONE/datamatrix/encoder/C40Encoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/DataMatrixSymbolInfo144.java b/port_src/core/DONE/datamatrix/encoder/DataMatrixSymbolInfo144.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/DataMatrixSymbolInfo144.java rename to port_src/core/DONE/datamatrix/encoder/DataMatrixSymbolInfo144.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/DefaultPlacement.java b/port_src/core/DONE/datamatrix/encoder/DefaultPlacement.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/DefaultPlacement.java rename to port_src/core/DONE/datamatrix/encoder/DefaultPlacement.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/EdifactEncoder.java b/port_src/core/DONE/datamatrix/encoder/EdifactEncoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/EdifactEncoder.java rename to port_src/core/DONE/datamatrix/encoder/EdifactEncoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/Encoder.java b/port_src/core/DONE/datamatrix/encoder/Encoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/Encoder.java rename to port_src/core/DONE/datamatrix/encoder/Encoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/EncoderContext.java b/port_src/core/DONE/datamatrix/encoder/EncoderContext.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/EncoderContext.java rename to port_src/core/DONE/datamatrix/encoder/EncoderContext.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/ErrorCorrection.java b/port_src/core/DONE/datamatrix/encoder/ErrorCorrection.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/ErrorCorrection.java rename to port_src/core/DONE/datamatrix/encoder/ErrorCorrection.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/HighLevelEncoder.java b/port_src/core/DONE/datamatrix/encoder/HighLevelEncoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/HighLevelEncoder.java rename to port_src/core/DONE/datamatrix/encoder/HighLevelEncoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/MinimalEncoder.java b/port_src/core/DONE/datamatrix/encoder/MinimalEncoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/MinimalEncoder.java rename to port_src/core/DONE/datamatrix/encoder/MinimalEncoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/SymbolInfo.java b/port_src/core/DONE/datamatrix/encoder/SymbolInfo.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/SymbolInfo.java rename to port_src/core/DONE/datamatrix/encoder/SymbolInfo.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/SymbolShapeHint.java b/port_src/core/DONE/datamatrix/encoder/SymbolShapeHint.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/SymbolShapeHint.java rename to port_src/core/DONE/datamatrix/encoder/SymbolShapeHint.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/TextEncoder.java b/port_src/core/DONE/datamatrix/encoder/TextEncoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/TextEncoder.java rename to port_src/core/DONE/datamatrix/encoder/TextEncoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/X12Encoder.java b/port_src/core/DONE/datamatrix/encoder/X12Encoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/datamatrix/encoder/X12Encoder.java rename to port_src/core/DONE/datamatrix/encoder/X12Encoder.java diff --git a/port_src/output/zxing/datamatrix/data_matrix_reader.rs b/port_src/output/zxing/datamatrix/data_matrix_reader.rs deleted file mode 100644 index 2dc76ee..0000000 --- a/port_src/output/zxing/datamatrix/data_matrix_reader.rs +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2007 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix; - -/** - * This implementation can detect and decode Data Matrix codes in an image. - * - * @author bbrown@google.com (Brian Brown) - */ - - const NO_POINTS: [Option; 0] = [None; 0]; -#[derive(Reader)] -pub struct DataMatrixReader { - - let decoder: Decoder = Decoder::new(); -} - -impl DataMatrixReader { - - /** - * 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 - * @throws ChecksumException if error correction fails - */ - pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { - return Ok(self.decode(image, null)); - } - - pub fn decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { - let decoder_result: DecoderResult; - let mut points: Vec; - if hints != null && hints.contains_key(DecodeHintType::PURE_BARCODE) { - let bits: BitMatrix = ::extract_pure_bits(&image.get_black_matrix()); - decoder_result = self.decoder.decode(bits); - points = NO_POINTS; - } else { - let detector_result: DetectorResult = Detector::new(&image.get_black_matrix()).detect(); - decoder_result = self.decoder.decode(&detector_result.get_bits()); - points = detector_result.get_points(); - } - let result: Result = Result::new(&decoder_result.get_text(), &decoder_result.get_raw_bytes(), points, BarcodeFormat::DATA_MATRIX); - 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(); - if ec_level != null { - result.put_metadata(ResultMetadataType::ERROR_CORRECTION_LEVEL, &ec_level); - } - result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]d{}", decoder_result.get_symbology_modifier())); - return Ok(result); - } - - pub fn reset(&self) { - // do nothing - } - - /** - * This method detects a code in a "pure" image -- that is, pure monochrome image - * which contains only an unrotated, unskewed, image of a code, with some white border - * around it. This is a specialized method that works exceptionally fast in this special - * case. - */ - fn extract_pure_bits( image: &BitMatrix) -> /* throws NotFoundException */Result> { - let left_top_black: Vec = image.get_top_left_on_bit(); - let right_bottom_black: Vec = image.get_bottom_right_on_bit(); - if left_top_black == null || right_bottom_black == null { - throw NotFoundException::get_not_found_instance(); - } - let module_size: i32 = self.module_size(&left_top_black, image); - let mut top: i32 = left_top_black[1]; - let bottom: i32 = right_bottom_black[1]; - let mut left: i32 = left_top_black[0]; - let right: i32 = right_bottom_black[0]; - let matrix_width: i32 = (right - left + 1) / module_size; - let matrix_height: i32 = (bottom - top + 1) / module_size; - if matrix_width <= 0 || matrix_height <= 0 { - throw NotFoundException::get_not_found_instance(); - } - // Push in the "border" by half the module width so that we start - // sampling in the middle of the module. Just in case the image is a - // little off, this will help recover. - let nudge: i32 = module_size / 2; - top += nudge; - left += nudge; - // Now just read off the bits - let bits: BitMatrix = BitMatrix::new(matrix_width, matrix_height); - { - let mut y: i32 = 0; - while y < matrix_height { - { - let i_offset: i32 = top + y * module_size; - { - let mut x: i32 = 0; - while x < matrix_width { - { - if image.get(left + x * module_size, i_offset) { - bits.set(x, y); - } - } - x += 1; - } - } - - } - y += 1; - } - } - - return Ok(bits); - } - - fn module_size( left_top_black: &Vec, image: &BitMatrix) -> /* throws NotFoundException */Result> { - let width: i32 = image.get_width(); - let mut x: i32 = left_top_black[0]; - let y: i32 = left_top_black[1]; - while x < width && image.get(x, y) { - x += 1; - } - if x == width { - throw NotFoundException::get_not_found_instance(); - } - let module_size: i32 = x - left_top_black[0]; - if module_size == 0 { - throw NotFoundException::get_not_found_instance(); - } - return Ok(module_size); - } -} - diff --git a/port_src/output/zxing/datamatrix/data_matrix_writer.rs b/port_src/output/zxing/datamatrix/data_matrix_writer.rs deleted file mode 100644 index 7a40b62..0000000 --- a/port_src/output/zxing/datamatrix/data_matrix_writer.rs +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2008 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix; - -/** - * This object renders a Data Matrix code as a BitMatrix 2D array of greyscale values. - * - * @author dswitkin@google.com (Daniel Switkin) - * @author Guillaume Le Biller Added to zxing lib. - */ -#[derive(Writer)] -pub struct DataMatrixWriter { -} - -impl DataMatrixWriter { - - pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32) -> BitMatrix { - return self.encode(&contents, format, width, height, null); - } - - pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32, hints: &Map) -> BitMatrix { - if contents.is_empty() { - throw IllegalArgumentException::new("Found empty contents"); - } - if format != BarcodeFormat::DATA_MATRIX { - throw IllegalArgumentException::new(format!("Can only encode DATA_MATRIX, but got {}", format)); - } - if width < 0 || height < 0 { - throw IllegalArgumentException::new(format!("Requested dimensions can't be negative: {}x{}", width, height)); - } - // Try to get force shape & min / max size - let mut shape: SymbolShapeHint = SymbolShapeHint::FORCE_NONE; - let min_size: Dimension = null; - let max_size: Dimension = null; - if hints != null { - let requested_shape: SymbolShapeHint = hints.get(EncodeHintType::DATA_MATRIX_SHAPE) as SymbolShapeHint; - if requested_shape != null { - shape = requested_shape; - } - let requested_min_size: Dimension = hints.get(EncodeHintType::MIN_SIZE) as Dimension; - if requested_min_size != null { - min_size = requested_min_size; - } - let requested_max_size: Dimension = hints.get(EncodeHintType::MAX_SIZE) as Dimension; - if requested_max_size != null { - max_size = requested_max_size; - } - } - //1. step: Data encodation - let mut encoded: String; - let has_compaction_hint: bool = hints != null && hints.contains_key(EncodeHintType::DATA_MATRIX_COMPACT) && Boolean::parse_boolean(&hints.get(EncodeHintType::DATA_MATRIX_COMPACT).to_string()); - if has_compaction_hint { - let has_g_s1_format_hint: bool = hints.contains_key(EncodeHintType::GS1_FORMAT) && Boolean::parse_boolean(&hints.get(EncodeHintType::GS1_FORMAT).to_string()); - let mut charset: Charset = null; - let has_encoding_hint: bool = hints.contains_key(EncodeHintType::CHARACTER_SET); - if has_encoding_hint { - charset = Charset::for_name(&hints.get(EncodeHintType::CHARACTER_SET).to_string()); - } - encoded = MinimalEncoder::encode_high_level(&contents, &charset, if has_g_s1_format_hint { 0x1D } else { -1 }, shape); - } else { - let has_force_c40_hint: bool = hints != null && hints.contains_key(EncodeHintType::FORCE_C40) && Boolean::parse_boolean(&hints.get(EncodeHintType::FORCE_C40).to_string()); - encoded = HighLevelEncoder::encode_high_level(&contents, shape, min_size, max_size, has_force_c40_hint); - } - let symbol_info: SymbolInfo = SymbolInfo::lookup(&encoded.length(), shape, min_size, max_size, true); - //2. step: ECC generation - let codewords: String = ErrorCorrection::encode_e_c_c200(&encoded, symbol_info); - //3. step: Module placement in Matrix - let placement: DefaultPlacement = DefaultPlacement::new(&codewords, &symbol_info.get_symbol_data_width(), &symbol_info.get_symbol_data_height()); - placement.place(); - //4. step: low-level encoding - return ::encode_low_level(placement, symbol_info, width, height); - } - - /** - * Encode the given symbol info to a bit matrix. - * - * @param placement The DataMatrix placement. - * @param symbolInfo The symbol info to encode. - * @return The bit matrix generated. - */ - fn encode_low_level( placement: &DefaultPlacement, symbol_info: &SymbolInfo, width: i32, height: i32) -> BitMatrix { - let symbol_width: i32 = symbol_info.get_symbol_data_width(); - let symbol_height: i32 = symbol_info.get_symbol_data_height(); - let matrix: ByteMatrix = ByteMatrix::new(&symbol_info.get_symbol_width(), &symbol_info.get_symbol_height()); - let matrix_y: i32 = 0; - { - let mut y: i32 = 0; - while y < symbol_height { - { - // Fill the top edge with alternate 0 / 1 - let matrix_x: i32; - if (y % symbol_info.matrixHeight) == 0 { - matrix_x = 0; - { - let mut x: i32 = 0; - while x < symbol_info.get_symbol_width() { - { - matrix.set(matrix_x, matrix_y, (x % 2) == 0); - matrix_x += 1; - } - x += 1; - } - } - - matrix_y += 1; - } - matrix_x = 0; - { - let mut x: i32 = 0; - while x < symbol_width { - { - // Fill the right edge with full 1 - if (x % symbol_info.matrixWidth) == 0 { - matrix.set(matrix_x, matrix_y, true); - matrix_x += 1; - } - matrix.set(matrix_x, matrix_y, &placement.get_bit(x, y)); - matrix_x += 1; - // Fill the right edge with alternate 0 / 1 - if (x % symbol_info.matrixWidth) == symbol_info.matrixWidth - 1 { - matrix.set(matrix_x, matrix_y, (y % 2) == 0); - matrix_x += 1; - } - } - x += 1; - } - } - - matrix_y += 1; - // Fill the bottom edge with full 1 - if (y % symbol_info.matrixHeight) == symbol_info.matrixHeight - 1 { - matrix_x = 0; - { - let mut x: i32 = 0; - while x < symbol_info.get_symbol_width() { - { - matrix.set(matrix_x, matrix_y, true); - matrix_x += 1; - } - x += 1; - } - } - - matrix_y += 1; - } - } - y += 1; - } - } - - return ::convert_byte_matrix_to_bit_matrix(matrix, width, height); - } - - /** - * Convert the ByteMatrix to BitMatrix. - * - * @param reqHeight The requested height of the image (in pixels) with the Datamatrix code - * @param reqWidth The requested width of the image (in pixels) with the Datamatrix code - * @param matrix The input matrix. - * @return The output matrix. - */ - fn convert_byte_matrix_to_bit_matrix( matrix: &ByteMatrix, req_width: i32, req_height: i32) -> BitMatrix { - let matrix_width: i32 = matrix.get_width(); - let matrix_height: i32 = matrix.get_height(); - let output_width: i32 = Math::max(req_width, matrix_width); - let output_height: i32 = Math::max(req_height, matrix_height); - let multiple: i32 = Math::min(output_width / matrix_width, output_height / matrix_height); - let left_padding: i32 = (output_width - (matrix_width * multiple)) / 2; - let top_padding: i32 = (output_height - (matrix_height * multiple)) / 2; - let mut output: BitMatrix; - // remove padding if requested width and height are too small - if req_height < matrix_height || req_width < matrix_width { - left_padding = 0; - top_padding = 0; - output = BitMatrix::new(matrix_width, matrix_height); - } else { - output = BitMatrix::new(req_width, req_height); - } - output.clear(); - { - let input_y: i32 = 0, let output_y: i32 = top_padding; - while input_y < matrix_height { - { - // Write the contents of this row of the bytematrix - { - let input_x: i32 = 0, let output_x: i32 = left_padding; - while input_x < matrix_width { - { - if matrix.get(input_x, input_y) == 1 { - output.set_region(output_x, output_y, multiple, multiple); - } - } - input_x += 1; - output_x += multiple; - } - } - - } - input_y += 1; - output_y += multiple; - } - } - - return output; - } -} - diff --git a/port_src/output/zxing/datamatrix/decoder/bit_matrix_parser.rs b/port_src/output/zxing/datamatrix/decoder/bit_matrix_parser.rs deleted file mode 100644 index 044209e..0000000 --- a/port_src/output/zxing/datamatrix/decoder/bit_matrix_parser.rs +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright 2007 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::decoder; - -/** - * @author bbrown@google.com (Brian Brown) - */ -struct BitMatrixParser { - - let mapping_bit_matrix: BitMatrix; - - let read_mapping_matrix: BitMatrix; - - let mut version: Version; -} - -impl BitMatrixParser { - - /** - * @param bitMatrix {@link BitMatrix} to parse - * @throws FormatException if dimension is < 8 or > 144 or not 0 mod 2 - */ - fn new( bit_matrix: &BitMatrix) -> BitMatrixParser throws FormatException { - let dimension: i32 = bit_matrix.get_height(); - if dimension < 8 || dimension > 144 || (dimension & 0x01) != 0 { - throw FormatException::get_format_instance(); - } - version = ::read_version(bit_matrix); - let .mappingBitMatrix = self.extract_data_region(bit_matrix); - let .readMappingMatrix = BitMatrix::new(&let .mappingBitMatrix.get_width(), &let .mappingBitMatrix.get_height()); - } - - fn get_version(&self) -> Version { - return self.version; - } - - /** - *

Creates the version object based on the dimension of the original bit matrix from - * the datamatrix code.

- * - *

See ISO 16022:2006 Table 7 - ECC 200 symbol attributes

- * - * @param bitMatrix Original {@link BitMatrix} including alignment patterns - * @return {@link Version} encapsulating the Data Matrix Code's "version" - * @throws FormatException if the dimensions of the mapping matrix are not valid - * Data Matrix dimensions. - */ - fn read_version( bit_matrix: &BitMatrix) -> /* throws FormatException */Result> { - let num_rows: i32 = bit_matrix.get_height(); - let num_columns: i32 = bit_matrix.get_width(); - return Ok(Version::get_version_for_dimensions(num_rows, num_columns)); - } - - /** - *

Reads the bits in the {@link BitMatrix} representing the mapping matrix (No alignment patterns) - * in the correct order in order to reconstitute the codewords bytes contained within the - * Data Matrix Code.

- * - * @return bytes encoded within the Data Matrix Code - * @throws FormatException if the exact number of bytes expected is not read - */ - fn read_codewords(&self) -> /* throws FormatException */Result, Rc> { - let mut result: [i8; self.version.get_total_codewords()] = [0; self.version.get_total_codewords()]; - let result_offset: i32 = 0; - let mut row: i32 = 4; - let mut column: i32 = 0; - let num_rows: i32 = self.mapping_bit_matrix.get_height(); - let num_columns: i32 = self.mapping_bit_matrix.get_width(); - let corner1_read: bool = false; - let corner2_read: bool = false; - let corner3_read: bool = false; - let corner4_read: bool = false; - // Read all of the codewords - loop { { - // Check the four corner cases - if (row == num_rows) && (column == 0) && !corner1_read { - result[result_offset += 1 !!!check!!! post increment] = self.read_corner1(num_rows, num_columns) as i8; - row -= 2; - column += 2; - corner1_read = true; - } else if (row == num_rows - 2) && (column == 0) && ((num_columns & 0x03) != 0) && !corner2_read { - result[result_offset += 1 !!!check!!! post increment] = self.read_corner2(num_rows, num_columns) as i8; - row -= 2; - column += 2; - corner2_read = true; - } else if (row == num_rows + 4) && (column == 2) && ((num_columns & 0x07) == 0) && !corner3_read { - result[result_offset += 1 !!!check!!! post increment] = self.read_corner3(num_rows, num_columns) as i8; - row -= 2; - column += 2; - corner3_read = true; - } else if (row == num_rows - 2) && (column == 0) && ((num_columns & 0x07) == 4) && !corner4_read { - result[result_offset += 1 !!!check!!! post increment] = self.read_corner4(num_rows, num_columns) as i8; - row -= 2; - column += 2; - corner4_read = true; - } else { - // Sweep upward diagonally to the right - loop { { - if (row < num_rows) && (column >= 0) && !self.read_mapping_matrix.get(column, row) { - result[result_offset += 1 !!!check!!! post increment] = self.read_utah(row, column, num_rows, num_columns) as i8; - } - row -= 2; - column += 2; - }if !((row >= 0) && (column < num_columns)) break;} - row += 1; - column += 3; - // Sweep downward diagonally to the left - loop { { - if (row >= 0) && (column < num_columns) && !self.read_mapping_matrix.get(column, row) { - result[result_offset += 1 !!!check!!! post increment] = self.read_utah(row, column, num_rows, num_columns) as i8; - } - row += 2; - column -= 2; - }if !((row < num_rows) && (column >= 0)) break;} - row += 3; - column += 1; - } - }if !((row < num_rows) || (column < num_columns)) break;} - if result_offset != self.version.get_total_codewords() { - throw FormatException::get_format_instance(); - } - return Ok(result); - } - - /** - *

Reads a bit of the mapping matrix accounting for boundary wrapping.

- * - * @param row Row to read in the mapping matrix - * @param column Column to read in the mapping matrix - * @param numRows Number of rows in the mapping matrix - * @param numColumns Number of columns in the mapping matrix - * @return value of the given bit in the mapping matrix - */ - fn read_module(&self, row: i32, column: i32, num_rows: i32, num_columns: i32) -> bool { - // Adjust the row and column indices based on boundary wrapping - if row < 0 { - row += num_rows; - column += 4 - ((num_rows + 4) & 0x07); - } - if column < 0 { - column += num_columns; - row += 4 - ((num_columns + 4) & 0x07); - } - if row >= num_rows { - row -= num_rows; - } - self.read_mapping_matrix.set(column, row); - return self.mapping_bit_matrix.get(column, row); - } - - /** - *

Reads the 8 bits of the standard Utah-shaped pattern.

- * - *

See ISO 16022:2006, 5.8.1 Figure 6

- * - * @param row Current row in the mapping matrix, anchored at the 8th bit (LSB) of the pattern - * @param column Current column in the mapping matrix, anchored at the 8th bit (LSB) of the pattern - * @param numRows Number of rows in the mapping matrix - * @param numColumns Number of columns in the mapping matrix - * @return byte from the utah shape - */ - fn read_utah(&self, row: i32, column: i32, num_rows: i32, num_columns: i32) -> i32 { - let current_byte: i32 = 0; - if self.read_module(row - 2, column - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(row - 2, column - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(row - 1, column - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(row - 1, column - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(row - 1, column, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(row, column - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(row, column - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(row, column, num_rows, num_columns) { - current_byte |= 1; - } - return current_byte; - } - - /** - *

Reads the 8 bits of the special corner condition 1.

- * - *

See ISO 16022:2006, Figure F.3

- * - * @param numRows Number of rows in the mapping matrix - * @param numColumns Number of columns in the mapping matrix - * @return byte from the Corner condition 1 - */ - fn read_corner1(&self, num_rows: i32, num_columns: i32) -> i32 { - let current_byte: i32 = 0; - if self.read_module(num_rows - 1, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(num_rows - 1, 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(num_rows - 1, 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(1, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(2, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(3, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - return current_byte; - } - - /** - *

Reads the 8 bits of the special corner condition 2.

- * - *

See ISO 16022:2006, Figure F.4

- * - * @param numRows Number of rows in the mapping matrix - * @param numColumns Number of columns in the mapping matrix - * @return byte from the Corner condition 2 - */ - fn read_corner2(&self, num_rows: i32, num_columns: i32) -> i32 { - let current_byte: i32 = 0; - if self.read_module(num_rows - 3, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(num_rows - 2, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(num_rows - 1, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 4, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 3, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(1, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - return current_byte; - } - - /** - *

Reads the 8 bits of the special corner condition 3.

- * - *

See ISO 16022:2006, Figure F.5

- * - * @param numRows Number of rows in the mapping matrix - * @param numColumns Number of columns in the mapping matrix - * @return byte from the Corner condition 3 - */ - fn read_corner3(&self, num_rows: i32, num_columns: i32) -> i32 { - let current_byte: i32 = 0; - if self.read_module(num_rows - 1, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(num_rows - 1, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 3, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(1, num_columns - 3, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(1, num_columns - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(1, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - return current_byte; - } - - /** - *

Reads the 8 bits of the special corner condition 4.

- * - *

See ISO 16022:2006, Figure F.6

- * - * @param numRows Number of rows in the mapping matrix - * @param numColumns Number of columns in the mapping matrix - * @return byte from the Corner condition 4 - */ - fn read_corner4(&self, num_rows: i32, num_columns: i32) -> i32 { - let current_byte: i32 = 0; - if self.read_module(num_rows - 3, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(num_rows - 2, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(num_rows - 1, 0, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 2, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(0, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(1, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(2, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - current_byte <<= 1; - if self.read_module(3, num_columns - 1, num_rows, num_columns) { - current_byte |= 1; - } - return current_byte; - } - - /** - *

Extracts the data region from a {@link BitMatrix} that contains - * alignment patterns.

- * - * @param bitMatrix Original {@link BitMatrix} with alignment patterns - * @return BitMatrix that has the alignment patterns removed - */ - fn extract_data_region(&self, bit_matrix: &BitMatrix) -> BitMatrix { - let symbol_size_rows: i32 = self.version.get_symbol_size_rows(); - let symbol_size_columns: i32 = self.version.get_symbol_size_columns(); - if bit_matrix.get_height() != symbol_size_rows { - throw IllegalArgumentException::new("Dimension of bitMatrix must match the version size"); - } - let data_region_size_rows: i32 = self.version.get_data_region_size_rows(); - let data_region_size_columns: i32 = self.version.get_data_region_size_columns(); - let num_data_regions_row: i32 = symbol_size_rows / data_region_size_rows; - let num_data_regions_column: i32 = symbol_size_columns / data_region_size_columns; - let size_data_region_row: i32 = num_data_regions_row * data_region_size_rows; - let size_data_region_column: i32 = num_data_regions_column * data_region_size_columns; - let bit_matrix_without_alignment: BitMatrix = BitMatrix::new(size_data_region_column, size_data_region_row); - { - let data_region_row: i32 = 0; - while data_region_row < num_data_regions_row { - { - let data_region_row_offset: i32 = data_region_row * data_region_size_rows; - { - let data_region_column: i32 = 0; - while data_region_column < num_data_regions_column { - { - let data_region_column_offset: i32 = data_region_column * data_region_size_columns; - { - let mut i: i32 = 0; - while i < data_region_size_rows { - { - let read_row_offset: i32 = data_region_row * (data_region_size_rows + 2) + 1 + i; - let write_row_offset: i32 = data_region_row_offset + i; - { - let mut j: i32 = 0; - while j < data_region_size_columns { - { - let read_column_offset: i32 = data_region_column * (data_region_size_columns + 2) + 1 + j; - if bit_matrix.get(read_column_offset, read_row_offset) { - let write_column_offset: i32 = data_region_column_offset + j; - bit_matrix_without_alignment.set(write_column_offset, write_row_offset); - } - } - j += 1; - } - } - - } - i += 1; - } - } - - } - data_region_column += 1; - } - } - - } - data_region_row += 1; - } - } - - return bit_matrix_without_alignment; - } -} - diff --git a/port_src/output/zxing/datamatrix/decoder/data_block.rs b/port_src/output/zxing/datamatrix/decoder/data_block.rs deleted file mode 100644 index b4c2e64..0000000 --- a/port_src/output/zxing/datamatrix/decoder/data_block.rs +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2008 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::decoder; - -/** - *

Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into - * multiple blocks, each of which is a unit of data and error-correction codewords. Each - * is represented by an instance of this class.

- * - * @author bbrown@google.com (Brian Brown) - */ -struct DataBlock { - - let num_data_codewords: i32; - - let mut codewords: Vec; -} - -impl DataBlock { - - fn new( num_data_codewords: i32, codewords: &Vec) -> DataBlock { - let .numDataCodewords = num_data_codewords; - let .codewords = codewords; - } - - /** - *

When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them. - * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This - * method will separate the data into original blocks.

- * - * @param rawCodewords bytes as read directly from the Data Matrix Code - * @param version version of the Data Matrix Code - * @return DataBlocks containing original bytes, "de-interleaved" from representation in the - * Data Matrix Code - */ - fn get_data_blocks( raw_codewords: &Vec, version: &Version) -> Vec { - // Figure out the number and size of data blocks used by this version - let ec_blocks: Version.ECBlocks = version.get_e_c_blocks(); - // First count the total number of data blocks - let total_blocks: i32 = 0; - let ec_block_array: Vec = ec_blocks.get_e_c_blocks(); - for let ec_block: Version.ECB in ec_block_array { - total_blocks += ec_block.get_count(); - } - // Now establish DataBlocks of the appropriate size and number of data codewords - let mut result: [Option; total_blocks] = [None; total_blocks]; - let num_result_blocks: i32 = 0; - for let ec_block: Version.ECB in ec_block_array { - { - let mut i: i32 = 0; - while i < ec_block.get_count() { - { - let num_data_codewords: i32 = ec_block.get_data_codewords(); - let num_block_codewords: i32 = ec_blocks.get_e_c_codewords() + num_data_codewords; - result[num_result_blocks += 1 !!!check!!! post increment] = DataBlock::new(num_data_codewords, : [i8; num_block_codewords] = [0; num_block_codewords]); - } - i += 1; - } - } - - } - // All blocks have the same amount of data, except that the last n - // (where n may be 0) have 1 less byte. Figure out where these start. - // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144 - let longer_blocks_total_codewords: i32 = result[0].codewords.len(); - //int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1; - let longer_blocks_num_data_codewords: i32 = longer_blocks_total_codewords - ec_blocks.get_e_c_codewords(); - let shorter_blocks_num_data_codewords: i32 = longer_blocks_num_data_codewords - 1; - // The last elements of result may be 1 element shorter for 144 matrix - // first fill out as many elements as all of them have minus 1 - let raw_codewords_offset: i32 = 0; - { - let mut i: i32 = 0; - while i < shorter_blocks_num_data_codewords { - { - { - let mut j: i32 = 0; - while j < num_result_blocks { - { - result[j].codewords[i] = raw_codewords[raw_codewords_offset += 1 !!!check!!! post increment]; - } - j += 1; - } - } - - } - i += 1; - } - } - - // Fill out the last data block in the longer ones - let special_version: bool = version.get_version_number() == 24; - let num_longer_blocks: i32 = if special_version { 8 } else { num_result_blocks }; - { - let mut j: i32 = 0; - while j < num_longer_blocks { - { - result[j].codewords[longer_blocks_num_data_codewords - 1] = raw_codewords[raw_codewords_offset += 1 !!!check!!! post increment]; - } - j += 1; - } - } - - // Now add in error correction blocks - let max: i32 = result[0].codewords.len(); - { - let mut i: i32 = longer_blocks_num_data_codewords; - while i < max { - { - { - let mut j: i32 = 0; - while j < num_result_blocks { - { - let j_offset: i32 = if special_version { (j + 8) % num_result_blocks } else { j }; - let i_offset: i32 = if special_version && j_offset > 7 { i - 1 } else { i }; - result[j_offset].codewords[i_offset] = raw_codewords[raw_codewords_offset += 1 !!!check!!! post increment]; - } - j += 1; - } - } - - } - i += 1; - } - } - - if raw_codewords_offset != raw_codewords.len() { - throw IllegalArgumentException::new(); - } - return result; - } - - fn get_num_data_codewords(&self) -> i32 { - return self.num_data_codewords; - } - - fn get_codewords(&self) -> Vec { - return self.codewords; - } -} - diff --git a/port_src/output/zxing/datamatrix/decoder/decoded_bit_stream_parser.rs b/port_src/output/zxing/datamatrix/decoder/decoded_bit_stream_parser.rs deleted file mode 100644 index bbfb101..0000000 --- a/port_src/output/zxing/datamatrix/decoder/decoded_bit_stream_parser.rs +++ /dev/null @@ -1,679 +0,0 @@ -/* - * Copyright 2008 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::decoder; - -/** - *

Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes - * in one Data Matrix Code. This class decodes the bits back into text.

- * - *

See ISO 16022:2006, 5.2.1 - 5.2.9.2

- * - * @author bbrown@google.com (Brian Brown) - * @author Sean Owen - */ - -/** - * See ISO 16022:2006, Annex C Table C.1 - * The C40 Basic Character Set (*'s used for placeholders for the shift values) - */ - const C40_BASIC_SET_CHARS: vec![Vec; 40] = vec!['*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', ] -; - - const C40_SHIFT2_SET_CHARS: vec![Vec; 27] = vec!['!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', ] -; - - const TEXT_BASIC_SET_CHARS: vec![Vec; 40] = vec!['*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', ] -; - -// Shift 2 for Text is the same encoding as C40 - const TEXT_SHIFT2_SET_CHARS: Vec = C40_SHIFT2_SET_CHARS; - - const TEXT_SHIFT3_SET_CHARS: vec![Vec; 32] = vec!['`', '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', '{', '|', '}', '~', 127 as char, ] -; -struct DecodedBitStreamParser { -} - -impl DecodedBitStreamParser { - - enum Mode { - - // Not really a mode - PAD_ENCODE(), ASCII_ENCODE(), C40_ENCODE(), TEXT_ENCODE(), ANSIX12_ENCODE(), EDIFACT_ENCODE(), BASE256_ENCODE(), ECI_ENCODE() - } - - fn new() -> DecodedBitStreamParser { - } - - fn decode( bytes: &Vec) -> /* throws FormatException */Result> { - let bits: BitSource = BitSource::new(&bytes); - let result: ECIStringBuilder = ECIStringBuilder::new(100); - let result_trailer: StringBuilder = StringBuilder::new(0); - let byte_segments: List> = ArrayList<>::new(1); - let mut mode: Mode = Mode::ASCII_ENCODE; - // Could look directly at 'bytes', if we're sure of not having to account for multi byte values - let fnc1_positions: Set = HashSet<>::new(); - let symbology_modifier: i32; - let is_e_c_iencoded: bool = false; - loop { { - if mode == Mode::ASCII_ENCODE { - mode = ::decode_ascii_segment(bits, result, &result_trailer, &fnc1_positions); - } else { - match mode { - C40_ENCODE => - { - ::decode_c40_segment(bits, result, &fnc1_positions); - break; - } - TEXT_ENCODE => - { - ::decode_text_segment(bits, result, &fnc1_positions); - break; - } - ANSIX12_ENCODE => - { - ::decode_ansi_x12_segment(bits, result); - break; - } - EDIFACT_ENCODE => - { - ::decode_edifact_segment(bits, result); - break; - } - BASE256_ENCODE => - { - ::decode_base256_segment(bits, result, &byte_segments); - break; - } - ECI_ENCODE => - { - ::decode_e_c_i_segment(bits, result); - // ECI detection only, atm continue decoding as ASCII - is_e_c_iencoded = true; - break; - } - _ => - { - throw FormatException::get_format_instance(); - } - } - mode = Mode::ASCII_ENCODE; - } - }if !(mode != Mode::PAD_ENCODE && bits.available() > 0) break;} - if result_trailer.length() > 0 { - result.append_characters(&result_trailer); - } - if is_e_c_iencoded { - // https://honeywellaidc.force.com/supportppr/s/article/List-of-barcode-symbology-AIM-Identifiers - if fnc1_positions.contains(0) || fnc1_positions.contains(4) { - symbology_modifier = 5; - } else if fnc1_positions.contains(1) || fnc1_positions.contains(5) { - symbology_modifier = 6; - } else { - symbology_modifier = 4; - } - } else { - if fnc1_positions.contains(0) || fnc1_positions.contains(4) { - symbology_modifier = 2; - } else if fnc1_positions.contains(1) || fnc1_positions.contains(5) { - symbology_modifier = 3; - } else { - symbology_modifier = 1; - } - } - return Ok(DecoderResult::new(&bytes, &result.to_string(), if byte_segments.is_empty() { null } else { byte_segments }, null, symbology_modifier)); - } - - /** - * See ISO 16022:2006, 5.2.3 and Annex C, Table C.2 - */ - fn decode_ascii_segment( bits: &BitSource, result: &ECIStringBuilder, result_trailer: &StringBuilder, fnc1positions: &Set) -> /* throws FormatException */Result> { - let upper_shift: bool = false; - loop { { - let one_byte: i32 = bits.read_bits(8); - if one_byte == 0 { - throw FormatException::get_format_instance(); - } else if one_byte <= 128 { - // ASCII data (ASCII value + 1) - if upper_shift { - one_byte += 128; - //upperShift = false; - } - result.append((one_byte - 1) as char); - return Ok(Mode::ASCII_ENCODE); - } else if one_byte == 129 { - // Pad - return Ok(Mode::PAD_ENCODE); - } else if one_byte <= 229 { - // 2-digit data 00-99 (Numeric Value + 130) - let value: i32 = one_byte - 130; - if value < 10 { - // pad with '0' for single digit values - result.append('0'); - } - result.append(value); - } else { - match one_byte { - // Latch to C40 encodation - 230 => - { - return Ok(Mode::C40_ENCODE); - } - // Latch to Base 256 encodation - 231 => - { - return Ok(Mode::BASE256_ENCODE); - } - // FNC1 - 232 => - { - fnc1positions.add(&result.length()); - // translate as ASCII 29 - result.append(29 as char); - break; - } - // Structured Append - 233 => - { - } - // Reader Programming - 234 => - { - //throw ReaderException.getInstance(); - break; - } - // Upper Shift (shift to Extended ASCII) - 235 => - { - upper_shift = true; - break; - } - // 05 Macro - 236 => - { - result.append("[)>05"); - result_trailer.insert(0, ""); - break; - } - // 06 Macro - 237 => - { - result.append("[)>06"); - result_trailer.insert(0, ""); - break; - } - // Latch to ANSI X12 encodation - 238 => - { - return Ok(Mode::ANSIX12_ENCODE); - } - // Latch to Text encodation - 239 => - { - return Ok(Mode::TEXT_ENCODE); - } - // Latch to EDIFACT encodation - 240 => - { - return Ok(Mode::EDIFACT_ENCODE); - } - // ECI Character - 241 => - { - return Ok(Mode::ECI_ENCODE); - } - _ => - { - // but work around encoders that end with 254, latch back to ASCII - if one_byte != 254 || bits.available() != 0 { - throw FormatException::get_format_instance(); - } - break; - } - } - } - }if !(bits.available() > 0) break;} - return Ok(Mode::ASCII_ENCODE); - } - - /** - * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1 - */ - fn decode_c40_segment( bits: &BitSource, result: &ECIStringBuilder, fnc1positions: &Set) -> /* throws FormatException */Result> { - // Three C40 values are encoded in a 16-bit value as - // (1600 * C1) + (40 * C2) + C3 + 1 - // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time - let upper_shift: bool = false; - let c_values: [i32; 3] = [0; 3]; - let mut shift: i32 = 0; - loop { { - // If there is only one byte left then it will be encoded as ASCII - if bits.available() == 8 { - return; - } - let first_byte: i32 = bits.read_bits(8); - if first_byte == 254 { - // Unlatch codeword - return; - } - ::parse_two_bytes(first_byte, &bits.read_bits(8), &c_values); - { - let mut i: i32 = 0; - while i < 3 { - { - let c_value: i32 = c_values[i]; - match shift { - 0 => - { - if c_value < 3 { - shift = c_value + 1; - } else if c_value < C40_BASIC_SET_CHARS.len() { - let c40char: char = C40_BASIC_SET_CHARS[c_value]; - if upper_shift { - result.append((c40char + 128) as char); - upper_shift = false; - } else { - result.append(c40char); - } - } else { - throw FormatException::get_format_instance(); - } - break; - } - 1 => - { - if upper_shift { - result.append((c_value + 128) as char); - upper_shift = false; - } else { - result.append(c_value as char); - } - shift = 0; - break; - } - 2 => - { - if c_value < C40_SHIFT2_SET_CHARS.len() { - let c40char: char = C40_SHIFT2_SET_CHARS[c_value]; - if upper_shift { - result.append((c40char + 128) as char); - upper_shift = false; - } else { - result.append(c40char); - } - } else { - match c_value { - // FNC1 - 27 => - { - fnc1positions.add(&result.length()); - // translate as ASCII 29 - result.append(29 as char); - break; - } - // Upper Shift - 30 => - { - upper_shift = true; - break; - } - _ => - { - throw FormatException::get_format_instance(); - } - } - } - shift = 0; - break; - } - 3 => - { - if upper_shift { - result.append((c_value + 224) as char); - upper_shift = false; - } else { - result.append((c_value + 96) as char); - } - shift = 0; - break; - } - _ => - { - throw FormatException::get_format_instance(); - } - } - } - i += 1; - } - } - - }if !(bits.available() > 0) break;} - } - - /** - * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2 - */ - fn decode_text_segment( bits: &BitSource, result: &ECIStringBuilder, fnc1positions: &Set) -> /* throws FormatException */Result> { - // Three Text values are encoded in a 16-bit value as - // (1600 * C1) + (40 * C2) + C3 + 1 - // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time - let upper_shift: bool = false; - let c_values: [i32; 3] = [0; 3]; - let mut shift: i32 = 0; - loop { { - // If there is only one byte left then it will be encoded as ASCII - if bits.available() == 8 { - return; - } - let first_byte: i32 = bits.read_bits(8); - if first_byte == 254 { - // Unlatch codeword - return; - } - ::parse_two_bytes(first_byte, &bits.read_bits(8), &c_values); - { - let mut i: i32 = 0; - while i < 3 { - { - let c_value: i32 = c_values[i]; - match shift { - 0 => - { - if c_value < 3 { - shift = c_value + 1; - } else if c_value < TEXT_BASIC_SET_CHARS.len() { - let text_char: char = TEXT_BASIC_SET_CHARS[c_value]; - if upper_shift { - result.append((text_char + 128) as char); - upper_shift = false; - } else { - result.append(text_char); - } - } else { - throw FormatException::get_format_instance(); - } - break; - } - 1 => - { - if upper_shift { - result.append((c_value + 128) as char); - upper_shift = false; - } else { - result.append(c_value as char); - } - shift = 0; - break; - } - 2 => - { - // Shift 2 for Text is the same encoding as C40 - if c_value < TEXT_SHIFT2_SET_CHARS.len() { - let text_char: char = TEXT_SHIFT2_SET_CHARS[c_value]; - if upper_shift { - result.append((text_char + 128) as char); - upper_shift = false; - } else { - result.append(text_char); - } - } else { - match c_value { - // FNC1 - 27 => - { - fnc1positions.add(&result.length()); - // translate as ASCII 29 - result.append(29 as char); - break; - } - // Upper Shift - 30 => - { - upper_shift = true; - break; - } - _ => - { - throw FormatException::get_format_instance(); - } - } - } - shift = 0; - break; - } - 3 => - { - if c_value < TEXT_SHIFT3_SET_CHARS.len() { - let text_char: char = TEXT_SHIFT3_SET_CHARS[c_value]; - if upper_shift { - result.append((text_char + 128) as char); - upper_shift = false; - } else { - result.append(text_char); - } - shift = 0; - } else { - throw FormatException::get_format_instance(); - } - break; - } - _ => - { - throw FormatException::get_format_instance(); - } - } - } - i += 1; - } - } - - }if !(bits.available() > 0) break;} - } - - /** - * See ISO 16022:2006, 5.2.7 - */ - fn decode_ansi_x12_segment( bits: &BitSource, result: &ECIStringBuilder) -> /* throws FormatException */Result> { - // Three ANSI X12 values are encoded in a 16-bit value as - // (1600 * C1) + (40 * C2) + C3 + 1 - let c_values: [i32; 3] = [0; 3]; - loop { { - // If there is only one byte left then it will be encoded as ASCII - if bits.available() == 8 { - return; - } - let first_byte: i32 = bits.read_bits(8); - if first_byte == 254 { - // Unlatch codeword - return; - } - ::parse_two_bytes(first_byte, &bits.read_bits(8), &c_values); - { - let mut i: i32 = 0; - while i < 3 { - { - let c_value: i32 = c_values[i]; - match c_value { - // X12 segment terminator - 0 => - { - result.append('\r'); - break; - } - // X12 segment separator * - 1 => - { - result.append('*'); - break; - } - // X12 sub-element separator > - 2 => - { - result.append('>'); - break; - } - // space - 3 => - { - result.append(' '); - break; - } - _ => - { - if c_value < 14 { - // 0 - 9 - result.append((c_value + 44) as char); - } else if c_value < 40 { - // A - Z - result.append((c_value + 51) as char); - } else { - throw FormatException::get_format_instance(); - } - break; - } - } - } - i += 1; - } - } - - }if !(bits.available() > 0) break;} - } - - fn parse_two_bytes( first_byte: i32, second_byte: i32, result: &Vec) { - let full_bit_value: i32 = (first_byte << 8) + second_byte - 1; - let mut temp: i32 = full_bit_value / 1600; - result[0] = temp; - full_bit_value -= temp * 1600; - temp = full_bit_value / 40; - result[1] = temp; - result[2] = full_bit_value - temp * 40; - } - - /** - * See ISO 16022:2006, 5.2.8 and Annex C Table C.3 - */ - fn decode_edifact_segment( bits: &BitSource, result: &ECIStringBuilder) { - loop { { - // If there is only two or less bytes left then it will be encoded as ASCII - if bits.available() <= 16 { - return; - } - { - let mut i: i32 = 0; - while i < 4 { - { - let edifact_value: i32 = bits.read_bits(6); - // Check for the unlatch character - if edifact_value == 0x1F { - // 011111 - // Read rest of byte, which should be 0, and stop - let bits_left: i32 = 8 - bits.get_bit_offset(); - if bits_left != 8 { - bits.read_bits(bits_left); - } - return; - } - if (edifact_value & 0x20) == 0 { - // no 1 in the leading (6th) bit - // Add a leading 01 to the 6 bit binary value - edifact_value |= 0x40; - } - result.append(edifact_value as char); - } - i += 1; - } - } - - }if !(bits.available() > 0) break;} - } - - /** - * See ISO 16022:2006, 5.2.9 and Annex B, B.2 - */ - fn decode_base256_segment( bits: &BitSource, result: &ECIStringBuilder, byte_segments: &Collection>) -> /* throws FormatException */Result> { - // Figure out how long the Base 256 Segment is. - // position is 1-indexed - let codeword_position: i32 = 1 + bits.get_byte_offset(); - let d1: i32 = ::unrandomize255_state(&bits.read_bits(8), codeword_position += 1 !!!check!!! post increment); - let mut count: i32; - if d1 == 0 { - // Read the remainder of the symbol - count = bits.available() / 8; - } else if d1 < 250 { - count = d1; - } else { - count = 250 * (d1 - 249) + ::unrandomize255_state(&bits.read_bits(8), codeword_position += 1 !!!check!!! post increment); - } - // We're seeing NegativeArraySizeException errors from users. - if count < 0 { - throw FormatException::get_format_instance(); - } - let mut bytes: [i8; count] = [0; count]; - { - let mut i: i32 = 0; - while i < count { - { - // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2 - if bits.available() < 8 { - throw FormatException::get_format_instance(); - } - bytes[i] = ::unrandomize255_state(&bits.read_bits(8), codeword_position += 1 !!!check!!! post increment) as i8; - } - i += 1; - } - } - - byte_segments.add(&bytes); - result.append(String::new(&bytes, StandardCharsets::ISO_8859_1)); - } - - /** - * See ISO 16022:2007, 5.4.1 - */ - fn decode_e_c_i_segment( bits: &BitSource, result: &ECIStringBuilder) -> /* throws FormatException */Result> { - if bits.available() < 8 { - throw FormatException::get_format_instance(); - } - let c1: i32 = bits.read_bits(8); - if c1 <= 127 { - result.append_e_c_i(c1 - 1); - } - //currently we only support character set ECIs - /*} else { - if (bits.available() < 8) { - throw FormatException.getFormatInstance(); - } - int c2 = bits.readBits(8); - if (c1 >= 128 && c1 <= 191) { - } else { - if (bits.available() < 8) { - throw FormatException.getFormatInstance(); - } - int c3 = bits.readBits(8); - } - }*/ - } - - /** - * See ISO 16022:2006, Annex B, B.2 - */ - fn unrandomize255_state( randomized_base256_codeword: i32, base256_codeword_position: i32) -> i32 { - let pseudo_random_number: i32 = ((149 * base256_codeword_position) % 255) + 1; - let temp_variable: i32 = randomized_base256_codeword - pseudo_random_number; - return if temp_variable >= 0 { temp_variable } else { temp_variable + 256 }; - } -} - diff --git a/port_src/output/zxing/datamatrix/decoder/decoder.rs b/port_src/output/zxing/datamatrix/decoder/decoder.rs deleted file mode 100644 index 7b9d6cc..0000000 --- a/port_src/output/zxing/datamatrix/decoder/decoder.rs +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2007 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::decoder; - -/** - *

The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting - * the Data Matrix Code from an image.

- * - * @author bbrown@google.com (Brian Brown) - */ -pub struct Decoder { - - let rs_decoder: ReedSolomonDecoder; -} - -impl Decoder { - - pub fn new() -> Decoder { - rs_decoder = ReedSolomonDecoder::new(GenericGF::DATA_MATRIX_FIELD_256); - } - - /** - *

Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans. - * "true" is taken to mean a black module.

- * - * @param image booleans representing white/black Data Matrix Code modules - * @return text and bytes encoded within the Data Matrix Code - * @throws FormatException if the Data Matrix Code cannot be decoded - * @throws ChecksumException if error correction fails - */ - pub fn decode(&self, image: &Vec>) -> /* throws FormatException, ChecksumException */Result> { - return Ok(self.decode(&BitMatrix::parse(&image))); - } - - /** - *

Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken - * to mean a black module.

- * - * @param bits booleans representing white/black Data Matrix Code modules - * @return text and bytes encoded within the Data Matrix Code - * @throws FormatException if the Data Matrix Code cannot be decoded - * @throws ChecksumException if error correction fails - */ - pub fn decode(&self, bits: &BitMatrix) -> /* throws FormatException, ChecksumException */Result> { - // Construct a parser and read version, error-correction level - let parser: BitMatrixParser = BitMatrixParser::new(bits); - let version: Version = parser.get_version(); - // Read codewords - let codewords: Vec = parser.read_codewords(); - // Separate into data blocks - let data_blocks: Vec = DataBlock::get_data_blocks(&codewords, version); - // Count total number of data bytes - let total_bytes: i32 = 0; - for let db: DataBlock in data_blocks { - total_bytes += db.get_num_data_codewords(); - } - let result_bytes: [i8; total_bytes] = [0; total_bytes]; - let data_blocks_count: i32 = data_blocks.len(); - // Error-correct and copy data blocks together into a stream of bytes - { - let mut j: i32 = 0; - while j < data_blocks_count { - { - let data_block: DataBlock = data_blocks[j]; - let codeword_bytes: Vec = data_block.get_codewords(); - let num_data_codewords: i32 = data_block.get_num_data_codewords(); - self.correct_errors(&codeword_bytes, num_data_codewords); - { - let mut i: i32 = 0; - while i < num_data_codewords { - { - // De-interlace data blocks. - result_bytes[i * data_blocks_count + j] = codeword_bytes[i]; - } - i += 1; - } - } - - } - j += 1; - } - } - - // Decode the contents of that stream of bytes - return Ok(DecodedBitStreamParser::decode(&result_bytes)); - } - - /** - *

Given data and error-correction codewords received, possibly corrupted by errors, attempts to - * correct the errors in-place using Reed-Solomon error correction.

- * - * @param codewordBytes data and error correction codewords - * @param numDataCodewords number of codewords that are data bytes - * @throws ChecksumException if error correction fails - */ - fn correct_errors(&self, codeword_bytes: &Vec, num_data_codewords: i32) -> /* throws ChecksumException */Result> { - let num_codewords: i32 = codeword_bytes.len(); - // First read into an array of ints - let codewords_ints: [i32; num_codewords] = [0; num_codewords]; - { - let mut i: i32 = 0; - while i < num_codewords { - { - codewords_ints[i] = codeword_bytes[i] & 0xFF; - } - i += 1; - } - } - - let tryResult1 = 0; - 'try1: loop { - { - self.rs_decoder.decode(&codewords_ints, codeword_bytes.len() - num_data_codewords); - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &ReedSolomonException) { - throw ChecksumException::get_checksum_instance(); - } 0 => break - } - - // We don't care about errors in the error-correction codewords - { - let mut i: i32 = 0; - while i < num_data_codewords { - { - codeword_bytes[i] = codewords_ints[i] as i8; - } - i += 1; - } - } - - } -} - diff --git a/port_src/output/zxing/datamatrix/decoder/version.rs b/port_src/output/zxing/datamatrix/decoder/version.rs deleted file mode 100644 index 68ffe85..0000000 --- a/port_src/output/zxing/datamatrix/decoder/version.rs +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2007 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::decoder; - -/** - * The Version object encapsulates attributes about a particular - * size Data Matrix Code. - * - * @author bbrown@google.com (Brian Brown) - */ - - const VERSIONS: Vec = ::build_versions(); -pub struct Version { - - let version_number: i32; - - let symbol_size_rows: i32; - - let symbol_size_columns: i32; - - let data_region_size_rows: i32; - - let data_region_size_columns: i32; - - let ec_blocks: ECBlocks; - - let total_codewords: i32; -} - -impl Version { - - fn new( version_number: i32, symbol_size_rows: i32, symbol_size_columns: i32, data_region_size_rows: i32, data_region_size_columns: i32, ec_blocks: &ECBlocks) -> Version { - let .versionNumber = version_number; - let .symbolSizeRows = symbol_size_rows; - let .symbolSizeColumns = symbol_size_columns; - let .dataRegionSizeRows = data_region_size_rows; - let .dataRegionSizeColumns = data_region_size_columns; - let .ecBlocks = ec_blocks; - // Calculate the total number of codewords - let mut total: i32 = 0; - let ec_codewords: i32 = ec_blocks.get_e_c_codewords(); - let ecb_array: Vec = ec_blocks.get_e_c_blocks(); - for let ec_block: ECB in ecb_array { - total += ec_block.get_count() * (ec_block.get_data_codewords() + ec_codewords); - } - let .totalCodewords = total; - } - - pub fn get_version_number(&self) -> i32 { - return self.version_number; - } - - pub fn get_symbol_size_rows(&self) -> i32 { - return self.symbol_size_rows; - } - - pub fn get_symbol_size_columns(&self) -> i32 { - return self.symbol_size_columns; - } - - pub fn get_data_region_size_rows(&self) -> i32 { - return self.data_region_size_rows; - } - - pub fn get_data_region_size_columns(&self) -> i32 { - return self.data_region_size_columns; - } - - pub fn get_total_codewords(&self) -> i32 { - return self.total_codewords; - } - - fn get_e_c_blocks(&self) -> ECBlocks { - return self.ec_blocks; - } - - /** - *

Deduces version information from Data Matrix dimensions.

- * - * @param numRows Number of rows in modules - * @param numColumns Number of columns in modules - * @return Version for a Data Matrix Code of those dimensions - * @throws FormatException if dimensions do correspond to a valid Data Matrix size - */ - pub fn get_version_for_dimensions( num_rows: i32, num_columns: i32) -> /* throws FormatException */Result> { - if (num_rows & 0x01) != 0 || (num_columns & 0x01) != 0 { - throw FormatException::get_format_instance(); - } - for let version: Version in VERSIONS { - if version.symbolSizeRows == num_rows && version.symbolSizeColumns == num_columns { - return Ok(version); - } - } - throw FormatException::get_format_instance(); - } - - /** - *

Encapsulates a set of error-correction blocks in one symbol version. Most versions will - * use blocks of differing sizes within one version, so, this encapsulates the parameters for - * each set of blocks. It also holds the number of error-correction codewords per block since it - * will be the same across all blocks within one version.

- */ - struct ECBlocks { - - let ec_codewords: i32; - - let ec_blocks: Vec; - } - - impl ECBlocks { - - fn new( ec_codewords: i32, ec_blocks: &ECB) -> ECBlocks { - let .ecCodewords = ec_codewords; - let .ecBlocks = : vec![ECB; 1] = vec![ec_blocks, ] - ; - } - - fn new( ec_codewords: i32, ec_blocks1: &ECB, ec_blocks2: &ECB) -> ECBlocks { - let .ecCodewords = ec_codewords; - let .ecBlocks = : vec![ECB; 2] = vec![ec_blocks1, ec_blocks2, ] - ; - } - - fn get_e_c_codewords(&self) -> i32 { - return self.ec_codewords; - } - - fn get_e_c_blocks(&self) -> Vec { - return self.ec_blocks; - } - } - - - /** - *

Encapsulates the parameters for one error-correction block in one symbol version. - * This includes the number of data codewords, and the number of times a block with these - * parameters is used consecutively in the Data Matrix code version's format.

- */ - struct ECB { - - let count: i32; - - let data_codewords: i32; - } - - impl ECB { - - fn new( count: i32, data_codewords: i32) -> ECB { - let .count = count; - let .dataCodewords = data_codewords; - } - - fn get_count(&self) -> i32 { - return self.count; - } - - fn get_data_codewords(&self) -> i32 { - return self.data_codewords; - } - } - - - pub fn to_string(&self) -> String { - return String::value_of(self.version_number); - } - - /** - * See ISO 16022:2006 5.5.1 Table 7 - */ - fn build_versions() -> Vec { - return : vec![Version; 48] = vec![Version::new(1, 10, 10, 8, 8, ECBlocks::new(5, ECB::new(1, 3))), Version::new(2, 12, 12, 10, 10, ECBlocks::new(7, ECB::new(1, 5))), Version::new(3, 14, 14, 12, 12, ECBlocks::new(10, ECB::new(1, 8))), Version::new(4, 16, 16, 14, 14, ECBlocks::new(12, ECB::new(1, 12))), Version::new(5, 18, 18, 16, 16, ECBlocks::new(14, ECB::new(1, 18))), Version::new(6, 20, 20, 18, 18, ECBlocks::new(18, ECB::new(1, 22))), Version::new(7, 22, 22, 20, 20, ECBlocks::new(20, ECB::new(1, 30))), Version::new(8, 24, 24, 22, 22, ECBlocks::new(24, ECB::new(1, 36))), Version::new(9, 26, 26, 24, 24, ECBlocks::new(28, ECB::new(1, 44))), Version::new(10, 32, 32, 14, 14, ECBlocks::new(36, ECB::new(1, 62))), Version::new(11, 36, 36, 16, 16, ECBlocks::new(42, ECB::new(1, 86))), Version::new(12, 40, 40, 18, 18, ECBlocks::new(48, ECB::new(1, 114))), Version::new(13, 44, 44, 20, 20, ECBlocks::new(56, ECB::new(1, 144))), Version::new(14, 48, 48, 22, 22, ECBlocks::new(68, ECB::new(1, 174))), Version::new(15, 52, 52, 24, 24, ECBlocks::new(42, ECB::new(2, 102))), Version::new(16, 64, 64, 14, 14, ECBlocks::new(56, ECB::new(2, 140))), Version::new(17, 72, 72, 16, 16, ECBlocks::new(36, ECB::new(4, 92))), Version::new(18, 80, 80, 18, 18, ECBlocks::new(48, ECB::new(4, 114))), Version::new(19, 88, 88, 20, 20, ECBlocks::new(56, ECB::new(4, 144))), Version::new(20, 96, 96, 22, 22, ECBlocks::new(68, ECB::new(4, 174))), Version::new(21, 104, 104, 24, 24, ECBlocks::new(56, ECB::new(6, 136))), Version::new(22, 120, 120, 18, 18, ECBlocks::new(68, ECB::new(6, 175))), Version::new(23, 132, 132, 20, 20, ECBlocks::new(62, ECB::new(8, 163))), Version::new(24, 144, 144, 22, 22, ECBlocks::new(62, ECB::new(8, 156), ECB::new(2, 155))), Version::new(25, 8, 18, 6, 16, ECBlocks::new(7, ECB::new(1, 5))), Version::new(26, 8, 32, 6, 14, ECBlocks::new(11, ECB::new(1, 10))), Version::new(27, 12, 26, 10, 24, ECBlocks::new(14, ECB::new(1, 16))), Version::new(28, 12, 36, 10, 16, ECBlocks::new(18, ECB::new(1, 22))), Version::new(29, 16, 36, 14, 16, ECBlocks::new(24, ECB::new(1, 32))), Version::new(30, 16, 48, 14, 22, ECBlocks::new(28, ECB::new(1, 49))), // ISO 21471:2020 (DMRE) 5.5.1 Table 7 - Version::new(31, 8, 48, 6, 22, ECBlocks::new(15, ECB::new(1, 18))), Version::new(32, 8, 64, 6, 14, ECBlocks::new(18, ECB::new(1, 24))), Version::new(33, 8, 80, 6, 18, ECBlocks::new(22, ECB::new(1, 32))), Version::new(34, 8, 96, 6, 22, ECBlocks::new(28, ECB::new(1, 38))), Version::new(35, 8, 120, 6, 18, ECBlocks::new(32, ECB::new(1, 49))), Version::new(36, 8, 144, 6, 22, ECBlocks::new(36, ECB::new(1, 63))), Version::new(37, 12, 64, 10, 14, ECBlocks::new(27, ECB::new(1, 43))), Version::new(38, 12, 88, 10, 20, ECBlocks::new(36, ECB::new(1, 64))), Version::new(39, 16, 64, 14, 14, ECBlocks::new(36, ECB::new(1, 62))), Version::new(40, 20, 36, 18, 16, ECBlocks::new(28, ECB::new(1, 44))), Version::new(41, 20, 44, 18, 20, ECBlocks::new(34, ECB::new(1, 56))), Version::new(42, 20, 64, 18, 14, ECBlocks::new(42, ECB::new(1, 84))), Version::new(43, 22, 48, 20, 22, ECBlocks::new(38, ECB::new(1, 72))), Version::new(44, 24, 48, 22, 22, ECBlocks::new(41, ECB::new(1, 80))), Version::new(45, 24, 64, 22, 14, ECBlocks::new(46, ECB::new(1, 108))), Version::new(46, 26, 40, 24, 18, ECBlocks::new(38, ECB::new(1, 70))), Version::new(47, 26, 48, 24, 22, ECBlocks::new(42, ECB::new(1, 90))), Version::new(48, 26, 64, 24, 14, ECBlocks::new(50, ECB::new(1, 118))), ] - ; - } -} - diff --git a/port_src/output/zxing/datamatrix/detector/detector.rs b/port_src/output/zxing/datamatrix/detector/detector.rs deleted file mode 100644 index ca3ca4a..0000000 --- a/port_src/output/zxing/datamatrix/detector/detector.rs +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright 2008 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::detector; - -/** - *

Encapsulates logic that can detect a Data Matrix Code in an image, even if the Data Matrix Code - * is rotated or skewed, or partially obscured.

- * - * @author Sean Owen - */ -pub struct Detector { - - let image: BitMatrix; - - let rectangle_detector: WhiteRectangleDetector; -} - -impl Detector { - - pub fn new( image: &BitMatrix) -> Detector throws NotFoundException { - let .image = image; - rectangle_detector = WhiteRectangleDetector::new(image); - } - - /** - *

Detects a Data Matrix Code in an image.

- * - * @return {@link DetectorResult} encapsulating results of detecting a Data Matrix Code - * @throws NotFoundException if no Data Matrix Code can be found - */ - pub fn detect(&self) -> /* throws NotFoundException */Result> { - let corner_points: Vec = self.rectangle_detector.detect(); - let mut points: Vec = self.detect_solid1(corner_points); - points = self.detect_solid2(points); - points[3] = self.correct_top_right(points); - if points[3] == null { - throw NotFoundException::get_not_found_instance(); - } - points = self.shift_to_module_center(points); - let top_left: ResultPoint = points[0]; - let bottom_left: ResultPoint = points[1]; - let bottom_right: ResultPoint = points[2]; - let top_right: ResultPoint = points[3]; - let dimension_top: i32 = self.transitions_between(top_left, top_right) + 1; - let dimension_right: i32 = self.transitions_between(bottom_right, top_right) + 1; - if (dimension_top & 0x01) == 1 { - dimension_top += 1; - } - if (dimension_right & 0x01) == 1 { - dimension_right += 1; - } - if 4 * dimension_top < 6 * dimension_right && 4 * dimension_right < 6 * dimension_top { - // The matrix is square - dimension_top = dimension_right = Math::max(dimension_top, dimension_right); - } - let bits: BitMatrix = ::sample_grid(self.image, top_left, bottom_left, bottom_right, top_right, dimension_top, dimension_right); - return Ok(DetectorResult::new(bits, : vec![ResultPoint; 4] = vec![top_left, bottom_left, bottom_right, top_right, ] - )); - } - - fn shift_point( point: &ResultPoint, to: &ResultPoint, div: i32) -> ResultPoint { - let x: f32 = (to.get_x() - point.get_x()) / (div + 1); - let y: f32 = (to.get_y() - point.get_y()) / (div + 1); - return ResultPoint::new(point.get_x() + x, point.get_y() + y); - } - - fn move_away( point: &ResultPoint, from_x: f32, from_y: f32) -> ResultPoint { - let mut x: f32 = point.get_x(); - let mut y: f32 = point.get_y(); - if x < from_x { - x -= 1.0; - } else { - x += 1.0; - } - if y < from_y { - y -= 1.0; - } else { - y += 1.0; - } - return ResultPoint::new(x, y); - } - - /** - * Detect a solid side which has minimum transition. - */ - fn detect_solid1(&self, corner_points: &Vec) -> Vec { - // 0 2 - // 1 3 - let point_a: ResultPoint = corner_points[0]; - let point_b: ResultPoint = corner_points[1]; - let point_c: ResultPoint = corner_points[3]; - let point_d: ResultPoint = corner_points[2]; - let tr_a_b: i32 = self.transitions_between(point_a, point_b); - let tr_b_c: i32 = self.transitions_between(point_b, point_c); - let tr_c_d: i32 = self.transitions_between(point_c, point_d); - let tr_d_a: i32 = self.transitions_between(point_d, point_a); - // 0..3 - // : : - // 1--2 - let mut min: i32 = tr_a_b; - let mut points: vec![Vec; 4] = vec![point_d, point_a, point_b, point_c, ] - ; - if min > tr_b_c { - min = tr_b_c; - points[0] = point_a; - points[1] = point_b; - points[2] = point_c; - points[3] = point_d; - } - if min > tr_c_d { - min = tr_c_d; - points[0] = point_b; - points[1] = point_c; - points[2] = point_d; - points[3] = point_a; - } - if min > tr_d_a { - points[0] = point_c; - points[1] = point_d; - points[2] = point_a; - points[3] = point_b; - } - return points; - } - - /** - * Detect a second solid side next to first solid side. - */ - fn detect_solid2(&self, points: &Vec) -> Vec { - // A..D - // : : - // B--C - let point_a: ResultPoint = points[0]; - let point_b: ResultPoint = points[1]; - let point_c: ResultPoint = points[2]; - let point_d: ResultPoint = points[3]; - // Transition detection on the edge is not stable. - // To safely detect, shift the points to the module center. - let tr: i32 = self.transitions_between(point_a, point_d); - let point_bs: ResultPoint = ::shift_point(point_b, point_c, (tr + 1) * 4); - let point_cs: ResultPoint = ::shift_point(point_c, point_b, (tr + 1) * 4); - let tr_b_a: i32 = self.transitions_between(point_bs, point_a); - let tr_c_d: i32 = self.transitions_between(point_cs, point_d); - // 1--2 - if tr_b_a < tr_c_d { - // solid sides: A-B-C - points[0] = point_a; - points[1] = point_b; - points[2] = point_c; - points[3] = point_d; - } else { - // solid sides: B-C-D - points[0] = point_b; - points[1] = point_c; - points[2] = point_d; - points[3] = point_a; - } - return points; - } - - /** - * Calculates the corner position of the white top right module. - */ - fn correct_top_right(&self, points: &Vec) -> ResultPoint { - // A..D - // | : - // B--C - let point_a: ResultPoint = points[0]; - let point_b: ResultPoint = points[1]; - let point_c: ResultPoint = points[2]; - let point_d: ResultPoint = points[3]; - // shift points for safe transition detection. - let tr_top: i32 = self.transitions_between(point_a, point_d); - let tr_right: i32 = self.transitions_between(point_b, point_d); - let point_as: ResultPoint = ::shift_point(point_a, point_b, (tr_right + 1) * 4); - let point_cs: ResultPoint = ::shift_point(point_c, point_b, (tr_top + 1) * 4); - tr_top = self.transitions_between(point_as, point_d); - tr_right = self.transitions_between(point_cs, point_d); - let candidate1: ResultPoint = ResultPoint::new(point_d.get_x() + (point_c.get_x() - point_b.get_x()) / (tr_top + 1), point_d.get_y() + (point_c.get_y() - point_b.get_y()) / (tr_top + 1)); - let candidate2: ResultPoint = ResultPoint::new(point_d.get_x() + (point_a.get_x() - point_b.get_x()) / (tr_right + 1), point_d.get_y() + (point_a.get_y() - point_b.get_y()) / (tr_right + 1)); - if !self.is_valid(candidate1) { - if self.is_valid(candidate2) { - return candidate2; - } - return null; - } - if !self.is_valid(candidate2) { - return candidate1; - } - let sumc1: i32 = self.transitions_between(point_as, candidate1) + self.transitions_between(point_cs, candidate1); - let sumc2: i32 = self.transitions_between(point_as, candidate2) + self.transitions_between(point_cs, candidate2); - if sumc1 > sumc2 { - return candidate1; - } else { - return candidate2; - } - } - - /** - * Shift the edge points to the module center. - */ - fn shift_to_module_center(&self, points: &Vec) -> Vec { - // A..D - // | : - // B--C - let point_a: ResultPoint = points[0]; - let point_b: ResultPoint = points[1]; - let point_c: ResultPoint = points[2]; - let point_d: ResultPoint = points[3]; - // calculate pseudo dimensions - let dim_h: i32 = self.transitions_between(point_a, point_d) + 1; - let dim_v: i32 = self.transitions_between(point_c, point_d) + 1; - // shift points for safe dimension detection - let point_as: ResultPoint = ::shift_point(point_a, point_b, dim_v * 4); - let point_cs: ResultPoint = ::shift_point(point_c, point_b, dim_h * 4); - // calculate more precise dimensions - dim_h = self.transitions_between(point_as, point_d) + 1; - dim_v = self.transitions_between(point_cs, point_d) + 1; - if (dim_h & 0x01) == 1 { - dim_h += 1; - } - if (dim_v & 0x01) == 1 { - dim_v += 1; - } - // WhiteRectangleDetector returns points inside of the rectangle. - // I want points on the edges. - let center_x: f32 = (point_a.get_x() + point_b.get_x() + point_c.get_x() + point_d.get_x()) / 4; - let center_y: f32 = (point_a.get_y() + point_b.get_y() + point_c.get_y() + point_d.get_y()) / 4; - point_a = ::move_away(point_a, center_x, center_y); - point_b = ::move_away(point_b, center_x, center_y); - point_c = ::move_away(point_c, center_x, center_y); - point_d = ::move_away(point_d, center_x, center_y); - let point_bs: ResultPoint; - let point_ds: ResultPoint; - // shift points to the center of each modules - point_as = ::shift_point(point_a, point_b, dim_v * 4); - point_as = ::shift_point(point_as, point_d, dim_h * 4); - point_bs = ::shift_point(point_b, point_a, dim_v * 4); - point_bs = ::shift_point(point_bs, point_c, dim_h * 4); - point_cs = ::shift_point(point_c, point_d, dim_v * 4); - point_cs = ::shift_point(point_cs, point_b, dim_h * 4); - point_ds = ::shift_point(point_d, point_c, dim_v * 4); - point_ds = ::shift_point(point_ds, point_a, dim_h * 4); - return : vec![ResultPoint; 4] = vec![point_as, point_bs, point_cs, point_ds, ] - ; - } - - fn is_valid(&self, p: &ResultPoint) -> bool { - return p.get_x() >= 0 && p.get_x() <= self.image.get_width() - 1 && p.get_y() > 0 && p.get_y() <= self.image.get_height() - 1; - } - - fn sample_grid( image: &BitMatrix, top_left: &ResultPoint, bottom_left: &ResultPoint, bottom_right: &ResultPoint, top_right: &ResultPoint, dimension_x: i32, dimension_y: i32) -> /* throws NotFoundException */Result> { - let sampler: GridSampler = GridSampler::get_instance(); - return Ok(sampler.sample_grid(image, dimension_x, dimension_y, 0.5f, 0.5f, dimension_x - 0.5f, 0.5f, dimension_x - 0.5f, dimension_y - 0.5f, 0.5f, dimension_y - 0.5f, &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())); - } - - /** - * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm. - */ - fn transitions_between(&self, from: &ResultPoint, to: &ResultPoint) -> i32 { - // See QR Code Detector, sizeOfBlackWhiteBlackRun() - let from_x: i32 = from.get_x() as i32; - let from_y: i32 = from.get_y() as i32; - let to_x: i32 = to.get_x() as i32; - let to_y: i32 = Math::min(self.image.get_height() - 1, to.get_y() as i32); - let steep: bool = Math::abs(to_y - from_y) > Math::abs(to_x - from_x); - if steep { - let mut temp: i32 = from_x; - from_x = from_y; - from_y = temp; - temp = to_x; - to_x = to_y; - to_y = temp; - } - let dx: i32 = Math::abs(to_x - from_x); - let dy: i32 = Math::abs(to_y - from_y); - let mut error: i32 = -dx / 2; - let ystep: i32 = if from_y < to_y { 1 } else { -1 }; - let xstep: i32 = if from_x < to_x { 1 } else { -1 }; - let mut transitions: i32 = 0; - let in_black: bool = self.image.get( if steep { from_y } else { from_x }, if steep { from_x } else { from_y }); - { - let mut x: i32 = from_x, let mut y: i32 = from_y; - while x != to_x { - { - let is_black: bool = self.image.get( if steep { y } else { x }, if steep { x } else { y }); - if is_black != in_black { - transitions += 1; - in_black = is_black; - } - error += dy; - if error > 0 { - if y == to_y { - break; - } - y += ystep; - error -= dx; - } - } - x += xstep; - } - } - - return transitions; - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/a_s_c_i_i_encoder.rs b/port_src/output/zxing/datamatrix/encoder/a_s_c_i_i_encoder.rs deleted file mode 100644 index c504d09..0000000 --- a/port_src/output/zxing/datamatrix/encoder/a_s_c_i_i_encoder.rs +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -#[derive(Encoder)] -struct ASCIIEncoder { -} - -impl ASCIIEncoder { - - pub fn get_encoding_mode(&self) -> i32 { - return HighLevelEncoder::ASCII_ENCODATION; - } - - pub fn encode(&self, context: &EncoderContext) { - //step B - let n: i32 = HighLevelEncoder::determine_consecutive_digit_count(&context.get_message(), context.pos); - if n >= 2 { - context.write_codeword(&::encode_a_s_c_i_i_digits(&context.get_message().char_at(context.pos), &context.get_message().char_at(context.pos + 1))); - context.pos += 2; - } else { - let c: char = context.get_current_char(); - let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); - if new_mode != self.get_encoding_mode() { - match new_mode { - HighLevelEncoder::BASE256_ENCODATION => - { - context.write_codeword(HighLevelEncoder::LATCH_TO_BASE256); - context.signal_encoder_change(HighLevelEncoder::BASE256_ENCODATION); - return; - } - HighLevelEncoder::C40_ENCODATION => - { - context.write_codeword(HighLevelEncoder::LATCH_TO_C40); - context.signal_encoder_change(HighLevelEncoder::C40_ENCODATION); - return; - } - HighLevelEncoder::X12_ENCODATION => - { - context.write_codeword(HighLevelEncoder::LATCH_TO_ANSIX12); - context.signal_encoder_change(HighLevelEncoder::X12_ENCODATION); - break; - } - HighLevelEncoder::TEXT_ENCODATION => - { - context.write_codeword(HighLevelEncoder::LATCH_TO_TEXT); - context.signal_encoder_change(HighLevelEncoder::TEXT_ENCODATION); - break; - } - HighLevelEncoder::EDIFACT_ENCODATION => - { - context.write_codeword(HighLevelEncoder::LATCH_TO_EDIFACT); - context.signal_encoder_change(HighLevelEncoder::EDIFACT_ENCODATION); - break; - } - _ => - { - throw IllegalStateException::new(format!("Illegal mode: {}", new_mode)); - } - } - } else if HighLevelEncoder::is_extended_a_s_c_i_i(c) { - context.write_codeword(HighLevelEncoder::UPPER_SHIFT); - context.write_codeword((c - 128 + 1) as char); - context.pos += 1; - } else { - context.write_codeword((c + 1) as char); - context.pos += 1; - } - } - } - - fn encode_a_s_c_i_i_digits( digit1: char, digit2: char) -> char { - if HighLevelEncoder::is_digit(digit1) && HighLevelEncoder::is_digit(digit2) { - let num: i32 = (digit1 - 48) * 10 + (digit2 - 48); - return (num + 130) as char; - } - throw IllegalArgumentException::new(format!("not digits: {}{}", digit1, digit2)); - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/base256_encoder.rs b/port_src/output/zxing/datamatrix/encoder/base256_encoder.rs deleted file mode 100644 index 1c85b27..0000000 --- a/port_src/output/zxing/datamatrix/encoder/base256_encoder.rs +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -#[derive(Encoder)] -struct Base256Encoder { -} - -impl Base256Encoder { - - pub fn get_encoding_mode(&self) -> i32 { - return HighLevelEncoder::BASE256_ENCODATION; - } - - pub fn encode(&self, context: &EncoderContext) { - let buffer: StringBuilder = StringBuilder::new(); - //Initialize length field - buffer.append('\0'); - while context.has_more_characters() { - let c: char = context.get_current_char(); - buffer.append(c); - context.pos += 1; - let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); - if new_mode != self.get_encoding_mode() { - // Return to ASCII encodation, which will actually handle latch to new mode - context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); - break; - } - } - let data_count: i32 = buffer.length() - 1; - let length_field_size: i32 = 1; - let current_size: i32 = context.get_codeword_count() + data_count + length_field_size; - context.update_symbol_info(current_size); - let must_pad: bool = (context.get_symbol_info().get_data_capacity() - current_size) > 0; - if context.has_more_characters() || must_pad { - if data_count <= 249 { - buffer.set_char_at(0, data_count as char); - } else if data_count <= 1555 { - buffer.set_char_at(0, ((data_count / 250) + 249) as char); - buffer.insert(1, (data_count % 250) as char); - } else { - throw IllegalStateException::new(format!("Message length not in valid ranges: {}", data_count)); - } - } - { - let mut i: i32 = 0, let c: i32 = buffer.length(); - while i < c { - { - context.write_codeword(&::randomize255_state(&buffer.char_at(i), context.get_codeword_count() + 1)); - } - i += 1; - } - } - - } - - fn randomize255_state( ch: char, codeword_position: i32) -> char { - let pseudo_random: i32 = ((149 * codeword_position) % 255) + 1; - let temp_variable: i32 = ch + pseudo_random; - if temp_variable <= 255 { - return temp_variable as char; - } else { - return (temp_variable - 256) as char; - } - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/c40_encoder.rs b/port_src/output/zxing/datamatrix/encoder/c40_encoder.rs deleted file mode 100644 index 458fdda..0000000 --- a/port_src/output/zxing/datamatrix/encoder/c40_encoder.rs +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -#[derive(Encoder)] -struct C40Encoder { -} - -impl C40Encoder { - - pub fn get_encoding_mode(&self) -> i32 { - return HighLevelEncoder::C40_ENCODATION; - } - - fn encode_maximal(&self, context: &EncoderContext) { - let buffer: StringBuilder = StringBuilder::new(); - let last_char_size: i32 = 0; - let backtrack_start_position: i32 = context.pos; - let backtrack_buffer_length: i32 = 0; - while context.has_more_characters() { - let c: char = context.get_current_char(); - context.pos += 1; - last_char_size = self.encode_char(c, &buffer); - if buffer.length() % 3 == 0 { - backtrack_start_position = context.pos; - backtrack_buffer_length = buffer.length(); - } - } - if backtrack_buffer_length != buffer.length() { - let unwritten: i32 = (buffer.length() / 3) * 2; - // +1 for the latch to C40 - let cur_codeword_count: i32 = context.get_codeword_count() + unwritten + 1; - context.update_symbol_info(cur_codeword_count); - let available: i32 = context.get_symbol_info().get_data_capacity() - cur_codeword_count; - let rest: i32 = buffer.length() % 3; - if (rest == 2 && available != 2) || (rest == 1 && (last_char_size > 3 || available != 1)) { - buffer.set_length(backtrack_buffer_length); - context.pos = backtrack_start_position; - } - } - if buffer.length() > 0 { - context.write_codeword(HighLevelEncoder::LATCH_TO_C40); - } - self.handle_e_o_d(context, &buffer); - } - - pub fn encode(&self, context: &EncoderContext) { - //step C - let buffer: StringBuilder = StringBuilder::new(); - while context.has_more_characters() { - let c: char = context.get_current_char(); - context.pos += 1; - let last_char_size: i32 = self.encode_char(c, &buffer); - let unwritten: i32 = (buffer.length() / 3) * 2; - let cur_codeword_count: i32 = context.get_codeword_count() + unwritten; - context.update_symbol_info(cur_codeword_count); - let available: i32 = context.get_symbol_info().get_data_capacity() - cur_codeword_count; - if !context.has_more_characters() { - //Avoid having a single C40 value in the last triplet - let removed: StringBuilder = StringBuilder::new(); - if (buffer.length() % 3) == 2 && available != 2 { - last_char_size = self.backtrack_one_character(context, &buffer, &removed, last_char_size); - } - while (buffer.length() % 3) == 1 && (last_char_size > 3 || available != 1) { - last_char_size = self.backtrack_one_character(context, &buffer, &removed, last_char_size); - } - break; - } - let count: i32 = buffer.length(); - if (count % 3) == 0 { - let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); - if new_mode != self.get_encoding_mode() { - // Return to ASCII encodation, which will actually handle latch to new mode - context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); - break; - } - } - } - self.handle_e_o_d(context, &buffer); - } - - fn backtrack_one_character(&self, context: &EncoderContext, buffer: &StringBuilder, removed: &StringBuilder, last_char_size: i32) -> i32 { - let count: i32 = buffer.length(); - buffer.delete(count - last_char_size, count); - context.pos -= 1; - let c: char = context.get_current_char(); - last_char_size = self.encode_char(c, &removed); - //Deal with possible reduction in symbol size - context.reset_symbol_info(); - return last_char_size; - } - - fn write_next_triplet( context: &EncoderContext, buffer: &StringBuilder) { - context.write_codewords(&::encode_to_codewords(&buffer)); - buffer.delete(0, 3); - } - - /** - * Handle "end of data" situations - * - * @param context the encoder context - * @param buffer the buffer with the remaining encoded characters - */ - fn handle_e_o_d(&self, context: &EncoderContext, buffer: &StringBuilder) { - let unwritten: i32 = (buffer.length() / 3) * 2; - let rest: i32 = buffer.length() % 3; - let cur_codeword_count: i32 = context.get_codeword_count() + unwritten; - context.update_symbol_info(cur_codeword_count); - let available: i32 = context.get_symbol_info().get_data_capacity() - cur_codeword_count; - if rest == 2 { - //Shift 1 - buffer.append('\0'); - while buffer.length() >= 3 { - ::write_next_triplet(context, &buffer); - } - if context.has_more_characters() { - context.write_codeword(HighLevelEncoder::C40_UNLATCH); - } - } else if available == 1 && rest == 1 { - while buffer.length() >= 3 { - ::write_next_triplet(context, &buffer); - } - if context.has_more_characters() { - context.write_codeword(HighLevelEncoder::C40_UNLATCH); - } - // else no unlatch - context.pos -= 1; - } else if rest == 0 { - while buffer.length() >= 3 { - ::write_next_triplet(context, &buffer); - } - if available > 0 || context.has_more_characters() { - context.write_codeword(HighLevelEncoder::C40_UNLATCH); - } - } else { - throw IllegalStateException::new("Unexpected case. Please report!"); - } - context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); - } - - fn encode_char(&self, c: char, sb: &StringBuilder) -> i32 { - if c == ' ' { - sb.append('\3'); - return 1; - } - if c >= '0' && c <= '9' { - sb.append((c - 48 + 4) as char); - return 1; - } - if c >= 'A' && c <= 'Z' { - sb.append((c - 65 + 14) as char); - return 1; - } - if c < ' ' { - //Shift 1 Set - sb.append('\0'); - sb.append(c); - return 2; - } - if c <= '/' { - //Shift 2 Set - sb.append('\1'); - sb.append((c - 33) as char); - return 2; - } - if c <= '@' { - //Shift 2 Set - sb.append('\1'); - sb.append((c - 58 + 15) as char); - return 2; - } - if c <= '_' { - //Shift 2 Set - sb.append('\1'); - sb.append((c - 91 + 22) as char); - return 2; - } - if c <= 127 { - //Shift 3 Set - sb.append('\2'); - sb.append((c - 96) as char); - return 2; - } - //Shift 2, Upper Shift - sb.append("\1"); - let mut len: i32 = 2; - len += self.encode_char((c - 128) as char, &sb); - return len; - } - - fn encode_to_codewords( sb: &CharSequence) -> String { - let v: i32 = (1600 * sb.char_at(0)) + (40 * sb.char_at(1)) + sb.char_at(2) + 1; - let cw1: char = (v / 256) as char; - let cw2: char = (v % 256) as char; - return String::new( : vec![char; 2] = vec![cw1, cw2, ] - ); - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/data_matrix_symbol_info144.rs b/port_src/output/zxing/datamatrix/encoder/data_matrix_symbol_info144.rs deleted file mode 100644 index 5375a3d..0000000 --- a/port_src/output/zxing/datamatrix/encoder/data_matrix_symbol_info144.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2006 Jeremias Maerki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -struct DataMatrixSymbolInfo144 { - super: SymbolInfo; -} - -impl DataMatrixSymbolInfo144 { - - fn new() -> DataMatrixSymbolInfo144 { - super(false, 1558, 620, 22, 22, 36, -1, 62); - } - - pub fn get_interleaved_block_count(&self) -> i32 { - return 10; - } - - pub fn get_data_length_for_interleaved_block(&self, index: i32) -> i32 { - return if (index <= 8) { 156 } else { 155 }; - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/default_placement.rs b/port_src/output/zxing/datamatrix/encoder/default_placement.rs deleted file mode 100644 index d696fc9..0000000 --- a/port_src/output/zxing/datamatrix/encoder/default_placement.rs +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2006 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -/** - * Symbol Character Placement Program. Adapted from Annex M.1 in ISO/IEC 16022:2000(E). - */ -pub struct DefaultPlacement { - - let codewords: CharSequence; - - let numrows: i32; - - let mut numcols: i32; - - let mut bits: Vec; -} - -impl DefaultPlacement { - - /** - * Main constructor - * - * @param codewords the codewords to place - * @param numcols the number of columns - * @param numrows the number of rows - */ - pub fn new( codewords: &CharSequence, numcols: i32, numrows: i32) -> DefaultPlacement { - let .codewords = codewords; - let .numcols = numcols; - let .numrows = numrows; - let .bits = : [i8; numcols * numrows] = [0; numcols * numrows]; - //Initialize with "not set" value - Arrays::fill(let .bits, -1 as i8); - } - - fn get_numrows(&self) -> i32 { - return self.numrows; - } - - fn get_numcols(&self) -> i32 { - return self.numcols; - } - - fn get_bits(&self) -> Vec { - return self.bits; - } - - pub fn get_bit(&self, col: i32, row: i32) -> bool { - return self.bits[row * self.numcols + col] == 1; - } - - fn set_bit(&self, col: i32, row: i32, bit: bool) { - self.bits[row * self.numcols + col] = ( if bit { 1 } else { 0 }) as i8; - } - - fn no_bit(&self, col: i32, row: i32) -> bool { - return self.bits[row * self.numcols + col] < 0; - } - - pub fn place(&self) { - let mut pos: i32 = 0; - let mut row: i32 = 4; - let mut col: i32 = 0; - loop { { - // repeatedly first check for one of the special corner cases, then... - if (row == self.numrows) && (col == 0) { - self.corner1(pos += 1 !!!check!!! post increment); - } - if (row == self.numrows - 2) && (col == 0) && ((self.numcols % 4) != 0) { - self.corner2(pos += 1 !!!check!!! post increment); - } - if (row == self.numrows - 2) && (col == 0) && (self.numcols % 8 == 4) { - self.corner3(pos += 1 !!!check!!! post increment); - } - if (row == self.numrows + 4) && (col == 2) && ((self.numcols % 8) == 0) { - self.corner4(pos += 1 !!!check!!! post increment); - } - // sweep upward diagonally, inserting successive characters... - loop { { - if (row < self.numrows) && (col >= 0) && self.no_bit(col, row) { - self.utah(row, col, pos += 1 !!!check!!! post increment); - } - row -= 2; - col += 2; - }if !(row >= 0 && (col < self.numcols)) break;} - row += 1; - col += 3; - // and then sweep downward diagonally, inserting successive characters, ... - loop { { - if (row >= 0) && (col < self.numcols) && self.no_bit(col, row) { - self.utah(row, col, pos += 1 !!!check!!! post increment); - } - row += 2; - col -= 2; - }if !((row < self.numrows) && (col >= 0)) break;} - row += 3; - col += 1; - // ...until the entire array is scanned - }if !((row < self.numrows) || (col < self.numcols)) break;} - // Lastly, if the lower right-hand corner is untouched, fill in fixed pattern - if self.no_bit(self.numcols - 1, self.numrows - 1) { - self.set_bit(self.numcols - 1, self.numrows - 1, true); - self.set_bit(self.numcols - 2, self.numrows - 2, true); - } - } - - fn module(&self, row: i32, col: i32, pos: i32, bit: i32) { - if row < 0 { - row += self.numrows; - col += 4 - ((self.numrows + 4) % 8); - } - if col < 0 { - col += self.numcols; - row += 4 - ((self.numcols + 4) % 8); - } - // Note the conversion: - let mut v: i32 = self.codewords.char_at(pos); - v &= 1 << (8 - bit); - self.set_bit(col, row, v != 0); - } - - /** - * Places the 8 bits of a utah-shaped symbol character in ECC200. - * - * @param row the row - * @param col the column - * @param pos character position - */ - fn utah(&self, row: i32, col: i32, pos: i32) { - self.module(row - 2, col - 2, pos, 1); - self.module(row - 2, col - 1, pos, 2); - self.module(row - 1, col - 2, pos, 3); - self.module(row - 1, col - 1, pos, 4); - self.module(row - 1, col, pos, 5); - self.module(row, col - 2, pos, 6); - self.module(row, col - 1, pos, 7); - self.module(row, col, pos, 8); - } - - fn corner1(&self, pos: i32) { - self.module(self.numrows - 1, 0, pos, 1); - self.module(self.numrows - 1, 1, pos, 2); - self.module(self.numrows - 1, 2, pos, 3); - self.module(0, self.numcols - 2, pos, 4); - self.module(0, self.numcols - 1, pos, 5); - self.module(1, self.numcols - 1, pos, 6); - self.module(2, self.numcols - 1, pos, 7); - self.module(3, self.numcols - 1, pos, 8); - } - - fn corner2(&self, pos: i32) { - self.module(self.numrows - 3, 0, pos, 1); - self.module(self.numrows - 2, 0, pos, 2); - self.module(self.numrows - 1, 0, pos, 3); - self.module(0, self.numcols - 4, pos, 4); - self.module(0, self.numcols - 3, pos, 5); - self.module(0, self.numcols - 2, pos, 6); - self.module(0, self.numcols - 1, pos, 7); - self.module(1, self.numcols - 1, pos, 8); - } - - fn corner3(&self, pos: i32) { - self.module(self.numrows - 3, 0, pos, 1); - self.module(self.numrows - 2, 0, pos, 2); - self.module(self.numrows - 1, 0, pos, 3); - self.module(0, self.numcols - 2, pos, 4); - self.module(0, self.numcols - 1, pos, 5); - self.module(1, self.numcols - 1, pos, 6); - self.module(2, self.numcols - 1, pos, 7); - self.module(3, self.numcols - 1, pos, 8); - } - - fn corner4(&self, pos: i32) { - self.module(self.numrows - 1, 0, pos, 1); - self.module(self.numrows - 1, self.numcols - 1, pos, 2); - self.module(0, self.numcols - 3, pos, 3); - self.module(0, self.numcols - 2, pos, 4); - self.module(0, self.numcols - 1, pos, 5); - self.module(1, self.numcols - 3, pos, 6); - self.module(1, self.numcols - 2, pos, 7); - self.module(1, self.numcols - 1, pos, 8); - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/edifact_encoder.rs b/port_src/output/zxing/datamatrix/encoder/edifact_encoder.rs deleted file mode 100644 index e3ea969..0000000 --- a/port_src/output/zxing/datamatrix/encoder/edifact_encoder.rs +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -#[derive(Encoder)] -struct EdifactEncoder { -} - -impl EdifactEncoder { - - pub fn get_encoding_mode(&self) -> i32 { - return HighLevelEncoder::EDIFACT_ENCODATION; - } - - pub fn encode(&self, context: &EncoderContext) { - //step F - let buffer: StringBuilder = StringBuilder::new(); - while context.has_more_characters() { - let c: char = context.get_current_char(); - ::encode_char(c, &buffer); - context.pos += 1; - let count: i32 = buffer.length(); - if count >= 4 { - context.write_codewords(&::encode_to_codewords(&buffer)); - buffer.delete(0, 4); - let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); - if new_mode != self.get_encoding_mode() { - // Return to ASCII encodation, which will actually handle latch to new mode - context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); - break; - } - } - } - //Unlatch - buffer.append(31 as char); - ::handle_e_o_d(context, &buffer); - } - - /** - * Handle "end of data" situations - * - * @param context the encoder context - * @param buffer the buffer with the remaining encoded characters - */ - fn handle_e_o_d( context: &EncoderContext, buffer: &CharSequence) { - let tryResult1 = 0; - 'try1: loop { - { - let count: i32 = buffer.length(); - if count == 0 { - //Already finished - return; - } - if count == 1 { - //Only an unlatch at the end - context.update_symbol_info(); - let mut available: i32 = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); - let remaining: i32 = context.get_remaining_characters(); - // The following two lines are a hack inspired by the 'fix' from https://sourceforge.net/p/barcode4j/svn/221/ - if remaining > available { - context.update_symbol_info(context.get_codeword_count() + 1); - available = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); - } - if remaining <= available && available <= 2 { - //No unlatch - return; - } - } - if count > 4 { - throw IllegalStateException::new("Count must not exceed 4"); - } - let rest_chars: i32 = count - 1; - let encoded: String = ::encode_to_codewords(&buffer); - let end_of_symbol_reached: bool = !context.has_more_characters(); - let rest_in_ascii: bool = end_of_symbol_reached && rest_chars <= 2; - if rest_chars <= 2 { - context.update_symbol_info(context.get_codeword_count() + rest_chars); - let available: i32 = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); - if available >= 3 { - rest_in_ascii = false; - context.update_symbol_info(context.get_codeword_count() + encoded.length()); - //available = context.symbolInfo.dataCapacity - context.getCodewordCount(); - } - } - if rest_in_ascii { - context.reset_symbol_info(); - context.pos -= rest_chars; - } else { - context.write_codewords(&encoded); - } - } - break 'try1 - } - match tryResult1 { - 0 => break - } - finally { - context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); - } - } - - fn encode_char( c: char, sb: &StringBuilder) { - if c >= ' ' && c <= '?' { - sb.append(c); - } else if c >= '@' && c <= '^' { - sb.append((c - 64) as char); - } else { - HighLevelEncoder::illegal_character(c); - } - } - - fn encode_to_codewords( sb: &CharSequence) -> String { - let len: i32 = sb.length(); - if len == 0 { - throw IllegalStateException::new("StringBuilder must not be empty"); - } - let c1: char = sb.char_at(0); - let c2: char = if len >= 2 { sb.char_at(1) } else { 0 }; - let c3: char = if len >= 3 { sb.char_at(2) } else { 0 }; - let c4: char = if len >= 4 { sb.char_at(3) } else { 0 }; - let v: i32 = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4; - let cw1: char = ((v >> 16) & 255) as char; - let cw2: char = ((v >> 8) & 255) as char; - let cw3: char = (v & 255) as char; - let res: StringBuilder = StringBuilder::new(3); - res.append(cw1); - if len >= 2 { - res.append(cw2); - } - if len >= 3 { - res.append(cw3); - } - return res.to_string(); - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/encoder.rs b/port_src/output/zxing/datamatrix/encoder/encoder.rs deleted file mode 100644 index 751be5e..0000000 --- a/port_src/output/zxing/datamatrix/encoder/encoder.rs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -trait Encoder { - - fn get_encoding_mode(&self) -> i32 ; - - fn encode(&self, context: &EncoderContext) ; -} - diff --git a/port_src/output/zxing/datamatrix/encoder/encoder_context.rs b/port_src/output/zxing/datamatrix/encoder/encoder_context.rs deleted file mode 100644 index 29179b8..0000000 --- a/port_src/output/zxing/datamatrix/encoder/encoder_context.rs +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -struct EncoderContext { - - let msg: String; - - let mut shape: SymbolShapeHint; - - let min_size: Dimension; - - let max_size: Dimension; - - let mut codewords: StringBuilder; - - let pos: i32; - - let new_encoding: i32; - - let symbol_info: SymbolInfo; - - let skip_at_end: i32; -} - -impl EncoderContext { - - fn new( msg: &String) -> EncoderContext { - //From this point on Strings are not Unicode anymore! - let msg_binary: Vec = msg.get_bytes(StandardCharsets::ISO_8859_1); - let sb: StringBuilder = StringBuilder::new(msg_binary.len()); - { - let mut i: i32 = 0, let c: i32 = msg_binary.len(); - while i < c { - { - let ch: char = (msg_binary[i] & 0xff) as char; - if ch == '?' && msg.char_at(i) != '?' { - throw IllegalArgumentException::new("Message contains characters outside ISO-8859-1 encoding."); - } - sb.append(ch); - } - i += 1; - } - } - - //Not Unicode here! - let .msg = sb.to_string(); - shape = SymbolShapeHint::FORCE_NONE; - let .codewords = StringBuilder::new(&msg.length()); - new_encoding = -1; - } - - pub fn set_symbol_shape(&self, shape: &SymbolShapeHint) { - self.shape = shape; - } - - pub fn set_size_constraints(&self, min_size: &Dimension, max_size: &Dimension) { - self.minSize = min_size; - self.maxSize = max_size; - } - - pub fn get_message(&self) -> String { - return self.msg; - } - - pub fn set_skip_at_end(&self, count: i32) { - self.skipAtEnd = count; - } - - pub fn get_current_char(&self) -> char { - return self.msg.char_at(self.pos); - } - - pub fn get_current(&self) -> char { - return self.msg.char_at(self.pos); - } - - pub fn get_codewords(&self) -> StringBuilder { - return self.codewords; - } - - pub fn write_codewords(&self, codewords: &String) { - self.codewords.append(&codewords); - } - - pub fn write_codeword(&self, codeword: char) { - self.codewords.append(codeword); - } - - pub fn get_codeword_count(&self) -> i32 { - return self.codewords.length(); - } - - pub fn get_new_encoding(&self) -> i32 { - return self.new_encoding; - } - - pub fn signal_encoder_change(&self, encoding: i32) { - self.newEncoding = encoding; - } - - pub fn reset_encoder_signal(&self) { - self.newEncoding = -1; - } - - pub fn has_more_characters(&self) -> bool { - return self.pos < self.get_total_message_char_count(); - } - - fn get_total_message_char_count(&self) -> i32 { - return self.msg.length() - self.skip_at_end; - } - - pub fn get_remaining_characters(&self) -> i32 { - return self.get_total_message_char_count() - self.pos; - } - - pub fn get_symbol_info(&self) -> SymbolInfo { - return self.symbol_info; - } - - pub fn update_symbol_info(&self) { - self.update_symbol_info(&self.get_codeword_count()); - } - - pub fn update_symbol_info(&self, len: i32) { - if self.symbolInfo == null || len > self.symbolInfo.get_data_capacity() { - self.symbolInfo = SymbolInfo::lookup(len, self.shape, self.min_size, self.max_size, true); - } - } - - pub fn reset_symbol_info(&self) { - self.symbolInfo = null; - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/error_correction.rs b/port_src/output/zxing/datamatrix/encoder/error_correction.rs deleted file mode 100644 index 35f9db7..0000000 --- a/port_src/output/zxing/datamatrix/encoder/error_correction.rs +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2006 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -/** - * Error Correction Code for ECC200. - */ - -/** - * Lookup table which factors to use for which number of error correction codewords. - * See FACTORS. - */ - const FACTOR_SETS: vec![Vec; 16] = vec![5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68, ] -; - -/** - * Precomputed polynomial factors for ECC 200. - */ - const FACTORS: vec![vec![Vec>; 68]; 16] = vec![vec![228, 48, 15, 111, 62, ] -, vec![23, 68, 144, 134, 240, 92, 254, ] -, vec![28, 24, 185, 166, 223, 248, 116, 255, 110, 61, ] -, vec![175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120, ] -, vec![41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242, ] -, vec![156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185, ] -, vec![83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, 90, 188, ] -, vec![15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27, 174, 186, 172, ] -, vec![52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172, 254, 124, 12, 181, 184, 96, 50, 193, ] -, vec![211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121, 17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255, ] -, vec![245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, 182, 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25, 225, 98, 81, 112, ] -, vec![77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8, 175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101, 248, 202, 69, 50, 150, 177, 226, 5, 9, 5, ] -, vec![245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87, 191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138, 186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19, ] -, vec![175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235, 150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232, 144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28, 155, 43, 203, 107, 233, 53, 143, 46, ] -, vec![242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37, 185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71, 161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31, 176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204, ] -, vec![220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127, 213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236, 66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239, 181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63, 96, 103, 82, 186, ] -, ] -; - - const MODULO_VALUE: i32 = 0x12D; - - const LOG: Vec; - - const ALOG: Vec; -pub struct ErrorCorrection { -} - -impl ErrorCorrection { - - static { - //Create log and antilog table - LOG = : [i32; 256] = [0; 256]; - ALOG = : [i32; 255] = [0; 255]; - let mut p: i32 = 1; - { - let mut i: i32 = 0; - while i < 255 { - { - ALOG[i] = p; - LOG[p] = i; - p *= 2; - if p >= 256 { - p ^= MODULO_VALUE; - } - } - i += 1; - } - } - - } - - fn new() -> ErrorCorrection { - } - - /** - * Creates the ECC200 error correction for an encoded message. - * - * @param codewords the codewords - * @param symbolInfo information about the symbol to be encoded - * @return the codewords with interleaved error correction. - */ - pub fn encode_e_c_c200( codewords: &String, symbol_info: &SymbolInfo) -> String { - if codewords.length() != symbol_info.get_data_capacity() { - throw IllegalArgumentException::new("The number of codewords does not match the selected symbol"); - } - let sb: StringBuilder = StringBuilder::new(symbol_info.get_data_capacity() + symbol_info.get_error_codewords()); - sb.append(&codewords); - let block_count: i32 = symbol_info.get_interleaved_block_count(); - if block_count == 1 { - let ecc: String = ::create_e_c_c_block(&codewords, &symbol_info.get_error_codewords()); - sb.append(&ecc); - } else { - sb.set_length(&sb.capacity()); - let data_sizes: [i32; block_count] = [0; block_count]; - let error_sizes: [i32; block_count] = [0; block_count]; - { - let mut i: i32 = 0; - while i < block_count { - { - data_sizes[i] = symbol_info.get_data_length_for_interleaved_block(i + 1); - error_sizes[i] = symbol_info.get_error_length_for_interleaved_block(i + 1); - } - i += 1; - } - } - - { - let mut block: i32 = 0; - while block < block_count { - { - let temp: StringBuilder = StringBuilder::new(data_sizes[block]); - { - let mut d: i32 = block; - while d < symbol_info.get_data_capacity() { - { - temp.append(&codewords.char_at(d)); - } - d += block_count; - } - } - - let ecc: String = ::create_e_c_c_block(&temp.to_string(), error_sizes[block]); - let mut pos: i32 = 0; - { - let mut e: i32 = block; - while e < error_sizes[block] * block_count { - { - sb.set_char_at(symbol_info.get_data_capacity() + e, &ecc.char_at(pos += 1 !!!check!!! post increment)); - } - e += block_count; - } - } - - } - block += 1; - } - } - - } - return sb.to_string(); - } - - fn create_e_c_c_block( codewords: &CharSequence, num_e_c_words: i32) -> String { - let mut table: i32 = -1; - { - let mut i: i32 = 0; - while i < FACTOR_SETS.len() { - { - if FACTOR_SETS[i] == num_e_c_words { - table = i; - break; - } - } - i += 1; - } - } - - if table < 0 { - throw IllegalArgumentException::new(format!("Illegal number of error correction codewords specified: {}", num_e_c_words)); - } - let poly: Vec = FACTORS[table]; - let mut ecc: [Option; num_e_c_words] = [None; num_e_c_words]; - { - let mut i: i32 = 0; - while i < num_e_c_words { - { - ecc[i] = 0; - } - i += 1; - } - } - - { - let mut i: i32 = 0; - while i < codewords.length() { - { - let m: i32 = ecc[num_e_c_words - 1] ^ codewords.char_at(i); - { - let mut k: i32 = num_e_c_words - 1; - while k > 0 { - { - if m != 0 && poly[k] != 0 { - ecc[k] = (ecc[k - 1] ^ ALOG[(LOG[m] + LOG[poly[k]]) % 255]) as char; - } else { - ecc[k] = ecc[k - 1]; - } - } - k -= 1; - } - } - - if m != 0 && poly[0] != 0 { - ecc[0] = ALOG[(LOG[m] + LOG[poly[0]]) % 255] as char; - } else { - ecc[0] = 0; - } - } - i += 1; - } - } - - let ecc_reversed: [Option; num_e_c_words] = [None; num_e_c_words]; - { - let mut i: i32 = 0; - while i < num_e_c_words { - { - ecc_reversed[i] = ecc[num_e_c_words - i - 1]; - } - i += 1; - } - } - - return String::value_of(&ecc_reversed); - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/high_level_encoder.rs b/port_src/output/zxing/datamatrix/encoder/high_level_encoder.rs deleted file mode 100644 index e4d7b59..0000000 --- a/port_src/output/zxing/datamatrix/encoder/high_level_encoder.rs +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -/** - * DataMatrix ECC 200 data encoder following the algorithm described in ISO/IEC 16022:200(E) in - * annex S. - */ - -/** - * Padding character - */ - const PAD: char = 129; - -/** - * mode latch to C40 encodation mode - */ - const LATCH_TO_C40: char = 230; - -/** - * mode latch to Base 256 encodation mode - */ - const LATCH_TO_BASE256: char = 231; - -/** - * FNC1 Codeword - */ -//private static final char FNC1 = 232; -/** - * Structured Append Codeword - */ -//private static final char STRUCTURED_APPEND = 233; -/** - * Reader Programming - */ -//private static final char READER_PROGRAMMING = 234; -/** - * Upper Shift - */ - const UPPER_SHIFT: char = 235; - -/** - * 05 Macro - */ - const MACRO_05: char = 236; - -/** - * 06 Macro - */ - const MACRO_06: char = 237; - -/** - * mode latch to ANSI X.12 encodation mode - */ - const LATCH_TO_ANSIX12: char = 238; - -/** - * mode latch to Text encodation mode - */ - const LATCH_TO_TEXT: char = 239; - -/** - * mode latch to EDIFACT encodation mode - */ - const LATCH_TO_EDIFACT: char = 240; - -/** - * ECI character (Extended Channel Interpretation) - */ -//private static final char ECI = 241; -/** - * Unlatch from C40 encodation - */ - const C40_UNLATCH: char = 254; - -/** - * Unlatch from X12 encodation - */ - const X12_UNLATCH: char = 254; - -/** - * 05 Macro header - */ - const MACRO_05_HEADER: &'static str = "[)>05"; - -/** - * 06 Macro header - */ - const MACRO_06_HEADER: &'static str = "[)>06"; - -/** - * Macro trailer - */ - const MACRO_TRAILER: &'static str = ""; - - const ASCII_ENCODATION: i32 = 0; - - const C40_ENCODATION: i32 = 1; - - const TEXT_ENCODATION: i32 = 2; - - const X12_ENCODATION: i32 = 3; - - const EDIFACT_ENCODATION: i32 = 4; - - const BASE256_ENCODATION: i32 = 5; -pub struct HighLevelEncoder { -} - -impl HighLevelEncoder { - - fn new() -> HighLevelEncoder { - } - - fn randomize253_state( codeword_position: i32) -> char { - let pseudo_random: i32 = ((149 * codeword_position) % 253) + 1; - let temp_variable: i32 = PAD + pseudo_random; - return ( if temp_variable <= 254 { temp_variable } else { temp_variable - 254 }) as char; - } - - /** - * Performs message encoding of a DataMatrix message using the algorithm described in annex P - * of ISO/IEC 16022:2000(E). - * - * @param msg the message - * @return the encoded message (the char values range from 0 to 255) - */ - pub fn encode_high_level( msg: &String) -> String { - return ::encode_high_level(&msg, SymbolShapeHint::FORCE_NONE, null, null, false); - } - - /** - * Performs message encoding of a DataMatrix message using the algorithm described in annex P - * of ISO/IEC 16022:2000(E). - * - * @param msg the message - * @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE}, - * {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}. - * @param minSize the minimum symbol size constraint or null for no constraint - * @param maxSize the maximum symbol size constraint or null for no constraint - * @return the encoded message (the char values range from 0 to 255) - */ - pub fn encode_high_level( msg: &String, shape: &SymbolShapeHint, min_size: &Dimension, max_size: &Dimension) -> String { - return ::encode_high_level(&msg, shape, min_size, max_size, false); - } - - /** - * Performs message encoding of a DataMatrix message using the algorithm described in annex P - * of ISO/IEC 16022:2000(E). - * - * @param msg the message - * @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE}, - * {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}. - * @param minSize the minimum symbol size constraint or null for no constraint - * @param maxSize the maximum symbol size constraint or null for no constraint - * @param forceC40 enforce C40 encoding - * @return the encoded message (the char values range from 0 to 255) - */ - pub fn encode_high_level( msg: &String, shape: &SymbolShapeHint, min_size: &Dimension, max_size: &Dimension, force_c40: bool) -> String { - //the codewords 0..255 are encoded as Unicode characters - let c40_encoder: C40Encoder = C40Encoder::new(); - let encoders: vec![Vec; 6] = vec![ASCIIEncoder::new(), c40_encoder, TextEncoder::new(), X12Encoder::new(), EdifactEncoder::new(), Base256Encoder::new(), ] - ; - let mut context: EncoderContext = EncoderContext::new(&msg); - context.set_symbol_shape(shape); - context.set_size_constraints(min_size, max_size); - if msg.starts_with(&MACRO_05_HEADER) && msg.ends_with(&MACRO_TRAILER) { - context.write_codeword(MACRO_05); - context.set_skip_at_end(2); - context.pos += MACRO_05_HEADER::length(); - } else if msg.starts_with(&MACRO_06_HEADER) && msg.ends_with(&MACRO_TRAILER) { - context.write_codeword(MACRO_06); - context.set_skip_at_end(2); - context.pos += MACRO_06_HEADER::length(); - } - //Default mode - let encoding_mode: i32 = ASCII_ENCODATION; - if force_c40 { - c40_encoder.encode_maximal(context); - encoding_mode = context.get_new_encoding(); - context.reset_encoder_signal(); - } - while context.has_more_characters() { - encoders[encoding_mode].encode(context); - if context.get_new_encoding() >= 0 { - encoding_mode = context.get_new_encoding(); - context.reset_encoder_signal(); - } - } - let len: i32 = context.get_codeword_count(); - context.update_symbol_info(); - let capacity: i32 = context.get_symbol_info().get_data_capacity(); - if len < capacity && encoding_mode != ASCII_ENCODATION && encoding_mode != BASE256_ENCODATION && encoding_mode != EDIFACT_ENCODATION { - //Unlatch (254) - context.write_codeword('þ'); - } - //Padding - let codewords: StringBuilder = context.get_codewords(); - if codewords.length() < capacity { - codewords.append(PAD); - } - while codewords.length() < capacity { - codewords.append(&::randomize253_state(codewords.length() + 1)); - } - return context.get_codewords().to_string(); - } - - fn look_ahead_test( msg: &CharSequence, startpos: i32, current_mode: i32) -> i32 { - let new_mode: i32 = ::look_ahead_test_intern(&msg, startpos, current_mode); - if current_mode == X12_ENCODATION && new_mode == X12_ENCODATION { - let endpos: i32 = Math::min(startpos + 3, &msg.length()); - { - let mut i: i32 = startpos; - while i < endpos { - { - if !::is_native_x12(&msg.char_at(i)) { - return ASCII_ENCODATION; - } - } - i += 1; - } - } - - } else if current_mode == EDIFACT_ENCODATION && new_mode == EDIFACT_ENCODATION { - let endpos: i32 = Math::min(startpos + 4, &msg.length()); - { - let mut i: i32 = startpos; - while i < endpos { - { - if !::is_native_e_d_i_f_a_c_t(&msg.char_at(i)) { - return ASCII_ENCODATION; - } - } - i += 1; - } - } - - } - return new_mode; - } - - fn look_ahead_test_intern( msg: &CharSequence, startpos: i32, current_mode: i32) -> i32 { - if startpos >= msg.length() { - return current_mode; - } - let char_counts: Vec; - //step J - if current_mode == ASCII_ENCODATION { - char_counts = : vec![f32; 6] = vec![0.0, 1.0, 1.0, 1.0, 1.0, 1.25f, ] - ; - } else { - char_counts = : vec![f32; 6] = vec![1.0, 2.0, 2.0, 2.0, 2.0, 2.25f, ] - ; - char_counts[current_mode] = 0.0; - } - let chars_processed: i32 = 0; - let mins: [i8; 6] = [0; 6]; - let int_char_counts: [i32; 6] = [0; 6]; - while true { - //step K - if (startpos + chars_processed) == msg.length() { - Arrays::fill(&mins, 0 as i8); - Arrays::fill(&int_char_counts, 0); - let min: i32 = ::find_minimums(&char_counts, &int_char_counts, Integer::MAX_VALUE, &mins); - let min_count: i32 = ::get_minimum_count(&mins); - if int_char_counts[ASCII_ENCODATION] == min { - return ASCII_ENCODATION; - } - if min_count == 1 { - if mins[BASE256_ENCODATION] > 0 { - return BASE256_ENCODATION; - } - if mins[EDIFACT_ENCODATION] > 0 { - return EDIFACT_ENCODATION; - } - if mins[TEXT_ENCODATION] > 0 { - return TEXT_ENCODATION; - } - if mins[X12_ENCODATION] > 0 { - return X12_ENCODATION; - } - } - return C40_ENCODATION; - } - let c: char = msg.char_at(startpos + chars_processed); - chars_processed += 1; - //step L - if ::is_digit(c) { - char_counts[ASCII_ENCODATION] += 0.5f; - } else if ::is_extended_a_s_c_i_i(c) { - char_counts[ASCII_ENCODATION] = Math::ceil(char_counts[ASCII_ENCODATION]) as f32; - char_counts[ASCII_ENCODATION] += 2.0f; - } else { - char_counts[ASCII_ENCODATION] = Math::ceil(char_counts[ASCII_ENCODATION]) as f32; - char_counts[ASCII_ENCODATION] += 1; - } - //step M - if ::is_native_c40(c) { - char_counts[C40_ENCODATION] += 2.0f / 3.0f; - } else if ::is_extended_a_s_c_i_i(c) { - char_counts[C40_ENCODATION] += 8.0f / 3.0f; - } else { - char_counts[C40_ENCODATION] += 4.0f / 3.0f; - } - //step N - if ::is_native_text(c) { - char_counts[TEXT_ENCODATION] += 2.0f / 3.0f; - } else if ::is_extended_a_s_c_i_i(c) { - char_counts[TEXT_ENCODATION] += 8.0f / 3.0f; - } else { - char_counts[TEXT_ENCODATION] += 4.0f / 3.0f; - } - //step O - if ::is_native_x12(c) { - char_counts[X12_ENCODATION] += 2.0f / 3.0f; - } else if ::is_extended_a_s_c_i_i(c) { - char_counts[X12_ENCODATION] += 13.0f / 3.0f; - } else { - char_counts[X12_ENCODATION] += 10.0f / 3.0f; - } - //step P - if ::is_native_e_d_i_f_a_c_t(c) { - char_counts[EDIFACT_ENCODATION] += 3.0f / 4.0f; - } else if ::is_extended_a_s_c_i_i(c) { - char_counts[EDIFACT_ENCODATION] += 17.0f / 4.0f; - } else { - char_counts[EDIFACT_ENCODATION] += 13.0f / 4.0f; - } - // step Q - if ::is_special_b256(c) { - char_counts[BASE256_ENCODATION] += 4.0f; - } else { - char_counts[BASE256_ENCODATION] += 1; - } - //step R - if chars_processed >= 4 { - Arrays::fill(&mins, 0 as i8); - Arrays::fill(&int_char_counts, 0); - ::find_minimums(&char_counts, &int_char_counts, Integer::MAX_VALUE, &mins); - if int_char_counts[ASCII_ENCODATION] < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[EDIFACT_ENCODATION]) { - return ASCII_ENCODATION; - } - if int_char_counts[BASE256_ENCODATION] < int_char_counts[ASCII_ENCODATION] || int_char_counts[BASE256_ENCODATION] + 1 < ::min(int_char_counts[C40_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[EDIFACT_ENCODATION]) { - return BASE256_ENCODATION; - } - if int_char_counts[EDIFACT_ENCODATION] + 1 < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[ASCII_ENCODATION]) { - return EDIFACT_ENCODATION; - } - if int_char_counts[TEXT_ENCODATION] + 1 < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[EDIFACT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[ASCII_ENCODATION]) { - return TEXT_ENCODATION; - } - if int_char_counts[X12_ENCODATION] + 1 < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[EDIFACT_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[ASCII_ENCODATION]) { - return X12_ENCODATION; - } - if int_char_counts[C40_ENCODATION] + 1 < ::min(int_char_counts[ASCII_ENCODATION], int_char_counts[BASE256_ENCODATION], int_char_counts[EDIFACT_ENCODATION], int_char_counts[TEXT_ENCODATION]) { - if int_char_counts[C40_ENCODATION] < int_char_counts[X12_ENCODATION] { - return C40_ENCODATION; - } - if int_char_counts[C40_ENCODATION] == int_char_counts[X12_ENCODATION] { - let mut p: i32 = startpos + chars_processed + 1; - while p < msg.length() { - let tc: char = msg.char_at(p); - if ::is_x12_term_sep(tc) { - return X12_ENCODATION; - } - if !::is_native_x12(tc) { - break; - } - p += 1; - } - return C40_ENCODATION; - } - } - } - } - } - - fn min( f1: i32, f2: i32, f3: i32, f4: i32, f5: i32) -> i32 { - return Math::min(&::min(f1, f2, f3, f4), f5); - } - - fn min( f1: i32, f2: i32, f3: i32, f4: i32) -> i32 { - return Math::min(f1, &Math::min(f2, &Math::min(f3, f4))); - } - - fn find_minimums( char_counts: &Vec, int_char_counts: &Vec, min: i32, mins: &Vec) -> i32 { - { - let mut i: i32 = 0; - while i < 6 { - { - let current: i32 = (int_char_counts[i] = Math::ceil(char_counts[i]) as i32); - if min > current { - min = current; - Arrays::fill(&mins, 0 as i8); - } - if min == current { - mins[i] += 1; - } - } - i += 1; - } - } - - return min; - } - - fn get_minimum_count( mins: &Vec) -> i32 { - let min_count: i32 = 0; - { - let mut i: i32 = 0; - while i < 6 { - { - min_count += mins[i]; - } - i += 1; - } - } - - return min_count; - } - - fn is_digit( ch: char) -> bool { - return ch >= '0' && ch <= '9'; - } - - fn is_extended_a_s_c_i_i( ch: char) -> bool { - return ch >= 128 && ch <= 255; - } - - fn is_native_c40( ch: char) -> bool { - return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); - } - - fn is_native_text( ch: char) -> bool { - return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z'); - } - - fn is_native_x12( ch: char) -> bool { - return ::is_x12_term_sep(ch) || (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); - } - - fn is_x12_term_sep( ch: char) -> bool { - return //CR - (ch == '\r') || (ch == '*') || (ch == '>'); - } - - fn is_native_e_d_i_f_a_c_t( ch: char) -> bool { - return ch >= ' ' && ch <= '^'; - } - - fn is_special_b256( ch: char) -> bool { - //TODO NOT IMPLEMENTED YET!!! - return false; - } - - /** - * Determines the number of consecutive characters that are encodable using numeric compaction. - * - * @param msg the message - * @param startpos the start position within the message - * @return the requested character count - */ - pub fn determine_consecutive_digit_count( msg: &CharSequence, startpos: i32) -> i32 { - let len: i32 = msg.length(); - let mut idx: i32 = startpos; - while idx < len && ::is_digit(&msg.char_at(idx)) { - idx += 1; - } - return idx - startpos; - } - - fn illegal_character( c: char) { - let mut hex: String = Integer::to_hex_string(c); - hex = format!("{}{}", "0000".substring(0, 4 - hex.length()), hex); - throw IllegalArgumentException::new(format!("Illegal character: {} (0x{})", c, hex)); - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/minimal_encoder.rs b/port_src/output/zxing/datamatrix/encoder/minimal_encoder.rs deleted file mode 100644 index 11cebf5..0000000 --- a/port_src/output/zxing/datamatrix/encoder/minimal_encoder.rs +++ /dev/null @@ -1,947 +0,0 @@ -/* - * Copyright 2021 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -/** - * Encoder that encodes minimally - * - * Algorithm: - * - * Uses Dijkstra to produce mathematically minimal encodings that are in some cases smaller than the results produced - * by the algorithm described in annex S in the specification ISO/IEC 16022:200(E). The biggest improvment of this - * algorithm over that one is the case when the algorithm enters the most inefficient mode, the B256 mode. The - * algorithm from the specification algorithm will exit this mode only if it encounters digits so that arbitrarily - * inefficient results can be produced if the postfix contains no digits. - * - * Multi ECI support and ECI switching: - * - * For multi language content the algorithm selects the most compact representation using ECI modes. Note that unlike - * the compaction algorithm used for QR-Codes, this implementation operates in two stages and therfore is not - * mathematically optimal. In the first stage, the input string is encoded minimally as a stream of ECI character set - * selectors and bytes encoded in the selected encoding. In this stage the algorithm might for example decide to - * encode ocurrences of the characters "\u0150\u015C" (O-double-acute, S-circumflex) in UTF-8 by a single ECI or - * alternatively by multiple ECIs that switch between IS0-8859-2 and ISO-8859-3 (e.g. in the case that the input - * contains many * characters from ISO-8859-2 (Latin 2) and few from ISO-8859-3 (Latin 3)). - * In a second stage this stream of ECIs and bytes is minimally encoded using the various Data Matrix encoding modes. - * While both stages encode mathematically minimally it is not ensured that the result is mathematically minimal since - * the size growth for inserting an ECI in the first stage can only be approximated as the first stage does not know - * in which mode the ECI will occur in the second stage (may, or may not require an extra latch to ASCII depending on - * the current mode). The reason for this shortcoming are difficulties in implementing it in a straightforward and - * readable manner. - * - * GS1 support - * - * FNC1 delimiters can be encoded in the input string by using the FNC1 character specified in the encoding function. - * When a FNC1 character is specified then a leading FNC1 will be encoded and all ocurrences of delimiter characters - * while result in FNC1 codewords in the symbol. - * - * @author Alex Geller - */ - - const C40_SHIFT2_CHARS: vec![Vec; 27] = vec!['!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', ] -; -pub struct MinimalEncoder { -} - -impl MinimalEncoder { - - enum Mode { - - ASCII(), C40(), TEXT(), X12(), EDF(), B256() - } - - fn new() -> MinimalEncoder { - } - - fn is_extended_a_s_c_i_i( ch: char, fnc1: i32) -> bool { - return ch != fnc1 && ch >= 128 && ch <= 255; - } - - fn is_in_c40_shift1_set( ch: char) -> bool { - return ch <= 31; - } - - fn is_in_c40_shift2_set( ch: char, fnc1: i32) -> bool { - for let c40_shift2_char: char in C40_SHIFT2_CHARS { - if c40_shift2_char == ch { - return true; - } - } - return ch == fnc1; - } - - fn is_in_text_shift1_set( ch: char) -> bool { - return ::is_in_c40_shift1_set(ch); - } - - fn is_in_text_shift2_set( ch: char, fnc1: i32) -> bool { - return ::is_in_c40_shift2_set(ch, fnc1); - } - - pub fn encode_high_level( msg: &String) -> String { - return ::encode_high_level(&msg, null, -1, SymbolShapeHint::FORCE_NONE); - } - - pub fn encode_high_level( msg: &String, priority_charset: &Charset, fnc1: i32, shape: &SymbolShapeHint) -> String { - let macro_id: i32 = 0; - if msg.starts_with(HighLevelEncoder::MACRO_05_HEADER) && msg.ends_with(HighLevelEncoder::MACRO_TRAILER) { - macro_id = 5; - msg = msg.substring(&HighLevelEncoder::MACRO_05_HEADER::length(), msg.length() - 2); - } else if msg.starts_with(HighLevelEncoder::MACRO_06_HEADER) && msg.ends_with(HighLevelEncoder::MACRO_TRAILER) { - macro_id = 6; - msg = msg.substring(&HighLevelEncoder::MACRO_06_HEADER::length(), msg.length() - 2); - } - return String::new(&::encode(&msg, &priority_charset, fnc1, shape, macro_id), StandardCharsets::ISO_8859_1); - } - - fn encode( input: &String, priority_charset: &Charset, fnc1: i32, shape: &SymbolShapeHint, macro_id: i32) -> Vec { - return ::encode_minimally(Input::new(&input, &priority_charset, fnc1, shape, macro_id)).get_bytes(); - } - - fn add_edge( edges: &Vec>, edge: &Edge) { - let vertex_index: i32 = edge.fromPosition + edge.characterLength; - if edges[vertex_index][edge.get_end_mode().ordinal()] == null || edges[vertex_index][edge.get_end_mode().ordinal()].cachedTotalSize > edge.cachedTotalSize { - edges[vertex_index][edge.get_end_mode().ordinal()] = edge; - } - } - - fn get_number_of_c40_words( input: &Input, from: i32, c40: bool, character_length: &Vec) -> i32 { - let thirds_count: i32 = 0; - { - let mut i: i32 = from; - while i < input.length() { - { - if input.is_e_c_i(i) { - character_length[0] = 0; - return 0; - } - let ci: char = input.char_at(i); - if c40 && HighLevelEncoder::is_native_c40(ci) || !c40 && HighLevelEncoder::is_native_text(ci) { - thirds_count += 1; - } else if !::is_extended_a_s_c_i_i(ci, &input.get_f_n_c1_character()) { - thirds_count += 2; - } else { - let ascii_value: i32 = ci & 0xff; - if ascii_value >= 128 && (c40 && HighLevelEncoder::is_native_c40((ascii_value - 128) as char) || !c40 && HighLevelEncoder::is_native_text((ascii_value - 128) as char)) { - thirds_count += 3; - } else { - thirds_count += 4; - } - } - if thirds_count % 3 == 0 || ((thirds_count - 2) % 3 == 0 && i + 1 == input.length()) { - character_length[0] = i - from + 1; - return Math::ceil((thirds_count as f64) / 3.0) as i32; - } - } - i += 1; - } - } - - character_length[0] = 0; - return 0; - } - - fn add_edges( input: &Input, edges: &Vec>, from: i32, previous: &Edge) { - if input.is_e_c_i(from) { - ::add_edge(edges, Edge::new(input, Mode::ASCII, from, 1, previous)); - return; - } - let ch: char = input.char_at(from); - if previous == null || previous.get_end_mode() != Mode::EDF { - if HighLevelEncoder::is_digit(ch) && input.have_n_characters(from, 2) && HighLevelEncoder::is_digit(&input.char_at(from + 1)) { - ::add_edge(edges, Edge::new(input, Mode::ASCII, from, 2, previous)); - } else { - ::add_edge(edges, Edge::new(input, Mode::ASCII, from, 1, previous)); - } - let modes: vec![Vec; 2] = vec![Mode::C40, Mode::TEXT, ] - ; - for let mode: Mode in modes { - let character_length: [i32; 1] = [0; 1]; - if ::get_number_of_c40_words(input, from, mode == Mode::C40, &character_length) > 0 { - ::add_edge(edges, Edge::new(input, mode, from, character_length[0], previous)); - } - } - if input.have_n_characters(from, 3) && HighLevelEncoder::is_native_x12(&input.char_at(from)) && HighLevelEncoder::is_native_x12(&input.char_at(from + 1)) && HighLevelEncoder::is_native_x12(&input.char_at(from + 2)) { - ::add_edge(edges, Edge::new(input, Mode::X12, from, 3, previous)); - } - ::add_edge(edges, Edge::new(input, Mode::B256, from, 1, previous)); - } - //unless it is 2 characters away from the end of the input. - let mut i: i32; - { - i = 0; - while i < 3 { - { - let pos: i32 = from + i; - if input.have_n_characters(pos, 1) && HighLevelEncoder::is_native_e_d_i_f_a_c_t(&input.char_at(pos)) { - ::add_edge(edges, Edge::new(input, Mode::EDF, from, i + 1, previous)); - } else { - break; - } - } - i += 1; - } - } - - if i == 3 && input.have_n_characters(from, 4) && HighLevelEncoder::is_native_e_d_i_f_a_c_t(&input.char_at(from + 3)) { - ::add_edge(edges, Edge::new(input, Mode::EDF, from, 4, previous)); - } - } - - fn encode_minimally( input: &Input) -> Result { - let input_length: i32 = input.length(); - // Array that represents vertices. There is a vertex for every character and mode. - // The last dimension in the array below encodes the 6 modes ASCII, C40, TEXT, X12, EDF and B256 - let mut edges: [[Option; 6]; input_length + 1] = [[None; 6]; input_length + 1]; - ::add_edges(input, edges, 0, null); - { - let mut i: i32 = 1; - while i <= input_length { - { - { - let mut j: i32 = 0; - while j < 6 { - { - if edges[i][j] != null && i < input_length { - ::add_edges(input, edges, i, edges[i][j]); - } - } - j += 1; - } - } - - //optimize memory by removing edges that have been passed. - { - let mut j: i32 = 0; - while j < 6 { - { - edges[i - 1][j] = null; - } - j += 1; - } - } - - } - i += 1; - } - } - - let minimal_j: i32 = -1; - let minimal_size: i32 = Integer::MAX_VALUE; - { - let mut j: i32 = 0; - while j < 6 { - { - if edges[input_length][j] != null { - let edge: Edge = edges[input_length][j]; - //C40, TEXT and X12 need an - let size: i32 = if j >= 1 && j <= 3 { edge.cachedTotalSize + 1 } else { edge.cachedTotalSize }; - // extra unlatch at the end - if size < minimal_size { - minimal_size = size; - minimal_j = j; - } - } - } - j += 1; - } - } - - if minimal_j < 0 { - throw RuntimeException::new(format!("Internal error: failed to encode \"{}\"", input)); - } - return Result::new(edges[input_length][minimal_j]); - } - - - let all_codeword_capacities: vec![Vec; 28] = vec![3, 5, 8, 10, 12, 16, 18, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558, ] - ; - - let square_codeword_capacities: vec![Vec; 24] = vec![3, 5, 8, 12, 18, 22, 30, 36, 44, 62, 86, 114, 144, 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558, ] - ; - - let rectangular_codeword_capacities: vec![Vec; 6] = vec![5, 10, 16, 33, 32, 49, ] - ; - struct Edge { - - let input: Input; - - //the mode at the start of this edge. - let mode: Mode; - - let from_position: i32; - - let character_length: i32; - - let previous: Edge; - - let cached_total_size: i32; - } - - impl Edge { - - fn new( input: &Input, mode: &Mode, from_position: i32, character_length: i32, previous: &Edge) -> Edge { - let .input = input; - let .mode = mode; - let .fromPosition = from_position; - let .characterLength = character_length; - let .previous = previous; - assert!( from_position + character_length <= input.length()); - let mut size: i32 = if previous != null { previous.cachedTotalSize } else { 0 }; - let previous_mode: Mode = self.get_previous_mode(); - /* - * Switching modes - * ASCII -> C40: latch 230 - * ASCII -> TEXT: latch 239 - * ASCII -> X12: latch 238 - * ASCII -> EDF: latch 240 - * ASCII -> B256: latch 231 - * C40 -> ASCII: word(c1,c2,c3), 254 - * TEXT -> ASCII: word(c1,c2,c3), 254 - * X12 -> ASCII: word(c1,c2,c3), 254 - * EDIFACT -> ASCII: Unlatch character,0,0,0 or c1,Unlatch character,0,0 or c1,c2,Unlatch character,0 or - * c1,c2,c3,Unlatch character - * B256 -> ASCII: without latch after n bytes - */ - match mode { - ASCII => - { - size += 1; - if input.is_e_c_i(from_position) || ::is_extended_a_s_c_i_i(&input.char_at(from_position), &input.get_f_n_c1_character()) { - size += 1; - } - if previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12 { - // unlatch 254 to ASCII - size += 1; - } - break; - } - B256 => - { - size += 1; - if previous_mode != Mode::B256 { - //byte count - size += 1; - } else if self.get_b256_size() == 250 { - //extra byte count - size += 1; - } - if previous_mode == Mode::ASCII { - //latch to B256 - size += 1; - } else if previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12 { - //unlatch to ASCII, latch to B256 - size += 2; - } - break; - } - C40 => - { - } - TEXT => - { - } - X12 => - { - if mode == Mode::X12 { - size += 2; - } else { - let char_len: [i32; 1] = [0; 1]; - size += ::get_number_of_c40_words(input, from_position, mode == Mode::C40, &char_len) * 2; - } - if previous_mode == Mode::ASCII || previous_mode == Mode::B256 { - //additional byte for latch from ASCII to this mode - size += 1; - } else if previous_mode != mode && (previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12) { - //unlatch 254 to ASCII followed by latch to this mode - size += 2; - } - break; - } - EDF => - { - size += 3; - if previous_mode == Mode::ASCII || previous_mode == Mode::B256 { - //additional byte for latch from ASCII to this mode - size += 1; - } else if previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12 { - //unlatch 254 to ASCII followed by latch to this mode - size += 2; - } - break; - } - } - cached_total_size = size; - } - - // does not count beyond 250 - fn get_b256_size(&self) -> i32 { - let mut cnt: i32 = 0; - let mut current: Edge = self; - while current != null && current.mode == Mode::B256 && cnt <= 250 { - cnt += 1; - current = current.previous; - } - return cnt; - } - - fn get_previous_start_mode(&self) -> Mode { - return if self.previous == null { Mode::ASCII } else { self.previous.mode }; - } - - fn get_previous_mode(&self) -> Mode { - return if self.previous == null { Mode::ASCII } else { self.previous.get_end_mode() }; - } - - /** Returns Mode.ASCII in case that: - * - Mode is EDIFACT and characterLength is less than 4 or the remaining characters can be encoded in at most 2 - * ASCII bytes. - * - Mode is C40, TEXT or X12 and the remaining characters can be encoded in at most 1 ASCII byte. - * Returns mode in all other cases. - * */ - fn get_end_mode(&self) -> Mode { - if self.mode == Mode::EDF { - if self.character_length < 4 { - return Mode::ASCII; - } - // see 5.2.8.2 EDIFACT encodation Rules - let last_a_s_c_i_i: i32 = self.get_last_a_s_c_i_i(); - if last_a_s_c_i_i > 0 && self.get_codewords_remaining(self.cached_total_size + last_a_s_c_i_i) <= 2 - last_a_s_c_i_i { - return Mode::ASCII; - } - } - if self.mode == Mode::C40 || self.mode == Mode::TEXT || self.mode == Mode::X12 { - // see 5.2.5.2 C40 encodation rules and 5.2.7.2 ANSI X12 encodation rules - if self.from_position + self.character_length >= self.input.length() && self.get_codewords_remaining(self.cached_total_size) == 0 { - return Mode::ASCII; - } - let last_a_s_c_i_i: i32 = self.get_last_a_s_c_i_i(); - if last_a_s_c_i_i == 1 && self.get_codewords_remaining(self.cached_total_size + 1) == 0 { - return Mode::ASCII; - } - } - return self.mode; - } - - fn get_mode(&self) -> Mode { - return self.mode; - } - - /** Peeks ahead and returns 1 if the postfix consists of exactly two digits, 2 if the postfix consists of exactly - * two consecutive digits and a non extended character or of 4 digits. - * Returns 0 in any other case - **/ - fn get_last_a_s_c_i_i(&self) -> i32 { - let length: i32 = self.input.length(); - let from: i32 = self.from_position + self.character_length; - if length - from > 4 || from >= length { - return 0; - } - if length - from == 1 { - if ::is_extended_a_s_c_i_i(&self.input.char_at(from), &self.input.get_f_n_c1_character()) { - return 0; - } - return 1; - } - if length - from == 2 { - if ::is_extended_a_s_c_i_i(&self.input.char_at(from), &self.input.get_f_n_c1_character()) || ::is_extended_a_s_c_i_i(&self.input.char_at(from + 1), &self.input.get_f_n_c1_character()) { - return 0; - } - if HighLevelEncoder::is_digit(&self.input.char_at(from)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) { - return 1; - } - return 2; - } - if length - from == 3 { - if HighLevelEncoder::is_digit(&self.input.char_at(from)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) && !::is_extended_a_s_c_i_i(&self.input.char_at(from + 2), &self.input.get_f_n_c1_character()) { - return 2; - } - if HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 2)) && !::is_extended_a_s_c_i_i(&self.input.char_at(from), &self.input.get_f_n_c1_character()) { - return 2; - } - return 0; - } - if HighLevelEncoder::is_digit(&self.input.char_at(from)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 2)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 3)) { - return 2; - } - return 0; - } - - /** Returns the capacity in codewords of the smallest symbol that has enough capacity to fit the given minimal - * number of codewords. - **/ - fn get_min_symbol_size(&self, minimum: i32) -> i32 { - match self.input.get_shape_hint() { - FORCE_SQUARE => - { - for let capacity: i32 in square_codeword_capacities { - if capacity >= minimum { - return capacity; - } - } - break; - } - FORCE_RECTANGLE => - { - for let capacity: i32 in rectangular_codeword_capacities { - if capacity >= minimum { - return capacity; - } - } - break; - } - } - for let capacity: i32 in all_codeword_capacities { - if capacity >= minimum { - return capacity; - } - } - return all_codeword_capacities[all_codeword_capacities.len() - 1]; - } - - /** Returns the remaining capacity in codewords of the smallest symbol that has enough capacity to fit the given - * minimal number of codewords. - **/ - fn get_codewords_remaining(&self, minimum: i32) -> i32 { - return self.get_min_symbol_size(minimum) - minimum; - } - - fn get_bytes( c: i32) -> Vec { - let mut result: [i8; 1] = [0; 1]; - result[0] = c as i8; - return result; - } - - fn get_bytes( c1: i32, c2: i32) -> Vec { - let mut result: [i8; 2] = [0; 2]; - result[0] = c1 as i8; - result[1] = c2 as i8; - return result; - } - - fn set_c40_word( bytes: &Vec, offset: i32, c1: i32, c2: i32, c3: i32) { - let val16: i32 = (1600 * (c1 & 0xff)) + (40 * (c2 & 0xff)) + (c3 & 0xff) + 1; - bytes[offset] = (val16 / 256) as i8; - bytes[offset + 1] = (val16 % 256) as i8; - } - - fn get_x12_value( c: char) -> i32 { - return if c == 13 { 0 } else { if c == 42 { 1 } else { if c == 62 { 2 } else { if c == 32 { 3 } else { if c >= 48 && c <= 57 { c - 44 } else { if c >= 65 && c <= 90 { c - 51 } else { c } } } } } }; - } - - fn get_x12_words(&self) -> Vec { - assert!( self.character_length % 3 == 0); - let result: [i8; self.character_length / 3 * 2] = [0; self.character_length / 3 * 2]; - { - let mut i: i32 = 0; - while i < result.len() { - { - ::set_c40_word(&result, i, &::get_x12_value(&self.input.char_at(self.from_position + i / 2 * 3)), &::get_x12_value(&self.input.char_at(self.from_position + i / 2 * 3 + 1)), &::get_x12_value(&self.input.char_at(self.from_position + i / 2 * 3 + 2))); - } - i += 2; - } - } - - return result; - } - - fn get_shift_value( c: char, c40: bool, fnc1: i32) -> i32 { - return if (c40 && ::is_in_c40_shift1_set(c) || !c40 && ::is_in_text_shift1_set(c)) { 0 } else { if (c40 && ::is_in_c40_shift2_set(c, fnc1) || !c40 && ::is_in_text_shift2_set(c, fnc1)) { 1 } else { 2 } }; - } - - fn get_c40_value( c40: bool, set_index: i32, c: char, fnc1: i32) -> i32 { - if c == fnc1 { - assert!( set_index == 2); - return 27; - } - if c40 { - return if c <= 31 { c } else { if c == 32 { 3 } else { if c <= 47 { c - 33 } else { if c <= 57 { c - 44 } else { if c <= 64 { c - 43 } else { if c <= 90 { c - 51 } else { if c <= 95 { c - 69 } else { if c <= 127 { c - 96 } else { c } } } } } } } }; - } else { - return if c == 0 { 0 } else { if //is this a bug in the spec? - set_index == 0 && c <= 3 { //is this a bug in the spec? - c - 1 } else { if set_index == 1 && c <= 31 { c } else { if c == 32 { 3 } else { if c >= 33 && c <= 47 { c - 33 } else { if c >= 48 && c <= 57 { c - 44 } else { if c >= 58 && c <= 64 { c - 43 } else { if c >= 65 && c <= 90 { c - 64 } else { if c >= 91 && c <= 95 { c - 69 } else { if c == 96 { 0 } else { if c >= 97 && c <= 122 { c - 83 } else { if c >= 123 && c <= 127 { c - 96 } else { c } } } } } } } } } } } }; - } - } - - fn get_c40_words(&self, c40: bool, fnc1: i32) -> Vec { - let c40_values: List = ArrayList<>::new(); - { - let mut i: i32 = 0; - while i < self.character_length { - { - let ci: char = self.input.char_at(self.from_position + i); - if c40 && HighLevelEncoder::is_native_c40(ci) || !c40 && HighLevelEncoder::is_native_text(ci) { - c40_values.add(::get_c40_value(c40, 0, ci, fnc1) as i8); - } else if !::is_extended_a_s_c_i_i(ci, fnc1) { - let shift_value: i32 = ::get_shift_value(ci, c40, fnc1); - //Shift[123] - c40_values.add(shift_value as i8); - c40_values.add(::get_c40_value(c40, shift_value, ci, fnc1) as i8); - } else { - let ascii_value: char = ((ci & 0xff) - 128) as char; - if c40 && HighLevelEncoder::is_native_c40(ascii_value) || !c40 && HighLevelEncoder::is_native_text(ascii_value) { - //Shift 2 - c40_values.add(1 as i8); - //Upper Shift - c40_values.add(30 as i8); - c40_values.add(::get_c40_value(c40, 0, ascii_value, fnc1) as i8); - } else { - //Shift 2 - c40_values.add(1 as i8); - //Upper Shift - c40_values.add(30 as i8); - let shift_value: i32 = ::get_shift_value(ascii_value, c40, fnc1); - // Shift[123] - c40_values.add(shift_value as i8); - c40_values.add(::get_c40_value(c40, shift_value, ascii_value, fnc1) as i8); - } - } - } - i += 1; - } - } - - if (c40_values.size() % 3) != 0 { - assert!( (c40_values.size() - 2) % 3 == 0 && self.from_position + self.character_length == self.input.length()); - // pad with 0 (Shift 1) - c40_values.add(0 as i8); - } - let result: [i8; c40_values.size() / 3 * 2] = [0; c40_values.size() / 3 * 2]; - let byte_index: i32 = 0; - { - let mut i: i32 = 0; - while i < c40_values.size() { - { - ::set_c40_word(&result, byte_index, c40_values.get(i) & 0xff, c40_values.get(i + 1) & 0xff, c40_values.get(i + 2) & 0xff); - byte_index += 2; - } - i += 3; - } - } - - return result; - } - - fn get_e_d_f_bytes(&self) -> Vec { - let number_of_thirds: i32 = Math::ceil(self.character_length / 4.0) as i32; - let mut result: [i8; number_of_thirds * 3] = [0; number_of_thirds * 3]; - let mut pos: i32 = self.from_position; - let end_pos: i32 = Math::min(self.from_position + self.character_length - 1, self.input.length() - 1); - { - let mut i: i32 = 0; - while i < number_of_thirds { - { - let edf_values: [i32; 4] = [0; 4]; - { - let mut j: i32 = 0; - while j < 4 { - { - if pos <= end_pos { - edf_values[j] = self.input.char_at(pos += 1 !!!check!!! post increment) & 0x3f; - } else { - edf_values[j] = if pos == end_pos + 1 { 0x1f } else { 0 }; - } - } - j += 1; - } - } - - let mut val24: i32 = edf_values[0] << 18; - val24 |= edf_values[1] << 12; - val24 |= edf_values[2] << 6; - val24 |= edf_values[3]; - result[i] = ((val24 >> 16) & 0xff) as i8; - result[i + 1] = ((val24 >> 8) & 0xff) as i8; - result[i + 2] = (val24 & 0xff) as i8; - } - i += 3; - } - } - - return result; - } - - fn get_latch_bytes(&self) -> Vec { - match self.get_previous_mode() { - ASCII => - { - } - //after B256 ends (via length) we are back to ASCII - B256 => - { - match self.mode { - B256 => - { - return ::get_bytes(231); - } - C40 => - { - return ::get_bytes(230); - } - TEXT => - { - return ::get_bytes(239); - } - X12 => - { - return ::get_bytes(238); - } - EDF => - { - return ::get_bytes(240); - } - } - break; - } - C40 => - { - } - TEXT => - { - } - X12 => - { - if self.mode != self.get_previous_mode() { - match self.mode { - ASCII => - { - return ::get_bytes(254); - } - B256 => - { - return ::get_bytes(254, 231); - } - C40 => - { - return ::get_bytes(254, 230); - } - TEXT => - { - return ::get_bytes(254, 239); - } - X12 => - { - return ::get_bytes(254, 238); - } - EDF => - { - return ::get_bytes(254, 240); - } - } - } - break; - } - EDF => - { - //The rightmost EDIFACT edge always contains an unlatch character - assert!( self.mode == Mode::EDF); - break; - } - } - return : [i8; 0] = [0; 0]; - } - - // Important: The function does not return the length bytes (one or two) in case of B256 encoding - fn get_data_bytes(&self) -> Vec { - match self.mode { - ASCII => - { - if self.input.is_e_c_i(self.from_position) { - return ::get_bytes(241, self.input.get_e_c_i_value(self.from_position) + 1); - } else if ::is_extended_a_s_c_i_i(&self.input.char_at(self.from_position), &self.input.get_f_n_c1_character()) { - return ::get_bytes(235, self.input.char_at(self.from_position) - 127); - } else if self.character_length == 2 { - return ::get_bytes((self.input.char_at(self.from_position) - '0') * 10 + self.input.char_at(self.from_position + 1) - '0' + 130); - } else if self.input.is_f_n_c1(self.from_position) { - return ::get_bytes(232); - } else { - return ::get_bytes(self.input.char_at(self.from_position) + 1); - } - } - B256 => - { - return ::get_bytes(&self.input.char_at(self.from_position)); - } - C40 => - { - return self.get_c40_words(true, &self.input.get_f_n_c1_character()); - } - TEXT => - { - return self.get_c40_words(false, &self.input.get_f_n_c1_character()); - } - X12 => - { - return self.get_x12_words(); - } - EDF => - { - return self.get_e_d_f_bytes(); - } - } - assert!( false); - return : [i8; 0] = [0; 0]; - } - } - - - struct Result { - - let mut bytes: Vec; - } - - impl Result { - - fn new( solution: &Edge) -> Result { - let input: Input = solution.input; - let mut size: i32 = 0; - let bytes_a_l: List = ArrayList<>::new(); - let randomize_postfix_length: List = ArrayList<>::new(); - let randomize_lengths: List = ArrayList<>::new(); - if (solution.mode == Mode::C40 || solution.mode == Mode::TEXT || solution.mode == Mode::X12) && solution.get_end_mode() != Mode::ASCII { - size += ::prepend(&MinimalEncoder::Edge::get_bytes(254), &bytes_a_l); - } - let mut current: Edge = solution; - while current != null { - size += ::prepend(¤t.get_data_bytes(), &bytes_a_l); - if current.previous == null || current.get_previous_start_mode() != current.get_mode() { - if current.get_mode() == Mode::B256 { - if size <= 249 { - bytes_a_l.add(0, size as i8); - size += 1; - } else { - bytes_a_l.add(0, (size % 250) as i8); - bytes_a_l.add(0, (size / 250 + 249) as i8); - size += 2; - } - randomize_postfix_length.add(&bytes_a_l.size()); - randomize_lengths.add(size); - } - ::prepend(¤t.get_latch_bytes(), &bytes_a_l); - size = 0; - } - current = current.previous; - } - if input.get_macro_id() == 5 { - size += ::prepend(&MinimalEncoder::Edge::get_bytes(236), &bytes_a_l); - } else if input.get_macro_id() == 6 { - size += ::prepend(&MinimalEncoder::Edge::get_bytes(237), &bytes_a_l); - } - if input.get_f_n_c1_character() > 0 { - size += ::prepend(&MinimalEncoder::Edge::get_bytes(232), &bytes_a_l); - } - { - let mut i: i32 = 0; - while i < randomize_postfix_length.size() { - { - ::apply_random_pattern(&bytes_a_l, bytes_a_l.size() - randomize_postfix_length.get(i), &randomize_lengths.get(i)); - } - i += 1; - } - } - - //add padding - let capacity: i32 = solution.get_min_symbol_size(&bytes_a_l.size()); - if bytes_a_l.size() < capacity { - bytes_a_l.add(129 as i8); - } - while bytes_a_l.size() < capacity { - bytes_a_l.add(::randomize253_state(bytes_a_l.size() + 1) as i8); - } - bytes = : [i8; bytes_a_l.size()] = [0; bytes_a_l.size()]; - { - let mut i: i32 = 0; - while i < bytes.len() { - { - bytes[i] = bytes_a_l.get(i); - } - i += 1; - } - } - - } - - fn prepend( bytes: &Vec, into: &List) -> i32 { - { - let mut i: i32 = bytes.len() - 1; - while i >= 0 { - { - into.add(0, bytes[i]); - } - i -= 1; - } - } - - return bytes.len(); - } - - fn randomize253_state( codeword_position: i32) -> i32 { - let pseudo_random: i32 = ((149 * codeword_position) % 253) + 1; - let temp_variable: i32 = 129 + pseudo_random; - return if temp_variable <= 254 { temp_variable } else { temp_variable - 254 }; - } - - fn apply_random_pattern( bytes_a_l: &List, start_position: i32, length: i32) { - { - let mut i: i32 = 0; - while i < length { - { - //See "B.1 253-state algorithm - const Pad_codeword_position: i32 = start_position + i; - const Pad_codeword_value: i32 = bytes_a_l.get(Pad_codeword_position) & 0xff; - let pseudo_random_number: i32 = ((149 * (Pad_codeword_position + 1)) % 255) + 1; - let temp_variable: i32 = Pad_codeword_value + pseudo_random_number; - bytes_a_l.set(Pad_codeword_position, ( if temp_variable <= 255 { temp_variable } else { temp_variable - 256 }) as i8); - } - i += 1; - } - } - - } - - pub fn get_bytes(&self) -> Vec { - return self.bytes; - } - } - - - struct Input { - super: MinimalECIInput; - - let shape: SymbolShapeHint; - - let macro_id: i32; - } - - impl Input { - - fn new( string_to_encode: &String, priority_charset: &Charset, fnc1: i32, shape: &SymbolShapeHint, macro_id: i32) -> Input { - super(&string_to_encode, &priority_charset, fnc1); - let .shape = shape; - let .macroId = macro_id; - } - - fn get_macro_id(&self) -> i32 { - return self.macro_id; - } - - fn get_shape_hint(&self) -> SymbolShapeHint { - return self.shape; - } - } - -} - diff --git a/port_src/output/zxing/datamatrix/encoder/symbol_info.rs b/port_src/output/zxing/datamatrix/encoder/symbol_info.rs deleted file mode 100644 index e7cd7d8..0000000 --- a/port_src/output/zxing/datamatrix/encoder/symbol_info.rs +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2006 Jeremias Maerki - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -/** - * Symbol info table for DataMatrix. - * - * @version $Id$ - */ - - const PROD_SYMBOLS: vec![Vec; 30] = vec![SymbolInfo::new(false, 3, 5, 8, 8, 1), SymbolInfo::new(false, 5, 7, 10, 10, 1), /*rect*/ -SymbolInfo::new(true, 5, 7, 16, 6, 1), SymbolInfo::new(false, 8, 10, 12, 12, 1), /*rect*/ -SymbolInfo::new(true, 10, 11, 14, 6, 2), SymbolInfo::new(false, 12, 12, 14, 14, 1), /*rect*/ -SymbolInfo::new(true, 16, 14, 24, 10, 1), SymbolInfo::new(false, 18, 14, 16, 16, 1), SymbolInfo::new(false, 22, 18, 18, 18, 1), /*rect*/ -SymbolInfo::new(true, 22, 18, 16, 10, 2), SymbolInfo::new(false, 30, 20, 20, 20, 1), /*rect*/ -SymbolInfo::new(true, 32, 24, 16, 14, 2), SymbolInfo::new(false, 36, 24, 22, 22, 1), SymbolInfo::new(false, 44, 28, 24, 24, 1), /*rect*/ -SymbolInfo::new(true, 49, 28, 22, 14, 2), SymbolInfo::new(false, 62, 36, 14, 14, 4), SymbolInfo::new(false, 86, 42, 16, 16, 4), SymbolInfo::new(false, 114, 48, 18, 18, 4), SymbolInfo::new(false, 144, 56, 20, 20, 4), SymbolInfo::new(false, 174, 68, 22, 22, 4), SymbolInfo::new(false, 204, 84, 24, 24, 4, 102, 42), SymbolInfo::new(false, 280, 112, 14, 14, 16, 140, 56), SymbolInfo::new(false, 368, 144, 16, 16, 16, 92, 36), SymbolInfo::new(false, 456, 192, 18, 18, 16, 114, 48), SymbolInfo::new(false, 576, 224, 20, 20, 16, 144, 56), SymbolInfo::new(false, 696, 272, 22, 22, 16, 174, 68), SymbolInfo::new(false, 816, 336, 24, 24, 16, 136, 56), SymbolInfo::new(false, 1050, 408, 18, 18, 36, 175, 68), SymbolInfo::new(false, 1304, 496, 20, 20, 36, 163, 62), DataMatrixSymbolInfo144::new(), ] -; - - let mut symbols: Vec = PROD_SYMBOLS; -pub struct SymbolInfo { - - let rectangular: bool; - - let data_capacity: i32; - - let error_codewords: i32; - - let matrix_width: i32; - - let matrix_height: i32; - - let data_regions: i32; - - let rs_block_data: i32; - - let rs_block_error: i32; -} - -impl SymbolInfo { - - /** - * Overrides the symbol info set used by this class. Used for testing purposes. - * - * @param override the symbol info set to use - */ - pub fn override_symbol_set( override: &Vec) { - symbols = override; - } - - pub fn new( rectangular: bool, data_capacity: i32, error_codewords: i32, matrix_width: i32, matrix_height: i32, data_regions: i32) -> SymbolInfo { - this(rectangular, data_capacity, error_codewords, matrix_width, matrix_height, data_regions, data_capacity, error_codewords); - } - - fn new( rectangular: bool, data_capacity: i32, error_codewords: i32, matrix_width: i32, matrix_height: i32, data_regions: i32, rs_block_data: i32, rs_block_error: i32) -> SymbolInfo { - let .rectangular = rectangular; - let .dataCapacity = data_capacity; - let .errorCodewords = error_codewords; - let .matrixWidth = matrix_width; - let .matrixHeight = matrix_height; - let .dataRegions = data_regions; - let .rsBlockData = rs_block_data; - let .rsBlockError = rs_block_error; - } - - pub fn lookup( data_codewords: i32) -> SymbolInfo { - return ::lookup(data_codewords, SymbolShapeHint::FORCE_NONE, true); - } - - pub fn lookup( data_codewords: i32, shape: &SymbolShapeHint) -> SymbolInfo { - return ::lookup(data_codewords, shape, true); - } - - pub fn lookup( data_codewords: i32, allow_rectangular: bool, fail: bool) -> SymbolInfo { - let shape: SymbolShapeHint = if allow_rectangular { SymbolShapeHint::FORCE_NONE } else { SymbolShapeHint::FORCE_SQUARE }; - return ::lookup(data_codewords, shape, fail); - } - - fn lookup( data_codewords: i32, shape: &SymbolShapeHint, fail: bool) -> SymbolInfo { - return ::lookup(data_codewords, shape, null, null, fail); - } - - pub fn lookup( data_codewords: i32, shape: &SymbolShapeHint, min_size: &Dimension, max_size: &Dimension, fail: bool) -> SymbolInfo { - for let symbol: SymbolInfo in symbols { - if shape == SymbolShapeHint::FORCE_SQUARE && symbol.rectangular { - continue; - } - if shape == SymbolShapeHint::FORCE_RECTANGLE && !symbol.rectangular { - continue; - } - if min_size != null && (symbol.get_symbol_width() < min_size.get_width() || symbol.get_symbol_height() < min_size.get_height()) { - continue; - } - if max_size != null && (symbol.get_symbol_width() > max_size.get_width() || symbol.get_symbol_height() > max_size.get_height()) { - continue; - } - if data_codewords <= symbol.dataCapacity { - return symbol; - } - } - if fail { - throw IllegalArgumentException::new(format!("Can't find a symbol arrangement that matches the message. Data codewords: {}", data_codewords)); - } - return null; - } - - fn get_horizontal_data_regions(&self) -> i32 { - match self.data_regions { - 1 => - { - return 1; - } - 2 => - { - } - 4 => - { - return 2; - } - 16 => - { - return 4; - } - 36 => - { - return 6; - } - _ => - { - throw IllegalStateException::new("Cannot handle this number of data regions"); - } - } - } - - fn get_vertical_data_regions(&self) -> i32 { - match self.data_regions { - 1 => - { - } - 2 => - { - return 1; - } - 4 => - { - return 2; - } - 16 => - { - return 4; - } - 36 => - { - return 6; - } - _ => - { - throw IllegalStateException::new("Cannot handle this number of data regions"); - } - } - } - - pub fn get_symbol_data_width(&self) -> i32 { - return self.get_horizontal_data_regions() * self.matrix_width; - } - - pub fn get_symbol_data_height(&self) -> i32 { - return self.get_vertical_data_regions() * self.matrix_height; - } - - pub fn get_symbol_width(&self) -> i32 { - return self.get_symbol_data_width() + (self.get_horizontal_data_regions() * 2); - } - - pub fn get_symbol_height(&self) -> i32 { - return self.get_symbol_data_height() + (self.get_vertical_data_regions() * 2); - } - - pub fn get_codeword_count(&self) -> i32 { - return self.data_capacity + self.error_codewords; - } - - pub fn get_interleaved_block_count(&self) -> i32 { - return self.data_capacity / self.rs_block_data; - } - - pub fn get_data_capacity(&self) -> i32 { - return self.data_capacity; - } - - pub fn get_error_codewords(&self) -> i32 { - return self.error_codewords; - } - - pub fn get_data_length_for_interleaved_block(&self, index: i32) -> i32 { - return self.rs_block_data; - } - - pub fn get_error_length_for_interleaved_block(&self, index: i32) -> i32 { - return self.rs_block_error; - } - - pub fn to_string(&self) -> String { - return format!("{} data region {}x{}, symbol size {}x{}, symbol data size {}x{}, codewords {}+{}", ( if self.rectangular { "Rectangular Symbol:" } else { "Square Symbol:" }), self.matrix_width, self.matrix_height, self.get_symbol_width(), self.get_symbol_height(), self.get_symbol_data_width(), self.get_symbol_data_height(), self.data_capacity, self.error_codewords); - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/symbol_shape_hint.rs b/port_src/output/zxing/datamatrix/encoder/symbol_shape_hint.rs deleted file mode 100644 index eed8414..0000000 --- a/port_src/output/zxing/datamatrix/encoder/symbol_shape_hint.rs +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -/** - * Enumeration for DataMatrix symbol shape hint. It can be used to force square or rectangular - * symbols. - */ -pub enum SymbolShapeHint { - - FORCE_NONE(), FORCE_SQUARE(), FORCE_RECTANGLE() -} diff --git a/port_src/output/zxing/datamatrix/encoder/text_encoder.rs b/port_src/output/zxing/datamatrix/encoder/text_encoder.rs deleted file mode 100644 index 193c94a..0000000 --- a/port_src/output/zxing/datamatrix/encoder/text_encoder.rs +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -struct TextEncoder { - super: C40Encoder; -} - -impl TextEncoder { - - pub fn get_encoding_mode(&self) -> i32 { - return HighLevelEncoder::TEXT_ENCODATION; - } - - fn encode_char(&self, c: char, sb: &StringBuilder) -> i32 { - if c == ' ' { - sb.append('\3'); - return 1; - } - if c >= '0' && c <= '9' { - sb.append((c - 48 + 4) as char); - return 1; - } - if c >= 'a' && c <= 'z' { - sb.append((c - 97 + 14) as char); - return 1; - } - if c < ' ' { - //Shift 1 Set - sb.append('\0'); - sb.append(c); - return 2; - } - if c <= '/' { - //Shift 2 Set - sb.append('\1'); - sb.append((c - 33) as char); - return 2; - } - if c <= '@' { - //Shift 2 Set - sb.append('\1'); - sb.append((c - 58 + 15) as char); - return 2; - } - if c >= '[' && c <= '_' { - //Shift 2 Set - sb.append('\1'); - sb.append((c - 91 + 22) as char); - return 2; - } - if c == '`' { - //Shift 3 Set - sb.append('\2'); - // '`' - 96 == 0 - sb.append(0 as char); - return 2; - } - if c <= 'Z' { - //Shift 3 Set - sb.append('\2'); - sb.append((c - 65 + 1) as char); - return 2; - } - if c <= 127 { - //Shift 3 Set - sb.append('\2'); - sb.append((c - 123 + 27) as char); - return 2; - } - //Shift 2, Upper Shift - sb.append("\1"); - let mut len: i32 = 2; - len += self.encode_char((c - 128) as char, &sb); - return len; - } -} - diff --git a/port_src/output/zxing/datamatrix/encoder/x12_encoder.rs b/port_src/output/zxing/datamatrix/encoder/x12_encoder.rs deleted file mode 100644 index 3d27727..0000000 --- a/port_src/output/zxing/datamatrix/encoder/x12_encoder.rs +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// package com::google::zxing::datamatrix::encoder; - -struct X12Encoder { - super: C40Encoder; -} - -impl X12Encoder { - - pub fn get_encoding_mode(&self) -> i32 { - return HighLevelEncoder::X12_ENCODATION; - } - - pub fn encode(&self, context: &EncoderContext) { - //step C - let buffer: StringBuilder = StringBuilder::new(); - while context.has_more_characters() { - let c: char = context.get_current_char(); - context.pos += 1; - self.encode_char(c, &buffer); - let count: i32 = buffer.length(); - if (count % 3) == 0 { - write_next_triplet(context, &buffer); - let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); - if new_mode != self.get_encoding_mode() { - // Return to ASCII encodation, which will actually handle latch to new mode - context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); - break; - } - } - } - self.handle_e_o_d(context, &buffer); - } - - fn encode_char(&self, c: char, sb: &StringBuilder) -> i32 { - match c { - '\r' => - { - sb.append('\0'); - break; - } - '*' => - { - sb.append('\1'); - break; - } - '>' => - { - sb.append('\2'); - break; - } - ' ' => - { - sb.append('\3'); - break; - } - _ => - { - if c >= '0' && c <= '9' { - sb.append((c - 48 + 4) as char); - } else if c >= 'A' && c <= 'Z' { - sb.append((c - 65 + 14) as char); - } else { - HighLevelEncoder::illegal_character(c); - } - break; - } - } - return 1; - } - - fn handle_e_o_d(&self, context: &EncoderContext, buffer: &StringBuilder) { - context.update_symbol_info(); - let available: i32 = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); - let count: i32 = buffer.length(); - context.pos -= count; - if context.get_remaining_characters() > 1 || available > 1 || context.get_remaining_characters() != available { - context.write_codeword(HighLevelEncoder::X12_UNLATCH); - } - if context.get_new_encoding() < 0 { - context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); - } - } -} - diff --git a/src/datamatrix.rs b/src/datamatrix.rs index e69de29..d6af627 100644 --- a/src/datamatrix.rs +++ b/src/datamatrix.rs @@ -0,0 +1,373 @@ +import com.google.zxing.BarcodeFormat; +import com.google.zxing.BinaryBitmap; +import com.google.zxing.ChecksumException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.Reader; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.DecoderResult; +import com.google.zxing.common.DetectorResult; +import com.google.zxing.datamatrix.decoder.Decoder; +import com.google.zxing.datamatrix.detector.Detector; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.Writer; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.datamatrix.encoder.DefaultPlacement; +import com.google.zxing.Dimension; +import com.google.zxing.datamatrix.encoder.ErrorCorrection; +import com.google.zxing.datamatrix.encoder.HighLevelEncoder; +import com.google.zxing.datamatrix.encoder.MinimalEncoder; +import com.google.zxing.datamatrix.encoder.SymbolInfo; +import com.google.zxing.datamatrix.encoder.SymbolShapeHint; +import com.google.zxing.qrcode.encoder.ByteMatrix; + +// DataMatrixReader.java +/** + * This implementation can detect and decode Data Matrix codes in an image. + * + * @author bbrown@google.com (Brian Brown) + */ + +const NO_POINTS: [Option; 0] = [None; 0]; +#[derive(Reader)] +pub struct DataMatrixReader { + + let decoder: Decoder = Decoder::new(); +} + +impl Reader for DataMatrixReader{ + /** + * 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 + * @throws ChecksumException if error correction fails + */ + pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { + return Ok(self.decode(image, null)); +} + +pub fn decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { + let decoder_result: DecoderResult; + let mut points: Vec; + if hints != null && hints.contains_key(DecodeHintType::PURE_BARCODE) { + let bits: BitMatrix = ::extract_pure_bits(&image.get_black_matrix()); + decoder_result = self.decoder.decode(bits); + points = NO_POINTS; + } else { + let detector_result: DetectorResult = Detector::new(&image.get_black_matrix()).detect(); + decoder_result = self.decoder.decode(&detector_result.get_bits()); + points = detector_result.get_points(); + } + let result: Result = Result::new(&decoder_result.get_text(), &decoder_result.get_raw_bytes(), points, BarcodeFormat::DATA_MATRIX); + 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(); + if ec_level != null { + result.put_metadata(ResultMetadataType::ERROR_CORRECTION_LEVEL, &ec_level); + } + result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]d{}", decoder_result.get_symbology_modifier())); + return Ok(result); +} + +pub fn reset(&self) { +// do nothing +} +} + +impl DataMatrixReader { + + + + /** + * This method detects a code in a "pure" image -- that is, pure monochrome image + * which contains only an unrotated, unskewed, image of a code, with some white border + * around it. This is a specialized method that works exceptionally fast in this special + * case. + */ + fn extract_pure_bits( image: &BitMatrix) -> /* throws NotFoundException */Result> { + let left_top_black: Vec = image.get_top_left_on_bit(); + let right_bottom_black: Vec = image.get_bottom_right_on_bit(); + if left_top_black == null || right_bottom_black == null { + throw NotFoundException::get_not_found_instance(); + } + let module_size: i32 = self.module_size(&left_top_black, image); + let mut top: i32 = left_top_black[1]; + let bottom: i32 = right_bottom_black[1]; + let mut left: i32 = left_top_black[0]; + let right: i32 = right_bottom_black[0]; + let matrix_width: i32 = (right - left + 1) / module_size; + let matrix_height: i32 = (bottom - top + 1) / module_size; + if matrix_width <= 0 || matrix_height <= 0 { + throw NotFoundException::get_not_found_instance(); + } + // Push in the "border" by half the module width so that we start + // sampling in the middle of the module. Just in case the image is a + // little off, this will help recover. + let nudge: i32 = module_size / 2; + top += nudge; + left += nudge; + // Now just read off the bits + let bits: BitMatrix = BitMatrix::new(matrix_width, matrix_height); + { + let mut y: i32 = 0; + while y < matrix_height { + { + let i_offset: i32 = top + y * module_size; + { + let mut x: i32 = 0; + while x < matrix_width { + { + if image.get(left + x * module_size, i_offset) { + bits.set(x, y); + } + } + x += 1; + } + } + + } + y += 1; + } + } + + return Ok(bits); + } + + fn module_size( left_top_black: &Vec, image: &BitMatrix) -> /* throws NotFoundException */Result> { + let width: i32 = image.get_width(); + let mut x: i32 = left_top_black[0]; + let y: i32 = left_top_black[1]; + while x < width && image.get(x, y) { + x += 1; + } + if x == width { + throw NotFoundException::get_not_found_instance(); + } + let module_size: i32 = x - left_top_black[0]; + if module_size == 0 { + throw NotFoundException::get_not_found_instance(); + } + return Ok(module_size); + } +} + + + + +// DataMatrixWriter.java +/** + * This object renders a Data Matrix code as a BitMatrix 2D array of greyscale values. + * + * @author dswitkin@google.com (Daniel Switkin) + * @author Guillaume Le Biller Added to zxing lib. + */ +#[derive(Writer)] +pub struct DataMatrixWriter { +} + +impl Writer for DataMatrixWriter{ + pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32) -> BitMatrix { + return self.encode(&contents, format, width, height, null); + } + + pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32, hints: &Map) -> BitMatrix { + if contents.is_empty() { + throw IllegalArgumentException::new("Found empty contents"); + } + if format != BarcodeFormat::DATA_MATRIX { + throw IllegalArgumentException::new(format!("Can only encode DATA_MATRIX, but got {}", format)); + } + if width < 0 || height < 0 { + throw IllegalArgumentException::new(format!("Requested dimensions can't be negative: {}x{}", width, height)); + } + // Try to get force shape & min / max size + let mut shape: SymbolShapeHint = SymbolShapeHint::FORCE_NONE; + let min_size: Dimension = null; + let max_size: Dimension = null; + if hints != null { + let requested_shape: SymbolShapeHint = hints.get(EncodeHintType::DATA_MATRIX_SHAPE) as SymbolShapeHint; + if requested_shape != null { + shape = requested_shape; + } + let requested_min_size: Dimension = hints.get(EncodeHintType::MIN_SIZE) as Dimension; + if requested_min_size != null { + min_size = requested_min_size; + } + let requested_max_size: Dimension = hints.get(EncodeHintType::MAX_SIZE) as Dimension; + if requested_max_size != null { + max_size = requested_max_size; + } + } + //1. step: Data encodation + let mut encoded: String; + let has_compaction_hint: bool = hints != null && hints.contains_key(EncodeHintType::DATA_MATRIX_COMPACT) && Boolean::parse_boolean(&hints.get(EncodeHintType::DATA_MATRIX_COMPACT).to_string()); + if has_compaction_hint { + let has_g_s1_format_hint: bool = hints.contains_key(EncodeHintType::GS1_FORMAT) && Boolean::parse_boolean(&hints.get(EncodeHintType::GS1_FORMAT).to_string()); + let mut charset: Charset = null; + let has_encoding_hint: bool = hints.contains_key(EncodeHintType::CHARACTER_SET); + if has_encoding_hint { + charset = Charset::for_name(&hints.get(EncodeHintType::CHARACTER_SET).to_string()); + } + encoded = MinimalEncoder::encode_high_level(&contents, &charset, if has_g_s1_format_hint { 0x1D } else { -1 }, shape); + } else { + let has_force_c40_hint: bool = hints != null && hints.contains_key(EncodeHintType::FORCE_C40) && Boolean::parse_boolean(&hints.get(EncodeHintType::FORCE_C40).to_string()); + encoded = HighLevelEncoder::encode_high_level(&contents, shape, min_size, max_size, has_force_c40_hint); + } + let symbol_info: SymbolInfo = SymbolInfo::lookup(&encoded.length(), shape, min_size, max_size, true); + //2. step: ECC generation + let codewords: String = ErrorCorrection::encode_e_c_c200(&encoded, symbol_info); + //3. step: Module placement in Matrix + let placement: DefaultPlacement = DefaultPlacement::new(&codewords, &symbol_info.get_symbol_data_width(), &symbol_info.get_symbol_data_height()); + placement.place(); + //4. step: low-level encoding + return ::encode_low_level(placement, symbol_info, width, height); + } +} + +impl DataMatrixWriter { + + + /** + * Encode the given symbol info to a bit matrix. + * + * @param placement The DataMatrix placement. + * @param symbolInfo The symbol info to encode. + * @return The bit matrix generated. + */ + fn encode_low_level( placement: &DefaultPlacement, symbol_info: &SymbolInfo, width: i32, height: i32) -> BitMatrix { + let symbol_width: i32 = symbol_info.get_symbol_data_width(); + let symbol_height: i32 = symbol_info.get_symbol_data_height(); + let matrix: ByteMatrix = ByteMatrix::new(&symbol_info.get_symbol_width(), &symbol_info.get_symbol_height()); + let matrix_y: i32 = 0; + { + let mut y: i32 = 0; + while y < symbol_height { + { + // Fill the top edge with alternate 0 / 1 + let matrix_x: i32; + if (y % symbol_info.matrixHeight) == 0 { + matrix_x = 0; + { + let mut x: i32 = 0; + while x < symbol_info.get_symbol_width() { + { + matrix.set(matrix_x, matrix_y, (x % 2) == 0); + matrix_x += 1; + } + x += 1; + } + } + + matrix_y += 1; + } + matrix_x = 0; + { + let mut x: i32 = 0; + while x < symbol_width { + { + // Fill the right edge with full 1 + if (x % symbol_info.matrixWidth) == 0 { + matrix.set(matrix_x, matrix_y, true); + matrix_x += 1; + } + matrix.set(matrix_x, matrix_y, &placement.get_bit(x, y)); + matrix_x += 1; + // Fill the right edge with alternate 0 / 1 + if (x % symbol_info.matrixWidth) == symbol_info.matrixWidth - 1 { + matrix.set(matrix_x, matrix_y, (y % 2) == 0); + matrix_x += 1; + } + } + x += 1; + } + } + + matrix_y += 1; + // Fill the bottom edge with full 1 + if (y % symbol_info.matrixHeight) == symbol_info.matrixHeight - 1 { + matrix_x = 0; + { + let mut x: i32 = 0; + while x < symbol_info.get_symbol_width() { + { + matrix.set(matrix_x, matrix_y, true); + matrix_x += 1; + } + x += 1; + } + } + + matrix_y += 1; + } + } + y += 1; + } + } + + return ::convert_byte_matrix_to_bit_matrix(matrix, width, height); + } + + /** + * Convert the ByteMatrix to BitMatrix. + * + * @param reqHeight The requested height of the image (in pixels) with the Datamatrix code + * @param reqWidth The requested width of the image (in pixels) with the Datamatrix code + * @param matrix The input matrix. + * @return The output matrix. + */ + fn convert_byte_matrix_to_bit_matrix( matrix: &ByteMatrix, req_width: i32, req_height: i32) -> BitMatrix { + let matrix_width: i32 = matrix.get_width(); + let matrix_height: i32 = matrix.get_height(); + let output_width: i32 = Math::max(req_width, matrix_width); + let output_height: i32 = Math::max(req_height, matrix_height); + let multiple: i32 = Math::min(output_width / matrix_width, output_height / matrix_height); + let left_padding: i32 = (output_width - (matrix_width * multiple)) / 2; + let top_padding: i32 = (output_height - (matrix_height * multiple)) / 2; + let mut output: BitMatrix; + // remove padding if requested width and height are too small + if req_height < matrix_height || req_width < matrix_width { + left_padding = 0; + top_padding = 0; + output = BitMatrix::new(matrix_width, matrix_height); + } else { + output = BitMatrix::new(req_width, req_height); + } + output.clear(); + { + let input_y: i32 = 0, let output_y: i32 = top_padding; + while input_y < matrix_height { + { + // Write the contents of this row of the bytematrix + { + let input_x: i32 = 0, let output_x: i32 = left_padding; + while input_x < matrix_width { + { + if matrix.get(input_x, input_y) == 1 { + output.set_region(output_x, output_y, multiple, multiple); + } + } + input_x += 1; + output_x += multiple; + } + } + + } + input_y += 1; + output_y += multiple; + } + } + + return output; + } +} + diff --git a/src/datamatrix/decoder.rs b/src/datamatrix/decoder.rs index e69de29..ae76062 100644 --- a/src/datamatrix/decoder.rs +++ b/src/datamatrix/decoder.rs @@ -0,0 +1,1573 @@ +// + +import com.google.zxing.FormatException; + +import com.google.zxing.ChecksumException; +import com.google.zxing.FormatException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.DecoderResult; +import com.google.zxing.common.reedsolomon.GenericGF; +import com.google.zxing.common.reedsolomon.ReedSolomonDecoder; +import com.google.zxing.common.reedsolomon.ReedSolomonException; +import com.google.zxing.FormatException; +import com.google.zxing.common.BitMatrix; + +import com.google.zxing.FormatException; +import com.google.zxing.common.BitSource; +import com.google.zxing.common.DecoderResult; +import com.google.zxing.common.ECIStringBuilder; + +// BitMatrixParser.java +/** + * @author bbrown@google.com (Brian Brown) + */ +struct BitMatrixParser { + + let mapping_bit_matrix: BitMatrix; + + let read_mapping_matrix: BitMatrix; + + let mut version: Version; +} + +impl BitMatrixParser { + + /** + * @param bitMatrix {@link BitMatrix} to parse + * @throws FormatException if dimension is < 8 or > 144 or not 0 mod 2 + */ + fn new( bit_matrix: &BitMatrix) -> BitMatrixParser throws FormatException { + let dimension: i32 = bit_matrix.get_height(); + if dimension < 8 || dimension > 144 || (dimension & 0x01) != 0 { + throw FormatException::get_format_instance(); + } + version = ::read_version(bit_matrix); + let .mappingBitMatrix = self.extract_data_region(bit_matrix); + let .readMappingMatrix = BitMatrix::new(&let .mappingBitMatrix.get_width(), &let .mappingBitMatrix.get_height()); + } + + fn get_version(&self) -> Version { + return self.version; + } + + /** + *

Creates the version object based on the dimension of the original bit matrix from + * the datamatrix code.

+ * + *

See ISO 16022:2006 Table 7 - ECC 200 symbol attributes

+ * + * @param bitMatrix Original {@link BitMatrix} including alignment patterns + * @return {@link Version} encapsulating the Data Matrix Code's "version" + * @throws FormatException if the dimensions of the mapping matrix are not valid + * Data Matrix dimensions. + */ + fn read_version( bit_matrix: &BitMatrix) -> /* throws FormatException */Result> { + let num_rows: i32 = bit_matrix.get_height(); + let num_columns: i32 = bit_matrix.get_width(); + return Ok(Version::get_version_for_dimensions(num_rows, num_columns)); + } + + /** + *

Reads the bits in the {@link BitMatrix} representing the mapping matrix (No alignment patterns) + * in the correct order in order to reconstitute the codewords bytes contained within the + * Data Matrix Code.

+ * + * @return bytes encoded within the Data Matrix Code + * @throws FormatException if the exact number of bytes expected is not read + */ + fn read_codewords(&self) -> /* throws FormatException */Result, Rc> { + let mut result: [i8; self.version.get_total_codewords()] = [0; self.version.get_total_codewords()]; + let result_offset: i32 = 0; + let mut row: i32 = 4; + let mut column: i32 = 0; + let num_rows: i32 = self.mapping_bit_matrix.get_height(); + let num_columns: i32 = self.mapping_bit_matrix.get_width(); + let corner1_read: bool = false; + let corner2_read: bool = false; + let corner3_read: bool = false; + let corner4_read: bool = false; + // Read all of the codewords + loop { { + // Check the four corner cases + if (row == num_rows) && (column == 0) && !corner1_read { + result[result_offset += 1 !!!check!!! post increment] = self.read_corner1(num_rows, num_columns) as i8; + row -= 2; + column += 2; + corner1_read = true; + } else if (row == num_rows - 2) && (column == 0) && ((num_columns & 0x03) != 0) && !corner2_read { + result[result_offset += 1 !!!check!!! post increment] = self.read_corner2(num_rows, num_columns) as i8; + row -= 2; + column += 2; + corner2_read = true; + } else if (row == num_rows + 4) && (column == 2) && ((num_columns & 0x07) == 0) && !corner3_read { + result[result_offset += 1 !!!check!!! post increment] = self.read_corner3(num_rows, num_columns) as i8; + row -= 2; + column += 2; + corner3_read = true; + } else if (row == num_rows - 2) && (column == 0) && ((num_columns & 0x07) == 4) && !corner4_read { + result[result_offset += 1 !!!check!!! post increment] = self.read_corner4(num_rows, num_columns) as i8; + row -= 2; + column += 2; + corner4_read = true; + } else { + // Sweep upward diagonally to the right + loop { { + if (row < num_rows) && (column >= 0) && !self.read_mapping_matrix.get(column, row) { + result[result_offset += 1 !!!check!!! post increment] = self.read_utah(row, column, num_rows, num_columns) as i8; + } + row -= 2; + column += 2; + }if !((row >= 0) && (column < num_columns)) break;} + row += 1; + column += 3; + // Sweep downward diagonally to the left + loop { { + if (row >= 0) && (column < num_columns) && !self.read_mapping_matrix.get(column, row) { + result[result_offset += 1 !!!check!!! post increment] = self.read_utah(row, column, num_rows, num_columns) as i8; + } + row += 2; + column -= 2; + }if !((row < num_rows) && (column >= 0)) break;} + row += 3; + column += 1; + } + }if !((row < num_rows) || (column < num_columns)) break;} + if result_offset != self.version.get_total_codewords() { + throw FormatException::get_format_instance(); + } + return Ok(result); + } + + /** + *

Reads a bit of the mapping matrix accounting for boundary wrapping.

+ * + * @param row Row to read in the mapping matrix + * @param column Column to read in the mapping matrix + * @param numRows Number of rows in the mapping matrix + * @param numColumns Number of columns in the mapping matrix + * @return value of the given bit in the mapping matrix + */ + fn read_module(&self, row: i32, column: i32, num_rows: i32, num_columns: i32) -> bool { + // Adjust the row and column indices based on boundary wrapping + if row < 0 { + row += num_rows; + column += 4 - ((num_rows + 4) & 0x07); + } + if column < 0 { + column += num_columns; + row += 4 - ((num_columns + 4) & 0x07); + } + if row >= num_rows { + row -= num_rows; + } + self.read_mapping_matrix.set(column, row); + return self.mapping_bit_matrix.get(column, row); + } + + /** + *

Reads the 8 bits of the standard Utah-shaped pattern.

+ * + *

See ISO 16022:2006, 5.8.1 Figure 6

+ * + * @param row Current row in the mapping matrix, anchored at the 8th bit (LSB) of the pattern + * @param column Current column in the mapping matrix, anchored at the 8th bit (LSB) of the pattern + * @param numRows Number of rows in the mapping matrix + * @param numColumns Number of columns in the mapping matrix + * @return byte from the utah shape + */ + fn read_utah(&self, row: i32, column: i32, num_rows: i32, num_columns: i32) -> i32 { + let current_byte: i32 = 0; + if self.read_module(row - 2, column - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(row - 2, column - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(row - 1, column - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(row - 1, column - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(row - 1, column, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(row, column - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(row, column - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(row, column, num_rows, num_columns) { + current_byte |= 1; + } + return current_byte; + } + + /** + *

Reads the 8 bits of the special corner condition 1.

+ * + *

See ISO 16022:2006, Figure F.3

+ * + * @param numRows Number of rows in the mapping matrix + * @param numColumns Number of columns in the mapping matrix + * @return byte from the Corner condition 1 + */ + fn read_corner1(&self, num_rows: i32, num_columns: i32) -> i32 { + let current_byte: i32 = 0; + if self.read_module(num_rows - 1, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(num_rows - 1, 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(num_rows - 1, 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(1, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(2, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(3, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + return current_byte; + } + + /** + *

Reads the 8 bits of the special corner condition 2.

+ * + *

See ISO 16022:2006, Figure F.4

+ * + * @param numRows Number of rows in the mapping matrix + * @param numColumns Number of columns in the mapping matrix + * @return byte from the Corner condition 2 + */ + fn read_corner2(&self, num_rows: i32, num_columns: i32) -> i32 { + let current_byte: i32 = 0; + if self.read_module(num_rows - 3, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(num_rows - 2, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(num_rows - 1, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 4, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 3, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(1, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + return current_byte; + } + + /** + *

Reads the 8 bits of the special corner condition 3.

+ * + *

See ISO 16022:2006, Figure F.5

+ * + * @param numRows Number of rows in the mapping matrix + * @param numColumns Number of columns in the mapping matrix + * @return byte from the Corner condition 3 + */ + fn read_corner3(&self, num_rows: i32, num_columns: i32) -> i32 { + let current_byte: i32 = 0; + if self.read_module(num_rows - 1, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(num_rows - 1, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 3, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(1, num_columns - 3, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(1, num_columns - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(1, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + return current_byte; + } + + /** + *

Reads the 8 bits of the special corner condition 4.

+ * + *

See ISO 16022:2006, Figure F.6

+ * + * @param numRows Number of rows in the mapping matrix + * @param numColumns Number of columns in the mapping matrix + * @return byte from the Corner condition 4 + */ + fn read_corner4(&self, num_rows: i32, num_columns: i32) -> i32 { + let current_byte: i32 = 0; + if self.read_module(num_rows - 3, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(num_rows - 2, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(num_rows - 1, 0, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 2, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(0, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(1, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(2, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + current_byte <<= 1; + if self.read_module(3, num_columns - 1, num_rows, num_columns) { + current_byte |= 1; + } + return current_byte; + } + + /** + *

Extracts the data region from a {@link BitMatrix} that contains + * alignment patterns.

+ * + * @param bitMatrix Original {@link BitMatrix} with alignment patterns + * @return BitMatrix that has the alignment patterns removed + */ + fn extract_data_region(&self, bit_matrix: &BitMatrix) -> BitMatrix { + let symbol_size_rows: i32 = self.version.get_symbol_size_rows(); + let symbol_size_columns: i32 = self.version.get_symbol_size_columns(); + if bit_matrix.get_height() != symbol_size_rows { + throw IllegalArgumentException::new("Dimension of bitMatrix must match the version size"); + } + let data_region_size_rows: i32 = self.version.get_data_region_size_rows(); + let data_region_size_columns: i32 = self.version.get_data_region_size_columns(); + let num_data_regions_row: i32 = symbol_size_rows / data_region_size_rows; + let num_data_regions_column: i32 = symbol_size_columns / data_region_size_columns; + let size_data_region_row: i32 = num_data_regions_row * data_region_size_rows; + let size_data_region_column: i32 = num_data_regions_column * data_region_size_columns; + let bit_matrix_without_alignment: BitMatrix = BitMatrix::new(size_data_region_column, size_data_region_row); + { + let data_region_row: i32 = 0; + while data_region_row < num_data_regions_row { + { + let data_region_row_offset: i32 = data_region_row * data_region_size_rows; + { + let data_region_column: i32 = 0; + while data_region_column < num_data_regions_column { + { + let data_region_column_offset: i32 = data_region_column * data_region_size_columns; + { + let mut i: i32 = 0; + while i < data_region_size_rows { + { + let read_row_offset: i32 = data_region_row * (data_region_size_rows + 2) + 1 + i; + let write_row_offset: i32 = data_region_row_offset + i; + { + let mut j: i32 = 0; + while j < data_region_size_columns { + { + let read_column_offset: i32 = data_region_column * (data_region_size_columns + 2) + 1 + j; + if bit_matrix.get(read_column_offset, read_row_offset) { + let write_column_offset: i32 = data_region_column_offset + j; + bit_matrix_without_alignment.set(write_column_offset, write_row_offset); + } + } + j += 1; + } + } + + } + i += 1; + } + } + + } + data_region_column += 1; + } + } + + } + data_region_row += 1; + } + } + + return bit_matrix_without_alignment; + } +} + + +// DataBlock.java +/** + *

Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into + * multiple blocks, each of which is a unit of data and error-correction codewords. Each + * is represented by an instance of this class.

+ * + * @author bbrown@google.com (Brian Brown) + */ +struct DataBlock { + + let num_data_codewords: i32; + + let mut codewords: Vec; +} + +impl DataBlock { + + fn new( num_data_codewords: i32, codewords: &Vec) -> DataBlock { + let .numDataCodewords = num_data_codewords; + let .codewords = codewords; + } + + /** + *

When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them. + * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This + * method will separate the data into original blocks.

+ * + * @param rawCodewords bytes as read directly from the Data Matrix Code + * @param version version of the Data Matrix Code + * @return DataBlocks containing original bytes, "de-interleaved" from representation in the + * Data Matrix Code + */ + fn get_data_blocks( raw_codewords: &Vec, version: &Version) -> Vec { + // Figure out the number and size of data blocks used by this version + let ec_blocks: Version.ECBlocks = version.get_e_c_blocks(); + // First count the total number of data blocks + let total_blocks: i32 = 0; + let ec_block_array: Vec = ec_blocks.get_e_c_blocks(); + for let ec_block: Version.ECB in ec_block_array { + total_blocks += ec_block.get_count(); + } + // Now establish DataBlocks of the appropriate size and number of data codewords + let mut result: [Option; total_blocks] = [None; total_blocks]; + let num_result_blocks: i32 = 0; + for let ec_block: Version.ECB in ec_block_array { + { + let mut i: i32 = 0; + while i < ec_block.get_count() { + { + let num_data_codewords: i32 = ec_block.get_data_codewords(); + let num_block_codewords: i32 = ec_blocks.get_e_c_codewords() + num_data_codewords; + result[num_result_blocks += 1 !!!check!!! post increment] = DataBlock::new(num_data_codewords, : [i8; num_block_codewords] = [0; num_block_codewords]); + } + i += 1; + } + } + + } + // All blocks have the same amount of data, except that the last n + // (where n may be 0) have 1 less byte. Figure out where these start. + // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144 + let longer_blocks_total_codewords: i32 = result[0].codewords.len(); + //int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1; + let longer_blocks_num_data_codewords: i32 = longer_blocks_total_codewords - ec_blocks.get_e_c_codewords(); + let shorter_blocks_num_data_codewords: i32 = longer_blocks_num_data_codewords - 1; + // The last elements of result may be 1 element shorter for 144 matrix + // first fill out as many elements as all of them have minus 1 + let raw_codewords_offset: i32 = 0; + { + let mut i: i32 = 0; + while i < shorter_blocks_num_data_codewords { + { + { + let mut j: i32 = 0; + while j < num_result_blocks { + { + result[j].codewords[i] = raw_codewords[raw_codewords_offset += 1 !!!check!!! post increment]; + } + j += 1; + } + } + + } + i += 1; + } + } + + // Fill out the last data block in the longer ones + let special_version: bool = version.get_version_number() == 24; + let num_longer_blocks: i32 = if special_version { 8 } else { num_result_blocks }; + { + let mut j: i32 = 0; + while j < num_longer_blocks { + { + result[j].codewords[longer_blocks_num_data_codewords - 1] = raw_codewords[raw_codewords_offset += 1 !!!check!!! post increment]; + } + j += 1; + } + } + + // Now add in error correction blocks + let max: i32 = result[0].codewords.len(); + { + let mut i: i32 = longer_blocks_num_data_codewords; + while i < max { + { + { + let mut j: i32 = 0; + while j < num_result_blocks { + { + let j_offset: i32 = if special_version { (j + 8) % num_result_blocks } else { j }; + let i_offset: i32 = if special_version && j_offset > 7 { i - 1 } else { i }; + result[j_offset].codewords[i_offset] = raw_codewords[raw_codewords_offset += 1 !!!check!!! post increment]; + } + j += 1; + } + } + + } + i += 1; + } + } + + if raw_codewords_offset != raw_codewords.len() { + throw IllegalArgumentException::new(); + } + return result; + } + + fn get_num_data_codewords(&self) -> i32 { + return self.num_data_codewords; + } + + fn get_codewords(&self) -> Vec { + return self.codewords; + } +} + + +// DecodedBitStreamParser.java +/** + *

Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes + * in one Data Matrix Code. This class decodes the bits back into text.

+ * + *

See ISO 16022:2006, 5.2.1 - 5.2.9.2

+ * + * @author bbrown@google.com (Brian Brown) + * @author Sean Owen + */ + +/** + * See ISO 16022:2006, Annex C Table C.1 + * The C40 Basic Character Set (*'s used for placeholders for the shift values) + */ + const C40_BASIC_SET_CHARS: vec![Vec; 40] = vec!['*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', ] + ; + + const C40_SHIFT2_SET_CHARS: vec![Vec; 27] = vec!['!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', ] + ; + + const TEXT_BASIC_SET_CHARS: vec![Vec; 40] = vec!['*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', ] + ; + + // Shift 2 for Text is the same encoding as C40 + const TEXT_SHIFT2_SET_CHARS: Vec = C40_SHIFT2_SET_CHARS; + + const TEXT_SHIFT3_SET_CHARS: vec![Vec; 32] = vec!['`', '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', '{', '|', '}', '~', 127 as char, ] + ; + struct DecodedBitStreamParser { + } + + impl DecodedBitStreamParser { + + enum Mode { + + // Not really a mode + PAD_ENCODE(), ASCII_ENCODE(), C40_ENCODE(), TEXT_ENCODE(), ANSIX12_ENCODE(), EDIFACT_ENCODE(), BASE256_ENCODE(), ECI_ENCODE() + } + + fn new() -> DecodedBitStreamParser { + } + + fn decode( bytes: &Vec) -> /* throws FormatException */Result> { + let bits: BitSource = BitSource::new(&bytes); + let result: ECIStringBuilder = ECIStringBuilder::new(100); + let result_trailer: StringBuilder = StringBuilder::new(0); + let byte_segments: List> = ArrayList<>::new(1); + let mut mode: Mode = Mode::ASCII_ENCODE; + // Could look directly at 'bytes', if we're sure of not having to account for multi byte values + let fnc1_positions: Set = HashSet<>::new(); + let symbology_modifier: i32; + let is_e_c_iencoded: bool = false; + loop { { + if mode == Mode::ASCII_ENCODE { + mode = ::decode_ascii_segment(bits, result, &result_trailer, &fnc1_positions); + } else { + match mode { + C40_ENCODE => + { + ::decode_c40_segment(bits, result, &fnc1_positions); + break; + } + TEXT_ENCODE => + { + ::decode_text_segment(bits, result, &fnc1_positions); + break; + } + ANSIX12_ENCODE => + { + ::decode_ansi_x12_segment(bits, result); + break; + } + EDIFACT_ENCODE => + { + ::decode_edifact_segment(bits, result); + break; + } + BASE256_ENCODE => + { + ::decode_base256_segment(bits, result, &byte_segments); + break; + } + ECI_ENCODE => + { + ::decode_e_c_i_segment(bits, result); + // ECI detection only, atm continue decoding as ASCII + is_e_c_iencoded = true; + break; + } + _ => + { + throw FormatException::get_format_instance(); + } + } + mode = Mode::ASCII_ENCODE; + } + }if !(mode != Mode::PAD_ENCODE && bits.available() > 0) break;} + if result_trailer.length() > 0 { + result.append_characters(&result_trailer); + } + if is_e_c_iencoded { + // https://honeywellaidc.force.com/supportppr/s/article/List-of-barcode-symbology-AIM-Identifiers + if fnc1_positions.contains(0) || fnc1_positions.contains(4) { + symbology_modifier = 5; + } else if fnc1_positions.contains(1) || fnc1_positions.contains(5) { + symbology_modifier = 6; + } else { + symbology_modifier = 4; + } + } else { + if fnc1_positions.contains(0) || fnc1_positions.contains(4) { + symbology_modifier = 2; + } else if fnc1_positions.contains(1) || fnc1_positions.contains(5) { + symbology_modifier = 3; + } else { + symbology_modifier = 1; + } + } + return Ok(DecoderResult::new(&bytes, &result.to_string(), if byte_segments.is_empty() { null } else { byte_segments }, null, symbology_modifier)); + } + + /** + * See ISO 16022:2006, 5.2.3 and Annex C, Table C.2 + */ + fn decode_ascii_segment( bits: &BitSource, result: &ECIStringBuilder, result_trailer: &StringBuilder, fnc1positions: &Set) -> /* throws FormatException */Result> { + let upper_shift: bool = false; + loop { { + let one_byte: i32 = bits.read_bits(8); + if one_byte == 0 { + throw FormatException::get_format_instance(); + } else if one_byte <= 128 { + // ASCII data (ASCII value + 1) + if upper_shift { + one_byte += 128; + //upperShift = false; + } + result.append((one_byte - 1) as char); + return Ok(Mode::ASCII_ENCODE); + } else if one_byte == 129 { + // Pad + return Ok(Mode::PAD_ENCODE); + } else if one_byte <= 229 { + // 2-digit data 00-99 (Numeric Value + 130) + let value: i32 = one_byte - 130; + if value < 10 { + // pad with '0' for single digit values + result.append('0'); + } + result.append(value); + } else { + match one_byte { + // Latch to C40 encodation + 230 => + { + return Ok(Mode::C40_ENCODE); + } + // Latch to Base 256 encodation + 231 => + { + return Ok(Mode::BASE256_ENCODE); + } + // FNC1 + 232 => + { + fnc1positions.add(&result.length()); + // translate as ASCII 29 + result.append(29 as char); + break; + } + // Structured Append + 233 => + { + } + // Reader Programming + 234 => + { + //throw ReaderException.getInstance(); + break; + } + // Upper Shift (shift to Extended ASCII) + 235 => + { + upper_shift = true; + break; + } + // 05 Macro + 236 => + { + result.append("[)>\u001E05\u001D"); + result_trailer.insert(0, "\u001E\u0004"); + break; + } + // 06 Macro + 237 => + { + result.append("[)>\u001E06\u001D"); + resultTrailer.insert(0, "\u001E\u0004"); + break; + } + // Latch to ANSI X12 encodation + 238 => + { + return Ok(Mode::ANSIX12_ENCODE); + } + // Latch to Text encodation + 239 => + { + return Ok(Mode::TEXT_ENCODE); + } + // Latch to EDIFACT encodation + 240 => + { + return Ok(Mode::EDIFACT_ENCODE); + } + // ECI Character + 241 => + { + return Ok(Mode::ECI_ENCODE); + } + _ => + { + // but work around encoders that end with 254, latch back to ASCII + if one_byte != 254 || bits.available() != 0 { + throw FormatException::get_format_instance(); + } + break; + } + } + } + }if !(bits.available() > 0) break;} + return Ok(Mode::ASCII_ENCODE); + } + + /** + * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1 + */ + fn decode_c40_segment( bits: &BitSource, result: &ECIStringBuilder, fnc1positions: &Set) -> /* throws FormatException */Result> { + // Three C40 values are encoded in a 16-bit value as + // (1600 * C1) + (40 * C2) + C3 + 1 + // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time + let upper_shift: bool = false; + let c_values: [i32; 3] = [0; 3]; + let mut shift: i32 = 0; + loop { { + // If there is only one byte left then it will be encoded as ASCII + if bits.available() == 8 { + return; + } + let first_byte: i32 = bits.read_bits(8); + if first_byte == 254 { + // Unlatch codeword + return; + } + ::parse_two_bytes(first_byte, &bits.read_bits(8), &c_values); + { + let mut i: i32 = 0; + while i < 3 { + { + let c_value: i32 = c_values[i]; + match shift { + 0 => + { + if c_value < 3 { + shift = c_value + 1; + } else if c_value < C40_BASIC_SET_CHARS.len() { + let c40char: char = C40_BASIC_SET_CHARS[c_value]; + if upper_shift { + result.append((c40char + 128) as char); + upper_shift = false; + } else { + result.append(c40char); + } + } else { + throw FormatException::get_format_instance(); + } + break; + } + 1 => + { + if upper_shift { + result.append((c_value + 128) as char); + upper_shift = false; + } else { + result.append(c_value as char); + } + shift = 0; + break; + } + 2 => + { + if c_value < C40_SHIFT2_SET_CHARS.len() { + let c40char: char = C40_SHIFT2_SET_CHARS[c_value]; + if upper_shift { + result.append((c40char + 128) as char); + upper_shift = false; + } else { + result.append(c40char); + } + } else { + match c_value { + // FNC1 + 27 => + { + fnc1positions.add(&result.length()); + // translate as ASCII 29 + result.append(29 as char); + break; + } + // Upper Shift + 30 => + { + upper_shift = true; + break; + } + _ => + { + throw FormatException::get_format_instance(); + } + } + } + shift = 0; + break; + } + 3 => + { + if upper_shift { + result.append((c_value + 224) as char); + upper_shift = false; + } else { + result.append((c_value + 96) as char); + } + shift = 0; + break; + } + _ => + { + throw FormatException::get_format_instance(); + } + } + } + i += 1; + } + } + + }if !(bits.available() > 0) break;} + } + + /** + * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2 + */ + fn decode_text_segment( bits: &BitSource, result: &ECIStringBuilder, fnc1positions: &Set) -> /* throws FormatException */Result> { + // Three Text values are encoded in a 16-bit value as + // (1600 * C1) + (40 * C2) + C3 + 1 + // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time + let upper_shift: bool = false; + let c_values: [i32; 3] = [0; 3]; + let mut shift: i32 = 0; + loop { { + // If there is only one byte left then it will be encoded as ASCII + if bits.available() == 8 { + return; + } + let first_byte: i32 = bits.read_bits(8); + if first_byte == 254 { + // Unlatch codeword + return; + } + ::parse_two_bytes(first_byte, &bits.read_bits(8), &c_values); + { + let mut i: i32 = 0; + while i < 3 { + { + let c_value: i32 = c_values[i]; + match shift { + 0 => + { + if c_value < 3 { + shift = c_value + 1; + } else if c_value < TEXT_BASIC_SET_CHARS.len() { + let text_char: char = TEXT_BASIC_SET_CHARS[c_value]; + if upper_shift { + result.append((text_char + 128) as char); + upper_shift = false; + } else { + result.append(text_char); + } + } else { + throw FormatException::get_format_instance(); + } + break; + } + 1 => + { + if upper_shift { + result.append((c_value + 128) as char); + upper_shift = false; + } else { + result.append(c_value as char); + } + shift = 0; + break; + } + 2 => + { + // Shift 2 for Text is the same encoding as C40 + if c_value < TEXT_SHIFT2_SET_CHARS.len() { + let text_char: char = TEXT_SHIFT2_SET_CHARS[c_value]; + if upper_shift { + result.append((text_char + 128) as char); + upper_shift = false; + } else { + result.append(text_char); + } + } else { + match c_value { + // FNC1 + 27 => + { + fnc1positions.add(&result.length()); + // translate as ASCII 29 + result.append(29 as char); + break; + } + // Upper Shift + 30 => + { + upper_shift = true; + break; + } + _ => + { + throw FormatException::get_format_instance(); + } + } + } + shift = 0; + break; + } + 3 => + { + if c_value < TEXT_SHIFT3_SET_CHARS.len() { + let text_char: char = TEXT_SHIFT3_SET_CHARS[c_value]; + if upper_shift { + result.append((text_char + 128) as char); + upper_shift = false; + } else { + result.append(text_char); + } + shift = 0; + } else { + throw FormatException::get_format_instance(); + } + break; + } + _ => + { + throw FormatException::get_format_instance(); + } + } + } + i += 1; + } + } + + }if !(bits.available() > 0) break;} + } + + /** + * See ISO 16022:2006, 5.2.7 + */ + fn decode_ansi_x12_segment( bits: &BitSource, result: &ECIStringBuilder) -> /* throws FormatException */Result> { + // Three ANSI X12 values are encoded in a 16-bit value as + // (1600 * C1) + (40 * C2) + C3 + 1 + let c_values: [i32; 3] = [0; 3]; + loop { { + // If there is only one byte left then it will be encoded as ASCII + if bits.available() == 8 { + return; + } + let first_byte: i32 = bits.read_bits(8); + if first_byte == 254 { + // Unlatch codeword + return; + } + ::parse_two_bytes(first_byte, &bits.read_bits(8), &c_values); + { + let mut i: i32 = 0; + while i < 3 { + { + let c_value: i32 = c_values[i]; + match c_value { + // X12 segment terminator + 0 => + { + result.append('\r'); + break; + } + // X12 segment separator * + 1 => + { + result.append('*'); + break; + } + // X12 sub-element separator > + 2 => + { + result.append('>'); + break; + } + // space + 3 => + { + result.append(' '); + break; + } + _ => + { + if c_value < 14 { + // 0 - 9 + result.append((c_value + 44) as char); + } else if c_value < 40 { + // A - Z + result.append((c_value + 51) as char); + } else { + throw FormatException::get_format_instance(); + } + break; + } + } + } + i += 1; + } + } + + }if !(bits.available() > 0) break;} + } + + fn parse_two_bytes( first_byte: i32, second_byte: i32, result: &Vec) { + let full_bit_value: i32 = (first_byte << 8) + second_byte - 1; + let mut temp: i32 = full_bit_value / 1600; + result[0] = temp; + full_bit_value -= temp * 1600; + temp = full_bit_value / 40; + result[1] = temp; + result[2] = full_bit_value - temp * 40; + } + + /** + * See ISO 16022:2006, 5.2.8 and Annex C Table C.3 + */ + fn decode_edifact_segment( bits: &BitSource, result: &ECIStringBuilder) { + loop { { + // If there is only two or less bytes left then it will be encoded as ASCII + if bits.available() <= 16 { + return; + } + { + let mut i: i32 = 0; + while i < 4 { + { + let edifact_value: i32 = bits.read_bits(6); + // Check for the unlatch character + if edifact_value == 0x1F { + // 011111 + // Read rest of byte, which should be 0, and stop + let bits_left: i32 = 8 - bits.get_bit_offset(); + if bits_left != 8 { + bits.read_bits(bits_left); + } + return; + } + if (edifact_value & 0x20) == 0 { + // no 1 in the leading (6th) bit + // Add a leading 01 to the 6 bit binary value + edifact_value |= 0x40; + } + result.append(edifact_value as char); + } + i += 1; + } + } + + }if !(bits.available() > 0) break;} + } + + /** + * See ISO 16022:2006, 5.2.9 and Annex B, B.2 + */ + fn decode_base256_segment( bits: &BitSource, result: &ECIStringBuilder, byte_segments: &Collection>) -> /* throws FormatException */Result> { + // Figure out how long the Base 256 Segment is. + // position is 1-indexed + let codeword_position: i32 = 1 + bits.get_byte_offset(); + let d1: i32 = ::unrandomize255_state(&bits.read_bits(8), codeword_position += 1 !!!check!!! post increment); + let mut count: i32; + if d1 == 0 { + // Read the remainder of the symbol + count = bits.available() / 8; + } else if d1 < 250 { + count = d1; + } else { + count = 250 * (d1 - 249) + ::unrandomize255_state(&bits.read_bits(8), codeword_position += 1 !!!check!!! post increment); + } + // We're seeing NegativeArraySizeException errors from users. + if count < 0 { + throw FormatException::get_format_instance(); + } + let mut bytes: [i8; count] = [0; count]; + { + let mut i: i32 = 0; + while i < count { + { + // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2 + if bits.available() < 8 { + throw FormatException::get_format_instance(); + } + bytes[i] = ::unrandomize255_state(&bits.read_bits(8), codeword_position += 1 !!!check!!! post increment) as i8; + } + i += 1; + } + } + + byte_segments.add(&bytes); + result.append(String::new(&bytes, StandardCharsets::ISO_8859_1)); + } + + /** + * See ISO 16022:2007, 5.4.1 + */ + fn decode_e_c_i_segment( bits: &BitSource, result: &ECIStringBuilder) -> /* throws FormatException */Result> { + if bits.available() < 8 { + throw FormatException::get_format_instance(); + } + let c1: i32 = bits.read_bits(8); + if c1 <= 127 { + result.append_e_c_i(c1 - 1); + } + //currently we only support character set ECIs + /*} else { + if (bits.available() < 8) { + throw FormatException.getFormatInstance(); + } + int c2 = bits.readBits(8); + if (c1 >= 128 && c1 <= 191) { + } else { + if (bits.available() < 8) { + throw FormatException.getFormatInstance(); + } + int c3 = bits.readBits(8); + } + }*/ + } + + /** + * See ISO 16022:2006, Annex B, B.2 + */ + fn unrandomize255_state( randomized_base256_codeword: i32, base256_codeword_position: i32) -> i32 { + let pseudo_random_number: i32 = ((149 * base256_codeword_position) % 255) + 1; + let temp_variable: i32 = randomized_base256_codeword - pseudo_random_number; + return if temp_variable >= 0 { temp_variable } else { temp_variable + 256 }; + } + } + + + // Decoder.java + /** + *

The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting + * the Data Matrix Code from an image.

+ * + * @author bbrown@google.com (Brian Brown) + */ +pub struct Decoder { + + let rs_decoder: ReedSolomonDecoder; +} + +impl Decoder { + + pub fn new() -> Decoder { + rs_decoder = ReedSolomonDecoder::new(GenericGF::DATA_MATRIX_FIELD_256); + } + + /** + *

Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans. + * "true" is taken to mean a black module.

+ * + * @param image booleans representing white/black Data Matrix Code modules + * @return text and bytes encoded within the Data Matrix Code + * @throws FormatException if the Data Matrix Code cannot be decoded + * @throws ChecksumException if error correction fails + */ + pub fn decode(&self, image: &Vec>) -> /* throws FormatException, ChecksumException */Result> { + return Ok(self.decode(&BitMatrix::parse(&image))); + } + + /** + *

Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken + * to mean a black module.

+ * + * @param bits booleans representing white/black Data Matrix Code modules + * @return text and bytes encoded within the Data Matrix Code + * @throws FormatException if the Data Matrix Code cannot be decoded + * @throws ChecksumException if error correction fails + */ + pub fn decode(&self, bits: &BitMatrix) -> /* throws FormatException, ChecksumException */Result> { + // Construct a parser and read version, error-correction level + let parser: BitMatrixParser = BitMatrixParser::new(bits); + let version: Version = parser.get_version(); + // Read codewords + let codewords: Vec = parser.read_codewords(); + // Separate into data blocks + let data_blocks: Vec = DataBlock::get_data_blocks(&codewords, version); + // Count total number of data bytes + let total_bytes: i32 = 0; + for let db: DataBlock in data_blocks { + total_bytes += db.get_num_data_codewords(); + } + let result_bytes: [i8; total_bytes] = [0; total_bytes]; + let data_blocks_count: i32 = data_blocks.len(); + // Error-correct and copy data blocks together into a stream of bytes + { + let mut j: i32 = 0; + while j < data_blocks_count { + { + let data_block: DataBlock = data_blocks[j]; + let codeword_bytes: Vec = data_block.get_codewords(); + let num_data_codewords: i32 = data_block.get_num_data_codewords(); + self.correct_errors(&codeword_bytes, num_data_codewords); + { + let mut i: i32 = 0; + while i < num_data_codewords { + { + // De-interlace data blocks. + result_bytes[i * data_blocks_count + j] = codeword_bytes[i]; + } + i += 1; + } + } + + } + j += 1; + } + } + + // Decode the contents of that stream of bytes + return Ok(DecodedBitStreamParser::decode(&result_bytes)); + } + + /** + *

Given data and error-correction codewords received, possibly corrupted by errors, attempts to + * correct the errors in-place using Reed-Solomon error correction.

+ * + * @param codewordBytes data and error correction codewords + * @param numDataCodewords number of codewords that are data bytes + * @throws ChecksumException if error correction fails + */ + fn correct_errors(&self, codeword_bytes: &Vec, num_data_codewords: i32) -> /* throws ChecksumException */Result> { + let num_codewords: i32 = codeword_bytes.len(); + // First read into an array of ints + let codewords_ints: [i32; num_codewords] = [0; num_codewords]; + { + let mut i: i32 = 0; + while i < num_codewords { + { + codewords_ints[i] = codeword_bytes[i] & 0xFF; + } + i += 1; + } + } + + let tryResult1 = 0; + 'try1: loop { + { + self.rs_decoder.decode(&codewords_ints, codeword_bytes.len() - num_data_codewords); + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &ReedSolomonException) { + throw ChecksumException::get_checksum_instance(); + } 0 => break + } + + // We don't care about errors in the error-correction codewords + { + let mut i: i32 = 0; + while i < num_data_codewords { + { + codeword_bytes[i] = codewords_ints[i] as i8; + } + i += 1; + } + } + + } +} + + +// Version.java +/** + * The Version object encapsulates attributes about a particular + * size Data Matrix Code. + * + * @author bbrown@google.com (Brian Brown) + */ + +const VERSIONS: Vec = ::build_versions(); +pub struct Version { + + let version_number: i32; + + let symbol_size_rows: i32; + + let symbol_size_columns: i32; + + let data_region_size_rows: i32; + + let data_region_size_columns: i32; + + let ec_blocks: ECBlocks; + + let total_codewords: i32; +} + +impl Version { + + fn new( version_number: i32, symbol_size_rows: i32, symbol_size_columns: i32, data_region_size_rows: i32, data_region_size_columns: i32, ec_blocks: &ECBlocks) -> Version { + let .versionNumber = version_number; + let .symbolSizeRows = symbol_size_rows; + let .symbolSizeColumns = symbol_size_columns; + let .dataRegionSizeRows = data_region_size_rows; + let .dataRegionSizeColumns = data_region_size_columns; + let .ecBlocks = ec_blocks; + // Calculate the total number of codewords + let mut total: i32 = 0; + let ec_codewords: i32 = ec_blocks.get_e_c_codewords(); + let ecb_array: Vec = ec_blocks.get_e_c_blocks(); + for let ec_block: ECB in ecb_array { + total += ec_block.get_count() * (ec_block.get_data_codewords() + ec_codewords); + } + let .totalCodewords = total; + } + + pub fn get_version_number(&self) -> i32 { + return self.version_number; + } + + pub fn get_symbol_size_rows(&self) -> i32 { + return self.symbol_size_rows; + } + + pub fn get_symbol_size_columns(&self) -> i32 { + return self.symbol_size_columns; + } + + pub fn get_data_region_size_rows(&self) -> i32 { + return self.data_region_size_rows; + } + + pub fn get_data_region_size_columns(&self) -> i32 { + return self.data_region_size_columns; + } + + pub fn get_total_codewords(&self) -> i32 { + return self.total_codewords; + } + + fn get_e_c_blocks(&self) -> ECBlocks { + return self.ec_blocks; + } + + /** + *

Deduces version information from Data Matrix dimensions.

+ * + * @param numRows Number of rows in modules + * @param numColumns Number of columns in modules + * @return Version for a Data Matrix Code of those dimensions + * @throws FormatException if dimensions do correspond to a valid Data Matrix size + */ + pub fn get_version_for_dimensions( num_rows: i32, num_columns: i32) -> /* throws FormatException */Result> { + if (num_rows & 0x01) != 0 || (num_columns & 0x01) != 0 { + throw FormatException::get_format_instance(); + } + for let version: Version in VERSIONS { + if version.symbolSizeRows == num_rows && version.symbolSizeColumns == num_columns { + return Ok(version); + } + } + throw FormatException::get_format_instance(); + } + + /** + *

Encapsulates a set of error-correction blocks in one symbol version. Most versions will + * use blocks of differing sizes within one version, so, this encapsulates the parameters for + * each set of blocks. It also holds the number of error-correction codewords per block since it + * will be the same across all blocks within one version.

+ */ + struct ECBlocks { + + let ec_codewords: i32; + + let ec_blocks: Vec; + } + + impl ECBlocks { + + fn new( ec_codewords: i32, ec_blocks: &ECB) -> ECBlocks { + let .ecCodewords = ec_codewords; + let .ecBlocks = : vec![ECB; 1] = vec![ec_blocks, ] + ; + } + + fn new( ec_codewords: i32, ec_blocks1: &ECB, ec_blocks2: &ECB) -> ECBlocks { + let .ecCodewords = ec_codewords; + let .ecBlocks = : vec![ECB; 2] = vec![ec_blocks1, ec_blocks2, ] + ; + } + + fn get_e_c_codewords(&self) -> i32 { + return self.ec_codewords; + } + + fn get_e_c_blocks(&self) -> Vec { + return self.ec_blocks; + } + } + + + /** + *

Encapsulates the parameters for one error-correction block in one symbol version. + * This includes the number of data codewords, and the number of times a block with these + * parameters is used consecutively in the Data Matrix code version's format.

+ */ + struct ECB { + + let count: i32; + + let data_codewords: i32; + } + + impl ECB { + + fn new( count: i32, data_codewords: i32) -> ECB { + let .count = count; + let .dataCodewords = data_codewords; + } + + fn get_count(&self) -> i32 { + return self.count; + } + + fn get_data_codewords(&self) -> i32 { + return self.data_codewords; + } + } + + + pub fn to_string(&self) -> String { + return String::value_of(self.version_number); + } + + /** + * See ISO 16022:2006 5.5.1 Table 7 + */ + fn build_versions() -> Vec { + return : vec![Version; 48] = vec![Version::new(1, 10, 10, 8, 8, ECBlocks::new(5, ECB::new(1, 3))), Version::new(2, 12, 12, 10, 10, ECBlocks::new(7, ECB::new(1, 5))), Version::new(3, 14, 14, 12, 12, ECBlocks::new(10, ECB::new(1, 8))), Version::new(4, 16, 16, 14, 14, ECBlocks::new(12, ECB::new(1, 12))), Version::new(5, 18, 18, 16, 16, ECBlocks::new(14, ECB::new(1, 18))), Version::new(6, 20, 20, 18, 18, ECBlocks::new(18, ECB::new(1, 22))), Version::new(7, 22, 22, 20, 20, ECBlocks::new(20, ECB::new(1, 30))), Version::new(8, 24, 24, 22, 22, ECBlocks::new(24, ECB::new(1, 36))), Version::new(9, 26, 26, 24, 24, ECBlocks::new(28, ECB::new(1, 44))), Version::new(10, 32, 32, 14, 14, ECBlocks::new(36, ECB::new(1, 62))), Version::new(11, 36, 36, 16, 16, ECBlocks::new(42, ECB::new(1, 86))), Version::new(12, 40, 40, 18, 18, ECBlocks::new(48, ECB::new(1, 114))), Version::new(13, 44, 44, 20, 20, ECBlocks::new(56, ECB::new(1, 144))), Version::new(14, 48, 48, 22, 22, ECBlocks::new(68, ECB::new(1, 174))), Version::new(15, 52, 52, 24, 24, ECBlocks::new(42, ECB::new(2, 102))), Version::new(16, 64, 64, 14, 14, ECBlocks::new(56, ECB::new(2, 140))), Version::new(17, 72, 72, 16, 16, ECBlocks::new(36, ECB::new(4, 92))), Version::new(18, 80, 80, 18, 18, ECBlocks::new(48, ECB::new(4, 114))), Version::new(19, 88, 88, 20, 20, ECBlocks::new(56, ECB::new(4, 144))), Version::new(20, 96, 96, 22, 22, ECBlocks::new(68, ECB::new(4, 174))), Version::new(21, 104, 104, 24, 24, ECBlocks::new(56, ECB::new(6, 136))), Version::new(22, 120, 120, 18, 18, ECBlocks::new(68, ECB::new(6, 175))), Version::new(23, 132, 132, 20, 20, ECBlocks::new(62, ECB::new(8, 163))), Version::new(24, 144, 144, 22, 22, ECBlocks::new(62, ECB::new(8, 156), ECB::new(2, 155))), Version::new(25, 8, 18, 6, 16, ECBlocks::new(7, ECB::new(1, 5))), Version::new(26, 8, 32, 6, 14, ECBlocks::new(11, ECB::new(1, 10))), Version::new(27, 12, 26, 10, 24, ECBlocks::new(14, ECB::new(1, 16))), Version::new(28, 12, 36, 10, 16, ECBlocks::new(18, ECB::new(1, 22))), Version::new(29, 16, 36, 14, 16, ECBlocks::new(24, ECB::new(1, 32))), Version::new(30, 16, 48, 14, 22, ECBlocks::new(28, ECB::new(1, 49))), // ISO 21471:2020 (DMRE) 5.5.1 Table 7 + Version::new(31, 8, 48, 6, 22, ECBlocks::new(15, ECB::new(1, 18))), Version::new(32, 8, 64, 6, 14, ECBlocks::new(18, ECB::new(1, 24))), Version::new(33, 8, 80, 6, 18, ECBlocks::new(22, ECB::new(1, 32))), Version::new(34, 8, 96, 6, 22, ECBlocks::new(28, ECB::new(1, 38))), Version::new(35, 8, 120, 6, 18, ECBlocks::new(32, ECB::new(1, 49))), Version::new(36, 8, 144, 6, 22, ECBlocks::new(36, ECB::new(1, 63))), Version::new(37, 12, 64, 10, 14, ECBlocks::new(27, ECB::new(1, 43))), Version::new(38, 12, 88, 10, 20, ECBlocks::new(36, ECB::new(1, 64))), Version::new(39, 16, 64, 14, 14, ECBlocks::new(36, ECB::new(1, 62))), Version::new(40, 20, 36, 18, 16, ECBlocks::new(28, ECB::new(1, 44))), Version::new(41, 20, 44, 18, 20, ECBlocks::new(34, ECB::new(1, 56))), Version::new(42, 20, 64, 18, 14, ECBlocks::new(42, ECB::new(1, 84))), Version::new(43, 22, 48, 20, 22, ECBlocks::new(38, ECB::new(1, 72))), Version::new(44, 24, 48, 22, 22, ECBlocks::new(41, ECB::new(1, 80))), Version::new(45, 24, 64, 22, 14, ECBlocks::new(46, ECB::new(1, 108))), Version::new(46, 26, 40, 24, 18, ECBlocks::new(38, ECB::new(1, 70))), Version::new(47, 26, 48, 24, 22, ECBlocks::new(42, ECB::new(1, 90))), Version::new(48, 26, 64, 24, 14, ECBlocks::new(50, ECB::new(1, 118))), ] + ; + } +} + diff --git a/src/datamatrix/detector.rs b/src/datamatrix/detector.rs index e69de29..931ea8d 100644 --- a/src/datamatrix/detector.rs +++ b/src/datamatrix/detector.rs @@ -0,0 +1,311 @@ +import com.google.zxing.NotFoundException; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.DetectorResult; +import com.google.zxing.common.GridSampler; +import com.google.zxing.common.detector.WhiteRectangleDetector; + +// Detector.java +/** + *

Encapsulates logic that can detect a Data Matrix Code in an image, even if the Data Matrix Code + * is rotated or skewed, or partially obscured.

+ * + * @author Sean Owen + */ +pub struct Detector { + + let image: BitMatrix; + + let rectangle_detector: WhiteRectangleDetector; +} + +impl Detector { + + pub fn new( image: &BitMatrix) -> Detector throws NotFoundException { + let .image = image; + rectangle_detector = WhiteRectangleDetector::new(image); + } + + /** + *

Detects a Data Matrix Code in an image.

+ * + * @return {@link DetectorResult} encapsulating results of detecting a Data Matrix Code + * @throws NotFoundException if no Data Matrix Code can be found + */ + pub fn detect(&self) -> /* throws NotFoundException */Result> { + let corner_points: Vec = self.rectangle_detector.detect(); + let mut points: Vec = self.detect_solid1(corner_points); + points = self.detect_solid2(points); + points[3] = self.correct_top_right(points); + if points[3] == null { + throw NotFoundException::get_not_found_instance(); + } + points = self.shift_to_module_center(points); + let top_left: ResultPoint = points[0]; + let bottom_left: ResultPoint = points[1]; + let bottom_right: ResultPoint = points[2]; + let top_right: ResultPoint = points[3]; + let dimension_top: i32 = self.transitions_between(top_left, top_right) + 1; + let dimension_right: i32 = self.transitions_between(bottom_right, top_right) + 1; + if (dimension_top & 0x01) == 1 { + dimension_top += 1; + } + if (dimension_right & 0x01) == 1 { + dimension_right += 1; + } + if 4 * dimension_top < 6 * dimension_right && 4 * dimension_right < 6 * dimension_top { + // The matrix is square + dimension_top = dimension_right = Math::max(dimension_top, dimension_right); + } + let bits: BitMatrix = ::sample_grid(self.image, top_left, bottom_left, bottom_right, top_right, dimension_top, dimension_right); + return Ok(DetectorResult::new(bits, : vec![ResultPoint; 4] = vec![top_left, bottom_left, bottom_right, top_right, ] + )); + } + + fn shift_point( point: &ResultPoint, to: &ResultPoint, div: i32) -> ResultPoint { + let x: f32 = (to.get_x() - point.get_x()) / (div + 1); + let y: f32 = (to.get_y() - point.get_y()) / (div + 1); + return ResultPoint::new(point.get_x() + x, point.get_y() + y); + } + + fn move_away( point: &ResultPoint, from_x: f32, from_y: f32) -> ResultPoint { + let mut x: f32 = point.get_x(); + let mut y: f32 = point.get_y(); + if x < from_x { + x -= 1.0; + } else { + x += 1.0; + } + if y < from_y { + y -= 1.0; + } else { + y += 1.0; + } + return ResultPoint::new(x, y); + } + + /** + * Detect a solid side which has minimum transition. + */ + fn detect_solid1(&self, corner_points: &Vec) -> Vec { + // 0 2 + // 1 3 + let point_a: ResultPoint = corner_points[0]; + let point_b: ResultPoint = corner_points[1]; + let point_c: ResultPoint = corner_points[3]; + let point_d: ResultPoint = corner_points[2]; + let tr_a_b: i32 = self.transitions_between(point_a, point_b); + let tr_b_c: i32 = self.transitions_between(point_b, point_c); + let tr_c_d: i32 = self.transitions_between(point_c, point_d); + let tr_d_a: i32 = self.transitions_between(point_d, point_a); + // 0..3 + // : : + // 1--2 + let mut min: i32 = tr_a_b; + let mut points: vec![Vec; 4] = vec![point_d, point_a, point_b, point_c, ] + ; + if min > tr_b_c { + min = tr_b_c; + points[0] = point_a; + points[1] = point_b; + points[2] = point_c; + points[3] = point_d; + } + if min > tr_c_d { + min = tr_c_d; + points[0] = point_b; + points[1] = point_c; + points[2] = point_d; + points[3] = point_a; + } + if min > tr_d_a { + points[0] = point_c; + points[1] = point_d; + points[2] = point_a; + points[3] = point_b; + } + return points; + } + + /** + * Detect a second solid side next to first solid side. + */ + fn detect_solid2(&self, points: &Vec) -> Vec { + // A..D + // : : + // B--C + let point_a: ResultPoint = points[0]; + let point_b: ResultPoint = points[1]; + let point_c: ResultPoint = points[2]; + let point_d: ResultPoint = points[3]; + // Transition detection on the edge is not stable. + // To safely detect, shift the points to the module center. + let tr: i32 = self.transitions_between(point_a, point_d); + let point_bs: ResultPoint = ::shift_point(point_b, point_c, (tr + 1) * 4); + let point_cs: ResultPoint = ::shift_point(point_c, point_b, (tr + 1) * 4); + let tr_b_a: i32 = self.transitions_between(point_bs, point_a); + let tr_c_d: i32 = self.transitions_between(point_cs, point_d); + // 1--2 + if tr_b_a < tr_c_d { + // solid sides: A-B-C + points[0] = point_a; + points[1] = point_b; + points[2] = point_c; + points[3] = point_d; + } else { + // solid sides: B-C-D + points[0] = point_b; + points[1] = point_c; + points[2] = point_d; + points[3] = point_a; + } + return points; + } + + /** + * Calculates the corner position of the white top right module. + */ + fn correct_top_right(&self, points: &Vec) -> ResultPoint { + // A..D + // | : + // B--C + let point_a: ResultPoint = points[0]; + let point_b: ResultPoint = points[1]; + let point_c: ResultPoint = points[2]; + let point_d: ResultPoint = points[3]; + // shift points for safe transition detection. + let tr_top: i32 = self.transitions_between(point_a, point_d); + let tr_right: i32 = self.transitions_between(point_b, point_d); + let point_as: ResultPoint = ::shift_point(point_a, point_b, (tr_right + 1) * 4); + let point_cs: ResultPoint = ::shift_point(point_c, point_b, (tr_top + 1) * 4); + tr_top = self.transitions_between(point_as, point_d); + tr_right = self.transitions_between(point_cs, point_d); + let candidate1: ResultPoint = ResultPoint::new(point_d.get_x() + (point_c.get_x() - point_b.get_x()) / (tr_top + 1), point_d.get_y() + (point_c.get_y() - point_b.get_y()) / (tr_top + 1)); + let candidate2: ResultPoint = ResultPoint::new(point_d.get_x() + (point_a.get_x() - point_b.get_x()) / (tr_right + 1), point_d.get_y() + (point_a.get_y() - point_b.get_y()) / (tr_right + 1)); + if !self.is_valid(candidate1) { + if self.is_valid(candidate2) { + return candidate2; + } + return null; + } + if !self.is_valid(candidate2) { + return candidate1; + } + let sumc1: i32 = self.transitions_between(point_as, candidate1) + self.transitions_between(point_cs, candidate1); + let sumc2: i32 = self.transitions_between(point_as, candidate2) + self.transitions_between(point_cs, candidate2); + if sumc1 > sumc2 { + return candidate1; + } else { + return candidate2; + } + } + + /** + * Shift the edge points to the module center. + */ + fn shift_to_module_center(&self, points: &Vec) -> Vec { + // A..D + // | : + // B--C + let point_a: ResultPoint = points[0]; + let point_b: ResultPoint = points[1]; + let point_c: ResultPoint = points[2]; + let point_d: ResultPoint = points[3]; + // calculate pseudo dimensions + let dim_h: i32 = self.transitions_between(point_a, point_d) + 1; + let dim_v: i32 = self.transitions_between(point_c, point_d) + 1; + // shift points for safe dimension detection + let point_as: ResultPoint = ::shift_point(point_a, point_b, dim_v * 4); + let point_cs: ResultPoint = ::shift_point(point_c, point_b, dim_h * 4); + // calculate more precise dimensions + dim_h = self.transitions_between(point_as, point_d) + 1; + dim_v = self.transitions_between(point_cs, point_d) + 1; + if (dim_h & 0x01) == 1 { + dim_h += 1; + } + if (dim_v & 0x01) == 1 { + dim_v += 1; + } + // WhiteRectangleDetector returns points inside of the rectangle. + // I want points on the edges. + let center_x: f32 = (point_a.get_x() + point_b.get_x() + point_c.get_x() + point_d.get_x()) / 4; + let center_y: f32 = (point_a.get_y() + point_b.get_y() + point_c.get_y() + point_d.get_y()) / 4; + point_a = ::move_away(point_a, center_x, center_y); + point_b = ::move_away(point_b, center_x, center_y); + point_c = ::move_away(point_c, center_x, center_y); + point_d = ::move_away(point_d, center_x, center_y); + let point_bs: ResultPoint; + let point_ds: ResultPoint; + // shift points to the center of each modules + point_as = ::shift_point(point_a, point_b, dim_v * 4); + point_as = ::shift_point(point_as, point_d, dim_h * 4); + point_bs = ::shift_point(point_b, point_a, dim_v * 4); + point_bs = ::shift_point(point_bs, point_c, dim_h * 4); + point_cs = ::shift_point(point_c, point_d, dim_v * 4); + point_cs = ::shift_point(point_cs, point_b, dim_h * 4); + point_ds = ::shift_point(point_d, point_c, dim_v * 4); + point_ds = ::shift_point(point_ds, point_a, dim_h * 4); + return : vec![ResultPoint; 4] = vec![point_as, point_bs, point_cs, point_ds, ] + ; + } + + fn is_valid(&self, p: &ResultPoint) -> bool { + return p.get_x() >= 0 && p.get_x() <= self.image.get_width() - 1 && p.get_y() > 0 && p.get_y() <= self.image.get_height() - 1; + } + + fn sample_grid( image: &BitMatrix, top_left: &ResultPoint, bottom_left: &ResultPoint, bottom_right: &ResultPoint, top_right: &ResultPoint, dimension_x: i32, dimension_y: i32) -> /* throws NotFoundException */Result> { + let sampler: GridSampler = GridSampler::get_instance(); + return Ok(sampler.sample_grid(image, dimension_x, dimension_y, 0.5f, 0.5f, dimension_x - 0.5f, 0.5f, dimension_x - 0.5f, dimension_y - 0.5f, 0.5f, dimension_y - 0.5f, &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())); + } + + /** + * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm. + */ + fn transitions_between(&self, from: &ResultPoint, to: &ResultPoint) -> i32 { + // See QR Code Detector, sizeOfBlackWhiteBlackRun() + let from_x: i32 = from.get_x() as i32; + let from_y: i32 = from.get_y() as i32; + let to_x: i32 = to.get_x() as i32; + let to_y: i32 = Math::min(self.image.get_height() - 1, to.get_y() as i32); + let steep: bool = Math::abs(to_y - from_y) > Math::abs(to_x - from_x); + if steep { + let mut temp: i32 = from_x; + from_x = from_y; + from_y = temp; + temp = to_x; + to_x = to_y; + to_y = temp; + } + let dx: i32 = Math::abs(to_x - from_x); + let dy: i32 = Math::abs(to_y - from_y); + let mut error: i32 = -dx / 2; + let ystep: i32 = if from_y < to_y { 1 } else { -1 }; + let xstep: i32 = if from_x < to_x { 1 } else { -1 }; + let mut transitions: i32 = 0; + let in_black: bool = self.image.get( if steep { from_y } else { from_x }, if steep { from_x } else { from_y }); + { + let mut x: i32 = from_x, let mut y: i32 = from_y; + while x != to_x { + { + let is_black: bool = self.image.get( if steep { y } else { x }, if steep { x } else { y }); + if is_black != in_black { + transitions += 1; + in_black = is_black; + } + error += dy; + if error > 0 { + if y == to_y { + break; + } + y += ystep; + error -= dx; + } + } + x += xstep; + } + } + + return transitions; + } +} + diff --git a/src/datamatrix/encoder.rs b/src/datamatrix/encoder.rs index e69de29..baf8f84 100644 --- a/src/datamatrix/encoder.rs +++ b/src/datamatrix/encoder.rs @@ -0,0 +1,2820 @@ +import com.google.zxing.Dimension; +import com.google.zxing.common.MinimalECIInput; + +// ASCIIEncoder.java + +struct ASCIIEncoder { +} + +impl Encoder for ASCIIEncoder {} + +impl ASCIIEncoder { + + pub fn get_encoding_mode(&self) -> i32 { + return HighLevelEncoder::ASCII_ENCODATION; + } + + pub fn encode(&self, context: &EncoderContext) { + //step B + let n: i32 = HighLevelEncoder::determine_consecutive_digit_count(&context.get_message(), context.pos); + if n >= 2 { + context.write_codeword(&::encode_a_s_c_i_i_digits(&context.get_message().char_at(context.pos), &context.get_message().char_at(context.pos + 1))); + context.pos += 2; + } else { + let c: char = context.get_current_char(); + let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); + if new_mode != self.get_encoding_mode() { + match new_mode { + HighLevelEncoder::BASE256_ENCODATION => + { + context.write_codeword(HighLevelEncoder::LATCH_TO_BASE256); + context.signal_encoder_change(HighLevelEncoder::BASE256_ENCODATION); + return; + } + HighLevelEncoder::C40_ENCODATION => + { + context.write_codeword(HighLevelEncoder::LATCH_TO_C40); + context.signal_encoder_change(HighLevelEncoder::C40_ENCODATION); + return; + } + HighLevelEncoder::X12_ENCODATION => + { + context.write_codeword(HighLevelEncoder::LATCH_TO_ANSIX12); + context.signal_encoder_change(HighLevelEncoder::X12_ENCODATION); + break; + } + HighLevelEncoder::TEXT_ENCODATION => + { + context.write_codeword(HighLevelEncoder::LATCH_TO_TEXT); + context.signal_encoder_change(HighLevelEncoder::TEXT_ENCODATION); + break; + } + HighLevelEncoder::EDIFACT_ENCODATION => + { + context.write_codeword(HighLevelEncoder::LATCH_TO_EDIFACT); + context.signal_encoder_change(HighLevelEncoder::EDIFACT_ENCODATION); + break; + } + _ => + { + throw IllegalStateException::new(format!("Illegal mode: {}", new_mode)); + } + } + } else if HighLevelEncoder::is_extended_a_s_c_i_i(c) { + context.write_codeword(HighLevelEncoder::UPPER_SHIFT); + context.write_codeword((c - 128 + 1) as char); + context.pos += 1; + } else { + context.write_codeword((c + 1) as char); + context.pos += 1; + } + } + } + + fn encode_a_s_c_i_i_digits( digit1: char, digit2: char) -> char { + if HighLevelEncoder::is_digit(digit1) && HighLevelEncoder::is_digit(digit2) { + let num: i32 = (digit1 - 48) * 10 + (digit2 - 48); + return (num + 130) as char; + } + throw IllegalArgumentException::new(format!("not digits: {}{}", digit1, digit2)); + } +} + + +// Base256Encoder.java +struct Base256Encoder { +} + +impl Encoder for Base256Encoder {} + +impl Base256Encoder { + + pub fn get_encoding_mode(&self) -> i32 { + return HighLevelEncoder::BASE256_ENCODATION; + } + + pub fn encode(&self, context: &EncoderContext) { + let buffer: StringBuilder = StringBuilder::new(); + //Initialize length field + buffer.append('\0'); + while context.has_more_characters() { + let c: char = context.get_current_char(); + buffer.append(c); + context.pos += 1; + let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); + if new_mode != self.get_encoding_mode() { + // Return to ASCII encodation, which will actually handle latch to new mode + context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); + break; + } + } + let data_count: i32 = buffer.length() - 1; + let length_field_size: i32 = 1; + let current_size: i32 = context.get_codeword_count() + data_count + length_field_size; + context.update_symbol_info(current_size); + let must_pad: bool = (context.get_symbol_info().get_data_capacity() - current_size) > 0; + if context.has_more_characters() || must_pad { + if data_count <= 249 { + buffer.set_char_at(0, data_count as char); + } else if data_count <= 1555 { + buffer.set_char_at(0, ((data_count / 250) + 249) as char); + buffer.insert(1, (data_count % 250) as char); + } else { + throw IllegalStateException::new(format!("Message length not in valid ranges: {}", data_count)); + } + } + { + let mut i: i32 = 0, let c: i32 = buffer.length(); + while i < c { + { + context.write_codeword(&::randomize255_state(&buffer.char_at(i), context.get_codeword_count() + 1)); + } + i += 1; + } + } + + } + + fn randomize255_state( ch: char, codeword_position: i32) -> char { + let pseudo_random: i32 = ((149 * codeword_position) % 255) + 1; + let temp_variable: i32 = ch + pseudo_random; + if temp_variable <= 255 { + return temp_variable as char; + } else { + return (temp_variable - 256) as char; + } + } +} + + +// C40Encoder.java +struct C40Encoder { +} + +impl Encoder for C40Encoder{} + +impl C40Encoder { + + pub fn get_encoding_mode(&self) -> i32 { + return HighLevelEncoder::C40_ENCODATION; + } + + fn encode_maximal(&self, context: &EncoderContext) { + let buffer: StringBuilder = StringBuilder::new(); + let last_char_size: i32 = 0; + let backtrack_start_position: i32 = context.pos; + let backtrack_buffer_length: i32 = 0; + while context.has_more_characters() { + let c: char = context.get_current_char(); + context.pos += 1; + last_char_size = self.encode_char(c, &buffer); + if buffer.length() % 3 == 0 { + backtrack_start_position = context.pos; + backtrack_buffer_length = buffer.length(); + } + } + if backtrack_buffer_length != buffer.length() { + let unwritten: i32 = (buffer.length() / 3) * 2; + // +1 for the latch to C40 + let cur_codeword_count: i32 = context.get_codeword_count() + unwritten + 1; + context.update_symbol_info(cur_codeword_count); + let available: i32 = context.get_symbol_info().get_data_capacity() - cur_codeword_count; + let rest: i32 = buffer.length() % 3; + if (rest == 2 && available != 2) || (rest == 1 && (last_char_size > 3 || available != 1)) { + buffer.set_length(backtrack_buffer_length); + context.pos = backtrack_start_position; + } + } + if buffer.length() > 0 { + context.write_codeword(HighLevelEncoder::LATCH_TO_C40); + } + self.handle_e_o_d(context, &buffer); + } + + pub fn encode(&self, context: &EncoderContext) { + //step C + let buffer: StringBuilder = StringBuilder::new(); + while context.has_more_characters() { + let c: char = context.get_current_char(); + context.pos += 1; + let last_char_size: i32 = self.encode_char(c, &buffer); + let unwritten: i32 = (buffer.length() / 3) * 2; + let cur_codeword_count: i32 = context.get_codeword_count() + unwritten; + context.update_symbol_info(cur_codeword_count); + let available: i32 = context.get_symbol_info().get_data_capacity() - cur_codeword_count; + if !context.has_more_characters() { + //Avoid having a single C40 value in the last triplet + let removed: StringBuilder = StringBuilder::new(); + if (buffer.length() % 3) == 2 && available != 2 { + last_char_size = self.backtrack_one_character(context, &buffer, &removed, last_char_size); + } + while (buffer.length() % 3) == 1 && (last_char_size > 3 || available != 1) { + last_char_size = self.backtrack_one_character(context, &buffer, &removed, last_char_size); + } + break; + } + let count: i32 = buffer.length(); + if (count % 3) == 0 { + let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); + if new_mode != self.get_encoding_mode() { + // Return to ASCII encodation, which will actually handle latch to new mode + context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); + break; + } + } + } + self.handle_e_o_d(context, &buffer); + } + + fn backtrack_one_character(&self, context: &EncoderContext, buffer: &StringBuilder, removed: &StringBuilder, last_char_size: i32) -> i32 { + let count: i32 = buffer.length(); + buffer.delete(count - last_char_size, count); + context.pos -= 1; + let c: char = context.get_current_char(); + last_char_size = self.encode_char(c, &removed); + //Deal with possible reduction in symbol size + context.reset_symbol_info(); + return last_char_size; + } + + fn write_next_triplet( context: &EncoderContext, buffer: &StringBuilder) { + context.write_codewords(&::encode_to_codewords(&buffer)); + buffer.delete(0, 3); + } + + /** + * Handle "end of data" situations + * + * @param context the encoder context + * @param buffer the buffer with the remaining encoded characters + */ + fn handle_e_o_d(&self, context: &EncoderContext, buffer: &StringBuilder) { + let unwritten: i32 = (buffer.length() / 3) * 2; + let rest: i32 = buffer.length() % 3; + let cur_codeword_count: i32 = context.get_codeword_count() + unwritten; + context.update_symbol_info(cur_codeword_count); + let available: i32 = context.get_symbol_info().get_data_capacity() - cur_codeword_count; + if rest == 2 { + //Shift 1 + buffer.append('\0'); + while buffer.length() >= 3 { + ::write_next_triplet(context, &buffer); + } + if context.has_more_characters() { + context.write_codeword(HighLevelEncoder::C40_UNLATCH); + } + } else if available == 1 && rest == 1 { + while buffer.length() >= 3 { + ::write_next_triplet(context, &buffer); + } + if context.has_more_characters() { + context.write_codeword(HighLevelEncoder::C40_UNLATCH); + } + // else no unlatch + context.pos -= 1; + } else if rest == 0 { + while buffer.length() >= 3 { + ::write_next_triplet(context, &buffer); + } + if available > 0 || context.has_more_characters() { + context.write_codeword(HighLevelEncoder::C40_UNLATCH); + } + } else { + throw IllegalStateException::new("Unexpected case. Please report!"); + } + context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); + } + + fn encode_char(&self, c: char, sb: &StringBuilder) -> i32 { + if c == ' ' { + sb.append('\3'); + return 1; + } + if c >= '0' && c <= '9' { + sb.append((c - 48 + 4) as char); + return 1; + } + if c >= 'A' && c <= 'Z' { + sb.append((c - 65 + 14) as char); + return 1; + } + if c < ' ' { + //Shift 1 Set + sb.append('\0'); + sb.append(c); + return 2; + } + if c <= '/' { + //Shift 2 Set + sb.append('\1'); + sb.append((c - 33) as char); + return 2; + } + if c <= '@' { + //Shift 2 Set + sb.append('\1'); + sb.append((c - 58 + 15) as char); + return 2; + } + if c <= '_' { + //Shift 2 Set + sb.append('\1'); + sb.append((c - 91 + 22) as char); + return 2; + } + if c <= 127 { + //Shift 3 Set + sb.append('\2'); + sb.append((c - 96) as char); + return 2; + } + //Shift 2, Upper Shift + sb.append("\1"); + let mut len: i32 = 2; + len += self.encode_char((c - 128) as char, &sb); + return len; + } + + fn encode_to_codewords( sb: &CharSequence) -> String { + let v: i32 = (1600 * sb.char_at(0)) + (40 * sb.char_at(1)) + sb.char_at(2) + 1; + let cw1: char = (v / 256) as char; + let cw2: char = (v % 256) as char; + return String::new( : vec![char; 2] = vec![cw1, cw2, ] + ); + } +} + + +// DataMatrixSymbolInfo144.java +struct DataMatrixSymbolInfo144 { + super: SymbolInfo; +} + +impl SymbolInfo for DataMatrixSymbolInfo144{} + +impl DataMatrixSymbolInfo144 { + + fn new() -> DataMatrixSymbolInfo144 { + super(false, 1558, 620, 22, 22, 36, -1, 62); + } + + pub fn get_interleaved_block_count(&self) -> i32 { + return 10; + } + + pub fn get_data_length_for_interleaved_block(&self, index: i32) -> i32 { + return if (index <= 8) { 156 } else { 155 }; + } +} + +// DefaultPlacement.java +/** + * Symbol Character Placement Program. Adapted from Annex M.1 in ISO/IEC 16022:2000(E). + */ +pub struct DefaultPlacement { + + let codewords: CharSequence; + + let numrows: i32; + + let mut numcols: i32; + + let mut bits: Vec; +} + +impl DefaultPlacement { + + /** + * Main constructor + * + * @param codewords the codewords to place + * @param numcols the number of columns + * @param numrows the number of rows + */ + pub fn new( codewords: &CharSequence, numcols: i32, numrows: i32) -> DefaultPlacement { + let .codewords = codewords; + let .numcols = numcols; + let .numrows = numrows; + let .bits = : [i8; numcols * numrows] = [0; numcols * numrows]; + //Initialize with "not set" value + Arrays::fill(let .bits, -1 as i8); + } + + fn get_numrows(&self) -> i32 { + return self.numrows; + } + + fn get_numcols(&self) -> i32 { + return self.numcols; + } + + fn get_bits(&self) -> Vec { + return self.bits; + } + + pub fn get_bit(&self, col: i32, row: i32) -> bool { + return self.bits[row * self.numcols + col] == 1; + } + + fn set_bit(&self, col: i32, row: i32, bit: bool) { + self.bits[row * self.numcols + col] = ( if bit { 1 } else { 0 }) as i8; + } + + fn no_bit(&self, col: i32, row: i32) -> bool { + return self.bits[row * self.numcols + col] < 0; + } + + pub fn place(&self) { + let mut pos: i32 = 0; + let mut row: i32 = 4; + let mut col: i32 = 0; + loop { { + // repeatedly first check for one of the special corner cases, then... + if (row == self.numrows) && (col == 0) { + self.corner1(pos += 1 !!!check!!! post increment); + } + if (row == self.numrows - 2) && (col == 0) && ((self.numcols % 4) != 0) { + self.corner2(pos += 1 !!!check!!! post increment); + } + if (row == self.numrows - 2) && (col == 0) && (self.numcols % 8 == 4) { + self.corner3(pos += 1 !!!check!!! post increment); + } + if (row == self.numrows + 4) && (col == 2) && ((self.numcols % 8) == 0) { + self.corner4(pos += 1 !!!check!!! post increment); + } + // sweep upward diagonally, inserting successive characters... + loop { { + if (row < self.numrows) && (col >= 0) && self.no_bit(col, row) { + self.utah(row, col, pos += 1 !!!check!!! post increment); + } + row -= 2; + col += 2; + }if !(row >= 0 && (col < self.numcols)) break;} + row += 1; + col += 3; + // and then sweep downward diagonally, inserting successive characters, ... + loop { { + if (row >= 0) && (col < self.numcols) && self.no_bit(col, row) { + self.utah(row, col, pos += 1 !!!check!!! post increment); + } + row += 2; + col -= 2; + }if !((row < self.numrows) && (col >= 0)) break;} + row += 3; + col += 1; + // ...until the entire array is scanned + }if !((row < self.numrows) || (col < self.numcols)) break;} + // Lastly, if the lower right-hand corner is untouched, fill in fixed pattern + if self.no_bit(self.numcols - 1, self.numrows - 1) { + self.set_bit(self.numcols - 1, self.numrows - 1, true); + self.set_bit(self.numcols - 2, self.numrows - 2, true); + } + } + + fn module(&self, row: i32, col: i32, pos: i32, bit: i32) { + if row < 0 { + row += self.numrows; + col += 4 - ((self.numrows + 4) % 8); + } + if col < 0 { + col += self.numcols; + row += 4 - ((self.numcols + 4) % 8); + } + // Note the conversion: + let mut v: i32 = self.codewords.char_at(pos); + v &= 1 << (8 - bit); + self.set_bit(col, row, v != 0); + } + + /** + * Places the 8 bits of a utah-shaped symbol character in ECC200. + * + * @param row the row + * @param col the column + * @param pos character position + */ + fn utah(&self, row: i32, col: i32, pos: i32) { + self.module(row - 2, col - 2, pos, 1); + self.module(row - 2, col - 1, pos, 2); + self.module(row - 1, col - 2, pos, 3); + self.module(row - 1, col - 1, pos, 4); + self.module(row - 1, col, pos, 5); + self.module(row, col - 2, pos, 6); + self.module(row, col - 1, pos, 7); + self.module(row, col, pos, 8); + } + + fn corner1(&self, pos: i32) { + self.module(self.numrows - 1, 0, pos, 1); + self.module(self.numrows - 1, 1, pos, 2); + self.module(self.numrows - 1, 2, pos, 3); + self.module(0, self.numcols - 2, pos, 4); + self.module(0, self.numcols - 1, pos, 5); + self.module(1, self.numcols - 1, pos, 6); + self.module(2, self.numcols - 1, pos, 7); + self.module(3, self.numcols - 1, pos, 8); + } + + fn corner2(&self, pos: i32) { + self.module(self.numrows - 3, 0, pos, 1); + self.module(self.numrows - 2, 0, pos, 2); + self.module(self.numrows - 1, 0, pos, 3); + self.module(0, self.numcols - 4, pos, 4); + self.module(0, self.numcols - 3, pos, 5); + self.module(0, self.numcols - 2, pos, 6); + self.module(0, self.numcols - 1, pos, 7); + self.module(1, self.numcols - 1, pos, 8); + } + + fn corner3(&self, pos: i32) { + self.module(self.numrows - 3, 0, pos, 1); + self.module(self.numrows - 2, 0, pos, 2); + self.module(self.numrows - 1, 0, pos, 3); + self.module(0, self.numcols - 2, pos, 4); + self.module(0, self.numcols - 1, pos, 5); + self.module(1, self.numcols - 1, pos, 6); + self.module(2, self.numcols - 1, pos, 7); + self.module(3, self.numcols - 1, pos, 8); + } + + fn corner4(&self, pos: i32) { + self.module(self.numrows - 1, 0, pos, 1); + self.module(self.numrows - 1, self.numcols - 1, pos, 2); + self.module(0, self.numcols - 3, pos, 3); + self.module(0, self.numcols - 2, pos, 4); + self.module(0, self.numcols - 1, pos, 5); + self.module(1, self.numcols - 3, pos, 6); + self.module(1, self.numcols - 2, pos, 7); + self.module(1, self.numcols - 1, pos, 8); + } +} + + +// EdifactEncoder.java +struct EdifactEncoder { +} + +impl Encoder for EdifactEncoder {} + +impl EdifactEncoder { + + pub fn get_encoding_mode(&self) -> i32 { + return HighLevelEncoder::EDIFACT_ENCODATION; + } + + pub fn encode(&self, context: &EncoderContext) { + //step F + let buffer: StringBuilder = StringBuilder::new(); + while context.has_more_characters() { + let c: char = context.get_current_char(); + ::encode_char(c, &buffer); + context.pos += 1; + let count: i32 = buffer.length(); + if count >= 4 { + context.write_codewords(&::encode_to_codewords(&buffer)); + buffer.delete(0, 4); + let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); + if new_mode != self.get_encoding_mode() { + // Return to ASCII encodation, which will actually handle latch to new mode + context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); + break; + } + } + } + //Unlatch + buffer.append(31 as char); + ::handle_e_o_d(context, &buffer); + } + + /** + * Handle "end of data" situations + * + * @param context the encoder context + * @param buffer the buffer with the remaining encoded characters + */ + fn handle_e_o_d( context: &EncoderContext, buffer: &CharSequence) { + let tryResult1 = 0; + 'try1: loop { + { + let count: i32 = buffer.length(); + if count == 0 { + //Already finished + return; + } + if count == 1 { + //Only an unlatch at the end + context.update_symbol_info(); + let mut available: i32 = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); + let remaining: i32 = context.get_remaining_characters(); + // The following two lines are a hack inspired by the 'fix' from https://sourceforge.net/p/barcode4j/svn/221/ + if remaining > available { + context.update_symbol_info(context.get_codeword_count() + 1); + available = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); + } + if remaining <= available && available <= 2 { + //No unlatch + return; + } + } + if count > 4 { + throw IllegalStateException::new("Count must not exceed 4"); + } + let rest_chars: i32 = count - 1; + let encoded: String = ::encode_to_codewords(&buffer); + let end_of_symbol_reached: bool = !context.has_more_characters(); + let rest_in_ascii: bool = end_of_symbol_reached && rest_chars <= 2; + if rest_chars <= 2 { + context.update_symbol_info(context.get_codeword_count() + rest_chars); + let available: i32 = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); + if available >= 3 { + rest_in_ascii = false; + context.update_symbol_info(context.get_codeword_count() + encoded.length()); + //available = context.symbolInfo.dataCapacity - context.getCodewordCount(); + } + } + if rest_in_ascii { + context.reset_symbol_info(); + context.pos -= rest_chars; + } else { + context.write_codewords(&encoded); + } + } + break 'try1 + } + match tryResult1 { + 0 => break + } + finally { + context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); + } + } + + fn encode_char( c: char, sb: &StringBuilder) { + if c >= ' ' && c <= '?' { + sb.append(c); + } else if c >= '@' && c <= '^' { + sb.append((c - 64) as char); + } else { + HighLevelEncoder::illegal_character(c); + } + } + + fn encode_to_codewords( sb: &CharSequence) -> String { + let len: i32 = sb.length(); + if len == 0 { + throw IllegalStateException::new("StringBuilder must not be empty"); + } + let c1: char = sb.char_at(0); + let c2: char = if len >= 2 { sb.char_at(1) } else { 0 }; + let c3: char = if len >= 3 { sb.char_at(2) } else { 0 }; + let c4: char = if len >= 4 { sb.char_at(3) } else { 0 }; + let v: i32 = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4; + let cw1: char = ((v >> 16) & 255) as char; + let cw2: char = ((v >> 8) & 255) as char; + let cw3: char = (v & 255) as char; + let res: StringBuilder = StringBuilder::new(3); + res.append(cw1); + if len >= 2 { + res.append(cw2); + } + if len >= 3 { + res.append(cw3); + } + return res.to_string(); + } +} + +// Encoder.java +trait Encoder { + + fn get_encoding_mode(&self) -> i32 ; + + fn encode(&self, context: &EncoderContext) ; +} + +// EncoderContext.java +struct EncoderContext { + + let msg: String; + + let mut shape: SymbolShapeHint; + + let min_size: Dimension; + + let max_size: Dimension; + + let mut codewords: StringBuilder; + + let pos: i32; + + let new_encoding: i32; + + let symbol_info: SymbolInfo; + + let skip_at_end: i32; +} + +impl EncoderContext { + + fn new( msg: &String) -> EncoderContext { + //From this point on Strings are not Unicode anymore! + let msg_binary: Vec = msg.get_bytes(StandardCharsets::ISO_8859_1); + let sb: StringBuilder = StringBuilder::new(msg_binary.len()); + { + let mut i: i32 = 0, let c: i32 = msg_binary.len(); + while i < c { + { + let ch: char = (msg_binary[i] & 0xff) as char; + if ch == '?' && msg.char_at(i) != '?' { + throw IllegalArgumentException::new("Message contains characters outside ISO-8859-1 encoding."); + } + sb.append(ch); + } + i += 1; + } + } + + //Not Unicode here! + let .msg = sb.to_string(); + shape = SymbolShapeHint::FORCE_NONE; + let .codewords = StringBuilder::new(&msg.length()); + new_encoding = -1; + } + + pub fn set_symbol_shape(&self, shape: &SymbolShapeHint) { + self.shape = shape; + } + + pub fn set_size_constraints(&self, min_size: &Dimension, max_size: &Dimension) { + self.minSize = min_size; + self.maxSize = max_size; + } + + pub fn get_message(&self) -> String { + return self.msg; + } + + pub fn set_skip_at_end(&self, count: i32) { + self.skipAtEnd = count; + } + + pub fn get_current_char(&self) -> char { + return self.msg.char_at(self.pos); + } + + pub fn get_current(&self) -> char { + return self.msg.char_at(self.pos); + } + + pub fn get_codewords(&self) -> StringBuilder { + return self.codewords; + } + + pub fn write_codewords(&self, codewords: &String) { + self.codewords.append(&codewords); + } + + pub fn write_codeword(&self, codeword: char) { + self.codewords.append(codeword); + } + + pub fn get_codeword_count(&self) -> i32 { + return self.codewords.length(); + } + + pub fn get_new_encoding(&self) -> i32 { + return self.new_encoding; + } + + pub fn signal_encoder_change(&self, encoding: i32) { + self.newEncoding = encoding; + } + + pub fn reset_encoder_signal(&self) { + self.newEncoding = -1; + } + + pub fn has_more_characters(&self) -> bool { + return self.pos < self.get_total_message_char_count(); + } + + fn get_total_message_char_count(&self) -> i32 { + return self.msg.length() - self.skip_at_end; + } + + pub fn get_remaining_characters(&self) -> i32 { + return self.get_total_message_char_count() - self.pos; + } + + pub fn get_symbol_info(&self) -> SymbolInfo { + return self.symbol_info; + } + + pub fn update_symbol_info(&self) { + self.update_symbol_info(&self.get_codeword_count()); + } + + pub fn update_symbol_info(&self, len: i32) { + if self.symbolInfo == null || len > self.symbolInfo.get_data_capacity() { + self.symbolInfo = SymbolInfo::lookup(len, self.shape, self.min_size, self.max_size, true); + } + } + + pub fn reset_symbol_info(&self) { + self.symbolInfo = null; + } +} + + +// ErrorCorrection.java +/** + * Error Correction Code for ECC200. + */ + +/** + * Lookup table which factors to use for which number of error correction codewords. + * See FACTORS. + */ + const FACTOR_SETS: vec![Vec; 16] = vec![5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68, ] + ; + + /** + * Precomputed polynomial factors for ECC 200. + */ + const FACTORS: vec![vec![Vec>; 68]; 16] = vec![vec![228, 48, 15, 111, 62, ] + , vec![23, 68, 144, 134, 240, 92, 254, ] + , vec![28, 24, 185, 166, 223, 248, 116, 255, 110, 61, ] + , vec![175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120, ] + , vec![41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242, ] + , vec![156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185, ] + , vec![83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, 90, 188, ] + , vec![15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27, 174, 186, 172, ] + , vec![52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172, 254, 124, 12, 181, 184, 96, 50, 193, ] + , vec![211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121, 17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255, ] + , vec![245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, 182, 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25, 225, 98, 81, 112, ] + , vec![77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8, 175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101, 248, 202, 69, 50, 150, 177, 226, 5, 9, 5, ] + , vec![245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87, 191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138, 186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19, ] + , vec![175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235, 150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232, 144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28, 155, 43, 203, 107, 233, 53, 143, 46, ] + , vec![242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37, 185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71, 161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31, 176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204, ] + , vec![220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127, 213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236, 66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239, 181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63, 96, 103, 82, 186, ] + , ] + ; + + const MODULO_VALUE: i32 = 0x12D; + + const LOG: Vec; + + const ALOG: Vec; + pub struct ErrorCorrection { + } + + impl ErrorCorrection { + + static { + //Create log and antilog table + LOG = : [i32; 256] = [0; 256]; + ALOG = : [i32; 255] = [0; 255]; + let mut p: i32 = 1; + { + let mut i: i32 = 0; + while i < 255 { + { + ALOG[i] = p; + LOG[p] = i; + p *= 2; + if p >= 256 { + p ^= MODULO_VALUE; + } + } + i += 1; + } + } + + } + + fn new() -> ErrorCorrection { + } + + /** + * Creates the ECC200 error correction for an encoded message. + * + * @param codewords the codewords + * @param symbolInfo information about the symbol to be encoded + * @return the codewords with interleaved error correction. + */ + pub fn encode_e_c_c200( codewords: &String, symbol_info: &SymbolInfo) -> String { + if codewords.length() != symbol_info.get_data_capacity() { + throw IllegalArgumentException::new("The number of codewords does not match the selected symbol"); + } + let sb: StringBuilder = StringBuilder::new(symbol_info.get_data_capacity() + symbol_info.get_error_codewords()); + sb.append(&codewords); + let block_count: i32 = symbol_info.get_interleaved_block_count(); + if block_count == 1 { + let ecc: String = ::create_e_c_c_block(&codewords, &symbol_info.get_error_codewords()); + sb.append(&ecc); + } else { + sb.set_length(&sb.capacity()); + let data_sizes: [i32; block_count] = [0; block_count]; + let error_sizes: [i32; block_count] = [0; block_count]; + { + let mut i: i32 = 0; + while i < block_count { + { + data_sizes[i] = symbol_info.get_data_length_for_interleaved_block(i + 1); + error_sizes[i] = symbol_info.get_error_length_for_interleaved_block(i + 1); + } + i += 1; + } + } + + { + let mut block: i32 = 0; + while block < block_count { + { + let temp: StringBuilder = StringBuilder::new(data_sizes[block]); + { + let mut d: i32 = block; + while d < symbol_info.get_data_capacity() { + { + temp.append(&codewords.char_at(d)); + } + d += block_count; + } + } + + let ecc: String = ::create_e_c_c_block(&temp.to_string(), error_sizes[block]); + let mut pos: i32 = 0; + { + let mut e: i32 = block; + while e < error_sizes[block] * block_count { + { + sb.set_char_at(symbol_info.get_data_capacity() + e, &ecc.char_at(pos += 1 !!!check!!! post increment)); + } + e += block_count; + } + } + + } + block += 1; + } + } + + } + return sb.to_string(); + } + + fn create_e_c_c_block( codewords: &CharSequence, num_e_c_words: i32) -> String { + let mut table: i32 = -1; + { + let mut i: i32 = 0; + while i < FACTOR_SETS.len() { + { + if FACTOR_SETS[i] == num_e_c_words { + table = i; + break; + } + } + i += 1; + } + } + + if table < 0 { + throw IllegalArgumentException::new(format!("Illegal number of error correction codewords specified: {}", num_e_c_words)); + } + let poly: Vec = FACTORS[table]; + let mut ecc: [Option; num_e_c_words] = [None; num_e_c_words]; + { + let mut i: i32 = 0; + while i < num_e_c_words { + { + ecc[i] = 0; + } + i += 1; + } + } + + { + let mut i: i32 = 0; + while i < codewords.length() { + { + let m: i32 = ecc[num_e_c_words - 1] ^ codewords.char_at(i); + { + let mut k: i32 = num_e_c_words - 1; + while k > 0 { + { + if m != 0 && poly[k] != 0 { + ecc[k] = (ecc[k - 1] ^ ALOG[(LOG[m] + LOG[poly[k]]) % 255]) as char; + } else { + ecc[k] = ecc[k - 1]; + } + } + k -= 1; + } + } + + if m != 0 && poly[0] != 0 { + ecc[0] = ALOG[(LOG[m] + LOG[poly[0]]) % 255] as char; + } else { + ecc[0] = 0; + } + } + i += 1; + } + } + + let ecc_reversed: [Option; num_e_c_words] = [None; num_e_c_words]; + { + let mut i: i32 = 0; + while i < num_e_c_words { + { + ecc_reversed[i] = ecc[num_e_c_words - i - 1]; + } + i += 1; + } + } + + return String::value_of(&ecc_reversed); + } + } + + + // HighLevelEncoder.java + /** + * DataMatrix ECC 200 data encoder following the algorithm described in ISO/IEC 16022:200(E) in + * annex S. + */ + +/** + * Padding character + */ + const PAD: char = 129; + + /** + * mode latch to C40 encodation mode + */ + const LATCH_TO_C40: char = 230; + + /** + * mode latch to Base 256 encodation mode + */ + const LATCH_TO_BASE256: char = 231; + + /** + * FNC1 Codeword + */ + //private static final char FNC1 = 232; + /** + * Structured Append Codeword + */ + //private static final char STRUCTURED_APPEND = 233; + /** + * Reader Programming + */ + //private static final char READER_PROGRAMMING = 234; + /** + * Upper Shift + */ + const UPPER_SHIFT: char = 235; + + /** + * 05 Macro + */ + const MACRO_05: char = 236; + + /** + * 06 Macro + */ + const MACRO_06: char = 237; + + /** + * mode latch to ANSI X.12 encodation mode + */ + const LATCH_TO_ANSIX12: char = 238; + + /** + * mode latch to Text encodation mode + */ + const LATCH_TO_TEXT: char = 239; + + /** + * mode latch to EDIFACT encodation mode + */ + const LATCH_TO_EDIFACT: char = 240; + + /** + * ECI character (Extended Channel Interpretation) + */ + //private static final char ECI = 241; + /** + * Unlatch from C40 encodation + */ + const C40_UNLATCH: char = 254; + + /** + * Unlatch from X12 encodation + */ + const X12_UNLATCH: char = 254; + + /** + * 05 Macro header + */ + const MACRO_05_HEADER: &'static str = "[)>05"; + + /** + * 06 Macro header + */ + const MACRO_06_HEADER: &'static str = "[)>06"; + + /** + * Macro trailer + */ + const MACRO_TRAILER: &'static str = ""; + + const ASCII_ENCODATION: i32 = 0; + + const C40_ENCODATION: i32 = 1; + + const TEXT_ENCODATION: i32 = 2; + + const X12_ENCODATION: i32 = 3; + + const EDIFACT_ENCODATION: i32 = 4; + + const BASE256_ENCODATION: i32 = 5; + pub struct HighLevelEncoder { + } + + impl HighLevelEncoder { + + fn new() -> HighLevelEncoder { + } + + fn randomize253_state( codeword_position: i32) -> char { + let pseudo_random: i32 = ((149 * codeword_position) % 253) + 1; + let temp_variable: i32 = PAD + pseudo_random; + return ( if temp_variable <= 254 { temp_variable } else { temp_variable - 254 }) as char; + } + + /** + * Performs message encoding of a DataMatrix message using the algorithm described in annex P + * of ISO/IEC 16022:2000(E). + * + * @param msg the message + * @return the encoded message (the char values range from 0 to 255) + */ + pub fn encode_high_level( msg: &String) -> String { + return ::encode_high_level(&msg, SymbolShapeHint::FORCE_NONE, null, null, false); + } + + /** + * Performs message encoding of a DataMatrix message using the algorithm described in annex P + * of ISO/IEC 16022:2000(E). + * + * @param msg the message + * @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE}, + * {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}. + * @param minSize the minimum symbol size constraint or null for no constraint + * @param maxSize the maximum symbol size constraint or null for no constraint + * @return the encoded message (the char values range from 0 to 255) + */ + pub fn encode_high_level( msg: &String, shape: &SymbolShapeHint, min_size: &Dimension, max_size: &Dimension) -> String { + return ::encode_high_level(&msg, shape, min_size, max_size, false); + } + + /** + * Performs message encoding of a DataMatrix message using the algorithm described in annex P + * of ISO/IEC 16022:2000(E). + * + * @param msg the message + * @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE}, + * {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}. + * @param minSize the minimum symbol size constraint or null for no constraint + * @param maxSize the maximum symbol size constraint or null for no constraint + * @param forceC40 enforce C40 encoding + * @return the encoded message (the char values range from 0 to 255) + */ + pub fn encode_high_level( msg: &String, shape: &SymbolShapeHint, min_size: &Dimension, max_size: &Dimension, force_c40: bool) -> String { + //the codewords 0..255 are encoded as Unicode characters + let c40_encoder: C40Encoder = C40Encoder::new(); + let encoders: vec![Vec; 6] = vec![ASCIIEncoder::new(), c40_encoder, TextEncoder::new(), X12Encoder::new(), EdifactEncoder::new(), Base256Encoder::new(), ] + ; + let mut context: EncoderContext = EncoderContext::new(&msg); + context.set_symbol_shape(shape); + context.set_size_constraints(min_size, max_size); + if msg.starts_with(&MACRO_05_HEADER) && msg.ends_with(&MACRO_TRAILER) { + context.write_codeword(MACRO_05); + context.set_skip_at_end(2); + context.pos += MACRO_05_HEADER::length(); + } else if msg.starts_with(&MACRO_06_HEADER) && msg.ends_with(&MACRO_TRAILER) { + context.write_codeword(MACRO_06); + context.set_skip_at_end(2); + context.pos += MACRO_06_HEADER::length(); + } + //Default mode + let encoding_mode: i32 = ASCII_ENCODATION; + if force_c40 { + c40_encoder.encode_maximal(context); + encoding_mode = context.get_new_encoding(); + context.reset_encoder_signal(); + } + while context.has_more_characters() { + encoders[encoding_mode].encode(context); + if context.get_new_encoding() >= 0 { + encoding_mode = context.get_new_encoding(); + context.reset_encoder_signal(); + } + } + let len: i32 = context.get_codeword_count(); + context.update_symbol_info(); + let capacity: i32 = context.get_symbol_info().get_data_capacity(); + if len < capacity && encoding_mode != ASCII_ENCODATION && encoding_mode != BASE256_ENCODATION && encoding_mode != EDIFACT_ENCODATION { + //Unlatch (254) + context.write_codeword('þ'); + } + //Padding + let codewords: StringBuilder = context.get_codewords(); + if codewords.length() < capacity { + codewords.append(PAD); + } + while codewords.length() < capacity { + codewords.append(&::randomize253_state(codewords.length() + 1)); + } + return context.get_codewords().to_string(); + } + + fn look_ahead_test( msg: &CharSequence, startpos: i32, current_mode: i32) -> i32 { + let new_mode: i32 = ::look_ahead_test_intern(&msg, startpos, current_mode); + if current_mode == X12_ENCODATION && new_mode == X12_ENCODATION { + let endpos: i32 = Math::min(startpos + 3, &msg.length()); + { + let mut i: i32 = startpos; + while i < endpos { + { + if !::is_native_x12(&msg.char_at(i)) { + return ASCII_ENCODATION; + } + } + i += 1; + } + } + + } else if current_mode == EDIFACT_ENCODATION && new_mode == EDIFACT_ENCODATION { + let endpos: i32 = Math::min(startpos + 4, &msg.length()); + { + let mut i: i32 = startpos; + while i < endpos { + { + if !::is_native_e_d_i_f_a_c_t(&msg.char_at(i)) { + return ASCII_ENCODATION; + } + } + i += 1; + } + } + + } + return new_mode; + } + + fn look_ahead_test_intern( msg: &CharSequence, startpos: i32, current_mode: i32) -> i32 { + if startpos >= msg.length() { + return current_mode; + } + let char_counts: Vec; + //step J + if current_mode == ASCII_ENCODATION { + char_counts = : vec![f32; 6] = vec![0.0, 1.0, 1.0, 1.0, 1.0, 1.25f, ] + ; + } else { + char_counts = : vec![f32; 6] = vec![1.0, 2.0, 2.0, 2.0, 2.0, 2.25f, ] + ; + char_counts[current_mode] = 0.0; + } + let chars_processed: i32 = 0; + let mins: [i8; 6] = [0; 6]; + let int_char_counts: [i32; 6] = [0; 6]; + while true { + //step K + if (startpos + chars_processed) == msg.length() { + Arrays::fill(&mins, 0 as i8); + Arrays::fill(&int_char_counts, 0); + let min: i32 = ::find_minimums(&char_counts, &int_char_counts, Integer::MAX_VALUE, &mins); + let min_count: i32 = ::get_minimum_count(&mins); + if int_char_counts[ASCII_ENCODATION] == min { + return ASCII_ENCODATION; + } + if min_count == 1 { + if mins[BASE256_ENCODATION] > 0 { + return BASE256_ENCODATION; + } + if mins[EDIFACT_ENCODATION] > 0 { + return EDIFACT_ENCODATION; + } + if mins[TEXT_ENCODATION] > 0 { + return TEXT_ENCODATION; + } + if mins[X12_ENCODATION] > 0 { + return X12_ENCODATION; + } + } + return C40_ENCODATION; + } + let c: char = msg.char_at(startpos + chars_processed); + chars_processed += 1; + //step L + if ::is_digit(c) { + char_counts[ASCII_ENCODATION] += 0.5f; + } else if ::is_extended_a_s_c_i_i(c) { + char_counts[ASCII_ENCODATION] = Math::ceil(char_counts[ASCII_ENCODATION]) as f32; + char_counts[ASCII_ENCODATION] += 2.0f; + } else { + char_counts[ASCII_ENCODATION] = Math::ceil(char_counts[ASCII_ENCODATION]) as f32; + char_counts[ASCII_ENCODATION] += 1; + } + //step M + if ::is_native_c40(c) { + char_counts[C40_ENCODATION] += 2.0f / 3.0f; + } else if ::is_extended_a_s_c_i_i(c) { + char_counts[C40_ENCODATION] += 8.0f / 3.0f; + } else { + char_counts[C40_ENCODATION] += 4.0f / 3.0f; + } + //step N + if ::is_native_text(c) { + char_counts[TEXT_ENCODATION] += 2.0f / 3.0f; + } else if ::is_extended_a_s_c_i_i(c) { + char_counts[TEXT_ENCODATION] += 8.0f / 3.0f; + } else { + char_counts[TEXT_ENCODATION] += 4.0f / 3.0f; + } + //step O + if ::is_native_x12(c) { + char_counts[X12_ENCODATION] += 2.0f / 3.0f; + } else if ::is_extended_a_s_c_i_i(c) { + char_counts[X12_ENCODATION] += 13.0f / 3.0f; + } else { + char_counts[X12_ENCODATION] += 10.0f / 3.0f; + } + //step P + if ::is_native_e_d_i_f_a_c_t(c) { + char_counts[EDIFACT_ENCODATION] += 3.0f / 4.0f; + } else if ::is_extended_a_s_c_i_i(c) { + char_counts[EDIFACT_ENCODATION] += 17.0f / 4.0f; + } else { + char_counts[EDIFACT_ENCODATION] += 13.0f / 4.0f; + } + // step Q + if ::is_special_b256(c) { + char_counts[BASE256_ENCODATION] += 4.0f; + } else { + char_counts[BASE256_ENCODATION] += 1; + } + //step R + if chars_processed >= 4 { + Arrays::fill(&mins, 0 as i8); + Arrays::fill(&int_char_counts, 0); + ::find_minimums(&char_counts, &int_char_counts, Integer::MAX_VALUE, &mins); + if int_char_counts[ASCII_ENCODATION] < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[EDIFACT_ENCODATION]) { + return ASCII_ENCODATION; + } + if int_char_counts[BASE256_ENCODATION] < int_char_counts[ASCII_ENCODATION] || int_char_counts[BASE256_ENCODATION] + 1 < ::min(int_char_counts[C40_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[EDIFACT_ENCODATION]) { + return BASE256_ENCODATION; + } + if int_char_counts[EDIFACT_ENCODATION] + 1 < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[ASCII_ENCODATION]) { + return EDIFACT_ENCODATION; + } + if int_char_counts[TEXT_ENCODATION] + 1 < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[EDIFACT_ENCODATION], int_char_counts[X12_ENCODATION], int_char_counts[ASCII_ENCODATION]) { + return TEXT_ENCODATION; + } + if int_char_counts[X12_ENCODATION] + 1 < ::min(int_char_counts[BASE256_ENCODATION], int_char_counts[C40_ENCODATION], int_char_counts[EDIFACT_ENCODATION], int_char_counts[TEXT_ENCODATION], int_char_counts[ASCII_ENCODATION]) { + return X12_ENCODATION; + } + if int_char_counts[C40_ENCODATION] + 1 < ::min(int_char_counts[ASCII_ENCODATION], int_char_counts[BASE256_ENCODATION], int_char_counts[EDIFACT_ENCODATION], int_char_counts[TEXT_ENCODATION]) { + if int_char_counts[C40_ENCODATION] < int_char_counts[X12_ENCODATION] { + return C40_ENCODATION; + } + if int_char_counts[C40_ENCODATION] == int_char_counts[X12_ENCODATION] { + let mut p: i32 = startpos + chars_processed + 1; + while p < msg.length() { + let tc: char = msg.char_at(p); + if ::is_x12_term_sep(tc) { + return X12_ENCODATION; + } + if !::is_native_x12(tc) { + break; + } + p += 1; + } + return C40_ENCODATION; + } + } + } + } + } + + fn min( f1: i32, f2: i32, f3: i32, f4: i32, f5: i32) -> i32 { + return Math::min(&::min(f1, f2, f3, f4), f5); + } + + fn min( f1: i32, f2: i32, f3: i32, f4: i32) -> i32 { + return Math::min(f1, &Math::min(f2, &Math::min(f3, f4))); + } + + fn find_minimums( char_counts: &Vec, int_char_counts: &Vec, min: i32, mins: &Vec) -> i32 { + { + let mut i: i32 = 0; + while i < 6 { + { + let current: i32 = (int_char_counts[i] = Math::ceil(char_counts[i]) as i32); + if min > current { + min = current; + Arrays::fill(&mins, 0 as i8); + } + if min == current { + mins[i] += 1; + } + } + i += 1; + } + } + + return min; + } + + fn get_minimum_count( mins: &Vec) -> i32 { + let min_count: i32 = 0; + { + let mut i: i32 = 0; + while i < 6 { + { + min_count += mins[i]; + } + i += 1; + } + } + + return min_count; + } + + fn is_digit( ch: char) -> bool { + return ch >= '0' && ch <= '9'; + } + + fn is_extended_a_s_c_i_i( ch: char) -> bool { + return ch >= 128 && ch <= 255; + } + + fn is_native_c40( ch: char) -> bool { + return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); + } + + fn is_native_text( ch: char) -> bool { + return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z'); + } + + fn is_native_x12( ch: char) -> bool { + return ::is_x12_term_sep(ch) || (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'); + } + + fn is_x12_term_sep( ch: char) -> bool { + return //CR + (ch == '\r') || (ch == '*') || (ch == '>'); + } + + fn is_native_e_d_i_f_a_c_t( ch: char) -> bool { + return ch >= ' ' && ch <= '^'; + } + + fn is_special_b256( ch: char) -> bool { + //TODO NOT IMPLEMENTED YET!!! + return false; + } + + /** + * Determines the number of consecutive characters that are encodable using numeric compaction. + * + * @param msg the message + * @param startpos the start position within the message + * @return the requested character count + */ + pub fn determine_consecutive_digit_count( msg: &CharSequence, startpos: i32) -> i32 { + let len: i32 = msg.length(); + let mut idx: i32 = startpos; + while idx < len && ::is_digit(&msg.char_at(idx)) { + idx += 1; + } + return idx - startpos; + } + + fn illegal_character( c: char) { + let mut hex: String = Integer::to_hex_string(c); + hex = format!("{}{}", "0000".substring(0, 4 - hex.length()), hex); + throw IllegalArgumentException::new(format!("Illegal character: {} (0x{})", c, hex)); + } + } + + + // MinimalEncoder.java + /** + * Encoder that encodes minimally + * + * Algorithm: + * + * Uses Dijkstra to produce mathematically minimal encodings that are in some cases smaller than the results produced + * by the algorithm described in annex S in the specification ISO/IEC 16022:200(E). The biggest improvment of this + * algorithm over that one is the case when the algorithm enters the most inefficient mode, the B256 mode. The + * algorithm from the specification algorithm will exit this mode only if it encounters digits so that arbitrarily + * inefficient results can be produced if the postfix contains no digits. + * + * Multi ECI support and ECI switching: + * + * For multi language content the algorithm selects the most compact representation using ECI modes. Note that unlike + * the compaction algorithm used for QR-Codes, this implementation operates in two stages and therfore is not + * mathematically optimal. In the first stage, the input string is encoded minimally as a stream of ECI character set + * selectors and bytes encoded in the selected encoding. In this stage the algorithm might for example decide to + * encode ocurrences of the characters "\u0150\u015C" (O-double-acute, S-circumflex) in UTF-8 by a single ECI or + * alternatively by multiple ECIs that switch between IS0-8859-2 and ISO-8859-3 (e.g. in the case that the input + * contains many * characters from ISO-8859-2 (Latin 2) and few from ISO-8859-3 (Latin 3)). + * In a second stage this stream of ECIs and bytes is minimally encoded using the various Data Matrix encoding modes. + * While both stages encode mathematically minimally it is not ensured that the result is mathematically minimal since + * the size growth for inserting an ECI in the first stage can only be approximated as the first stage does not know + * in which mode the ECI will occur in the second stage (may, or may not require an extra latch to ASCII depending on + * the current mode). The reason for this shortcoming are difficulties in implementing it in a straightforward and + * readable manner. + * + * GS1 support + * + * FNC1 delimiters can be encoded in the input string by using the FNC1 character specified in the encoding function. + * When a FNC1 character is specified then a leading FNC1 will be encoded and all ocurrences of delimiter characters + * while result in FNC1 codewords in the symbol. + * + * @author Alex Geller + */ + +const C40_SHIFT2_CHARS: vec![Vec; 27] = vec!['!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', ] +; +pub struct MinimalEncoder { +} + +impl MinimalEncoder { + + enum Mode { + + ASCII(), C40(), TEXT(), X12(), EDF(), B256() + } + + fn new() -> MinimalEncoder { + } + + fn is_extended_a_s_c_i_i( ch: char, fnc1: i32) -> bool { + return ch != fnc1 && ch >= 128 && ch <= 255; + } + + fn is_in_c40_shift1_set( ch: char) -> bool { + return ch <= 31; + } + + fn is_in_c40_shift2_set( ch: char, fnc1: i32) -> bool { + for let c40_shift2_char: char in C40_SHIFT2_CHARS { + if c40_shift2_char == ch { + return true; + } + } + return ch == fnc1; + } + + fn is_in_text_shift1_set( ch: char) -> bool { + return ::is_in_c40_shift1_set(ch); + } + + fn is_in_text_shift2_set( ch: char, fnc1: i32) -> bool { + return ::is_in_c40_shift2_set(ch, fnc1); + } + + pub fn encode_high_level( msg: &String) -> String { + return ::encode_high_level(&msg, null, -1, SymbolShapeHint::FORCE_NONE); + } + + pub fn encode_high_level( msg: &String, priority_charset: &Charset, fnc1: i32, shape: &SymbolShapeHint) -> String { + let macro_id: i32 = 0; + if msg.starts_with(HighLevelEncoder::MACRO_05_HEADER) && msg.ends_with(HighLevelEncoder::MACRO_TRAILER) { + macro_id = 5; + msg = msg.substring(&HighLevelEncoder::MACRO_05_HEADER::length(), msg.length() - 2); + } else if msg.starts_with(HighLevelEncoder::MACRO_06_HEADER) && msg.ends_with(HighLevelEncoder::MACRO_TRAILER) { + macro_id = 6; + msg = msg.substring(&HighLevelEncoder::MACRO_06_HEADER::length(), msg.length() - 2); + } + return String::new(&::encode(&msg, &priority_charset, fnc1, shape, macro_id), StandardCharsets::ISO_8859_1); + } + + fn encode( input: &String, priority_charset: &Charset, fnc1: i32, shape: &SymbolShapeHint, macro_id: i32) -> Vec { + return ::encode_minimally(Input::new(&input, &priority_charset, fnc1, shape, macro_id)).get_bytes(); + } + + fn add_edge( edges: &Vec>, edge: &Edge) { + let vertex_index: i32 = edge.fromPosition + edge.characterLength; + if edges[vertex_index][edge.get_end_mode().ordinal()] == null || edges[vertex_index][edge.get_end_mode().ordinal()].cachedTotalSize > edge.cachedTotalSize { + edges[vertex_index][edge.get_end_mode().ordinal()] = edge; + } + } + + fn get_number_of_c40_words( input: &Input, from: i32, c40: bool, character_length: &Vec) -> i32 { + let thirds_count: i32 = 0; + { + let mut i: i32 = from; + while i < input.length() { + { + if input.is_e_c_i(i) { + character_length[0] = 0; + return 0; + } + let ci: char = input.char_at(i); + if c40 && HighLevelEncoder::is_native_c40(ci) || !c40 && HighLevelEncoder::is_native_text(ci) { + thirds_count += 1; + } else if !::is_extended_a_s_c_i_i(ci, &input.get_f_n_c1_character()) { + thirds_count += 2; + } else { + let ascii_value: i32 = ci & 0xff; + if ascii_value >= 128 && (c40 && HighLevelEncoder::is_native_c40((ascii_value - 128) as char) || !c40 && HighLevelEncoder::is_native_text((ascii_value - 128) as char)) { + thirds_count += 3; + } else { + thirds_count += 4; + } + } + if thirds_count % 3 == 0 || ((thirds_count - 2) % 3 == 0 && i + 1 == input.length()) { + character_length[0] = i - from + 1; + return Math::ceil((thirds_count as f64) / 3.0) as i32; + } + } + i += 1; + } + } + + character_length[0] = 0; + return 0; + } + + fn add_edges( input: &Input, edges: &Vec>, from: i32, previous: &Edge) { + if input.is_e_c_i(from) { + ::add_edge(edges, Edge::new(input, Mode::ASCII, from, 1, previous)); + return; + } + let ch: char = input.char_at(from); + if previous == null || previous.get_end_mode() != Mode::EDF { + if HighLevelEncoder::is_digit(ch) && input.have_n_characters(from, 2) && HighLevelEncoder::is_digit(&input.char_at(from + 1)) { + ::add_edge(edges, Edge::new(input, Mode::ASCII, from, 2, previous)); + } else { + ::add_edge(edges, Edge::new(input, Mode::ASCII, from, 1, previous)); + } + let modes: vec![Vec; 2] = vec![Mode::C40, Mode::TEXT, ] + ; + for let mode: Mode in modes { + let character_length: [i32; 1] = [0; 1]; + if ::get_number_of_c40_words(input, from, mode == Mode::C40, &character_length) > 0 { + ::add_edge(edges, Edge::new(input, mode, from, character_length[0], previous)); + } + } + if input.have_n_characters(from, 3) && HighLevelEncoder::is_native_x12(&input.char_at(from)) && HighLevelEncoder::is_native_x12(&input.char_at(from + 1)) && HighLevelEncoder::is_native_x12(&input.char_at(from + 2)) { + ::add_edge(edges, Edge::new(input, Mode::X12, from, 3, previous)); + } + ::add_edge(edges, Edge::new(input, Mode::B256, from, 1, previous)); + } + //unless it is 2 characters away from the end of the input. + let mut i: i32; + { + i = 0; + while i < 3 { + { + let pos: i32 = from + i; + if input.have_n_characters(pos, 1) && HighLevelEncoder::is_native_e_d_i_f_a_c_t(&input.char_at(pos)) { + ::add_edge(edges, Edge::new(input, Mode::EDF, from, i + 1, previous)); + } else { + break; + } + } + i += 1; + } + } + + if i == 3 && input.have_n_characters(from, 4) && HighLevelEncoder::is_native_e_d_i_f_a_c_t(&input.char_at(from + 3)) { + ::add_edge(edges, Edge::new(input, Mode::EDF, from, 4, previous)); + } + } + + fn encode_minimally( input: &Input) -> Result { + let input_length: i32 = input.length(); + // Array that represents vertices. There is a vertex for every character and mode. + // The last dimension in the array below encodes the 6 modes ASCII, C40, TEXT, X12, EDF and B256 + let mut edges: [[Option; 6]; input_length + 1] = [[None; 6]; input_length + 1]; + ::add_edges(input, edges, 0, null); + { + let mut i: i32 = 1; + while i <= input_length { + { + { + let mut j: i32 = 0; + while j < 6 { + { + if edges[i][j] != null && i < input_length { + ::add_edges(input, edges, i, edges[i][j]); + } + } + j += 1; + } + } + + //optimize memory by removing edges that have been passed. + { + let mut j: i32 = 0; + while j < 6 { + { + edges[i - 1][j] = null; + } + j += 1; + } + } + + } + i += 1; + } + } + + let minimal_j: i32 = -1; + let minimal_size: i32 = Integer::MAX_VALUE; + { + let mut j: i32 = 0; + while j < 6 { + { + if edges[input_length][j] != null { + let edge: Edge = edges[input_length][j]; + //C40, TEXT and X12 need an + let size: i32 = if j >= 1 && j <= 3 { edge.cachedTotalSize + 1 } else { edge.cachedTotalSize }; + // extra unlatch at the end + if size < minimal_size { + minimal_size = size; + minimal_j = j; + } + } + } + j += 1; + } + } + + if minimal_j < 0 { + throw RuntimeException::new(format!("Internal error: failed to encode \"{}\"", input)); + } + return Result::new(edges[input_length][minimal_j]); + } + + + let all_codeword_capacities: vec![Vec; 28] = vec![3, 5, 8, 10, 12, 16, 18, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558, ] + ; + + let square_codeword_capacities: vec![Vec; 24] = vec![3, 5, 8, 12, 18, 22, 30, 36, 44, 62, 86, 114, 144, 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558, ] + ; + + let rectangular_codeword_capacities: vec![Vec; 6] = vec![5, 10, 16, 33, 32, 49, ] + ; + struct Edge { + + let input: Input; + + //the mode at the start of this edge. + let mode: Mode; + + let from_position: i32; + + let character_length: i32; + + let previous: Edge; + + let cached_total_size: i32; + } + + impl Edge { + + fn new( input: &Input, mode: &Mode, from_position: i32, character_length: i32, previous: &Edge) -> Edge { + let .input = input; + let .mode = mode; + let .fromPosition = from_position; + let .characterLength = character_length; + let .previous = previous; + assert!( from_position + character_length <= input.length()); + let mut size: i32 = if previous != null { previous.cachedTotalSize } else { 0 }; + let previous_mode: Mode = self.get_previous_mode(); + /* + * Switching modes + * ASCII -> C40: latch 230 + * ASCII -> TEXT: latch 239 + * ASCII -> X12: latch 238 + * ASCII -> EDF: latch 240 + * ASCII -> B256: latch 231 + * C40 -> ASCII: word(c1,c2,c3), 254 + * TEXT -> ASCII: word(c1,c2,c3), 254 + * X12 -> ASCII: word(c1,c2,c3), 254 + * EDIFACT -> ASCII: Unlatch character,0,0,0 or c1,Unlatch character,0,0 or c1,c2,Unlatch character,0 or + * c1,c2,c3,Unlatch character + * B256 -> ASCII: without latch after n bytes + */ + match mode { + ASCII => + { + size += 1; + if input.is_e_c_i(from_position) || ::is_extended_a_s_c_i_i(&input.char_at(from_position), &input.get_f_n_c1_character()) { + size += 1; + } + if previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12 { + // unlatch 254 to ASCII + size += 1; + } + break; + } + B256 => + { + size += 1; + if previous_mode != Mode::B256 { + //byte count + size += 1; + } else if self.get_b256_size() == 250 { + //extra byte count + size += 1; + } + if previous_mode == Mode::ASCII { + //latch to B256 + size += 1; + } else if previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12 { + //unlatch to ASCII, latch to B256 + size += 2; + } + break; + } + C40 => + { + } + TEXT => + { + } + X12 => + { + if mode == Mode::X12 { + size += 2; + } else { + let char_len: [i32; 1] = [0; 1]; + size += ::get_number_of_c40_words(input, from_position, mode == Mode::C40, &char_len) * 2; + } + if previous_mode == Mode::ASCII || previous_mode == Mode::B256 { + //additional byte for latch from ASCII to this mode + size += 1; + } else if previous_mode != mode && (previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12) { + //unlatch 254 to ASCII followed by latch to this mode + size += 2; + } + break; + } + EDF => + { + size += 3; + if previous_mode == Mode::ASCII || previous_mode == Mode::B256 { + //additional byte for latch from ASCII to this mode + size += 1; + } else if previous_mode == Mode::C40 || previous_mode == Mode::TEXT || previous_mode == Mode::X12 { + //unlatch 254 to ASCII followed by latch to this mode + size += 2; + } + break; + } + } + cached_total_size = size; + } + + // does not count beyond 250 + fn get_b256_size(&self) -> i32 { + let mut cnt: i32 = 0; + let mut current: Edge = self; + while current != null && current.mode == Mode::B256 && cnt <= 250 { + cnt += 1; + current = current.previous; + } + return cnt; + } + + fn get_previous_start_mode(&self) -> Mode { + return if self.previous == null { Mode::ASCII } else { self.previous.mode }; + } + + fn get_previous_mode(&self) -> Mode { + return if self.previous == null { Mode::ASCII } else { self.previous.get_end_mode() }; + } + + /** Returns Mode.ASCII in case that: + * - Mode is EDIFACT and characterLength is less than 4 or the remaining characters can be encoded in at most 2 + * ASCII bytes. + * - Mode is C40, TEXT or X12 and the remaining characters can be encoded in at most 1 ASCII byte. + * Returns mode in all other cases. + * */ + fn get_end_mode(&self) -> Mode { + if self.mode == Mode::EDF { + if self.character_length < 4 { + return Mode::ASCII; + } + // see 5.2.8.2 EDIFACT encodation Rules + let last_a_s_c_i_i: i32 = self.get_last_a_s_c_i_i(); + if last_a_s_c_i_i > 0 && self.get_codewords_remaining(self.cached_total_size + last_a_s_c_i_i) <= 2 - last_a_s_c_i_i { + return Mode::ASCII; + } + } + if self.mode == Mode::C40 || self.mode == Mode::TEXT || self.mode == Mode::X12 { + // see 5.2.5.2 C40 encodation rules and 5.2.7.2 ANSI X12 encodation rules + if self.from_position + self.character_length >= self.input.length() && self.get_codewords_remaining(self.cached_total_size) == 0 { + return Mode::ASCII; + } + let last_a_s_c_i_i: i32 = self.get_last_a_s_c_i_i(); + if last_a_s_c_i_i == 1 && self.get_codewords_remaining(self.cached_total_size + 1) == 0 { + return Mode::ASCII; + } + } + return self.mode; + } + + fn get_mode(&self) -> Mode { + return self.mode; + } + + /** Peeks ahead and returns 1 if the postfix consists of exactly two digits, 2 if the postfix consists of exactly + * two consecutive digits and a non extended character or of 4 digits. + * Returns 0 in any other case + **/ + fn get_last_a_s_c_i_i(&self) -> i32 { + let length: i32 = self.input.length(); + let from: i32 = self.from_position + self.character_length; + if length - from > 4 || from >= length { + return 0; + } + if length - from == 1 { + if ::is_extended_a_s_c_i_i(&self.input.char_at(from), &self.input.get_f_n_c1_character()) { + return 0; + } + return 1; + } + if length - from == 2 { + if ::is_extended_a_s_c_i_i(&self.input.char_at(from), &self.input.get_f_n_c1_character()) || ::is_extended_a_s_c_i_i(&self.input.char_at(from + 1), &self.input.get_f_n_c1_character()) { + return 0; + } + if HighLevelEncoder::is_digit(&self.input.char_at(from)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) { + return 1; + } + return 2; + } + if length - from == 3 { + if HighLevelEncoder::is_digit(&self.input.char_at(from)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) && !::is_extended_a_s_c_i_i(&self.input.char_at(from + 2), &self.input.get_f_n_c1_character()) { + return 2; + } + if HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 2)) && !::is_extended_a_s_c_i_i(&self.input.char_at(from), &self.input.get_f_n_c1_character()) { + return 2; + } + return 0; + } + if HighLevelEncoder::is_digit(&self.input.char_at(from)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 1)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 2)) && HighLevelEncoder::is_digit(&self.input.char_at(from + 3)) { + return 2; + } + return 0; + } + + /** Returns the capacity in codewords of the smallest symbol that has enough capacity to fit the given minimal + * number of codewords. + **/ + fn get_min_symbol_size(&self, minimum: i32) -> i32 { + match self.input.get_shape_hint() { + FORCE_SQUARE => + { + for let capacity: i32 in square_codeword_capacities { + if capacity >= minimum { + return capacity; + } + } + break; + } + FORCE_RECTANGLE => + { + for let capacity: i32 in rectangular_codeword_capacities { + if capacity >= minimum { + return capacity; + } + } + break; + } + } + for let capacity: i32 in all_codeword_capacities { + if capacity >= minimum { + return capacity; + } + } + return all_codeword_capacities[all_codeword_capacities.len() - 1]; + } + + /** Returns the remaining capacity in codewords of the smallest symbol that has enough capacity to fit the given + * minimal number of codewords. + **/ + fn get_codewords_remaining(&self, minimum: i32) -> i32 { + return self.get_min_symbol_size(minimum) - minimum; + } + + fn get_bytes( c: i32) -> Vec { + let mut result: [i8; 1] = [0; 1]; + result[0] = c as i8; + return result; + } + + fn get_bytes( c1: i32, c2: i32) -> Vec { + let mut result: [i8; 2] = [0; 2]; + result[0] = c1 as i8; + result[1] = c2 as i8; + return result; + } + + fn set_c40_word( bytes: &Vec, offset: i32, c1: i32, c2: i32, c3: i32) { + let val16: i32 = (1600 * (c1 & 0xff)) + (40 * (c2 & 0xff)) + (c3 & 0xff) + 1; + bytes[offset] = (val16 / 256) as i8; + bytes[offset + 1] = (val16 % 256) as i8; + } + + fn get_x12_value( c: char) -> i32 { + return if c == 13 { 0 } else { if c == 42 { 1 } else { if c == 62 { 2 } else { if c == 32 { 3 } else { if c >= 48 && c <= 57 { c - 44 } else { if c >= 65 && c <= 90 { c - 51 } else { c } } } } } }; + } + + fn get_x12_words(&self) -> Vec { + assert!( self.character_length % 3 == 0); + let result: [i8; self.character_length / 3 * 2] = [0; self.character_length / 3 * 2]; + { + let mut i: i32 = 0; + while i < result.len() { + { + ::set_c40_word(&result, i, &::get_x12_value(&self.input.char_at(self.from_position + i / 2 * 3)), &::get_x12_value(&self.input.char_at(self.from_position + i / 2 * 3 + 1)), &::get_x12_value(&self.input.char_at(self.from_position + i / 2 * 3 + 2))); + } + i += 2; + } + } + + return result; + } + + fn get_shift_value( c: char, c40: bool, fnc1: i32) -> i32 { + return if (c40 && ::is_in_c40_shift1_set(c) || !c40 && ::is_in_text_shift1_set(c)) { 0 } else { if (c40 && ::is_in_c40_shift2_set(c, fnc1) || !c40 && ::is_in_text_shift2_set(c, fnc1)) { 1 } else { 2 } }; + } + + fn get_c40_value( c40: bool, set_index: i32, c: char, fnc1: i32) -> i32 { + if c == fnc1 { + assert!( set_index == 2); + return 27; + } + if c40 { + return if c <= 31 { c } else { if c == 32 { 3 } else { if c <= 47 { c - 33 } else { if c <= 57 { c - 44 } else { if c <= 64 { c - 43 } else { if c <= 90 { c - 51 } else { if c <= 95 { c - 69 } else { if c <= 127 { c - 96 } else { c } } } } } } } }; + } else { + return if c == 0 { 0 } else { if //is this a bug in the spec? + set_index == 0 && c <= 3 { //is this a bug in the spec? + c - 1 } else { if set_index == 1 && c <= 31 { c } else { if c == 32 { 3 } else { if c >= 33 && c <= 47 { c - 33 } else { if c >= 48 && c <= 57 { c - 44 } else { if c >= 58 && c <= 64 { c - 43 } else { if c >= 65 && c <= 90 { c - 64 } else { if c >= 91 && c <= 95 { c - 69 } else { if c == 96 { 0 } else { if c >= 97 && c <= 122 { c - 83 } else { if c >= 123 && c <= 127 { c - 96 } else { c } } } } } } } } } } } }; + } + } + + fn get_c40_words(&self, c40: bool, fnc1: i32) -> Vec { + let c40_values: List = ArrayList<>::new(); + { + let mut i: i32 = 0; + while i < self.character_length { + { + let ci: char = self.input.char_at(self.from_position + i); + if c40 && HighLevelEncoder::is_native_c40(ci) || !c40 && HighLevelEncoder::is_native_text(ci) { + c40_values.add(::get_c40_value(c40, 0, ci, fnc1) as i8); + } else if !::is_extended_a_s_c_i_i(ci, fnc1) { + let shift_value: i32 = ::get_shift_value(ci, c40, fnc1); + //Shift[123] + c40_values.add(shift_value as i8); + c40_values.add(::get_c40_value(c40, shift_value, ci, fnc1) as i8); + } else { + let ascii_value: char = ((ci & 0xff) - 128) as char; + if c40 && HighLevelEncoder::is_native_c40(ascii_value) || !c40 && HighLevelEncoder::is_native_text(ascii_value) { + //Shift 2 + c40_values.add(1 as i8); + //Upper Shift + c40_values.add(30 as i8); + c40_values.add(::get_c40_value(c40, 0, ascii_value, fnc1) as i8); + } else { + //Shift 2 + c40_values.add(1 as i8); + //Upper Shift + c40_values.add(30 as i8); + let shift_value: i32 = ::get_shift_value(ascii_value, c40, fnc1); + // Shift[123] + c40_values.add(shift_value as i8); + c40_values.add(::get_c40_value(c40, shift_value, ascii_value, fnc1) as i8); + } + } + } + i += 1; + } + } + + if (c40_values.size() % 3) != 0 { + assert!( (c40_values.size() - 2) % 3 == 0 && self.from_position + self.character_length == self.input.length()); + // pad with 0 (Shift 1) + c40_values.add(0 as i8); + } + let result: [i8; c40_values.size() / 3 * 2] = [0; c40_values.size() / 3 * 2]; + let byte_index: i32 = 0; + { + let mut i: i32 = 0; + while i < c40_values.size() { + { + ::set_c40_word(&result, byte_index, c40_values.get(i) & 0xff, c40_values.get(i + 1) & 0xff, c40_values.get(i + 2) & 0xff); + byte_index += 2; + } + i += 3; + } + } + + return result; + } + + fn get_e_d_f_bytes(&self) -> Vec { + let number_of_thirds: i32 = Math::ceil(self.character_length / 4.0) as i32; + let mut result: [i8; number_of_thirds * 3] = [0; number_of_thirds * 3]; + let mut pos: i32 = self.from_position; + let end_pos: i32 = Math::min(self.from_position + self.character_length - 1, self.input.length() - 1); + { + let mut i: i32 = 0; + while i < number_of_thirds { + { + let edf_values: [i32; 4] = [0; 4]; + { + let mut j: i32 = 0; + while j < 4 { + { + if pos <= end_pos { + edf_values[j] = self.input.char_at(pos += 1 !!!check!!! post increment) & 0x3f; + } else { + edf_values[j] = if pos == end_pos + 1 { 0x1f } else { 0 }; + } + } + j += 1; + } + } + + let mut val24: i32 = edf_values[0] << 18; + val24 |= edf_values[1] << 12; + val24 |= edf_values[2] << 6; + val24 |= edf_values[3]; + result[i] = ((val24 >> 16) & 0xff) as i8; + result[i + 1] = ((val24 >> 8) & 0xff) as i8; + result[i + 2] = (val24 & 0xff) as i8; + } + i += 3; + } + } + + return result; + } + + fn get_latch_bytes(&self) -> Vec { + match self.get_previous_mode() { + ASCII => + { + } + //after B256 ends (via length) we are back to ASCII + B256 => + { + match self.mode { + B256 => + { + return ::get_bytes(231); + } + C40 => + { + return ::get_bytes(230); + } + TEXT => + { + return ::get_bytes(239); + } + X12 => + { + return ::get_bytes(238); + } + EDF => + { + return ::get_bytes(240); + } + } + break; + } + C40 => + { + } + TEXT => + { + } + X12 => + { + if self.mode != self.get_previous_mode() { + match self.mode { + ASCII => + { + return ::get_bytes(254); + } + B256 => + { + return ::get_bytes(254, 231); + } + C40 => + { + return ::get_bytes(254, 230); + } + TEXT => + { + return ::get_bytes(254, 239); + } + X12 => + { + return ::get_bytes(254, 238); + } + EDF => + { + return ::get_bytes(254, 240); + } + } + } + break; + } + EDF => + { + //The rightmost EDIFACT edge always contains an unlatch character + assert!( self.mode == Mode::EDF); + break; + } + } + return : [i8; 0] = [0; 0]; + } + + // Important: The function does not return the length bytes (one or two) in case of B256 encoding + fn get_data_bytes(&self) -> Vec { + match self.mode { + ASCII => + { + if self.input.is_e_c_i(self.from_position) { + return ::get_bytes(241, self.input.get_e_c_i_value(self.from_position) + 1); + } else if ::is_extended_a_s_c_i_i(&self.input.char_at(self.from_position), &self.input.get_f_n_c1_character()) { + return ::get_bytes(235, self.input.char_at(self.from_position) - 127); + } else if self.character_length == 2 { + return ::get_bytes((self.input.char_at(self.from_position) - '0') * 10 + self.input.char_at(self.from_position + 1) - '0' + 130); + } else if self.input.is_f_n_c1(self.from_position) { + return ::get_bytes(232); + } else { + return ::get_bytes(self.input.char_at(self.from_position) + 1); + } + } + B256 => + { + return ::get_bytes(&self.input.char_at(self.from_position)); + } + C40 => + { + return self.get_c40_words(true, &self.input.get_f_n_c1_character()); + } + TEXT => + { + return self.get_c40_words(false, &self.input.get_f_n_c1_character()); + } + X12 => + { + return self.get_x12_words(); + } + EDF => + { + return self.get_e_d_f_bytes(); + } + } + assert!( false); + return : [i8; 0] = [0; 0]; + } + } + + + struct Result { + + let mut bytes: Vec; + } + + impl Result { + + fn new( solution: &Edge) -> Result { + let input: Input = solution.input; + let mut size: i32 = 0; + let bytes_a_l: List = ArrayList<>::new(); + let randomize_postfix_length: List = ArrayList<>::new(); + let randomize_lengths: List = ArrayList<>::new(); + if (solution.mode == Mode::C40 || solution.mode == Mode::TEXT || solution.mode == Mode::X12) && solution.get_end_mode() != Mode::ASCII { + size += ::prepend(&MinimalEncoder::Edge::get_bytes(254), &bytes_a_l); + } + let mut current: Edge = solution; + while current != null { + size += ::prepend(¤t.get_data_bytes(), &bytes_a_l); + if current.previous == null || current.get_previous_start_mode() != current.get_mode() { + if current.get_mode() == Mode::B256 { + if size <= 249 { + bytes_a_l.add(0, size as i8); + size += 1; + } else { + bytes_a_l.add(0, (size % 250) as i8); + bytes_a_l.add(0, (size / 250 + 249) as i8); + size += 2; + } + randomize_postfix_length.add(&bytes_a_l.size()); + randomize_lengths.add(size); + } + ::prepend(¤t.get_latch_bytes(), &bytes_a_l); + size = 0; + } + current = current.previous; + } + if input.get_macro_id() == 5 { + size += ::prepend(&MinimalEncoder::Edge::get_bytes(236), &bytes_a_l); + } else if input.get_macro_id() == 6 { + size += ::prepend(&MinimalEncoder::Edge::get_bytes(237), &bytes_a_l); + } + if input.get_f_n_c1_character() > 0 { + size += ::prepend(&MinimalEncoder::Edge::get_bytes(232), &bytes_a_l); + } + { + let mut i: i32 = 0; + while i < randomize_postfix_length.size() { + { + ::apply_random_pattern(&bytes_a_l, bytes_a_l.size() - randomize_postfix_length.get(i), &randomize_lengths.get(i)); + } + i += 1; + } + } + + //add padding + let capacity: i32 = solution.get_min_symbol_size(&bytes_a_l.size()); + if bytes_a_l.size() < capacity { + bytes_a_l.add(129 as i8); + } + while bytes_a_l.size() < capacity { + bytes_a_l.add(::randomize253_state(bytes_a_l.size() + 1) as i8); + } + bytes = : [i8; bytes_a_l.size()] = [0; bytes_a_l.size()]; + { + let mut i: i32 = 0; + while i < bytes.len() { + { + bytes[i] = bytes_a_l.get(i); + } + i += 1; + } + } + + } + + fn prepend( bytes: &Vec, into: &List) -> i32 { + { + let mut i: i32 = bytes.len() - 1; + while i >= 0 { + { + into.add(0, bytes[i]); + } + i -= 1; + } + } + + return bytes.len(); + } + + fn randomize253_state( codeword_position: i32) -> i32 { + let pseudo_random: i32 = ((149 * codeword_position) % 253) + 1; + let temp_variable: i32 = 129 + pseudo_random; + return if temp_variable <= 254 { temp_variable } else { temp_variable - 254 }; + } + + fn apply_random_pattern( bytes_a_l: &List, start_position: i32, length: i32) { + { + let mut i: i32 = 0; + while i < length { + { + //See "B.1 253-state algorithm + const Pad_codeword_position: i32 = start_position + i; + const Pad_codeword_value: i32 = bytes_a_l.get(Pad_codeword_position) & 0xff; + let pseudo_random_number: i32 = ((149 * (Pad_codeword_position + 1)) % 255) + 1; + let temp_variable: i32 = Pad_codeword_value + pseudo_random_number; + bytes_a_l.set(Pad_codeword_position, ( if temp_variable <= 255 { temp_variable } else { temp_variable - 256 }) as i8); + } + i += 1; + } + } + + } + + pub fn get_bytes(&self) -> Vec { + return self.bytes; + } + } + + + struct Input { + super: MinimalECIInput; + + let shape: SymbolShapeHint; + + let macro_id: i32; + } + + impl Input { + + fn new( string_to_encode: &String, priority_charset: &Charset, fnc1: i32, shape: &SymbolShapeHint, macro_id: i32) -> Input { + super(&string_to_encode, &priority_charset, fnc1); + let .shape = shape; + let .macroId = macro_id; + } + + fn get_macro_id(&self) -> i32 { + return self.macro_id; + } + + fn get_shape_hint(&self) -> SymbolShapeHint { + return self.shape; + } + } + +} + +// SymbolInfo.java +/** + * Symbol info table for DataMatrix. + * + * @version $Id$ + */ + +const PROD_SYMBOLS: vec![Vec; 30] = vec![SymbolInfo::new(false, 3, 5, 8, 8, 1), SymbolInfo::new(false, 5, 7, 10, 10, 1), /*rect*/ +SymbolInfo::new(true, 5, 7, 16, 6, 1), SymbolInfo::new(false, 8, 10, 12, 12, 1), /*rect*/ +SymbolInfo::new(true, 10, 11, 14, 6, 2), SymbolInfo::new(false, 12, 12, 14, 14, 1), /*rect*/ +SymbolInfo::new(true, 16, 14, 24, 10, 1), SymbolInfo::new(false, 18, 14, 16, 16, 1), SymbolInfo::new(false, 22, 18, 18, 18, 1), /*rect*/ +SymbolInfo::new(true, 22, 18, 16, 10, 2), SymbolInfo::new(false, 30, 20, 20, 20, 1), /*rect*/ +SymbolInfo::new(true, 32, 24, 16, 14, 2), SymbolInfo::new(false, 36, 24, 22, 22, 1), SymbolInfo::new(false, 44, 28, 24, 24, 1), /*rect*/ +SymbolInfo::new(true, 49, 28, 22, 14, 2), SymbolInfo::new(false, 62, 36, 14, 14, 4), SymbolInfo::new(false, 86, 42, 16, 16, 4), SymbolInfo::new(false, 114, 48, 18, 18, 4), SymbolInfo::new(false, 144, 56, 20, 20, 4), SymbolInfo::new(false, 174, 68, 22, 22, 4), SymbolInfo::new(false, 204, 84, 24, 24, 4, 102, 42), SymbolInfo::new(false, 280, 112, 14, 14, 16, 140, 56), SymbolInfo::new(false, 368, 144, 16, 16, 16, 92, 36), SymbolInfo::new(false, 456, 192, 18, 18, 16, 114, 48), SymbolInfo::new(false, 576, 224, 20, 20, 16, 144, 56), SymbolInfo::new(false, 696, 272, 22, 22, 16, 174, 68), SymbolInfo::new(false, 816, 336, 24, 24, 16, 136, 56), SymbolInfo::new(false, 1050, 408, 18, 18, 36, 175, 68), SymbolInfo::new(false, 1304, 496, 20, 20, 36, 163, 62), DataMatrixSymbolInfo144::new(), ] +; + + let mut symbols: Vec = PROD_SYMBOLS; +pub struct SymbolInfo { + + let rectangular: bool; + + let data_capacity: i32; + + let error_codewords: i32; + + let matrix_width: i32; + + let matrix_height: i32; + + let data_regions: i32; + + let rs_block_data: i32; + + let rs_block_error: i32; +} + +impl SymbolInfo { + + /** + * Overrides the symbol info set used by this class. Used for testing purposes. + * + * @param override the symbol info set to use + */ + pub fn override_symbol_set( override: &Vec) { + symbols = override; + } + + pub fn new( rectangular: bool, data_capacity: i32, error_codewords: i32, matrix_width: i32, matrix_height: i32, data_regions: i32) -> SymbolInfo { + this(rectangular, data_capacity, error_codewords, matrix_width, matrix_height, data_regions, data_capacity, error_codewords); + } + + fn new( rectangular: bool, data_capacity: i32, error_codewords: i32, matrix_width: i32, matrix_height: i32, data_regions: i32, rs_block_data: i32, rs_block_error: i32) -> SymbolInfo { + let .rectangular = rectangular; + let .dataCapacity = data_capacity; + let .errorCodewords = error_codewords; + let .matrixWidth = matrix_width; + let .matrixHeight = matrix_height; + let .dataRegions = data_regions; + let .rsBlockData = rs_block_data; + let .rsBlockError = rs_block_error; + } + + pub fn lookup( data_codewords: i32) -> SymbolInfo { + return ::lookup(data_codewords, SymbolShapeHint::FORCE_NONE, true); + } + + pub fn lookup( data_codewords: i32, shape: &SymbolShapeHint) -> SymbolInfo { + return ::lookup(data_codewords, shape, true); + } + + pub fn lookup( data_codewords: i32, allow_rectangular: bool, fail: bool) -> SymbolInfo { + let shape: SymbolShapeHint = if allow_rectangular { SymbolShapeHint::FORCE_NONE } else { SymbolShapeHint::FORCE_SQUARE }; + return ::lookup(data_codewords, shape, fail); + } + + fn lookup( data_codewords: i32, shape: &SymbolShapeHint, fail: bool) -> SymbolInfo { + return ::lookup(data_codewords, shape, null, null, fail); + } + + pub fn lookup( data_codewords: i32, shape: &SymbolShapeHint, min_size: &Dimension, max_size: &Dimension, fail: bool) -> SymbolInfo { + for let symbol: SymbolInfo in symbols { + if shape == SymbolShapeHint::FORCE_SQUARE && symbol.rectangular { + continue; + } + if shape == SymbolShapeHint::FORCE_RECTANGLE && !symbol.rectangular { + continue; + } + if min_size != null && (symbol.get_symbol_width() < min_size.get_width() || symbol.get_symbol_height() < min_size.get_height()) { + continue; + } + if max_size != null && (symbol.get_symbol_width() > max_size.get_width() || symbol.get_symbol_height() > max_size.get_height()) { + continue; + } + if data_codewords <= symbol.dataCapacity { + return symbol; + } + } + if fail { + throw IllegalArgumentException::new(format!("Can't find a symbol arrangement that matches the message. Data codewords: {}", data_codewords)); + } + return null; + } + + fn get_horizontal_data_regions(&self) -> i32 { + match self.data_regions { + 1 => + { + return 1; + } + 2 => + { + } + 4 => + { + return 2; + } + 16 => + { + return 4; + } + 36 => + { + return 6; + } + _ => + { + throw IllegalStateException::new("Cannot handle this number of data regions"); + } + } + } + + fn get_vertical_data_regions(&self) -> i32 { + match self.data_regions { + 1 => + { + } + 2 => + { + return 1; + } + 4 => + { + return 2; + } + 16 => + { + return 4; + } + 36 => + { + return 6; + } + _ => + { + throw IllegalStateException::new("Cannot handle this number of data regions"); + } + } + } + + pub fn get_symbol_data_width(&self) -> i32 { + return self.get_horizontal_data_regions() * self.matrix_width; + } + + pub fn get_symbol_data_height(&self) -> i32 { + return self.get_vertical_data_regions() * self.matrix_height; + } + + pub fn get_symbol_width(&self) -> i32 { + return self.get_symbol_data_width() + (self.get_horizontal_data_regions() * 2); + } + + pub fn get_symbol_height(&self) -> i32 { + return self.get_symbol_data_height() + (self.get_vertical_data_regions() * 2); + } + + pub fn get_codeword_count(&self) -> i32 { + return self.data_capacity + self.error_codewords; + } + + pub fn get_interleaved_block_count(&self) -> i32 { + return self.data_capacity / self.rs_block_data; + } + + pub fn get_data_capacity(&self) -> i32 { + return self.data_capacity; + } + + pub fn get_error_codewords(&self) -> i32 { + return self.error_codewords; + } + + pub fn get_data_length_for_interleaved_block(&self, index: i32) -> i32 { + return self.rs_block_data; + } + + pub fn get_error_length_for_interleaved_block(&self, index: i32) -> i32 { + return self.rs_block_error; + } + + pub fn to_string(&self) -> String { + return format!("{} data region {}x{}, symbol size {}x{}, symbol data size {}x{}, codewords {}+{}", ( if self.rectangular { "Rectangular Symbol:" } else { "Square Symbol:" }), self.matrix_width, self.matrix_height, self.get_symbol_width(), self.get_symbol_height(), self.get_symbol_data_width(), self.get_symbol_data_height(), self.data_capacity, self.error_codewords); + } +} + + +// SymbolShapeHint.java +/** + * Enumeration for DataMatrix symbol shape hint. It can be used to force square or rectangular + * symbols. + */ +pub enum SymbolShapeHint { + + FORCE_NONE(), FORCE_SQUARE(), FORCE_RECTANGLE() +} + +// TextEncoder.java +struct TextEncoder { + super: C40Encoder; +} + +impl TextEncoder { + + pub fn get_encoding_mode(&self) -> i32 { + return HighLevelEncoder::TEXT_ENCODATION; + } + + fn encode_char(&self, c: char, sb: &StringBuilder) -> i32 { + if c == ' ' { + sb.append('\3'); + return 1; + } + if c >= '0' && c <= '9' { + sb.append((c - 48 + 4) as char); + return 1; + } + if c >= 'a' && c <= 'z' { + sb.append((c - 97 + 14) as char); + return 1; + } + if c < ' ' { + //Shift 1 Set + sb.append('\0'); + sb.append(c); + return 2; + } + if c <= '/' { + //Shift 2 Set + sb.append('\1'); + sb.append((c - 33) as char); + return 2; + } + if c <= '@' { + //Shift 2 Set + sb.append('\1'); + sb.append((c - 58 + 15) as char); + return 2; + } + if c >= '[' && c <= '_' { + //Shift 2 Set + sb.append('\1'); + sb.append((c - 91 + 22) as char); + return 2; + } + if c == '`' { + //Shift 3 Set + sb.append('\2'); + // '`' - 96 == 0 + sb.append(0 as char); + return 2; + } + if c <= 'Z' { + //Shift 3 Set + sb.append('\2'); + sb.append((c - 65 + 1) as char); + return 2; + } + if c <= 127 { + //Shift 3 Set + sb.append('\2'); + sb.append((c - 123 + 27) as char); + return 2; + } + //Shift 2, Upper Shift + sb.append("\1"); + let mut len: i32 = 2; + len += self.encode_char((c - 128) as char, &sb); + return len; + } +} + +// X12Encoder.java +struct X12Encoder { + super: C40Encoder; +} + +impl X12Encoder { + + pub fn get_encoding_mode(&self) -> i32 { + return HighLevelEncoder::X12_ENCODATION; + } + + pub fn encode(&self, context: &EncoderContext) { + //step C + let buffer: StringBuilder = StringBuilder::new(); + while context.has_more_characters() { + let c: char = context.get_current_char(); + context.pos += 1; + self.encode_char(c, &buffer); + let count: i32 = buffer.length(); + if (count % 3) == 0 { + write_next_triplet(context, &buffer); + let new_mode: i32 = HighLevelEncoder::look_ahead_test(&context.get_message(), context.pos, &self.get_encoding_mode()); + if new_mode != self.get_encoding_mode() { + // Return to ASCII encodation, which will actually handle latch to new mode + context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); + break; + } + } + } + self.handle_e_o_d(context, &buffer); + } + + fn encode_char(&self, c: char, sb: &StringBuilder) -> i32 { + match c { + '\r' => + { + sb.append('\0'); + break; + } + '*' => + { + sb.append('\1'); + break; + } + '>' => + { + sb.append('\2'); + break; + } + ' ' => + { + sb.append('\3'); + break; + } + _ => + { + if c >= '0' && c <= '9' { + sb.append((c - 48 + 4) as char); + } else if c >= 'A' && c <= 'Z' { + sb.append((c - 65 + 14) as char); + } else { + HighLevelEncoder::illegal_character(c); + } + break; + } + } + return 1; + } + + fn handle_e_o_d(&self, context: &EncoderContext, buffer: &StringBuilder) { + context.update_symbol_info(); + let available: i32 = context.get_symbol_info().get_data_capacity() - context.get_codeword_count(); + let count: i32 = buffer.length(); + context.pos -= count; + if context.get_remaining_characters() > 1 || available > 1 || context.get_remaining_characters() != available { + context.write_codeword(HighLevelEncoder::X12_UNLATCH); + } + if context.get_new_encoding() < 0 { + context.signal_encoder_change(HighLevelEncoder::ASCII_ENCODATION); + } + } +} +