diff --git a/comp.sh b/comp.sh new file mode 100644 index 0000000..1776ff4 --- /dev/null +++ b/comp.sh @@ -0,0 +1,13 @@ +IN_DIR=$1 +OUT_FILE=$2 +COUNT=0 +echo "Writing from '${IN_DIR}' to '${OUT_FILE}'" +for fn in $(ls -p ${IN_DIR} | grep -v /) +do + echo "Found file ${IN_DIR}/${fn}" + echo "Adding contents of ${fn} to ${OUT_FILE}" + ECHO "// NEW FILE: ${fn}" >> ${OUT_FILE} + cat ${IN_DIR}/${fn} >> ${OUT_FILE} + COUNT=$((COUNT + 1)) +done; +echo "Done compiling ${COUNT} files from ${IN_DIR} to ${OUT_FILE}" \ No newline at end of file diff --git a/port_src/core/src/main/java/com/google/zxing/oned/CodaBarReader.java b/port_src/core/DONE/oned/CodaBarReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/CodaBarReader.java rename to port_src/core/DONE/oned/CodaBarReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/CodaBarWriter.java b/port_src/core/DONE/oned/CodaBarWriter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/CodaBarWriter.java rename to port_src/core/DONE/oned/CodaBarWriter.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/Code128Reader.java b/port_src/core/DONE/oned/Code128Reader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/Code128Reader.java rename to port_src/core/DONE/oned/Code128Reader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/Code128Writer.java b/port_src/core/DONE/oned/Code128Writer.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/Code128Writer.java rename to port_src/core/DONE/oned/Code128Writer.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/Code39Reader.java b/port_src/core/DONE/oned/Code39Reader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/Code39Reader.java rename to port_src/core/DONE/oned/Code39Reader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/Code39Writer.java b/port_src/core/DONE/oned/Code39Writer.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/Code39Writer.java rename to port_src/core/DONE/oned/Code39Writer.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/Code93Reader.java b/port_src/core/DONE/oned/Code93Reader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/Code93Reader.java rename to port_src/core/DONE/oned/Code93Reader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/Code93Writer.java b/port_src/core/DONE/oned/Code93Writer.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/Code93Writer.java rename to port_src/core/DONE/oned/Code93Writer.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/EAN13Reader.java b/port_src/core/DONE/oned/EAN13Reader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/EAN13Reader.java rename to port_src/core/DONE/oned/EAN13Reader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/EAN13Writer.java b/port_src/core/DONE/oned/EAN13Writer.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/EAN13Writer.java rename to port_src/core/DONE/oned/EAN13Writer.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/EAN8Reader.java b/port_src/core/DONE/oned/EAN8Reader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/EAN8Reader.java rename to port_src/core/DONE/oned/EAN8Reader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/EAN8Writer.java b/port_src/core/DONE/oned/EAN8Writer.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/EAN8Writer.java rename to port_src/core/DONE/oned/EAN8Writer.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/EANManufacturerOrgSupport.java b/port_src/core/DONE/oned/EANManufacturerOrgSupport.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/EANManufacturerOrgSupport.java rename to port_src/core/DONE/oned/EANManufacturerOrgSupport.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/ITFReader.java b/port_src/core/DONE/oned/ITFReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/ITFReader.java rename to port_src/core/DONE/oned/ITFReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/ITFWriter.java b/port_src/core/DONE/oned/ITFWriter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/ITFWriter.java rename to port_src/core/DONE/oned/ITFWriter.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/MultiFormatOneDReader.java b/port_src/core/DONE/oned/MultiFormatOneDReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/MultiFormatOneDReader.java rename to port_src/core/DONE/oned/MultiFormatOneDReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/MultiFormatUPCEANReader.java b/port_src/core/DONE/oned/MultiFormatUPCEANReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/MultiFormatUPCEANReader.java rename to port_src/core/DONE/oned/MultiFormatUPCEANReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/OneDReader.java b/port_src/core/DONE/oned/OneDReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/OneDReader.java rename to port_src/core/DONE/oned/OneDReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/OneDimensionalCodeWriter.java b/port_src/core/DONE/oned/OneDimensionalCodeWriter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/OneDimensionalCodeWriter.java rename to port_src/core/DONE/oned/OneDimensionalCodeWriter.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCAReader.java b/port_src/core/DONE/oned/UPCAReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCAReader.java rename to port_src/core/DONE/oned/UPCAReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCAWriter.java b/port_src/core/DONE/oned/UPCAWriter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCAWriter.java rename to port_src/core/DONE/oned/UPCAWriter.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCEANExtension2Support.java b/port_src/core/DONE/oned/UPCEANExtension2Support.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCEANExtension2Support.java rename to port_src/core/DONE/oned/UPCEANExtension2Support.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCEANExtension5Support.java b/port_src/core/DONE/oned/UPCEANExtension5Support.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCEANExtension5Support.java rename to port_src/core/DONE/oned/UPCEANExtension5Support.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCEANExtensionSupport.java b/port_src/core/DONE/oned/UPCEANExtensionSupport.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCEANExtensionSupport.java rename to port_src/core/DONE/oned/UPCEANExtensionSupport.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCEANReader.java b/port_src/core/DONE/oned/UPCEANReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCEANReader.java rename to port_src/core/DONE/oned/UPCEANReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCEANWriter.java b/port_src/core/DONE/oned/UPCEANWriter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCEANWriter.java rename to port_src/core/DONE/oned/UPCEANWriter.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCEReader.java b/port_src/core/DONE/oned/UPCEReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCEReader.java rename to port_src/core/DONE/oned/UPCEReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/UPCEWriter.java b/port_src/core/DONE/oned/UPCEWriter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/UPCEWriter.java rename to port_src/core/DONE/oned/UPCEWriter.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/AbstractRSSReader.java b/port_src/core/DONE/oned/rss/AbstractRSSReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/AbstractRSSReader.java rename to port_src/core/DONE/oned/rss/AbstractRSSReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/DataCharacter.java b/port_src/core/DONE/oned/rss/DataCharacter.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/DataCharacter.java rename to port_src/core/DONE/oned/rss/DataCharacter.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/FinderPattern.java b/port_src/core/DONE/oned/rss/FinderPattern.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/FinderPattern.java rename to port_src/core/DONE/oned/rss/FinderPattern.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/Pair.java b/port_src/core/DONE/oned/rss/Pair.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/Pair.java rename to port_src/core/DONE/oned/rss/Pair.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/RSS14Reader.java b/port_src/core/DONE/oned/rss/RSS14Reader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/RSS14Reader.java rename to port_src/core/DONE/oned/rss/RSS14Reader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/RSSUtils.java b/port_src/core/DONE/oned/rss/RSSUtils.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/RSSUtils.java rename to port_src/core/DONE/oned/rss/RSSUtils.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java b/port_src/core/DONE/oned/rss/expanded/BitArrayBuilder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java rename to port_src/core/DONE/oned/rss/expanded/BitArrayBuilder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/ExpandedPair.java b/port_src/core/DONE/oned/rss/expanded/ExpandedPair.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/ExpandedPair.java rename to port_src/core/DONE/oned/rss/expanded/ExpandedPair.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/ExpandedRow.java b/port_src/core/DONE/oned/rss/expanded/ExpandedRow.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/ExpandedRow.java rename to port_src/core/DONE/oned/rss/expanded/ExpandedRow.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java b/port_src/core/DONE/oned/rss/expanded/RSSExpandedReader.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java rename to port_src/core/DONE/oned/rss/expanded/RSSExpandedReader.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI013103decoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI013103decoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI013103decoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI013103decoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01320xDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI01320xDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01320xDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI01320xDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01392xDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI01392xDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01392xDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI01392xDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01393xDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI01393xDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01393xDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI01393xDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI013x0x1xDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI013x0x1xDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI013x0xDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI013x0xDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI01AndOtherAIs.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI01AndOtherAIs.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01decoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI01decoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01decoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI01decoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01weightDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AI01weightDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AI01weightDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AI01weightDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AbstractExpandedDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AbstractExpandedDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/AnyAIDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/AnyAIDecoder.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/BlockParsedResult.java b/port_src/core/DONE/oned/rss/expanded/decoders/BlockParsedResult.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/BlockParsedResult.java rename to port_src/core/DONE/oned/rss/expanded/decoders/BlockParsedResult.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/CurrentParsingState.java b/port_src/core/DONE/oned/rss/expanded/decoders/CurrentParsingState.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/CurrentParsingState.java rename to port_src/core/DONE/oned/rss/expanded/decoders/CurrentParsingState.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedChar.java b/port_src/core/DONE/oned/rss/expanded/decoders/DecodedChar.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedChar.java rename to port_src/core/DONE/oned/rss/expanded/decoders/DecodedChar.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedInformation.java b/port_src/core/DONE/oned/rss/expanded/decoders/DecodedInformation.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedInformation.java rename to port_src/core/DONE/oned/rss/expanded/decoders/DecodedInformation.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedNumeric.java b/port_src/core/DONE/oned/rss/expanded/decoders/DecodedNumeric.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedNumeric.java rename to port_src/core/DONE/oned/rss/expanded/decoders/DecodedNumeric.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedObject.java b/port_src/core/DONE/oned/rss/expanded/decoders/DecodedObject.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/DecodedObject.java rename to port_src/core/DONE/oned/rss/expanded/decoders/DecodedObject.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/FieldParser.java b/port_src/core/DONE/oned/rss/expanded/decoders/FieldParser.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/FieldParser.java rename to port_src/core/DONE/oned/rss/expanded/decoders/FieldParser.java diff --git a/port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.java b/port_src/core/DONE/oned/rss/expanded/decoders/GeneralAppIdDecoder.java similarity index 100% rename from port_src/core/src/main/java/com/google/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.java rename to port_src/core/DONE/oned/rss/expanded/decoders/GeneralAppIdDecoder.java diff --git a/port_src/output/zxing/oned/coda_bar_reader.rs b/port_src/output/zxing/oned/coda_bar_reader.rs deleted file mode 100644 index 676e3f1..0000000 --- a/port_src/output/zxing/oned/coda_bar_reader.rs +++ /dev/null @@ -1,437 +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::oned; - -/** - *

Decodes Codabar barcodes.

- * - * @author Bas Vijfwinkel - * @author David Walker - */ - -// These values are critical for determining how permissive the decoding -// will be. All stripe sizes must be within the window these define, as -// compared to the average stripe size. - const MAX_ACCEPTABLE: f32 = 2.0f; - - const PADDING: f32 = 1.5f; - - const ALPHABET_STRING: &'static str = "0123456789-$:/.+ABCD"; - - const ALPHABET: Vec = ALPHABET_STRING::to_char_array(); - -/** - * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of - * each int correspond to the pattern of wide and narrow, with 1s representing "wide" and 0s representing narrow. - */ - const CHARACTER_ENCODINGS: vec![Vec; 20] = vec![// 0-9 -0x003, // 0-9 -0x006, // 0-9 -0x009, // 0-9 -0x060, // 0-9 -0x012, // 0-9 -0x042, // 0-9 -0x021, // 0-9 -0x024, // 0-9 -0x030, // 0-9 -0x048, // -$:/.+ABCD -0x00c, // -$:/.+ABCD -0x018, // -$:/.+ABCD -0x045, // -$:/.+ABCD -0x051, // -$:/.+ABCD -0x054, // -$:/.+ABCD -0x015, // -$:/.+ABCD -0x01A, // -$:/.+ABCD -0x029, // -$:/.+ABCD -0x00B, // -$:/.+ABCD -0x00E, ] -; - -// minimal number of characters that should be present (including start and stop characters) -// under normal circumstances this should be set to 3, but can be set higher -// as a last-ditch attempt to reduce false positives. - const MIN_CHARACTER_LENGTH: i32 = 3; - -// official start and end patterns - const STARTEND_ENCODING: vec![Vec; 4] = vec!['A', 'B', 'C', 'D', ] -; -pub struct CodaBarReader { - super: OneDReader; - - // some Codabar generator allow the Codabar string to be closed by every - // character. This will cause lots of false positives! - // some industries use a checksum standard but this is not part of the original Codabar standard - // for more information see : http://www.mecsw.com/specs/codabar.html - // Keep some instance variables to avoid reallocations - let decode_row_result: StringBuilder; - - let mut counters: Vec; - - let counter_length: i32; -} - -impl CodaBarReader { - - pub fn new() -> CodaBarReader { - decode_row_result = StringBuilder::new(20); - counters = : [i32; 80] = [0; 80]; - counter_length = 0; - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { - Arrays::fill(&self.counters, 0); - self.set_counters(row); - let start_offset: i32 = self.find_start_pattern(); - let next_start: i32 = start_offset; - self.decode_row_result.set_length(0); - loop { { - let char_offset: i32 = self.to_narrow_wide_pattern(next_start); - if char_offset == -1 { - throw NotFoundException::get_not_found_instance(); - } - // Hack: We store the position in the alphabet table into a - // StringBuilder, so that we can access the decoded patterns in - // validatePattern. We'll translate to the actual characters later. - self.decode_row_result.append(char_offset as char); - next_start += 8; - // Stop as soon as we see the end character. - if self.decode_row_result.length() > 1 && ::array_contains(&STARTEND_ENCODING, ALPHABET[char_offset]) { - break; - } - }if !(// no fixed end pattern so keep on reading while data is available - next_start < self.counter_length) break;} - // Look for whitespace after pattern: - let trailing_whitespace: i32 = self.counters[next_start - 1]; - let last_pattern_size: i32 = 0; - { - let mut i: i32 = -8; - while i < -1 { - { - last_pattern_size += self.counters[next_start + i]; - } - i += 1; - } - } - - // at the end of the row. (I.e. the barcode barely fits.) - if next_start < self.counter_length && trailing_whitespace < last_pattern_size / 2 { - throw NotFoundException::get_not_found_instance(); - } - self.validate_pattern(start_offset); - // Translate character table offsets to actual characters. - { - let mut i: i32 = 0; - while i < self.decode_row_result.length() { - { - self.decode_row_result.set_char_at(i, ALPHABET[self.decode_row_result.char_at(i)]); - } - i += 1; - } - } - - // Ensure a valid start and end character - let startchar: char = self.decode_row_result.char_at(0); - if !::array_contains(&STARTEND_ENCODING, startchar) { - throw NotFoundException::get_not_found_instance(); - } - let endchar: char = self.decode_row_result.char_at(self.decode_row_result.length() - 1); - if !::array_contains(&STARTEND_ENCODING, endchar) { - throw NotFoundException::get_not_found_instance(); - } - // remove stop/start characters character and check if a long enough string is contained - if self.decode_row_result.length() <= MIN_CHARACTER_LENGTH { - // Almost surely a false positive ( start + stop + at least 1 character) - throw NotFoundException::get_not_found_instance(); - } - if hints == null || !hints.contains_key(DecodeHintType::RETURN_CODABAR_START_END) { - self.decode_row_result.delete_char_at(self.decode_row_result.length() - 1); - self.decode_row_result.delete_char_at(0); - } - let running_count: i32 = 0; - { - let mut i: i32 = 0; - while i < start_offset { - { - running_count += self.counters[i]; - } - i += 1; - } - } - - let left: f32 = running_count; - { - let mut i: i32 = start_offset; - while i < next_start - 1 { - { - running_count += self.counters[i]; - } - i += 1; - } - } - - let right: f32 = running_count; - let result: Result = Result::new(&self.decode_row_result.to_string(), null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] - , BarcodeFormat::CODABAR); - result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]F0"); - return Ok(result); - } - - fn validate_pattern(&self, start: i32) -> /* throws NotFoundException */Result> { - // First, sum up the total size of our four categories of stripe sizes; - let mut sizes: vec![Vec; 4] = vec![0, 0, 0, 0, ] - ; - let mut counts: vec![Vec; 4] = vec![0, 0, 0, 0, ] - ; - let end: i32 = self.decode_row_result.length() - 1; - // We break out of this loop in the middle, in order to handle - // inter-character spaces properly. - let mut pos: i32 = start; - { - let mut i: i32 = 0; - while i <= end { - { - let mut pattern: i32 = CHARACTER_ENCODINGS[self.decode_row_result.char_at(i)]; - { - let mut j: i32 = 6; - while j >= 0 { - { - // Even j = bars, while odd j = spaces. Categories 2 and 3 are for - // long stripes, while 0 and 1 are for short stripes. - let mut category: i32 = (j & 1) + (pattern & 1) * 2; - sizes[category] += self.counters[pos + j]; - counts[category] += 1; - pattern >>= 1; - } - j -= 1; - } - } - - // We ignore the inter-character space - it could be of any size. - pos += 8; - } - i += 1; - } - } - - // Calculate our allowable size thresholds using fixed-point math. - let mut maxes: [f32; 4.0] = [0.0; 4.0]; - let mut mins: [f32; 4.0] = [0.0; 4.0]; - // should be on the "wrong" side of that line. - { - let mut i: i32 = 0; - while i < 2 { - { - // Accept arbitrarily small "short" stripes. - mins[i] = 0.0f; - mins[i + 2] = (sizes[i] as f32 / counts[i] + sizes[i + 2] as f32 / counts[i + 2]) / 2.0f; - maxes[i] = mins[i + 2]; - maxes[i + 2] = (sizes[i + 2] * MAX_ACCEPTABLE + PADDING) / counts[i + 2]; - } - i += 1; - } - } - - // Now verify that all of the stripes are within the thresholds. - pos = start; - { - let mut i: i32 = 0; - while i <= end { - { - let mut pattern: i32 = CHARACTER_ENCODINGS[self.decode_row_result.char_at(i)]; - { - let mut j: i32 = 6; - while j >= 0 { - { - // Even j = bars, while odd j = spaces. Categories 2 and 3 are for - // long stripes, while 0 and 1 are for short stripes. - let category: i32 = (j & 1) + (pattern & 1) * 2; - let size: i32 = self.counters[pos + j]; - if size < mins[category] || size > maxes[category] { - throw NotFoundException::get_not_found_instance(); - } - pattern >>= 1; - } - j -= 1; - } - } - - pos += 8; - } - i += 1; - } - } - - } - - /** - * Records the size of all runs of white and black pixels, starting with white. - * This is just like recordPattern, except it records all the counters, and - * uses our builtin "counters" member for storage. - * @param row row to count from - */ - fn set_counters(&self, row: &BitArray) -> /* throws NotFoundException */Result> { - self.counter_length = 0; - // Start from the first white bit. - let mut i: i32 = row.get_next_unset(0); - let end: i32 = row.get_size(); - if i >= end { - throw NotFoundException::get_not_found_instance(); - } - let is_white: bool = true; - let mut count: i32 = 0; - while i < end { - if row.get(i) != is_white { - count += 1; - } else { - self.counter_append(count); - count = 1; - is_white = !is_white; - } - i += 1; - } - self.counter_append(count); - } - - fn counter_append(&self, e: i32) { - self.counters[self.counter_length] = e; - self.counter_length += 1; - if self.counter_length >= self.counters.len() { - let temp: [i32; self.counter_length * 2] = [0; self.counter_length * 2]; - System::arraycopy(&self.counters, 0, &temp, 0, self.counter_length); - self.counters = temp; - } - } - - fn find_start_pattern(&self) -> /* throws NotFoundException */Result> { - { - let mut i: i32 = 1; - while i < self.counter_length { - { - let char_offset: i32 = self.to_narrow_wide_pattern(i); - if char_offset != -1 && ::array_contains(&STARTEND_ENCODING, ALPHABET[char_offset]) { - // Look for whitespace before start pattern, >= 50% of width of start pattern - // We make an exception if the whitespace is the first element. - let pattern_size: i32 = 0; - { - let mut j: i32 = i; - while j < i + 7 { - { - pattern_size += self.counters[j]; - } - j += 1; - } - } - - if i == 1 || self.counters[i - 1] >= pattern_size / 2 { - return Ok(i); - } - } - } - i += 2; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - fn array_contains( array: &Vec, key: char) -> bool { - if array != null { - for let c: char in array { - if c == key { - return true; - } - } - } - return false; - } - - // Assumes that counters[position] is a bar. - fn to_narrow_wide_pattern(&self, position: i32) -> i32 { - let end: i32 = position + 7; - if end >= self.counter_length { - return -1; - } - let the_counters: Vec = self.counters; - let max_bar: i32 = 0; - let min_bar: i32 = Integer::MAX_VALUE; - { - let mut j: i32 = position; - while j < end { - { - let current_counter: i32 = the_counters[j]; - if current_counter < min_bar { - min_bar = current_counter; - } - if current_counter > max_bar { - max_bar = current_counter; - } - } - j += 2; - } - } - - let threshold_bar: i32 = (min_bar + max_bar) / 2; - let max_space: i32 = 0; - let min_space: i32 = Integer::MAX_VALUE; - { - let mut j: i32 = position + 1; - while j < end { - { - let current_counter: i32 = the_counters[j]; - if current_counter < min_space { - min_space = current_counter; - } - if current_counter > max_space { - max_space = current_counter; - } - } - j += 2; - } - } - - let threshold_space: i32 = (min_space + max_space) / 2; - let mut bitmask: i32 = 1 << 7; - let mut pattern: i32 = 0; - { - let mut i: i32 = 0; - while i < 7 { - { - let threshold: i32 = if (i & 1) == 0 { threshold_bar } else { threshold_space }; - bitmask >>= 1; - if the_counters[position + i] > threshold { - pattern |= bitmask; - } - } - i += 1; - } - } - - { - let mut i: i32 = 0; - while i < CHARACTER_ENCODINGS.len() { - { - if CHARACTER_ENCODINGS[i] == pattern { - return i; - } - } - i += 1; - } - } - - return -1; - } -} - diff --git a/port_src/output/zxing/oned/coda_bar_writer.rs b/port_src/output/zxing/oned/coda_bar_writer.rs deleted file mode 100644 index 259b870..0000000 --- a/port_src/output/zxing/oned/coda_bar_writer.rs +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2011 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::oned; - -/** - * This class renders CodaBar as {@code boolean[]}. - * - * @author dsbnatut@gmail.com (Kazuki Nishiura) - */ - - const START_END_CHARS: vec![Vec; 4] = vec!['A', 'B', 'C', 'D', ] -; - - const ALT_START_END_CHARS: vec![Vec; 4] = vec!['T', 'N', '*', 'E', ] -; - - const CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED: vec![Vec; 4] = vec!['/', ':', '+', '.', ] -; - - const DEFAULT_GUARD: char = START_END_CHARS[0]; -pub struct CodaBarWriter { - super: OneDimensionalCodeWriter; -} - -impl CodaBarWriter { - - pub fn get_supported_write_formats(&self) -> Collection { - return Collections::singleton(BarcodeFormat::CODABAR); - } - - pub fn encode(&self, contents: &String) -> Vec { - if contents.length() < 2 { - // Can't have a start/end guard, so tentatively add default guards - contents = format!("{}{}{}", DEFAULT_GUARD, contents, DEFAULT_GUARD); - } else { - // Verify input and calculate decoded length. - let first_char: char = Character::to_upper_case(&contents.char_at(0)); - let last_char: char = Character::to_upper_case(&contents.char_at(contents.length() - 1)); - let starts_normal: bool = CodaBarReader::array_contains(&START_END_CHARS, first_char); - let ends_normal: bool = CodaBarReader::array_contains(&START_END_CHARS, last_char); - let starts_alt: bool = CodaBarReader::array_contains(&ALT_START_END_CHARS, first_char); - let ends_alt: bool = CodaBarReader::array_contains(&ALT_START_END_CHARS, last_char); - if starts_normal { - if !ends_normal { - throw IllegalArgumentException::new(format!("Invalid start/end guards: {}", contents)); - } - // else already has valid start/end - } else if starts_alt { - if !ends_alt { - throw IllegalArgumentException::new(format!("Invalid start/end guards: {}", contents)); - } - // else already has valid start/end - } else { - // Doesn't start with a guard - if ends_normal || ends_alt { - throw IllegalArgumentException::new(format!("Invalid start/end guards: {}", contents)); - } - // else doesn't end with guard either, so add a default - contents = format!("{}{}{}", DEFAULT_GUARD, contents, DEFAULT_GUARD); - } - } - // The start character and the end character are decoded to 10 length each. - let result_length: i32 = 20; - { - let mut i: i32 = 1; - while i < contents.length() - 1 { - { - if Character::is_digit(&contents.char_at(i)) || contents.char_at(i) == '-' || contents.char_at(i) == '$' { - result_length += 9; - } else if CodaBarReader::array_contains(&CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED, &contents.char_at(i)) { - result_length += 10; - } else { - throw IllegalArgumentException::new(format!("Cannot encode : '{}\'", contents.char_at(i))); - } - } - i += 1; - } - } - - // A blank is placed between each character. - result_length += contents.length() - 1; - let mut result: [bool; result_length] = [false; result_length]; - let mut position: i32 = 0; - { - let mut index: i32 = 0; - while index < contents.length() { - { - let mut c: char = Character::to_upper_case(&contents.char_at(index)); - if index == 0 || index == contents.length() - 1 { - // The start/end chars are not in the CodaBarReader.ALPHABET. - match c { - 'T' => - { - c = 'A'; - break; - } - 'N' => - { - c = 'B'; - break; - } - '*' => - { - c = 'C'; - break; - } - 'E' => - { - c = 'D'; - break; - } - } - } - let mut code: i32 = 0; - { - let mut i: i32 = 0; - while i < CodaBarReader::ALPHABET::len() { - { - // Found any, because I checked above. - if c == CodaBarReader::ALPHABET[i] { - code = CodaBarReader::CHARACTER_ENCODINGS[i]; - break; - } - } - i += 1; - } - } - - let mut color: bool = true; - let mut counter: i32 = 0; - let mut bit: i32 = 0; - while bit < 7 { - // A character consists of 7 digit. - result[position] = color; - position += 1; - if ((code >> (6 - bit)) & 1) == 0 || counter == 1 { - // Flip the color. - color = !color; - bit += 1; - counter = 0; - } else { - counter += 1; - } - } - if index < contents.length() - 1 { - result[position] = false; - position += 1; - } - } - index += 1; - } - } - - return result; - } -} - diff --git a/port_src/output/zxing/oned/code128_reader.rs b/port_src/output/zxing/oned/code128_reader.rs deleted file mode 100644 index 6141395..0000000 --- a/port_src/output/zxing/oned/code128_reader.rs +++ /dev/null @@ -1,630 +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::oned; - -/** - *

Decodes Code 128 barcodes.

- * - * @author Sean Owen - */ - - const CODE_PATTERNS: vec![vec![Vec>; 7]; 107] = vec![// 0 -vec![2, 1, 2, 2, 2, 2, ] -, vec![2, 2, 2, 1, 2, 2, ] -, vec![2, 2, 2, 2, 2, 1, ] -, vec![1, 2, 1, 2, 2, 3, ] -, vec![1, 2, 1, 3, 2, 2, ] -, // 5 -vec![1, 3, 1, 2, 2, 2, ] -, vec![1, 2, 2, 2, 1, 3, ] -, vec![1, 2, 2, 3, 1, 2, ] -, vec![1, 3, 2, 2, 1, 2, ] -, vec![2, 2, 1, 2, 1, 3, ] -, // 10 -vec![2, 2, 1, 3, 1, 2, ] -, vec![2, 3, 1, 2, 1, 2, ] -, vec![1, 1, 2, 2, 3, 2, ] -, vec![1, 2, 2, 1, 3, 2, ] -, vec![1, 2, 2, 2, 3, 1, ] -, // 15 -vec![1, 1, 3, 2, 2, 2, ] -, vec![1, 2, 3, 1, 2, 2, ] -, vec![1, 2, 3, 2, 2, 1, ] -, vec![2, 2, 3, 2, 1, 1, ] -, vec![2, 2, 1, 1, 3, 2, ] -, // 20 -vec![2, 2, 1, 2, 3, 1, ] -, vec![2, 1, 3, 2, 1, 2, ] -, vec![2, 2, 3, 1, 1, 2, ] -, vec![3, 1, 2, 1, 3, 1, ] -, vec![3, 1, 1, 2, 2, 2, ] -, // 25 -vec![3, 2, 1, 1, 2, 2, ] -, vec![3, 2, 1, 2, 2, 1, ] -, vec![3, 1, 2, 2, 1, 2, ] -, vec![3, 2, 2, 1, 1, 2, ] -, vec![3, 2, 2, 2, 1, 1, ] -, // 30 -vec![2, 1, 2, 1, 2, 3, ] -, vec![2, 1, 2, 3, 2, 1, ] -, vec![2, 3, 2, 1, 2, 1, ] -, vec![1, 1, 1, 3, 2, 3, ] -, vec![1, 3, 1, 1, 2, 3, ] -, // 35 -vec![1, 3, 1, 3, 2, 1, ] -, vec![1, 1, 2, 3, 1, 3, ] -, vec![1, 3, 2, 1, 1, 3, ] -, vec![1, 3, 2, 3, 1, 1, ] -, vec![2, 1, 1, 3, 1, 3, ] -, // 40 -vec![2, 3, 1, 1, 1, 3, ] -, vec![2, 3, 1, 3, 1, 1, ] -, vec![1, 1, 2, 1, 3, 3, ] -, vec![1, 1, 2, 3, 3, 1, ] -, vec![1, 3, 2, 1, 3, 1, ] -, // 45 -vec![1, 1, 3, 1, 2, 3, ] -, vec![1, 1, 3, 3, 2, 1, ] -, vec![1, 3, 3, 1, 2, 1, ] -, vec![3, 1, 3, 1, 2, 1, ] -, vec![2, 1, 1, 3, 3, 1, ] -, // 50 -vec![2, 3, 1, 1, 3, 1, ] -, vec![2, 1, 3, 1, 1, 3, ] -, vec![2, 1, 3, 3, 1, 1, ] -, vec![2, 1, 3, 1, 3, 1, ] -, vec![3, 1, 1, 1, 2, 3, ] -, // 55 -vec![3, 1, 1, 3, 2, 1, ] -, vec![3, 3, 1, 1, 2, 1, ] -, vec![3, 1, 2, 1, 1, 3, ] -, vec![3, 1, 2, 3, 1, 1, ] -, vec![3, 3, 2, 1, 1, 1, ] -, // 60 -vec![3, 1, 4, 1, 1, 1, ] -, vec![2, 2, 1, 4, 1, 1, ] -, vec![4, 3, 1, 1, 1, 1, ] -, vec![1, 1, 1, 2, 2, 4, ] -, vec![1, 1, 1, 4, 2, 2, ] -, // 65 -vec![1, 2, 1, 1, 2, 4, ] -, vec![1, 2, 1, 4, 2, 1, ] -, vec![1, 4, 1, 1, 2, 2, ] -, vec![1, 4, 1, 2, 2, 1, ] -, vec![1, 1, 2, 2, 1, 4, ] -, // 70 -vec![1, 1, 2, 4, 1, 2, ] -, vec![1, 2, 2, 1, 1, 4, ] -, vec![1, 2, 2, 4, 1, 1, ] -, vec![1, 4, 2, 1, 1, 2, ] -, vec![1, 4, 2, 2, 1, 1, ] -, // 75 -vec![2, 4, 1, 2, 1, 1, ] -, vec![2, 2, 1, 1, 1, 4, ] -, vec![4, 1, 3, 1, 1, 1, ] -, vec![2, 4, 1, 1, 1, 2, ] -, vec![1, 3, 4, 1, 1, 1, ] -, // 80 -vec![1, 1, 1, 2, 4, 2, ] -, vec![1, 2, 1, 1, 4, 2, ] -, vec![1, 2, 1, 2, 4, 1, ] -, vec![1, 1, 4, 2, 1, 2, ] -, vec![1, 2, 4, 1, 1, 2, ] -, // 85 -vec![1, 2, 4, 2, 1, 1, ] -, vec![4, 1, 1, 2, 1, 2, ] -, vec![4, 2, 1, 1, 1, 2, ] -, vec![4, 2, 1, 2, 1, 1, ] -, vec![2, 1, 2, 1, 4, 1, ] -, // 90 -vec![2, 1, 4, 1, 2, 1, ] -, vec![4, 1, 2, 1, 2, 1, ] -, vec![1, 1, 1, 1, 4, 3, ] -, vec![1, 1, 1, 3, 4, 1, ] -, vec![1, 3, 1, 1, 4, 1, ] -, // 95 -vec![1, 1, 4, 1, 1, 3, ] -, vec![1, 1, 4, 3, 1, 1, ] -, vec![4, 1, 1, 1, 1, 3, ] -, vec![4, 1, 1, 3, 1, 1, ] -, vec![1, 1, 3, 1, 4, 1, ] -, // 100 -vec![1, 1, 4, 1, 3, 1, ] -, vec![3, 1, 1, 1, 4, 1, ] -, vec![4, 1, 1, 1, 3, 1, ] -, vec![2, 1, 1, 4, 1, 2, ] -, vec![2, 1, 1, 2, 1, 4, ] -, // 105 -vec![2, 1, 1, 2, 3, 2, ] -, vec![2, 3, 3, 1, 1, 1, 2, ] -, ] -; - - const MAX_AVG_VARIANCE: f32 = 0.25f; - - const MAX_INDIVIDUAL_VARIANCE: f32 = 0.7f; - - const CODE_SHIFT: i32 = 98; - - const CODE_CODE_C: i32 = 99; - - const CODE_CODE_B: i32 = 100; - - const CODE_CODE_A: i32 = 101; - - const CODE_FNC_1: i32 = 102; - - const CODE_FNC_2: i32 = 97; - - const CODE_FNC_3: i32 = 96; - - const CODE_FNC_4_A: i32 = 101; - - const CODE_FNC_4_B: i32 = 100; - - const CODE_START_A: i32 = 103; - - const CODE_START_B: i32 = 104; - - const CODE_START_C: i32 = 105; - - const CODE_STOP: i32 = 106; -pub struct Code128Reader { - super: OneDReader; -} - -impl Code128Reader { - - fn find_start_pattern( row: &BitArray) -> /* throws NotFoundException */Result, Rc> { - let width: i32 = row.get_size(); - let row_offset: i32 = row.get_next_set(0); - let counter_position: i32 = 0; - let mut counters: [i32; 6] = [0; 6]; - let pattern_start: i32 = row_offset; - let is_white: bool = false; - let pattern_length: i32 = counters.len(); - { - let mut i: i32 = row_offset; - while i < width { - { - if row.get(i) != is_white { - counters[counter_position] += 1; - } else { - if counter_position == pattern_length - 1 { - let best_variance: f32 = MAX_AVG_VARIANCE; - let best_match: i32 = -1; - { - let start_code: i32 = CODE_START_A; - while start_code <= CODE_START_C { - { - let variance: f32 = pattern_match_variance(&counters, CODE_PATTERNS[start_code], MAX_INDIVIDUAL_VARIANCE); - if variance < best_variance { - best_variance = variance; - best_match = start_code; - } - } - start_code += 1; - } - } - - // Look for whitespace before start pattern, >= 50% of width of start pattern - if best_match >= 0 && row.is_range(&Math::max(0, pattern_start - (i - pattern_start) / 2), pattern_start, false) { - return Ok( : vec![i32; 3] = vec![pattern_start, i, best_match, ] - ); - } - pattern_start += counters[0] + counters[1]; - System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); - counters[counter_position - 1] = 0; - counters[counter_position] = 0; - counter_position -= 1; - } else { - counter_position += 1; - } - counters[counter_position] = 1; - is_white = !is_white; - } - } - i += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - fn decode_code( row: &BitArray, counters: &Vec, row_offset: i32) -> /* throws NotFoundException */Result> { - record_pattern(row, row_offset, &counters); - // worst variance we'll accept - let best_variance: f32 = MAX_AVG_VARIANCE; - let best_match: i32 = -1; - { - let mut d: i32 = 0; - while d < CODE_PATTERNS.len() { - { - let pattern: Vec = CODE_PATTERNS[d]; - let variance: f32 = pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE); - if variance < best_variance { - best_variance = variance; - best_match = d; - } - } - d += 1; - } - } - - // TODO We're overlooking the fact that the STOP pattern has 7 values, not 6. - if best_match >= 0 { - return Ok(best_match); - } else { - throw NotFoundException::get_not_found_instance(); - } - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, FormatException, ChecksumException */Result> { - let convert_f_n_c1: bool = hints != null && hints.contains_key(DecodeHintType::ASSUME_GS1); - let symbology_modifier: i32 = 0; - let start_pattern_info: Vec = ::find_start_pattern(row); - let start_code: i32 = start_pattern_info[2]; - let raw_codes: List = ArrayList<>::new(20); - raw_codes.add(start_code as i8); - let code_set: i32; - match start_code { - CODE_START_A => - { - code_set = CODE_CODE_A; - break; - } - CODE_START_B => - { - code_set = CODE_CODE_B; - break; - } - CODE_START_C => - { - code_set = CODE_CODE_C; - break; - } - _ => - { - throw FormatException::get_format_instance(); - } - } - let mut done: bool = false; - let is_next_shifted: bool = false; - let result: StringBuilder = StringBuilder::new(20); - let last_start: i32 = start_pattern_info[0]; - let next_start: i32 = start_pattern_info[1]; - let counters: [i32; 6] = [0; 6]; - let last_code: i32 = 0; - let mut code: i32 = 0; - let checksum_total: i32 = start_code; - let mut multiplier: i32 = 0; - let last_character_was_printable: bool = true; - let upper_mode: bool = false; - let shift_upper_mode: bool = false; - while !done { - let unshift: bool = is_next_shifted; - is_next_shifted = false; - // Save off last code - last_code = code; - // Decode another code from image - code = ::decode_code(row, &counters, next_start); - raw_codes.add(code as i8); - // Remember whether the last code was printable or not (excluding CODE_STOP) - if code != CODE_STOP { - last_character_was_printable = true; - } - // Add to checksum computation (if not CODE_STOP of course) - if code != CODE_STOP { - multiplier += 1; - checksum_total += multiplier * code; - } - // Advance to where the next code will to start - last_start = next_start; - for let counter: i32 in counters { - next_start += counter; - } - // Take care of illegal start codes - match code { - CODE_START_A => - { - } - CODE_START_B => - { - } - CODE_START_C => - { - throw FormatException::get_format_instance(); - } - } - match code_set { - CODE_CODE_A => - { - if code < 64 { - if shift_upper_mode == upper_mode { - result.append((' ' + code) as char); - } else { - result.append((' ' + code + 128) as char); - } - shift_upper_mode = false; - } else if code < 96 { - if shift_upper_mode == upper_mode { - result.append((code - 64) as char); - } else { - result.append((code + 64) as char); - } - shift_upper_mode = false; - } else { - // code was printable or not. - if code != CODE_STOP { - last_character_was_printable = false; - } - match code { - CODE_FNC_1 => - { - if result.length() == 0 { - // FNC1 at first or second character determines the symbology - symbology_modifier = 1; - } else if result.length() == 1 { - symbology_modifier = 2; - } - if convert_f_n_c1 { - if result.length() == 0 { - // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code - // is FNC1 then this is GS1-128. We add the symbology identifier. - result.append("]C1"); - } else { - // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) - result.append(29 as char); - } - } - break; - } - CODE_FNC_2 => - { - symbology_modifier = 4; - break; - } - CODE_FNC_3 => - { - // do nothing? - break; - } - CODE_FNC_4_A => - { - if !upper_mode && shift_upper_mode { - upper_mode = true; - shift_upper_mode = false; - } else if upper_mode && shift_upper_mode { - upper_mode = false; - shift_upper_mode = false; - } else { - shift_upper_mode = true; - } - break; - } - CODE_SHIFT => - { - is_next_shifted = true; - code_set = CODE_CODE_B; - break; - } - CODE_CODE_B => - { - code_set = CODE_CODE_B; - break; - } - CODE_CODE_C => - { - code_set = CODE_CODE_C; - break; - } - CODE_STOP => - { - done = true; - break; - } - } - } - break; - } - CODE_CODE_B => - { - if code < 96 { - if shift_upper_mode == upper_mode { - result.append((' ' + code) as char); - } else { - result.append((' ' + code + 128) as char); - } - shift_upper_mode = false; - } else { - if code != CODE_STOP { - last_character_was_printable = false; - } - match code { - CODE_FNC_1 => - { - if result.length() == 0 { - // FNC1 at first or second character determines the symbology - symbology_modifier = 1; - } else if result.length() == 1 { - symbology_modifier = 2; - } - if convert_f_n_c1 { - if result.length() == 0 { - // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code - // is FNC1 then this is GS1-128. We add the symbology identifier. - result.append("]C1"); - } else { - // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) - result.append(29 as char); - } - } - break; - } - CODE_FNC_2 => - { - symbology_modifier = 4; - break; - } - CODE_FNC_3 => - { - // do nothing? - break; - } - CODE_FNC_4_B => - { - if !upper_mode && shift_upper_mode { - upper_mode = true; - shift_upper_mode = false; - } else if upper_mode && shift_upper_mode { - upper_mode = false; - shift_upper_mode = false; - } else { - shift_upper_mode = true; - } - break; - } - CODE_SHIFT => - { - is_next_shifted = true; - code_set = CODE_CODE_A; - break; - } - CODE_CODE_A => - { - code_set = CODE_CODE_A; - break; - } - CODE_CODE_C => - { - code_set = CODE_CODE_C; - break; - } - CODE_STOP => - { - done = true; - break; - } - } - } - break; - } - CODE_CODE_C => - { - if code < 100 { - if code < 10 { - result.append('0'); - } - result.append(code); - } else { - if code != CODE_STOP { - last_character_was_printable = false; - } - match code { - CODE_FNC_1 => - { - if result.length() == 0 { - // FNC1 at first or second character determines the symbology - symbology_modifier = 1; - } else if result.length() == 1 { - symbology_modifier = 2; - } - if convert_f_n_c1 { - if result.length() == 0 { - // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code - // is FNC1 then this is GS1-128. We add the symbology identifier. - result.append("]C1"); - } else { - // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) - result.append(29 as char); - } - } - break; - } - CODE_CODE_A => - { - code_set = CODE_CODE_A; - break; - } - CODE_CODE_B => - { - code_set = CODE_CODE_B; - break; - } - CODE_STOP => - { - done = true; - break; - } - } - } - break; - } - } - // Unshift back to another code set if we were shifted - if unshift { - code_set = if code_set == CODE_CODE_A { CODE_CODE_B } else { CODE_CODE_A }; - } - } - let last_pattern_size: i32 = next_start - last_start; - // Check for ample whitespace following pattern, but, to do this we first need to remember that - // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left - // to read off. Would be slightly better to properly read. Here we just skip it: - next_start = row.get_next_unset(next_start); - if !row.is_range(next_start, &Math::min(&row.get_size(), next_start + (next_start - last_start) / 2), false) { - throw NotFoundException::get_not_found_instance(); - } - // Pull out from sum the value of the penultimate check code - checksum_total -= multiplier * last_code; - // lastCode is the checksum then: - if checksum_total % 103 != last_code { - throw ChecksumException::get_checksum_instance(); - } - // Need to pull out the check digits from string - let result_length: i32 = result.length(); - if result_length == 0 { - // false positive - throw NotFoundException::get_not_found_instance(); - } - // be a printable character. If it was just interpreted as a control code, nothing to remove. - if result_length > 0 && last_character_was_printable { - if code_set == CODE_CODE_C { - result.delete(result_length - 2, result_length); - } else { - result.delete(result_length - 1, result_length); - } - } - let left: f32 = (start_pattern_info[1] + start_pattern_info[0]) / 2.0f; - let right: f32 = last_start + last_pattern_size / 2.0f; - let raw_codes_size: i32 = raw_codes.size(); - let raw_bytes: [i8; raw_codes_size] = [0; raw_codes_size]; - { - let mut i: i32 = 0; - while i < raw_codes_size { - { - raw_bytes[i] = raw_codes.get(i); - } - i += 1; - } - } - - let result_object: Result = Result::new(&result.to_string(), &raw_bytes, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] - , BarcodeFormat::CODE_128); - result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]C{}", symbology_modifier)); - return Ok(result_object); - } -} - diff --git a/port_src/output/zxing/oned/code128_writer.rs b/port_src/output/zxing/oned/code128_writer.rs deleted file mode 100644 index f87719c..0000000 --- a/port_src/output/zxing/oned/code128_writer.rs +++ /dev/null @@ -1,661 +0,0 @@ -/* - * Copyright 2010 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::oned; - -/** - * This object renders a CODE128 code as a {@link BitMatrix}. - * - * @author erik.barbara@gmail.com (Erik Barbara) - */ - - const CODE_START_A: i32 = 103; - - const CODE_START_B: i32 = 104; - - const CODE_START_C: i32 = 105; - - const CODE_CODE_A: i32 = 101; - - const CODE_CODE_B: i32 = 100; - - const CODE_CODE_C: i32 = 99; - - const CODE_STOP: i32 = 106; - -// Dummy characters used to specify control characters in input - const ESCAPE_FNC_1: char = 'ñ'; - - const ESCAPE_FNC_2: char = 'ò'; - - const ESCAPE_FNC_3: char = 'ó'; - - const ESCAPE_FNC_4: char = 'ô'; - -// Code A, Code B, Code C - const CODE_FNC_1: i32 = 102; - -// Code A, Code B - const CODE_FNC_2: i32 = 97; - -// Code A, Code B - const CODE_FNC_3: i32 = 96; - -// Code A - const CODE_FNC_4_A: i32 = 101; - -// Code B - const CODE_FNC_4_B: i32 = 100; -pub struct Code128Writer { - super: OneDimensionalCodeWriter; -} - -impl Code128Writer { - - // Results of minimal lookahead for code C - enum CType { - - UNCODABLE(), ONE_DIGIT(), TWO_DIGITS(), FNC_1() - } - - pub fn get_supported_write_formats(&self) -> Collection { - return Collections::singleton(BarcodeFormat::CODE_128); - } - - pub fn encode(&self, contents: &String) -> Vec { - return self.encode(&contents, null); - } - - pub fn encode(&self, contents: &String, hints: &Map) -> Vec { - let forced_code_set: i32 = ::check(&contents, &hints); - let has_compaction_hint: bool = hints != null && hints.contains_key(EncodeHintType::CODE128_COMPACT) && Boolean::parse_boolean(&hints.get(EncodeHintType::CODE128_COMPACT).to_string()); - return if has_compaction_hint { MinimalEncoder::new().encode(&contents) } else { ::encode_fast(&contents, forced_code_set) }; - } - - fn check( contents: &String, hints: &Map) -> i32 { - let length: i32 = contents.length(); - // Check length - if length < 1 || length > 80 { - throw IllegalArgumentException::new(format!("Contents length should be between 1 and 80 characters, but got {}", length)); - } - // Check for forced code set hint. - let forced_code_set: i32 = -1; - if hints != null && hints.contains_key(EncodeHintType::FORCE_CODE_SET) { - let code_set_hint: String = hints.get(EncodeHintType::FORCE_CODE_SET).to_string(); - match code_set_hint { - "A" => - { - forced_code_set = CODE_CODE_A; - break; - } - "B" => - { - forced_code_set = CODE_CODE_B; - break; - } - "C" => - { - forced_code_set = CODE_CODE_C; - break; - } - _ => - { - throw IllegalArgumentException::new(format!("Unsupported code set hint: {}", code_set_hint)); - } - } - } - // Check content - { - let mut i: i32 = 0; - while i < length { - { - let c: char = contents.char_at(i); - // check for non ascii characters that are not special GS1 characters - match c { - // special function characters - ESCAPE_FNC_1 => - { - } - ESCAPE_FNC_2 => - { - } - ESCAPE_FNC_3 => - { - } - ESCAPE_FNC_4 => - { - break; - } - // non ascii characters - _ => - { - if c > 127 { - // shift and manual code change are not supported - throw IllegalArgumentException::new(format!("Bad character in input: ASCII value={}", c as i32)); - } - } - } - // check characters for compatibility with forced code set - match forced_code_set { - CODE_CODE_A => - { - // allows no ascii above 95 (no lower caps, no special symbols) - if c > 95 && c <= 127 { - throw IllegalArgumentException::new(format!("Bad character in input for forced code set A: ASCII value={}", c as i32)); - } - break; - } - CODE_CODE_B => - { - // allows no ascii below 32 (terminal symbols) - if c <= 32 { - throw IllegalArgumentException::new(format!("Bad character in input for forced code set B: ASCII value={}", c as i32)); - } - break; - } - CODE_CODE_C => - { - // allows only numbers and no FNC 2/3/4 - if c < 48 || (c > 57 && c <= 127) || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 { - throw IllegalArgumentException::new(format!("Bad character in input for forced code set C: ASCII value={}", c as i32)); - } - break; - } - } - } - i += 1; - } - } - - return forced_code_set; - } - - fn encode_fast( contents: &String, forced_code_set: i32) -> Vec { - let length: i32 = contents.length(); - // temporary storage for patterns - let patterns: Collection> = ArrayList<>::new(); - let check_sum: i32 = 0; - let check_weight: i32 = 1; - // selected code (CODE_CODE_B or CODE_CODE_C) - let code_set: i32 = 0; - // position in contents - let mut position: i32 = 0; - while position < length { - //Select code to use - let new_code_set: i32; - if forced_code_set == -1 { - new_code_set = ::choose_code(&contents, position, code_set); - } else { - new_code_set = forced_code_set; - } - //Get the pattern index - let pattern_index: i32; - if new_code_set == code_set { - // First handle escapes - match contents.char_at(position) { - ESCAPE_FNC_1 => - { - pattern_index = CODE_FNC_1; - break; - } - ESCAPE_FNC_2 => - { - pattern_index = CODE_FNC_2; - break; - } - ESCAPE_FNC_3 => - { - pattern_index = CODE_FNC_3; - break; - } - ESCAPE_FNC_4 => - { - if code_set == CODE_CODE_A { - pattern_index = CODE_FNC_4_A; - } else { - pattern_index = CODE_FNC_4_B; - } - break; - } - _ => - { - // Then handle normal characters otherwise - match code_set { - CODE_CODE_A => - { - pattern_index = contents.char_at(position) - ' '; - if pattern_index < 0 { - // everything below a space character comes behind the underscore in the code patterns table - pattern_index += '`'; - } - break; - } - CODE_CODE_B => - { - pattern_index = contents.char_at(position) - ' '; - break; - } - _ => - { - // CODE_CODE_C - if position + 1 == length { - // this is the last character, but the encoding is C, which always encodes two characers - throw IllegalArgumentException::new("Bad number of characters for digit only encoding."); - } - pattern_index = Integer::parse_int(&contents.substring(position, position + 2)); - // Also incremented below - position += 1; - break; - } - } - } - } - position += 1; - } else { - // Do we have a code set? - if code_set == 0 { - // No, we don't have a code set - match new_code_set { - CODE_CODE_A => - { - pattern_index = CODE_START_A; - break; - } - CODE_CODE_B => - { - pattern_index = CODE_START_B; - break; - } - _ => - { - pattern_index = CODE_START_C; - break; - } - } - } else { - // Yes, we have a code set - pattern_index = new_code_set; - } - code_set = new_code_set; - } - // Get the pattern - patterns.add(Code128Reader::CODE_PATTERNS[pattern_index]); - // Compute checksum - check_sum += pattern_index * check_weight; - if position != 0 { - check_weight += 1; - } - } - return ::produce_result(&patterns, check_sum); - } - - fn produce_result( patterns: &Collection>, check_sum: i32) -> Vec { - // Compute and append checksum - check_sum %= 103; - patterns.add(Code128Reader::CODE_PATTERNS[check_sum]); - // Append stop code - patterns.add(Code128Reader::CODE_PATTERNS[CODE_STOP]); - // Compute code width - let code_width: i32 = 0; - for let pattern: Vec in patterns { - for let width: i32 in pattern { - code_width += width; - } - } - // Compute result - let result: [bool; code_width] = [false; code_width]; - let mut pos: i32 = 0; - for let pattern: Vec in patterns { - pos += append_pattern(&result, pos, &pattern, true); - } - return result; - } - - fn find_c_type( value: &CharSequence, start: i32) -> CType { - let last: i32 = value.length(); - if start >= last { - return CType.UNCODABLE; - } - let mut c: char = value.char_at(start); - if c == ESCAPE_FNC_1 { - return CType.FNC_1; - } - if c < '0' || c > '9' { - return CType.UNCODABLE; - } - if start + 1 >= last { - return CType.ONE_DIGIT; - } - c = value.char_at(start + 1); - if c < '0' || c > '9' { - return CType.ONE_DIGIT; - } - return CType.TWO_DIGITS; - } - - fn choose_code( value: &CharSequence, start: i32, old_code: i32) -> i32 { - let mut lookahead: CType = ::find_c_type(&value, start); - if lookahead == CType.ONE_DIGIT { - if old_code == CODE_CODE_A { - return CODE_CODE_A; - } - return CODE_CODE_B; - } - if lookahead == CType.UNCODABLE { - if start < value.length() { - let c: char = value.char_at(start); - if c < ' ' || (old_code == CODE_CODE_A && (c < '`' || (c >= ESCAPE_FNC_1 && c <= ESCAPE_FNC_4))) { - // can continue in code A, encodes ASCII 0 to 95 or FNC1 to FNC4 - return CODE_CODE_A; - } - } - // no choice - return CODE_CODE_B; - } - if old_code == CODE_CODE_A && lookahead == CType.FNC_1 { - return CODE_CODE_A; - } - if old_code == CODE_CODE_C { - // can continue in code C - return CODE_CODE_C; - } - if old_code == CODE_CODE_B { - if lookahead == CType.FNC_1 { - // can continue in code B - return CODE_CODE_B; - } - // Seen two consecutive digits, see what follows - lookahead = ::find_c_type(&value, start + 2); - if lookahead == CType.UNCODABLE || lookahead == CType.ONE_DIGIT { - // not worth switching now - return CODE_CODE_B; - } - if lookahead == CType.FNC_1 { - // two digits, then FNC_1... - lookahead = ::find_c_type(&value, start + 3); - if lookahead == CType.TWO_DIGITS { - // then two more digits, switch - return CODE_CODE_C; - } else { - // otherwise not worth switching - return CODE_CODE_B; - } - } - // At this point, there are at least 4 consecutive digits. - // Look ahead to choose whether to switch now or on the next round. - let mut index: i32 = start + 4; - while (lookahead = ::find_c_type(&value, index)) == CType.TWO_DIGITS { - index += 2; - } - if lookahead == CType.ONE_DIGIT { - // odd number of digits, switch later - return CODE_CODE_B; - } - // even number of digits, switch now - return CODE_CODE_C; - } - // Here oldCode == 0, which means we are choosing the initial code - if lookahead == CType.FNC_1 { - // ignore FNC_1 - lookahead = ::find_c_type(&value, start + 1); - } - if lookahead == CType.TWO_DIGITS { - // at least two digits, start in code C - return CODE_CODE_C; - } - return CODE_CODE_B; - } - - /** - * Encodes minimally using Divide-And-Conquer with Memoization - **/ - - const A: &'static str = format!(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ \n \rÿ"); - - const B: &'static str = format!(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÿ"); - - const CODE_SHIFT: i32 = 98; - struct MinimalEncoder { - - let memoized_cost: Vec>; - - let min_path: Vec>; - } - - impl MinimalEncoder { - - enum Charset { - - A(), B(), C(), NONE() - } - - enum Latch { - - A(), B(), C(), SHIFT(), NONE() - } - - fn encode(&self, contents: &String) -> Vec { - self.memoized_cost = : [[i32; contents.length()]; 4] = [[0; contents.length()]; 4]; - self.min_path = : [[Option; contents.length()]; 4] = [[None; contents.length()]; 4]; - self.encode(&contents, Charset::NONE, 0); - let patterns: Collection> = ArrayList<>::new(); - let check_sum : vec![i32; 1] = vec![0, ] - ; - let check_weight : vec![i32; 1] = vec![1, ] - ; - let length: i32 = contents.length(); - let mut charset: Charset = Charset::NONE; - { - let mut i: i32 = 0; - while i < length { - { - let latch: Latch = self.min_path[charset.ordinal()][i]; - match latch { - A => - { - charset = Charset::A; - ::add_pattern(&patterns, if i == 0 { CODE_START_A } else { CODE_CODE_A }, &check_sum, &check_weight, i); - break; - } - B => - { - charset = Charset::B; - ::add_pattern(&patterns, if i == 0 { CODE_START_B } else { CODE_CODE_B }, &check_sum, &check_weight, i); - break; - } - C => - { - charset = Charset::C; - ::add_pattern(&patterns, if i == 0 { CODE_START_C } else { CODE_CODE_C }, &check_sum, &check_weight, i); - break; - } - SHIFT => - { - ::add_pattern(&patterns, CODE_SHIFT, &check_sum, &check_weight, i); - break; - } - } - if charset == Charset::C { - if contents.char_at(i) == ESCAPE_FNC_1 { - ::add_pattern(&patterns, CODE_FNC_1, &check_sum, &check_weight, i); - } else { - ::add_pattern(&patterns, &Integer::parse_int(&contents.substring(i, i + 2)), &check_sum, &check_weight, i); - //the algorithm never leads to a single trailing digit in character set C - assert!( i + 1 < length); - if i + 1 < length { - i += 1; - } - } - } else { - // charset A or B - let pattern_index: i32; - match contents.char_at(i) { - ESCAPE_FNC_1 => - { - pattern_index = CODE_FNC_1; - break; - } - ESCAPE_FNC_2 => - { - pattern_index = CODE_FNC_2; - break; - } - ESCAPE_FNC_3 => - { - pattern_index = CODE_FNC_3; - break; - } - ESCAPE_FNC_4 => - { - if (charset == Charset::A && latch != Latch::SHIFT) || (charset == Charset::B && latch == Latch::SHIFT) { - pattern_index = CODE_FNC_4_A; - } else { - pattern_index = CODE_FNC_4_B; - } - break; - } - _ => - { - pattern_index = contents.char_at(i) - ' '; - } - } - if (charset == Charset::A && latch != Latch::SHIFT) || (charset == Charset::B && latch == Latch::SHIFT) { - if pattern_index < 0 { - pattern_index += '`'; - } - } - ::add_pattern(&patterns, pattern_index, &check_sum, &check_weight, i); - } - } - i += 1; - } - } - - self.memoized_cost = null; - self.min_path = null; - return ::produce_result(&patterns, check_sum[0]); - } - - fn add_pattern( patterns: &Collection>, pattern_index: i32, check_sum: &Vec, check_weight: &Vec, position: i32) { - patterns.add(Code128Reader::CODE_PATTERNS[pattern_index]); - if position != 0 { - check_weight[0] += 1; - } - check_sum[0] += pattern_index * check_weight[0]; - } - - fn is_digit( c: char) -> bool { - return c >= '0' && c <= '9'; - } - - fn can_encode(&self, contents: &CharSequence, charset: &Charset, position: i32) -> bool { - let c: char = contents.char_at(position); - match charset { - A => - { - return c == ESCAPE_FNC_1 || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 || A::index_of(c) >= 0; - } - B => - { - return c == ESCAPE_FNC_1 || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 || B::index_of(c) >= 0; - } - C => - { - return c == ESCAPE_FNC_1 || (position + 1 < contents.length() && ::is_digit(c) && ::is_digit(&contents.char_at(position + 1))); - } - _ => - { - return false; - } - } - } - - /** - * Encode the string starting at position position starting with the character set charset - **/ - fn encode(&self, contents: &CharSequence, charset: &Charset, position: i32) -> i32 { - assert!( position < contents.length()); - let m_cost: i32 = self.memoized_cost[charset.ordinal()][position]; - if m_cost > 0 { - return m_cost; - } - let min_cost: i32 = Integer::MAX_VALUE; - let min_latch: Latch = Latch::NONE; - let at_end: bool = position + 1 >= contents.length(); - let sets : vec![Charset; 2] = vec![Charset::A, Charset::B, ] - ; - { - let mut i: i32 = 0; - while i <= 1 { - { - if self.can_encode(&contents, sets[i], position) { - let mut cost: i32 = 1; - let mut latch: Latch = Latch::NONE; - if charset != sets[i] { - cost += 1; - latch = Latch::value_of(&sets[i].to_string()); - } - if !at_end { - cost += self.encode(&contents, sets[i], position + 1); - } - if cost < min_cost { - min_cost = cost; - min_latch = latch; - } - cost = 1; - if charset == sets[(i + 1) % 2] { - cost += 1; - latch = Latch::SHIFT; - if !at_end { - cost += self.encode(&contents, charset, position + 1); - } - if cost < min_cost { - min_cost = cost; - min_latch = latch; - } - } - } - } - i += 1; - } - } - - if self.can_encode(&contents, Charset::C, position) { - let mut cost: i32 = 1; - let mut latch: Latch = Latch::NONE; - if charset != Charset::C { - cost += 1; - latch = Latch::C; - } - let advance: i32 = if contents.char_at(position) == ESCAPE_FNC_1 { 1 } else { 2 }; - if position + advance < contents.length() { - cost += self.encode(&contents, Charset::C, position + advance); - } - if cost < min_cost { - min_cost = cost; - min_latch = latch; - } - } - if min_cost == Integer::MAX_VALUE { - throw IllegalArgumentException::new(format!("Bad character in input: ASCII value={}", contents.char_at(position) as i32)); - } - self.memoized_cost[charset.ordinal()][position] = min_cost; - self.min_path[charset.ordinal()][position] = min_latch; - return min_cost; - } - } - -} - diff --git a/port_src/output/zxing/oned/code39_reader.rs b/port_src/output/zxing/oned/code39_reader.rs deleted file mode 100644 index 78a038a..0000000 --- a/port_src/output/zxing/oned/code39_reader.rs +++ /dev/null @@ -1,401 +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::oned; - -/** - *

Decodes Code 39 barcodes. Supports "Full ASCII Code 39" if USE_CODE_39_EXTENDED_MODE is set.

- * - * @author Sean Owen - * @see Code93Reader - */ - - const ALPHABET_STRING: &'static str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; - -/** - * These represent the encodings of characters, as patterns of wide and narrow bars. - * The 9 least-significant bits of each int correspond to the pattern of wide and narrow, - * with 1s representing "wide" and 0s representing narrow. - */ - const CHARACTER_ENCODINGS: vec![Vec; 43] = vec![// 0-9 -0x034, // 0-9 -0x121, // 0-9 -0x061, // 0-9 -0x160, // 0-9 -0x031, // 0-9 -0x130, // 0-9 -0x070, // 0-9 -0x025, // 0-9 -0x124, // 0-9 -0x064, // A-J -0x109, // A-J -0x049, // A-J -0x148, // A-J -0x019, // A-J -0x118, // A-J -0x058, // A-J -0x00D, // A-J -0x10C, // A-J -0x04C, // A-J -0x01C, // K-T -0x103, // K-T -0x043, // K-T -0x142, // K-T -0x013, // K-T -0x112, // K-T -0x052, // K-T -0x007, // K-T -0x106, // K-T -0x046, // K-T -0x016, // U-$ -0x181, // U-$ -0x0C1, // U-$ -0x1C0, // U-$ -0x091, // U-$ -0x190, // U-$ -0x0D0, // U-$ -0x085, // U-$ -0x184, // U-$ -0x0C4, // U-$ -0x0A8, // /-% -0x0A2, // /-% -0x08A, // /-% -0x02A, ] -; - - const ASTERISK_ENCODING: i32 = 0x094; -pub struct Code39Reader { - super: OneDReader; - - let using_check_digit: bool; - - let extended_mode: bool; - - let decode_row_result: StringBuilder; - - let mut counters: Vec; -} - -impl Code39Reader { - - /** - * Creates a reader that assumes all encoded data is data, and does not treat the final - * character as a check digit. It will not decoded "extended Code 39" sequences. - */ - pub fn new() -> Code39Reader { - this(false); - } - - /** - * Creates a reader that can be configured to check the last character as a check digit. - * It will not decoded "extended Code 39" sequences. - * - * @param usingCheckDigit if true, treat the last data character as a check digit, not - * data, and verify that the checksum passes. - */ - pub fn new( using_check_digit: bool) -> Code39Reader { - this(using_check_digit, false); - } - - /** - * Creates a reader that can be configured to check the last character as a check digit, - * or optionally attempt to decode "extended Code 39" sequences that are used to encode - * the full ASCII character set. - * - * @param usingCheckDigit if true, treat the last data character as a check digit, not - * data, and verify that the checksum passes. - * @param extendedMode if true, will attempt to decode extended Code 39 sequences in the - * text. - */ - pub fn new( using_check_digit: bool, extended_mode: bool) -> Code39Reader { - let .usingCheckDigit = using_check_digit; - let .extendedMode = extended_mode; - decode_row_result = StringBuilder::new(20); - counters = : [i32; 9] = [0; 9]; - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { - let the_counters: Vec = self.counters; - Arrays::fill(&the_counters, 0); - let result: StringBuilder = self.decode_row_result; - result.set_length(0); - let start: Vec = ::find_asterisk_pattern(row, &the_counters); - // Read off white space - let next_start: i32 = row.get_next_set(start[1]); - let end: i32 = row.get_size(); - let decoded_char: char; - let last_start: i32; - loop { { - record_pattern(row, next_start, &the_counters); - let pattern: i32 = ::to_narrow_wide_pattern(&the_counters); - if pattern < 0 { - throw NotFoundException::get_not_found_instance(); - } - decoded_char = ::pattern_to_char(pattern); - result.append(decoded_char); - last_start = next_start; - for let counter: i32 in the_counters { - next_start += counter; - } - // Read off white space - next_start = row.get_next_set(next_start); - }if !(decoded_char != '*') break;} - // remove asterisk - result.set_length(result.length() - 1); - // Look for whitespace after pattern: - let last_pattern_size: i32 = 0; - for let counter: i32 in the_counters { - last_pattern_size += counter; - } - let white_space_after_end: i32 = next_start - last_start - last_pattern_size; - // (but if it's whitespace to the very end of the image, that's OK) - if next_start != end && (white_space_after_end * 2) < last_pattern_size { - throw NotFoundException::get_not_found_instance(); - } - if self.using_check_digit { - let max: i32 = result.length() - 1; - let mut total: i32 = 0; - { - let mut i: i32 = 0; - while i < max { - { - total += ALPHABET_STRING::index_of(&self.decode_row_result.char_at(i)); - } - i += 1; - } - } - - if result.char_at(max) != ALPHABET_STRING::char_at(total % 43) { - throw ChecksumException::get_checksum_instance(); - } - result.set_length(max); - } - if result.length() == 0 { - // false positive - throw NotFoundException::get_not_found_instance(); - } - let result_string: String; - if self.extended_mode { - result_string = ::decode_extended(&result); - } else { - result_string = result.to_string(); - } - let left: f32 = (start[1] + start[0]) / 2.0f; - let right: f32 = last_start + last_pattern_size / 2.0f; - let result_object: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] - , BarcodeFormat::CODE_39); - result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]A0"); - return Ok(result_object); - } - - fn find_asterisk_pattern( row: &BitArray, counters: &Vec) -> /* throws NotFoundException */Result, Rc> { - let width: i32 = row.get_size(); - let row_offset: i32 = row.get_next_set(0); - let counter_position: i32 = 0; - let pattern_start: i32 = row_offset; - let is_white: bool = false; - let pattern_length: i32 = counters.len(); - { - let mut i: i32 = row_offset; - while i < width { - { - if row.get(i) != is_white { - counters[counter_position] += 1; - } else { - if counter_position == pattern_length - 1 { - // Look for whitespace before start pattern, >= 50% of width of start pattern - if ::to_narrow_wide_pattern(&counters) == ASTERISK_ENCODING && row.is_range(&Math::max(0, pattern_start - ((i - pattern_start) / 2)), pattern_start, false) { - return Ok( : vec![i32; 2] = vec![pattern_start, i, ] - ); - } - pattern_start += counters[0] + counters[1]; - System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); - counters[counter_position - 1] = 0; - counters[counter_position] = 0; - counter_position -= 1; - } else { - counter_position += 1; - } - counters[counter_position] = 1; - is_white = !is_white; - } - } - i += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - // For efficiency, returns -1 on failure. Not throwing here saved as many as 700 exceptions - // per image when using some of our blackbox images. - fn to_narrow_wide_pattern( counters: &Vec) -> i32 { - let num_counters: i32 = counters.len(); - let max_narrow_counter: i32 = 0; - let wide_counters: i32; - loop { { - let min_counter: i32 = Integer::MAX_VALUE; - for let counter: i32 in counters { - if counter < min_counter && counter > max_narrow_counter { - min_counter = counter; - } - } - max_narrow_counter = min_counter; - wide_counters = 0; - let total_wide_counters_width: i32 = 0; - let mut pattern: i32 = 0; - { - let mut i: i32 = 0; - while i < num_counters { - { - let counter: i32 = counters[i]; - if counter > max_narrow_counter { - pattern |= 1 << (num_counters - 1 - i); - wide_counters += 1; - total_wide_counters_width += counter; - } - } - i += 1; - } - } - - if wide_counters == 3 { - // counter is more than 1.5 times the average: - { - let mut i: i32 = 0; - while i < num_counters && wide_counters > 0 { - { - let counter: i32 = counters[i]; - if counter > max_narrow_counter { - wide_counters -= 1; - // totalWideCountersWidth = 3 * average, so this checks if counter >= 3/2 * average - if (counter * 2) >= total_wide_counters_width { - return -1; - } - } - } - i += 1; - } - } - - return pattern; - } - }if !(wide_counters > 3) break;} - return -1; - } - - fn pattern_to_char( pattern: i32) -> /* throws NotFoundException */Result> { - { - let mut i: i32 = 0; - while i < CHARACTER_ENCODINGS.len() { - { - if CHARACTER_ENCODINGS[i] == pattern { - return Ok(ALPHABET_STRING::char_at(i)); - } - } - i += 1; - } - } - - if pattern == ASTERISK_ENCODING { - return Ok('*'); - } - throw NotFoundException::get_not_found_instance(); - } - - fn decode_extended( encoded: &CharSequence) -> /* throws FormatException */Result> { - let length: i32 = encoded.length(); - let decoded: StringBuilder = StringBuilder::new(length); - { - let mut i: i32 = 0; - while i < length { - { - let c: char = encoded.char_at(i); - if c == '+' || c == '$' || c == '%' || c == '/' { - let next: char = encoded.char_at(i + 1); - let decoded_char: char = '\0'; - match c { - '+' => - { - // +A to +Z map to a to z - if next >= 'A' && next <= 'Z' { - decoded_char = (next + 32) as char; - } else { - throw FormatException::get_format_instance(); - } - break; - } - '$' => - { - // $A to $Z map to control codes SH to SB - if next >= 'A' && next <= 'Z' { - decoded_char = (next - 64) as char; - } else { - throw FormatException::get_format_instance(); - } - break; - } - '%' => - { - // %A to %E map to control codes ESC to US - if next >= 'A' && next <= 'E' { - decoded_char = (next - 38) as char; - } else if next >= 'F' && next <= 'J' { - decoded_char = (next - 11) as char; - } else if next >= 'K' && next <= 'O' { - decoded_char = (next + 16) as char; - } else if next >= 'P' && next <= 'T' { - decoded_char = (next + 43) as char; - } else if next == 'U' { - decoded_char = 0 as char; - } else if next == 'V' { - decoded_char = '@'; - } else if next == 'W' { - decoded_char = '`'; - } else if next == 'X' || next == 'Y' || next == 'Z' { - decoded_char = 127 as char; - } else { - throw FormatException::get_format_instance(); - } - break; - } - '/' => - { - // /A to /O map to ! to , and /Z maps to : - if next >= 'A' && next <= 'O' { - decoded_char = (next - 32) as char; - } else if next == 'Z' { - decoded_char = ':'; - } else { - throw FormatException::get_format_instance(); - } - break; - } - } - decoded.append(decoded_char); - // bump up i again since we read two characters - i += 1; - } else { - decoded.append(c); - } - } - i += 1; - } - } - - return Ok(decoded.to_string()); - } -} - diff --git a/port_src/output/zxing/oned/code39_writer.rs b/port_src/output/zxing/oned/code39_writer.rs deleted file mode 100644 index ff4337e..0000000 Binary files a/port_src/output/zxing/oned/code39_writer.rs and /dev/null differ diff --git a/port_src/output/zxing/oned/code93_reader.rs b/port_src/output/zxing/oned/code93_reader.rs deleted file mode 100644 index 1d5c0a5..0000000 --- a/port_src/output/zxing/oned/code93_reader.rs +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2010 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::oned; - -/** - *

Decodes Code 93 barcodes.

- * - * @author Sean Owen - * @see Code39Reader - */ - -// Note that 'abcd' are dummy characters in place of control characters. - const ALPHABET_STRING: &'static str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*"; - - const ALPHABET: Vec = ALPHABET_STRING::to_char_array(); - -/** - * These represent the encodings of characters, as patterns of wide and narrow bars. - * The 9 least-significant bits of each int correspond to the pattern of wide and narrow. - */ - const CHARACTER_ENCODINGS: vec![Vec; 48] = vec![// 0-9 -0x114, // 0-9 -0x148, // 0-9 -0x144, // 0-9 -0x142, // 0-9 -0x128, // 0-9 -0x124, // 0-9 -0x122, // 0-9 -0x150, // 0-9 -0x112, // 0-9 -0x10A, // A-J -0x1A8, // A-J -0x1A4, // A-J -0x1A2, // A-J -0x194, // A-J -0x192, // A-J -0x18A, // A-J -0x168, // A-J -0x164, // A-J -0x162, // A-J -0x134, // K-T -0x11A, // K-T -0x158, // K-T -0x14C, // K-T -0x146, // K-T -0x12C, // K-T -0x116, // K-T -0x1B4, // K-T -0x1B2, // K-T -0x1AC, // K-T -0x1A6, // U-Z -0x196, // U-Z -0x19A, // U-Z -0x16C, // U-Z -0x166, // U-Z -0x136, // U-Z -0x13A, // - - % -0x12E, // - - % -0x1D4, // - - % -0x1D2, // - - % -0x1CA, // - - % -0x16E, // - - % -0x176, // - - % -0x1AE, // Control chars? $-* -0x126, // Control chars? $-* -0x1DA, // Control chars? $-* -0x1D6, // Control chars? $-* -0x132, // Control chars? $-* -0x15E, ] -; - - const ASTERISK_ENCODING: i32 = CHARACTER_ENCODINGS[47]; -pub struct Code93Reader { - super: OneDReader; - - let decode_row_result: StringBuilder; - - let mut counters: Vec; -} - -impl Code93Reader { - - pub fn new() -> Code93Reader { - decode_row_result = StringBuilder::new(20); - counters = : [i32; 6] = [0; 6]; - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { - let start: Vec = self.find_asterisk_pattern(row); - // Read off white space - let next_start: i32 = row.get_next_set(start[1]); - let end: i32 = row.get_size(); - let the_counters: Vec = self.counters; - Arrays::fill(&the_counters, 0); - let result: StringBuilder = self.decode_row_result; - result.set_length(0); - let decoded_char: char; - let last_start: i32; - loop { { - record_pattern(row, next_start, &the_counters); - let pattern: i32 = ::to_pattern(&the_counters); - if pattern < 0 { - throw NotFoundException::get_not_found_instance(); - } - decoded_char = ::pattern_to_char(pattern); - result.append(decoded_char); - last_start = next_start; - for let counter: i32 in the_counters { - next_start += counter; - } - // Read off white space - next_start = row.get_next_set(next_start); - }if !(decoded_char != '*') break;} - // remove asterisk - result.delete_char_at(result.length() - 1); - let last_pattern_size: i32 = 0; - for let counter: i32 in the_counters { - last_pattern_size += counter; - } - // Should be at least one more black module - if next_start == end || !row.get(next_start) { - throw NotFoundException::get_not_found_instance(); - } - if result.length() < 2 { - // false positive -- need at least 2 checksum digits - throw NotFoundException::get_not_found_instance(); - } - ::check_checksums(&result); - // Remove checksum digits - result.set_length(result.length() - 2); - let result_string: String = ::decode_extended(&result); - let left: f32 = (start[1] + start[0]) / 2.0f; - let right: f32 = last_start + last_pattern_size / 2.0f; - let result_object: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] - , BarcodeFormat::CODE_93); - result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]G0"); - return Ok(result_object); - } - - fn find_asterisk_pattern(&self, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { - let width: i32 = row.get_size(); - let row_offset: i32 = row.get_next_set(0); - Arrays::fill(&self.counters, 0); - let the_counters: Vec = self.counters; - let pattern_start: i32 = row_offset; - let is_white: bool = false; - let pattern_length: i32 = the_counters.len(); - let counter_position: i32 = 0; - { - let mut i: i32 = row_offset; - while i < width { - { - if row.get(i) != is_white { - the_counters[counter_position] += 1; - } else { - if counter_position == pattern_length - 1 { - if ::to_pattern(&the_counters) == ASTERISK_ENCODING { - return Ok( : vec![i32; 2] = vec![pattern_start, i, ] - ); - } - pattern_start += the_counters[0] + the_counters[1]; - System::arraycopy(&the_counters, 2, &the_counters, 0, counter_position - 1); - the_counters[counter_position - 1] = 0; - the_counters[counter_position] = 0; - counter_position -= 1; - } else { - counter_position += 1; - } - the_counters[counter_position] = 1; - is_white = !is_white; - } - } - i += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - fn to_pattern( counters: &Vec) -> i32 { - let mut sum: i32 = 0; - for let counter: i32 in counters { - sum += counter; - } - let mut pattern: i32 = 0; - let max: i32 = counters.len(); - { - let mut i: i32 = 0; - while i < max { - { - let scaled: i32 = Math::round(counters[i] * 9.0f / sum); - if scaled < 1 || scaled > 4 { - return -1; - } - if (i & 0x01) == 0 { - { - let mut j: i32 = 0; - while j < scaled { - { - pattern = (pattern << 1) | 0x01; - } - j += 1; - } - } - - } else { - pattern <<= scaled; - } - } - i += 1; - } - } - - return pattern; - } - - fn pattern_to_char( pattern: i32) -> /* throws NotFoundException */Result> { - { - let mut i: i32 = 0; - while i < CHARACTER_ENCODINGS.len() { - { - if CHARACTER_ENCODINGS[i] == pattern { - return Ok(ALPHABET[i]); - } - } - i += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - fn decode_extended( encoded: &CharSequence) -> /* throws FormatException */Result> { - let length: i32 = encoded.length(); - let decoded: StringBuilder = StringBuilder::new(length); - { - let mut i: i32 = 0; - while i < length { - { - let c: char = encoded.char_at(i); - if c >= 'a' && c <= 'd' { - if i >= length - 1 { - throw FormatException::get_format_instance(); - } - let next: char = encoded.char_at(i + 1); - let decoded_char: char = '\0'; - match c { - 'd' => - { - // +A to +Z map to a to z - if next >= 'A' && next <= 'Z' { - decoded_char = (next + 32) as char; - } else { - throw FormatException::get_format_instance(); - } - break; - } - 'a' => - { - // $A to $Z map to control codes SH to SB - if next >= 'A' && next <= 'Z' { - decoded_char = (next - 64) as char; - } else { - throw FormatException::get_format_instance(); - } - break; - } - 'b' => - { - if next >= 'A' && next <= 'E' { - // %A to %E map to control codes ESC to USep - decoded_char = (next - 38) as char; - } else if next >= 'F' && next <= 'J' { - // %F to %J map to ; < = > ? - decoded_char = (next - 11) as char; - } else if next >= 'K' && next <= 'O' { - // %K to %O map to [ \ ] ^ _ - decoded_char = (next + 16) as char; - } else if next >= 'P' && next <= 'T' { - // %P to %T map to { | } ~ DEL - decoded_char = (next + 43) as char; - } else if next == 'U' { - // %U map to NUL - decoded_char = '\0'; - } else if next == 'V' { - // %V map to @ - decoded_char = '@'; - } else if next == 'W' { - // %W map to ` - decoded_char = '`'; - } else if next >= 'X' && next <= 'Z' { - // %X to %Z all map to DEL (127) - decoded_char = 127; - } else { - throw FormatException::get_format_instance(); - } - break; - } - 'c' => - { - // /A to /O map to ! to , and /Z maps to : - if next >= 'A' && next <= 'O' { - decoded_char = (next - 32) as char; - } else if next == 'Z' { - decoded_char = ':'; - } else { - throw FormatException::get_format_instance(); - } - break; - } - } - decoded.append(decoded_char); - // bump up i again since we read two characters - i += 1; - } else { - decoded.append(c); - } - } - i += 1; - } - } - - return Ok(decoded.to_string()); - } - - fn check_checksums( result: &CharSequence) -> /* throws ChecksumException */Result> { - let length: i32 = result.length(); - ::check_one_checksum(&result, length - 2, 20); - ::check_one_checksum(&result, length - 1, 15); - } - - fn check_one_checksum( result: &CharSequence, check_position: i32, weight_max: i32) -> /* throws ChecksumException */Result> { - let mut weight: i32 = 1; - let mut total: i32 = 0; - { - let mut i: i32 = check_position - 1; - while i >= 0 { - { - total += weight * ALPHABET_STRING::index_of(&result.char_at(i)); - if weight += 1 > weight_max { - weight = 1; - } - } - i -= 1; - } - } - - if result.char_at(check_position) != ALPHABET[total % 47] { - throw ChecksumException::get_checksum_instance(); - } - } -} - diff --git a/port_src/output/zxing/oned/code93_writer.rs b/port_src/output/zxing/oned/code93_writer.rs deleted file mode 100644 index 5c331ec..0000000 --- a/port_src/output/zxing/oned/code93_writer.rs +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2015 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::oned; - -/** - * This object renders a CODE93 code as a BitMatrix - */ -pub struct Code93Writer { - super: OneDimensionalCodeWriter; -} - -impl Code93Writer { - - pub fn get_supported_write_formats(&self) -> Collection { - return Collections::singleton(BarcodeFormat::CODE_93); - } - - /** - * @param contents barcode contents to encode. It should not be encoded for extended characters. - * @return a {@code boolean[]} of horizontal pixels (false = white, true = black) - */ - pub fn encode(&self, contents: &String) -> Vec { - contents = ::convert_to_extended(&contents); - let length: i32 = contents.length(); - if length > 80 { - throw IllegalArgumentException::new(format!("Requested contents should be less than 80 digits long after converting to extended encoding, but got {}", length)); - } - //length of code + 2 start/stop characters + 2 checksums, each of 9 bits, plus a termination bar - let code_width: i32 = (contents.length() + 2 + 2) * 9 + 1; - let mut result: [bool; code_width] = [false; code_width]; - //start character (*) - let mut pos: i32 = ::append_pattern(&result, 0, Code93Reader::ASTERISK_ENCODING); - { - let mut i: i32 = 0; - while i < length { - { - let index_in_string: i32 = Code93Reader::ALPHABET_STRING::index_of(&contents.char_at(i)); - pos += ::append_pattern(&result, pos, Code93Reader::CHARACTER_ENCODINGS[index_in_string]); - } - i += 1; - } - } - - //add two checksums - let check1: i32 = ::compute_checksum_index(&contents, 20); - pos += ::append_pattern(&result, pos, Code93Reader::CHARACTER_ENCODINGS[check1]); - //append the contents to reflect the first checksum added - contents += Code93Reader::ALPHABET_STRING::char_at(check1); - let check2: i32 = ::compute_checksum_index(&contents, 15); - pos += ::append_pattern(&result, pos, Code93Reader::CHARACTER_ENCODINGS[check2]); - //end character (*) - pos += ::append_pattern(&result, pos, Code93Reader::ASTERISK_ENCODING); - //termination bar (single black bar) - result[pos] = true; - return result; - } - - /** - * @param target output to append to - * @param pos start position - * @param pattern pattern to append - * @param startColor unused - * @return 9 - * @deprecated without replacement; intended as an internal-only method - */ - pub fn append_pattern( target: &Vec, pos: i32, pattern: &Vec, start_color: bool) -> i32 { - for let bit: i32 in pattern { - target[pos += 1 !!!check!!! post increment] = bit != 0; - } - return 9; - } - - fn append_pattern( target: &Vec, pos: i32, a: i32) -> i32 { - { - let mut i: i32 = 0; - while i < 9 { - { - let temp: i32 = a & (1 << (8 - i)); - target[pos + i] = temp != 0; - } - i += 1; - } - } - - return 9; - } - - fn compute_checksum_index( contents: &String, max_weight: i32) -> i32 { - let mut weight: i32 = 1; - let mut total: i32 = 0; - { - let mut i: i32 = contents.length() - 1; - while i >= 0 { - { - let index_in_string: i32 = Code93Reader::ALPHABET_STRING::index_of(&contents.char_at(i)); - total += index_in_string * weight; - if weight += 1 > max_weight { - weight = 1; - } - } - i -= 1; - } - } - - return total % 47; - } - - fn convert_to_extended( contents: &String) -> String { - let length: i32 = contents.length(); - let extended_content: StringBuilder = StringBuilder::new(length * 2); - { - let mut i: i32 = 0; - while i < length { - { - let character: char = contents.char_at(i); - // ($)=a, (%)=b, (/)=c, (+)=d. see Code93Reader.ALPHABET_STRING - if character == 0 { - // NUL: (%)U - extended_content.append("bU"); - } else if character <= 26 { - // SOH - SUB: ($)A - ($)Z - extended_content.append('a'); - extended_content.append(('A' + character - 1) as char); - } else if character <= 31 { - // ESC - US: (%)A - (%)E - extended_content.append('b'); - extended_content.append(('A' + character - 27) as char); - } else if character == ' ' || character == '$' || character == '%' || character == '+' { - // space $ % + - extended_content.append(character); - } else if character <= ',' { - // ! " # & ' ( ) * ,: (/)A - (/)L - extended_content.append('c'); - extended_content.append(('A' + character - '!') as char); - } else if character <= '9' { - extended_content.append(character); - } else if character == ':' { - // :: (/)Z - extended_content.append("cZ"); - } else if character <= '?' { - // ; - ?: (%)F - (%)J - extended_content.append('b'); - extended_content.append(('F' + character - ';') as char); - } else if character == '@' { - // @: (%)V - extended_content.append("bV"); - } else if character <= 'Z' { - // A - Z - extended_content.append(character); - } else if character <= '_' { - // [ - _: (%)K - (%)O - extended_content.append('b'); - extended_content.append(('K' + character - '[') as char); - } else if character == '`' { - // `: (%)W - extended_content.append("bW"); - } else if character <= 'z' { - // a - z: (*)A - (*)Z - extended_content.append('d'); - extended_content.append(('A' + character - 'a') as char); - } else if character <= 127 { - // { - DEL: (%)P - (%)T - extended_content.append('b'); - extended_content.append(('P' + character - '{') as char); - } else { - throw IllegalArgumentException::new(format!("Requested content contains a non-encodable character: '{}'", character)); - } - } - i += 1; - } - } - - return extended_content.to_string(); - } -} - diff --git a/port_src/output/zxing/oned/e_a_n13_reader.rs b/port_src/output/zxing/oned/e_a_n13_reader.rs deleted file mode 100644 index d71c792..0000000 --- a/port_src/output/zxing/oned/e_a_n13_reader.rs +++ /dev/null @@ -1,146 +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::oned; - -/** - *

Implements decoding of the EAN-13 format.

- * - * @author dswitkin@google.com (Daniel Switkin) - * @author Sean Owen - * @author alasdair@google.com (Alasdair Mackintosh) - */ - -// For an EAN-13 barcode, the first digit is represented by the parities used -// to encode the next six digits, according to the table below. For example, -// if the barcode is 5 123456 789012 then the value of the first digit is -// signified by using odd for '1', even for '2', even for '3', odd for '4', -// odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13 -// -// Parity of next 6 digits -// Digit 0 1 2 3 4 5 -// 0 Odd Odd Odd Odd Odd Odd -// 1 Odd Odd Even Odd Even Even -// 2 Odd Odd Even Even Odd Even -// 3 Odd Odd Even Even Even Odd -// 4 Odd Even Odd Odd Even Even -// 5 Odd Even Even Odd Odd Even -// 6 Odd Even Even Even Odd Odd -// 7 Odd Even Odd Even Odd Even -// 8 Odd Even Odd Even Even Odd -// 9 Odd Even Even Odd Even Odd -// -// Note that the encoding for '0' uses the same parity as a UPC barcode. Hence -// a UPC barcode can be converted to an EAN-13 barcode by prepending a 0. -// -// The encoding is represented by the following array, which is a bit pattern -// using Odd = 0 and Even = 1. For example, 5 is represented by: -// -// Odd Even Even Odd Odd Even -// in binary: -// 0 1 1 0 0 1 == 0x19 -// - const FIRST_DIGIT_ENCODINGS: vec![Vec; 10] = vec![0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A, ] -; -pub struct EAN13Reader { - super: UPCEANReader; - - let decode_middle_counters: Vec; -} - -impl EAN13Reader { - - pub fn new() -> EAN13Reader { - decode_middle_counters = : [i32; 4] = [0; 4]; - } - - pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { - let mut counters: Vec = self.decode_middle_counters; - counters[0] = 0; - counters[1] = 0; - counters[2] = 0; - counters[3] = 0; - let end: i32 = row.get_size(); - let row_offset: i32 = start_range[1]; - let lg_pattern_found: i32 = 0; - { - let mut x: i32 = 0; - while x < 6 && row_offset < end { - { - let best_match: i32 = decode_digit(row, &counters, row_offset, L_AND_G_PATTERNS); - result_string.append(('0' + best_match % 10) as char); - for let counter: i32 in counters { - row_offset += counter; - } - if best_match >= 10 { - lg_pattern_found |= 1 << (5 - x); - } - } - x += 1; - } - } - - ::determine_first_digit(&result_string, lg_pattern_found); - let middle_range: Vec = find_guard_pattern(row, row_offset, true, MIDDLE_PATTERN); - row_offset = middle_range[1]; - { - let mut x: i32 = 0; - while x < 6 && row_offset < end { - { - let best_match: i32 = decode_digit(row, &counters, row_offset, L_PATTERNS); - result_string.append(('0' + best_match) as char); - for let counter: i32 in counters { - row_offset += counter; - } - } - x += 1; - } - } - - return Ok(row_offset); - } - - fn get_barcode_format(&self) -> BarcodeFormat { - return BarcodeFormat::EAN_13; - } - - /** - * Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded - * digits in a barcode, determines the implicitly encoded first digit and adds it to the - * result string. - * - * @param resultString string to insert decoded first digit into - * @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to - * encode digits - * @throws NotFoundException if first digit cannot be determined - */ - fn determine_first_digit( result_string: &StringBuilder, lg_pattern_found: i32) -> /* throws NotFoundException */Result> { - { - let mut d: i32 = 0; - while d < 10 { - { - if lg_pattern_found == FIRST_DIGIT_ENCODINGS[d] { - result_string.insert(0, ('0' + d) as char); - return; - } - } - d += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } -} - diff --git a/port_src/output/zxing/oned/e_a_n13_writer.rs b/port_src/output/zxing/oned/e_a_n13_writer.rs deleted file mode 100644 index 6f6157c..0000000 --- a/port_src/output/zxing/oned/e_a_n13_writer.rs +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2009 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::oned; - -/** - * This object renders an EAN13 code as a {@link BitMatrix}. - * - * @author aripollak@gmail.com (Ari Pollak) - */ - - const CODE_WIDTH: i32 = // start guard -3 + // left bars -(7 * 6) + // middle guard -5 + // right bars -(7 * 6) + // end guard -3; -pub struct EAN13Writer { - super: UPCEANWriter; -} - -impl EAN13Writer { - - pub fn get_supported_write_formats(&self) -> Collection { - return Collections::singleton(BarcodeFormat::EAN_13); - } - - pub fn encode(&self, contents: &String) -> Vec { - let length: i32 = contents.length(); - match length { - 12 => - { - // No check digit present, calculate it and add it - let mut check: i32; - let tryResult1 = 0; - 'try1: loop { - { - check = UPCEANReader::get_standard_u_p_c_e_a_n_checksum(&contents); - } - break 'try1 - } - match tryResult1 { - catch ( fe: &FormatException) { - throw IllegalArgumentException::new(fe); - } 0 => break - } - - contents += check; - break; - } - 13 => - { - let tryResult1 = 0; - 'try1: loop { - { - if !UPCEANReader::check_standard_u_p_c_e_a_n_checksum(&contents) { - throw IllegalArgumentException::new("Contents do not pass checksum"); - } - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &FormatException) { - throw IllegalArgumentException::new("Illegal contents"); - } 0 => break - } - - break; - } - _ => - { - throw IllegalArgumentException::new(format!("Requested contents should be 12 or 13 digits long, but got {}", length)); - } - } - check_numeric(&contents); - let first_digit: i32 = Character::digit(&contents.char_at(0), 10); - let parities: i32 = EAN13Reader.FIRST_DIGIT_ENCODINGS[first_digit]; - let result: [bool; CODE_WIDTH] = [false; CODE_WIDTH]; - let mut pos: i32 = 0; - pos += append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); - // See EAN13Reader for a description of how the first digit & left bars are encoded - { - let mut i: i32 = 1; - while i <= 6 { - { - let mut digit: i32 = Character::digit(&contents.char_at(i), 10); - if (parities >> (6 - i) & 1) == 1 { - digit += 10; - } - pos += append_pattern(&result, pos, UPCEANReader.L_AND_G_PATTERNS[digit], false); - } - i += 1; - } - } - - pos += append_pattern(&result, pos, UPCEANReader.MIDDLE_PATTERN, false); - { - let mut i: i32 = 7; - while i <= 12 { - { - let digit: i32 = Character::digit(&contents.char_at(i), 10); - pos += append_pattern(&result, pos, UPCEANReader.L_PATTERNS[digit], true); - } - i += 1; - } - } - - append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); - return result; - } -} - diff --git a/port_src/output/zxing/oned/e_a_n8_reader.rs b/port_src/output/zxing/oned/e_a_n8_reader.rs deleted file mode 100644 index cef0c8a..0000000 --- a/port_src/output/zxing/oned/e_a_n8_reader.rs +++ /dev/null @@ -1,80 +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::oned; - -/** - *

Implements decoding of the EAN-8 format.

- * - * @author Sean Owen - */ -pub struct EAN8Reader { - super: UPCEANReader; - - let decode_middle_counters: Vec; -} - -impl EAN8Reader { - - pub fn new() -> EAN8Reader { - decode_middle_counters = : [i32; 4] = [0; 4]; - } - - pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result: &StringBuilder) -> /* throws NotFoundException */Result> { - let mut counters: Vec = self.decode_middle_counters; - counters[0] = 0; - counters[1] = 0; - counters[2] = 0; - counters[3] = 0; - let end: i32 = row.get_size(); - let row_offset: i32 = start_range[1]; - { - let mut x: i32 = 0; - while x < 4 && row_offset < end { - { - let best_match: i32 = decode_digit(row, &counters, row_offset, L_PATTERNS); - result.append(('0' + best_match) as char); - for let counter: i32 in counters { - row_offset += counter; - } - } - x += 1; - } - } - - let middle_range: Vec = find_guard_pattern(row, row_offset, true, MIDDLE_PATTERN); - row_offset = middle_range[1]; - { - let mut x: i32 = 0; - while x < 4 && row_offset < end { - { - let best_match: i32 = decode_digit(row, &counters, row_offset, L_PATTERNS); - result.append(('0' + best_match) as char); - for let counter: i32 in counters { - row_offset += counter; - } - } - x += 1; - } - } - - return Ok(row_offset); - } - - fn get_barcode_format(&self) -> BarcodeFormat { - return BarcodeFormat::EAN_8; - } -} - diff --git a/port_src/output/zxing/oned/e_a_n8_writer.rs b/port_src/output/zxing/oned/e_a_n8_writer.rs deleted file mode 100644 index 416b166..0000000 --- a/port_src/output/zxing/oned/e_a_n8_writer.rs +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2009 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::oned; - -/** - * This object renders an EAN8 code as a {@link BitMatrix}. - * - * @author aripollak@gmail.com (Ari Pollak) - */ - - const CODE_WIDTH: i32 = // start guard -3 + // left bars -(7 * 4) + // middle guard -5 + // right bars -(7 * 4) + // end guard -3; -pub struct EAN8Writer { - super: UPCEANWriter; -} - -impl EAN8Writer { - - pub fn get_supported_write_formats(&self) -> Collection { - return Collections::singleton(BarcodeFormat::EAN_8); - } - - /** - * @return a byte array of horizontal pixels (false = white, true = black) - */ - pub fn encode(&self, contents: &String) -> Vec { - let length: i32 = contents.length(); - match length { - 7 => - { - // No check digit present, calculate it and add it - let mut check: i32; - let tryResult1 = 0; - 'try1: loop { - { - check = UPCEANReader::get_standard_u_p_c_e_a_n_checksum(&contents); - } - break 'try1 - } - match tryResult1 { - catch ( fe: &FormatException) { - throw IllegalArgumentException::new(fe); - } 0 => break - } - - contents += check; - break; - } - 8 => - { - let tryResult1 = 0; - 'try1: loop { - { - if !UPCEANReader::check_standard_u_p_c_e_a_n_checksum(&contents) { - throw IllegalArgumentException::new("Contents do not pass checksum"); - } - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &FormatException) { - throw IllegalArgumentException::new("Illegal contents"); - } 0 => break - } - - break; - } - _ => - { - throw IllegalArgumentException::new(format!("Requested contents should be 7 or 8 digits long, but got {}", length)); - } - } - check_numeric(&contents); - let result: [bool; CODE_WIDTH] = [false; CODE_WIDTH]; - let mut pos: i32 = 0; - pos += append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); - { - let mut i: i32 = 0; - while i <= 3 { - { - let digit: i32 = Character::digit(&contents.char_at(i), 10); - pos += append_pattern(&result, pos, UPCEANReader.L_PATTERNS[digit], false); - } - i += 1; - } - } - - pos += append_pattern(&result, pos, UPCEANReader.MIDDLE_PATTERN, false); - { - let mut i: i32 = 4; - while i <= 7 { - { - let digit: i32 = Character::digit(&contents.char_at(i), 10); - pos += append_pattern(&result, pos, UPCEANReader.L_PATTERNS[digit], true); - } - i += 1; - } - } - - append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); - return result; - } -} - diff --git a/port_src/output/zxing/oned/e_a_n_manufacturer_org_support.rs b/port_src/output/zxing/oned/e_a_n_manufacturer_org_support.rs deleted file mode 100644 index bf890cd..0000000 --- a/port_src/output/zxing/oned/e_a_n_manufacturer_org_support.rs +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2010 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::oned; - -/** - * Records EAN prefix to GS1 Member Organization, where the member organization - * correlates strongly with a country. This is an imperfect means of identifying - * a country of origin by EAN-13 barcode value. See - * - * http://en.wikipedia.org/wiki/List_of_GS1_country_codes. - * - * @author Sean Owen - */ -struct EANManufacturerOrgSupport { - - let ranges: List> = ArrayList<>::new(); - - let country_identifiers: List = ArrayList<>::new(); -} - -impl EANManufacturerOrgSupport { - - fn lookup_country_identifier(&self, product_code: &String) -> String { - self.init_if_needed(); - let prefix: i32 = Integer::parse_int(&product_code.substring(0, 3)); - let max: i32 = self.ranges.size(); - { - let mut i: i32 = 0; - while i < max { - { - let range: Vec = self.ranges.get(i); - let start: i32 = range[0]; - if prefix < start { - return null; - } - let end: i32 = if range.len() == 1 { start } else { range[1] }; - if prefix <= end { - return self.country_identifiers.get(i); - } - } - i += 1; - } - } - - return null; - } - - fn add(&self, range: &Vec, id: &String) { - self.ranges.add(&range); - self.country_identifiers.add(&id); - } - - fn init_if_needed(&self) { - if !self.ranges.is_empty() { - return; - } - self.add( : vec![i32; 2] = vec![0, 19, ] - , "US/CA"); - self.add( : vec![i32; 2] = vec![30, 39, ] - , "US"); - self.add( : vec![i32; 2] = vec![60, 139, ] - , "US/CA"); - self.add( : vec![i32; 2] = vec![300, 379, ] - , "FR"); - self.add( : vec![i32; 1] = vec![380, ] - , "BG"); - self.add( : vec![i32; 1] = vec![383, ] - , "SI"); - self.add( : vec![i32; 1] = vec![385, ] - , "HR"); - self.add( : vec![i32; 1] = vec![387, ] - , "BA"); - self.add( : vec![i32; 2] = vec![400, 440, ] - , "DE"); - self.add( : vec![i32; 2] = vec![450, 459, ] - , "JP"); - self.add( : vec![i32; 2] = vec![460, 469, ] - , "RU"); - self.add( : vec![i32; 1] = vec![471, ] - , "TW"); - self.add( : vec![i32; 1] = vec![474, ] - , "EE"); - self.add( : vec![i32; 1] = vec![475, ] - , "LV"); - self.add( : vec![i32; 1] = vec![476, ] - , "AZ"); - self.add( : vec![i32; 1] = vec![477, ] - , "LT"); - self.add( : vec![i32; 1] = vec![478, ] - , "UZ"); - self.add( : vec![i32; 1] = vec![479, ] - , "LK"); - self.add( : vec![i32; 1] = vec![480, ] - , "PH"); - self.add( : vec![i32; 1] = vec![481, ] - , "BY"); - self.add( : vec![i32; 1] = vec![482, ] - , "UA"); - self.add( : vec![i32; 1] = vec![484, ] - , "MD"); - self.add( : vec![i32; 1] = vec![485, ] - , "AM"); - self.add( : vec![i32; 1] = vec![486, ] - , "GE"); - self.add( : vec![i32; 1] = vec![487, ] - , "KZ"); - self.add( : vec![i32; 1] = vec![489, ] - , "HK"); - self.add( : vec![i32; 2] = vec![490, 499, ] - , "JP"); - self.add( : vec![i32; 2] = vec![500, 509, ] - , "GB"); - self.add( : vec![i32; 1] = vec![520, ] - , "GR"); - self.add( : vec![i32; 1] = vec![528, ] - , "LB"); - self.add( : vec![i32; 1] = vec![529, ] - , "CY"); - self.add( : vec![i32; 1] = vec![531, ] - , "MK"); - self.add( : vec![i32; 1] = vec![535, ] - , "MT"); - self.add( : vec![i32; 1] = vec![539, ] - , "IE"); - self.add( : vec![i32; 2] = vec![540, 549, ] - , "BE/LU"); - self.add( : vec![i32; 1] = vec![560, ] - , "PT"); - self.add( : vec![i32; 1] = vec![569, ] - , "IS"); - self.add( : vec![i32; 2] = vec![570, 579, ] - , "DK"); - self.add( : vec![i32; 1] = vec![590, ] - , "PL"); - self.add( : vec![i32; 1] = vec![594, ] - , "RO"); - self.add( : vec![i32; 1] = vec![599, ] - , "HU"); - self.add( : vec![i32; 2] = vec![600, 601, ] - , "ZA"); - self.add( : vec![i32; 1] = vec![603, ] - , "GH"); - self.add( : vec![i32; 1] = vec![608, ] - , "BH"); - self.add( : vec![i32; 1] = vec![609, ] - , "MU"); - self.add( : vec![i32; 1] = vec![611, ] - , "MA"); - self.add( : vec![i32; 1] = vec![613, ] - , "DZ"); - self.add( : vec![i32; 1] = vec![616, ] - , "KE"); - self.add( : vec![i32; 1] = vec![618, ] - , "CI"); - self.add( : vec![i32; 1] = vec![619, ] - , "TN"); - self.add( : vec![i32; 1] = vec![621, ] - , "SY"); - self.add( : vec![i32; 1] = vec![622, ] - , "EG"); - self.add( : vec![i32; 1] = vec![624, ] - , "LY"); - self.add( : vec![i32; 1] = vec![625, ] - , "JO"); - self.add( : vec![i32; 1] = vec![626, ] - , "IR"); - self.add( : vec![i32; 1] = vec![627, ] - , "KW"); - self.add( : vec![i32; 1] = vec![628, ] - , "SA"); - self.add( : vec![i32; 1] = vec![629, ] - , "AE"); - self.add( : vec![i32; 2] = vec![640, 649, ] - , "FI"); - self.add( : vec![i32; 2] = vec![690, 695, ] - , "CN"); - self.add( : vec![i32; 2] = vec![700, 709, ] - , "NO"); - self.add( : vec![i32; 1] = vec![729, ] - , "IL"); - self.add( : vec![i32; 2] = vec![730, 739, ] - , "SE"); - self.add( : vec![i32; 1] = vec![740, ] - , "GT"); - self.add( : vec![i32; 1] = vec![741, ] - , "SV"); - self.add( : vec![i32; 1] = vec![742, ] - , "HN"); - self.add( : vec![i32; 1] = vec![743, ] - , "NI"); - self.add( : vec![i32; 1] = vec![744, ] - , "CR"); - self.add( : vec![i32; 1] = vec![745, ] - , "PA"); - self.add( : vec![i32; 1] = vec![746, ] - , "DO"); - self.add( : vec![i32; 1] = vec![750, ] - , "MX"); - self.add( : vec![i32; 2] = vec![754, 755, ] - , "CA"); - self.add( : vec![i32; 1] = vec![759, ] - , "VE"); - self.add( : vec![i32; 2] = vec![760, 769, ] - , "CH"); - self.add( : vec![i32; 1] = vec![770, ] - , "CO"); - self.add( : vec![i32; 1] = vec![773, ] - , "UY"); - self.add( : vec![i32; 1] = vec![775, ] - , "PE"); - self.add( : vec![i32; 1] = vec![777, ] - , "BO"); - self.add( : vec![i32; 1] = vec![779, ] - , "AR"); - self.add( : vec![i32; 1] = vec![780, ] - , "CL"); - self.add( : vec![i32; 1] = vec![784, ] - , "PY"); - self.add( : vec![i32; 1] = vec![785, ] - , "PE"); - self.add( : vec![i32; 1] = vec![786, ] - , "EC"); - self.add( : vec![i32; 2] = vec![789, 790, ] - , "BR"); - self.add( : vec![i32; 2] = vec![800, 839, ] - , "IT"); - self.add( : vec![i32; 2] = vec![840, 849, ] - , "ES"); - self.add( : vec![i32; 1] = vec![850, ] - , "CU"); - self.add( : vec![i32; 1] = vec![858, ] - , "SK"); - self.add( : vec![i32; 1] = vec![859, ] - , "CZ"); - self.add( : vec![i32; 1] = vec![860, ] - , "YU"); - self.add( : vec![i32; 1] = vec![865, ] - , "MN"); - self.add( : vec![i32; 1] = vec![867, ] - , "KP"); - self.add( : vec![i32; 2] = vec![868, 869, ] - , "TR"); - self.add( : vec![i32; 2] = vec![870, 879, ] - , "NL"); - self.add( : vec![i32; 1] = vec![880, ] - , "KR"); - self.add( : vec![i32; 1] = vec![885, ] - , "TH"); - self.add( : vec![i32; 1] = vec![888, ] - , "SG"); - self.add( : vec![i32; 1] = vec![890, ] - , "IN"); - self.add( : vec![i32; 1] = vec![893, ] - , "VN"); - self.add( : vec![i32; 1] = vec![896, ] - , "PK"); - self.add( : vec![i32; 1] = vec![899, ] - , "ID"); - self.add( : vec![i32; 2] = vec![900, 919, ] - , "AT"); - self.add( : vec![i32; 2] = vec![930, 939, ] - , "AU"); - self.add( : vec![i32; 2] = vec![940, 949, ] - , "AZ"); - self.add( : vec![i32; 1] = vec![955, ] - , "MY"); - self.add( : vec![i32; 1] = vec![958, ] - , "MO"); - } -} - diff --git a/port_src/output/zxing/oned/i_t_f_reader.rs b/port_src/output/zxing/oned/i_t_f_reader.rs deleted file mode 100644 index b758864..0000000 --- a/port_src/output/zxing/oned/i_t_f_reader.rs +++ /dev/null @@ -1,415 +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::oned; - -/** - *

Implements decoding of the ITF format, or Interleaved Two of Five.

- * - *

This Reader will scan ITF barcodes of certain lengths only. - * At the moment it reads length 6, 8, 10, 12, 14, 16, 18, 20, 24, and 44 as these have appeared "in the wild". Not all - * lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of - * required checksum function.

- * - *

The checksum is optional and is not applied by this Reader. The consumer of the decoded - * value will have to apply a checksum if required.

- * - *

http://en.wikipedia.org/wiki/Interleaved_2_of_5 - * is a great reference for Interleaved 2 of 5 information.

- * - * @author kevin.osullivan@sita.aero, SITA Lab. - */ - - const MAX_AVG_VARIANCE: f32 = 0.38f; - - const MAX_INDIVIDUAL_VARIANCE: f32 = 0.5f; - -// Pixel width of a 3x wide line - const W: i32 = 3; - -// Pixel width of a 2x wide line - let w: i32 = 2; - -// Pixed width of a narrow line - const N: i32 = 1; - -/** Valid ITF lengths. Anything longer than the largest value is also allowed. */ - const DEFAULT_ALLOWED_LENGTHS: vec![Vec; 5] = vec![6, 8, 10, 12, 14, ] -; - -/** - * Start/end guard pattern. - * - * Note: The end pattern is reversed because the row is reversed before - * searching for the END_PATTERN - */ - const START_PATTERN: vec![Vec; 4] = vec![N, N, N, N, ] -; - - const END_PATTERN_REVERSED: vec![vec![Vec>; 3]; 2] = vec![// 2x -vec![N, N, w, ] -, // 3x -vec![N, N, W, ] -, ] -; - -// See ITFWriter.PATTERNS -/** - * Patterns of Wide / Narrow lines to indicate each digit - */ - const PATTERNS: vec![vec![Vec>; 5]; 20] = vec![// 0 -vec![N, N, w, w, N, ] -, // 1 -vec![w, N, N, N, w, ] -, // 2 -vec![N, w, N, N, w, ] -, // 3 -vec![w, w, N, N, N, ] -, // 4 -vec![N, N, w, N, w, ] -, // 5 -vec![w, N, w, N, N, ] -, // 6 -vec![N, w, w, N, N, ] -, // 7 -vec![N, N, N, w, w, ] -, // 8 -vec![w, N, N, w, N, ] -, // 9 -vec![N, w, N, w, N, ] -, // 0 -vec![N, N, W, W, N, ] -, // 1 -vec![W, N, N, N, W, ] -, // 2 -vec![N, W, N, N, W, ] -, // 3 -vec![W, W, N, N, N, ] -, // 4 -vec![N, N, W, N, W, ] -, // 5 -vec![W, N, W, N, N, ] -, // 6 -vec![N, W, W, N, N, ] -, // 7 -vec![N, N, N, W, W, ] -, // 8 -vec![W, N, N, W, N, ] -, // 9 -vec![N, W, N, W, N, ] -, ] -; -pub struct ITFReader { - super: OneDReader; - - // Stores the actual narrow line width of the image being decoded. - let narrow_line_width: i32 = -1; -} - -impl ITFReader { - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws FormatException, NotFoundException */Result> { - // Find out where the Middle section (payload) starts & ends - let start_range: Vec = self.decode_start(row); - let end_range: Vec = self.decode_end(row); - let result: StringBuilder = StringBuilder::new(20); - ::decode_middle(row, start_range[1], end_range[0], &result); - let result_string: String = result.to_string(); - let allowed_lengths: Vec = null; - if hints != null { - allowed_lengths = hints.get(DecodeHintType::ALLOWED_LENGTHS) as Vec; - } - if allowed_lengths == null { - allowed_lengths = DEFAULT_ALLOWED_LENGTHS; - } - // To avoid false positives with 2D barcodes (and other patterns), make - // an assumption that the decoded string must be a 'standard' length if it's short - let length: i32 = result_string.length(); - let length_o_k: bool = false; - let max_allowed_length: i32 = 0; - for let allowed_length: i32 in allowed_lengths { - if length == allowed_length { - length_o_k = true; - break; - } - if allowed_length > max_allowed_length { - max_allowed_length = allowed_length; - } - } - if !length_o_k && length > max_allowed_length { - length_o_k = true; - } - if !length_o_k { - throw FormatException::get_format_instance(); - } - let result_object: Result = Result::new(&result_string, // no natural byte representation for these barcodes - null, : vec![ResultPoint; 2] = vec![ResultPoint::new(start_range[1], row_number), ResultPoint::new(end_range[0], row_number), ] - , BarcodeFormat::ITF); - result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]I0"); - return Ok(result_object); - } - - /** - * @param row row of black/white values to search - * @param payloadStart offset of start pattern - * @param resultString {@link StringBuilder} to append decoded chars to - * @throws NotFoundException if decoding could not complete successfully - */ - fn decode_middle( row: &BitArray, payload_start: i32, payload_end: i32, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { - // Digits are interleaved in pairs - 5 black lines for one digit, and the - // 5 - // interleaved white lines for the second digit. - // Therefore, need to scan 10 lines and then - // split these into two arrays - let counter_digit_pair: [i32; 10] = [0; 10]; - let counter_black: [i32; 5] = [0; 5]; - let counter_white: [i32; 5] = [0; 5]; - while payload_start < payload_end { - // Get 10 runs of black/white. - record_pattern(row, payload_start, &counter_digit_pair); - // Split them into each array - { - let mut k: i32 = 0; - while k < 5 { - { - let two_k: i32 = 2 * k; - counter_black[k] = counter_digit_pair[two_k]; - counter_white[k] = counter_digit_pair[two_k + 1]; - } - k += 1; - } - } - - let best_match: i32 = ::decode_digit(&counter_black); - result_string.append(('0' + best_match) as char); - best_match = ::decode_digit(&counter_white); - result_string.append(('0' + best_match) as char); - for let counter_digit: i32 in counter_digit_pair { - payload_start += counter_digit; - } - } - } - - /** - * Identify where the start of the middle / payload section starts. - * - * @param row row of black/white values to search - * @return Array, containing index of start of 'start block' and end of - * 'start block' - */ - fn decode_start(&self, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { - let end_start: i32 = ::skip_white_space(row); - let start_pattern: Vec = ::find_guard_pattern(row, end_start, &START_PATTERN); - // Determine the width of a narrow line in pixels. We can do this by - // getting the width of the start pattern and dividing by 4 because its - // made up of 4 narrow lines. - self.narrowLineWidth = (start_pattern[1] - start_pattern[0]) / 4; - self.validate_quiet_zone(row, start_pattern[0]); - return Ok(start_pattern); - } - - /** - * The start & end patterns must be pre/post fixed by a quiet zone. This - * zone must be at least 10 times the width of a narrow line. Scan back until - * we either get to the start of the barcode or match the necessary number of - * quiet zone pixels. - * - * Note: Its assumed the row is reversed when using this method to find - * quiet zone after the end pattern. - * - * ref: http://www.barcode-1.net/i25code.html - * - * @param row bit array representing the scanned barcode. - * @param startPattern index into row of the start or end pattern. - * @throws NotFoundException if the quiet zone cannot be found - */ - fn validate_quiet_zone(&self, row: &BitArray, start_pattern: i32) -> /* throws NotFoundException */Result> { - // expect to find this many pixels of quiet zone - let quiet_count: i32 = self.narrowLineWidth * 10; - // if there are not so many pixel at all let's try as many as possible - quiet_count = Math::min(quiet_count, start_pattern); - { - let mut i: i32 = start_pattern - 1; - while quiet_count > 0 && i >= 0 { - { - if row.get(i) { - break; - } - quiet_count -= 1; - } - i -= 1; - } - } - - if quiet_count != 0 { - // Unable to find the necessary number of quiet zone pixels. - throw NotFoundException::get_not_found_instance(); - } - } - - /** - * Skip all whitespace until we get to the first black line. - * - * @param row row of black/white values to search - * @return index of the first black line. - * @throws NotFoundException Throws exception if no black lines are found in the row - */ - fn skip_white_space( row: &BitArray) -> /* throws NotFoundException */Result> { - let width: i32 = row.get_size(); - let end_start: i32 = row.get_next_set(0); - if end_start == width { - throw NotFoundException::get_not_found_instance(); - } - return Ok(end_start); - } - - /** - * Identify where the end of the middle / payload section ends. - * - * @param row row of black/white values to search - * @return Array, containing index of start of 'end block' and end of 'end - * block' - */ - fn decode_end(&self, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { - // For convenience, reverse the row and then - // search from 'the start' for the end block - row.reverse(); - let tryResult1 = 0; - 'try1: loop { - { - let end_start: i32 = ::skip_white_space(row); - let end_pattern: Vec; - let tryResult2 = 0; - 'try2: loop { - { - end_pattern = ::find_guard_pattern(row, end_start, END_PATTERN_REVERSED[0]); - } - break 'try2 - } - match tryResult2 { - catch ( nfe: &NotFoundException) { - end_pattern = ::find_guard_pattern(row, end_start, END_PATTERN_REVERSED[1]); - } 0 => break - } - - // The start & end patterns must be pre/post fixed by a quiet zone. This - // zone must be at least 10 times the width of a narrow line. - // ref: http://www.barcode-1.net/i25code.html - self.validate_quiet_zone(row, end_pattern[0]); - // Now recalculate the indices of where the 'endblock' starts & stops to - // accommodate - // the reversed nature of the search - let temp: i32 = end_pattern[0]; - end_pattern[0] = row.get_size() - end_pattern[1]; - end_pattern[1] = row.get_size() - temp; - return Ok(end_pattern); - } - break 'try1 - } - match tryResult1 { - 0 => break - } - finally { - // Put the row back the right way. - row.reverse(); - } - } - - /** - * @param row row of black/white values to search - * @param rowOffset position to start search - * @param pattern pattern of counts of number of black and white pixels that are - * being searched for as a pattern - * @return start/end horizontal offset of guard pattern, as an array of two - * ints - * @throws NotFoundException if pattern is not found - */ - fn find_guard_pattern( row: &BitArray, row_offset: i32, pattern: &Vec) -> /* throws NotFoundException */Result, Rc> { - let pattern_length: i32 = pattern.len(); - let mut counters: [i32; pattern_length] = [0; pattern_length]; - let width: i32 = row.get_size(); - let is_white: bool = false; - let counter_position: i32 = 0; - let pattern_start: i32 = row_offset; - { - let mut x: i32 = row_offset; - while x < width { - { - if row.get(x) != is_white { - counters[counter_position] += 1; - } else { - if counter_position == pattern_length - 1 { - if pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE { - return Ok( : vec![i32; 2] = vec![pattern_start, x, ] - ); - } - pattern_start += counters[0] + counters[1]; - System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); - counters[counter_position - 1] = 0; - counters[counter_position] = 0; - counter_position -= 1; - } else { - counter_position += 1; - } - counters[counter_position] = 1; - is_white = !is_white; - } - } - x += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - /** - * Attempts to decode a sequence of ITF black/white lines into single - * digit. - * - * @param counters the counts of runs of observed black/white/black/... values - * @return The decoded digit - * @throws NotFoundException if digit cannot be decoded - */ - fn decode_digit( counters: &Vec) -> /* throws NotFoundException */Result> { - // worst variance we'll accept - let best_variance: f32 = MAX_AVG_VARIANCE; - let best_match: i32 = -1; - let max: i32 = PATTERNS.len(); - { - let mut i: i32 = 0; - while i < max { - { - let pattern: Vec = PATTERNS[i]; - let variance: f32 = pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE); - if variance < best_variance { - best_variance = variance; - best_match = i; - } else if variance == best_variance { - // if we find a second 'best match' with the same variance, we can not reliably report to have a suitable match - best_match = -1; - } - } - i += 1; - } - } - - if best_match >= 0 { - return Ok(best_match % 10); - } else { - throw NotFoundException::get_not_found_instance(); - } - } -} - diff --git a/port_src/output/zxing/oned/i_t_f_writer.rs b/port_src/output/zxing/oned/i_t_f_writer.rs deleted file mode 100644 index af953bc..0000000 --- a/port_src/output/zxing/oned/i_t_f_writer.rs +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2010 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::oned; - -/** - * This object renders a ITF code as a {@link BitMatrix}. - * - * @author erik.barbara@gmail.com (Erik Barbara) - */ - - const START_PATTERN: vec![Vec; 4] = vec![1, 1, 1, 1, ] -; - - const END_PATTERN: vec![Vec; 3] = vec![3, 1, 1, ] -; - -// Pixel width of a 3x wide line - const W: i32 = 3; - -// Pixed width of a narrow line - const N: i32 = 1; - -// See ITFReader.PATTERNS - const PATTERNS: vec![vec![Vec>; 5]; 10] = vec![// 0 -vec![N, N, W, W, N, ] -, // 1 -vec![W, N, N, N, W, ] -, // 2 -vec![N, W, N, N, W, ] -, // 3 -vec![W, W, N, N, N, ] -, // 4 -vec![N, N, W, N, W, ] -, // 5 -vec![W, N, W, N, N, ] -, // 6 -vec![N, W, W, N, N, ] -, // 7 -vec![N, N, N, W, W, ] -, // 8 -vec![W, N, N, W, N, ] -, // 9 -vec![N, W, N, W, N, ] -, ] -; -pub struct ITFWriter { - super: OneDimensionalCodeWriter; -} - -impl ITFWriter { - - pub fn get_supported_write_formats(&self) -> Collection { - return Collections::singleton(BarcodeFormat::ITF); - } - - pub fn encode(&self, contents: &String) -> Vec { - let length: i32 = contents.length(); - if length % 2 != 0 { - throw IllegalArgumentException::new("The length of the input should be even"); - } - if length > 80 { - throw IllegalArgumentException::new(format!("Requested contents should be less than 80 digits long, but got {}", length)); - } - check_numeric(&contents); - let result: [bool; 9 + 9 * length] = [false; 9 + 9 * length]; - let mut pos: i32 = append_pattern(&result, 0, &START_PATTERN, true); - { - let mut i: i32 = 0; - while i < length { - { - let one: i32 = Character::digit(&contents.char_at(i), 10); - let two: i32 = Character::digit(&contents.char_at(i + 1), 10); - let mut encoding: [i32; 10] = [0; 10]; - { - let mut j: i32 = 0; - while j < 5 { - { - encoding[2 * j] = PATTERNS[one][j]; - encoding[2 * j + 1] = PATTERNS[two][j]; - } - j += 1; - } - } - - pos += append_pattern(&result, pos, &encoding, true); - } - i += 2; - } - } - - append_pattern(&result, pos, &END_PATTERN, true); - return result; - } -} - diff --git a/port_src/output/zxing/oned/multi_format_one_d_reader.rs b/port_src/output/zxing/oned/multi_format_one_d_reader.rs deleted file mode 100644 index bc7d76b..0000000 --- a/port_src/output/zxing/oned/multi_format_one_d_reader.rs +++ /dev/null @@ -1,99 +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::oned; - -/** - * @author dswitkin@google.com (Daniel Switkin) - * @author Sean Owen - */ - - const EMPTY_ONED_ARRAY: [Option; 0] = [None; 0]; -pub struct MultiFormatOneDReader { - super: OneDReader; - - let readers: Vec; -} - -impl MultiFormatOneDReader { - - pub fn new( hints: &Map) -> MultiFormatOneDReader { - let possible_formats: Collection = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection }; - let use_code39_check_digit: bool = hints != null && hints.get(DecodeHintType::ASSUME_CODE_39_CHECK_DIGIT) != null; - let mut readers: Collection = ArrayList<>::new(); - if possible_formats != null { - if possible_formats.contains(BarcodeFormat::EAN_13) || possible_formats.contains(BarcodeFormat::UPC_A) || possible_formats.contains(BarcodeFormat::EAN_8) || possible_formats.contains(BarcodeFormat::UPC_E) { - readers.add(MultiFormatUPCEANReader::new(&hints)); - } - if possible_formats.contains(BarcodeFormat::CODE_39) { - readers.add(Code39Reader::new(use_code39_check_digit)); - } - if possible_formats.contains(BarcodeFormat::CODE_93) { - readers.add(Code93Reader::new()); - } - if possible_formats.contains(BarcodeFormat::CODE_128) { - readers.add(Code128Reader::new()); - } - if possible_formats.contains(BarcodeFormat::ITF) { - readers.add(ITFReader::new()); - } - if possible_formats.contains(BarcodeFormat::CODABAR) { - readers.add(CodaBarReader::new()); - } - if possible_formats.contains(BarcodeFormat::RSS_14) { - readers.add(RSS14Reader::new()); - } - if possible_formats.contains(BarcodeFormat::RSS_EXPANDED) { - readers.add(RSSExpandedReader::new()); - } - } - if readers.is_empty() { - readers.add(MultiFormatUPCEANReader::new(&hints)); - readers.add(Code39Reader::new()); - readers.add(CodaBarReader::new()); - readers.add(Code93Reader::new()); - readers.add(Code128Reader::new()); - readers.add(ITFReader::new()); - readers.add(RSS14Reader::new()); - readers.add(RSSExpandedReader::new()); - } - let .readers = readers.to_array(EMPTY_ONED_ARRAY); - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { - for let reader: OneDReader in self.readers { - let tryResult1 = 0; - 'try1: loop { - { - return Ok(reader.decode_row(row_number, row, &hints)); - } - break 'try1 - } - match tryResult1 { - catch ( re: &ReaderException) { - } 0 => break - } - - } - throw NotFoundException::get_not_found_instance(); - } - - pub fn reset(&self) { - for let reader: Reader in self.readers { - reader.reset(); - } - } -} - diff --git a/port_src/output/zxing/oned/multi_format_u_p_c_e_a_n_reader.rs b/port_src/output/zxing/oned/multi_format_u_p_c_e_a_n_reader.rs deleted file mode 100644 index eb43fe3..0000000 --- a/port_src/output/zxing/oned/multi_format_u_p_c_e_a_n_reader.rs +++ /dev/null @@ -1,108 +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::oned; - -/** - *

A reader that can read all available UPC/EAN formats. If a caller wants to try to - * read all such formats, it is most efficient to use this implementation rather than invoke - * individual readers.

- * - * @author Sean Owen - */ - - const EMPTY_READER_ARRAY: [Option; 0] = [None; 0]; -pub struct MultiFormatUPCEANReader { - super: OneDReader; - - let readers: Vec; -} - -impl MultiFormatUPCEANReader { - - pub fn new( hints: &Map) -> MultiFormatUPCEANReader { - let possible_formats: Collection = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection }; - let mut readers: Collection = ArrayList<>::new(); - if possible_formats != null { - if possible_formats.contains(BarcodeFormat::EAN_13) { - readers.add(EAN13Reader::new()); - } else if possible_formats.contains(BarcodeFormat::UPC_A) { - readers.add(UPCAReader::new()); - } - if possible_formats.contains(BarcodeFormat::EAN_8) { - readers.add(EAN8Reader::new()); - } - if possible_formats.contains(BarcodeFormat::UPC_E) { - readers.add(UPCEReader::new()); - } - } - if readers.is_empty() { - readers.add(EAN13Reader::new()); - // UPC-A is covered by EAN-13 - readers.add(EAN8Reader::new()); - readers.add(UPCEReader::new()); - } - let .readers = readers.to_array(EMPTY_READER_ARRAY); - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { - // Compute this location once and reuse it on multiple implementations - let start_guard_pattern: Vec = UPCEANReader::find_start_guard_pattern(row); - for let reader: UPCEANReader in self.readers { - let tryResult1 = 0; - 'try1: loop { - { - let result: Result = reader.decode_row(row_number, row, &start_guard_pattern, &hints); - // Special case: a 12-digit code encoded in UPC-A is identical to a "0" - // followed by those 12 digits encoded as EAN-13. Each will recognize such a code, - // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0". - // Individually these are correct and their readers will both read such a code - // and correctly call it EAN-13, or UPC-A, respectively. - // - // In this case, if we've been looking for both types, we'd like to call it - // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read - // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A - // result if appropriate. - // - // But, don't return UPC-A if UPC-A was not a requested format! - let ean13_may_be_u_p_c_a: bool = result.get_barcode_format() == BarcodeFormat::EAN_13 && result.get_text().char_at(0) == '0'; - let possible_formats: Collection = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection }; - let can_return_u_p_c_a: bool = possible_formats == null || possible_formats.contains(BarcodeFormat::UPC_A); - if ean13_may_be_u_p_c_a && can_return_u_p_c_a { - // Transfer the metadata across - let result_u_p_c_a: Result = Result::new(&result.get_text().substring(1), &result.get_raw_bytes(), &result.get_result_points(), BarcodeFormat::UPC_A); - result_u_p_c_a.put_all_metadata(&result.get_result_metadata()); - return Ok(result_u_p_c_a); - } - return Ok(result); - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &ReaderException) { - } 0 => break - } - - } - throw NotFoundException::get_not_found_instance(); - } - - pub fn reset(&self) { - for let reader: Reader in self.readers { - reader.reset(); - } - } -} - diff --git a/port_src/output/zxing/oned/one_d_reader.rs b/port_src/output/zxing/oned/one_d_reader.rs deleted file mode 100644 index 906885e..0000000 --- a/port_src/output/zxing/oned/one_d_reader.rs +++ /dev/null @@ -1,317 +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::oned; - -/** - * Encapsulates functionality and implementation that is common to all families - * of one-dimensional barcodes. - * - * @author dswitkin@google.com (Daniel Switkin) - * @author Sean Owen - */ -#[derive(Reader)] -pub struct OneDReader { -} - -impl OneDReader { - - pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, FormatException */Result> { - return Ok(self.decode(image, null)); - } - - // Note that we don't try rotation without the try harder flag, even if rotation was supported. - pub fn decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException, FormatException */Result> { - let tryResult1 = 0; - 'try1: loop { - { - return Ok(self.do_decode(image, &hints)); - } - break 'try1 - } - match tryResult1 { - catch ( nfe: &NotFoundException) { - let try_harder: bool = hints != null && hints.contains_key(DecodeHintType::TRY_HARDER); - if try_harder && image.is_rotate_supported() { - let rotated_image: BinaryBitmap = image.rotate_counter_clockwise(); - let result: Result = self.do_decode(rotated_image, &hints); - let metadata: Map = result.get_result_metadata(); - let mut orientation: i32 = 270; - if metadata != null && metadata.contains_key(ResultMetadataType::ORIENTATION) { - orientation = (orientation + metadata.get(ResultMetadataType::ORIENTATION) as Integer) % 360; - } - result.put_metadata(ResultMetadataType::ORIENTATION, orientation); - let mut points: Vec = result.get_result_points(); - if points != null { - let height: i32 = rotated_image.get_height(); - { - let mut i: i32 = 0; - while i < points.len() { - { - points[i] = ResultPoint::new(height - points[i].get_y() - 1, &points[i].get_x()); - } - i += 1; - } - } - - } - return Ok(result); - } else { - throw nfe; - } - } 0 => break - } - - } - - pub fn reset(&self) { - // do nothing - } - - /** - * We're going to examine rows from the middle outward, searching alternately above and below the - * middle, and farther out each time. rowStep is the number of rows between each successive - * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then - * middle + rowStep, then middle - (2 * rowStep), etc. - * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily - * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the - * image if "trying harder". - * - * @param image The image to decode - * @param hints Any hints that were requested - * @return The contents of the decoded barcode - * @throws NotFoundException Any spontaneous errors which occur - */ - fn do_decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException */Result> { - let width: i32 = image.get_width(); - let height: i32 = image.get_height(); - let mut row: BitArray = BitArray::new(width); - let try_harder: bool = hints != null && hints.contains_key(DecodeHintType::TRY_HARDER); - let row_step: i32 = Math::max(1, height >> ( if try_harder { 8 } else { 5 })); - let max_lines: i32; - if try_harder { - // Look at the whole image, not just the center - max_lines = height; - } else { - // 15 rows spaced 1/32 apart is roughly the middle half of the image - max_lines = 15; - } - let middle: i32 = height / 2; - { - let mut x: i32 = 0; - while x < max_lines { - { - // Scanning from the middle out. Determine which row we're looking at next: - let row_steps_above_or_below: i32 = (x + 1) / 2; - // i.e. is x even? - let is_above: bool = (x & 0x01) == 0; - let row_number: i32 = middle + row_step * ( if is_above { row_steps_above_or_below } else { -row_steps_above_or_below }); - if row_number < 0 || row_number >= height { - // Oops, if we run off the top or bottom, stop - break; - } - // Estimate black point for this row and load it: - let tryResult1 = 0; - 'try1: loop { - { - row = image.get_black_row(row_number, row); - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &NotFoundException) { - continue; - } 0 => break - } - - // handle decoding upside down barcodes. - { - let mut attempt: i32 = 0; - while attempt < 2 { - { - if attempt == 1 { - // trying again? - // reverse the row and continue - row.reverse(); - // that start on the center line. - if hints != null && hints.contains_key(DecodeHintType::NEED_RESULT_POINT_CALLBACK) { - let new_hints: Map = EnumMap<>::new(DecodeHintType.class); - new_hints.put_all(&hints); - new_hints.remove(DecodeHintType::NEED_RESULT_POINT_CALLBACK); - hints = new_hints; - } - } - let tryResult1 = 0; - 'try1: loop { - { - // Look for a barcode - let result: Result = self.decode_row(row_number, row, &hints); - // We found our barcode - if attempt == 1 { - // But it was upside down, so note that - result.put_metadata(ResultMetadataType::ORIENTATION, 180); - // And remember to flip the result points horizontally. - let mut points: Vec = result.get_result_points(); - if points != null { - points[0] = ResultPoint::new(width - points[0].get_x() - 1, &points[0].get_y()); - points[1] = ResultPoint::new(width - points[1].get_x() - 1, &points[1].get_y()); - } - } - return Ok(result); - } - break 'try1 - } - match tryResult1 { - catch ( re: &ReaderException) { - } 0 => break - } - - } - attempt += 1; - } - } - - } - x += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - /** - * Records the size of successive runs of white and black pixels in a row, starting at a given point. - * The values are recorded in the given array, and the number of runs recorded is equal to the size - * of the array. If the row starts on a white pixel at the given start point, then the first count - * recorded is the run of white pixels starting from that point; likewise it is the count of a run - * of black pixels if the row begin on a black pixels at that point. - * - * @param row row to count from - * @param start offset into row to start at - * @param counters array into which to record counts - * @throws NotFoundException if counters cannot be filled entirely from row before running out - * of pixels - */ - pub fn record_pattern( row: &BitArray, start: i32, counters: &Vec) -> /* throws NotFoundException */Result> { - let num_counters: i32 = counters.len(); - Arrays::fill(&counters, 0, num_counters, 0); - let end: i32 = row.get_size(); - if start >= end { - throw NotFoundException::get_not_found_instance(); - } - let is_white: bool = !row.get(start); - let counter_position: i32 = 0; - let mut i: i32 = start; - while i < end { - if row.get(i) != is_white { - counters[counter_position] += 1; - } else { - if counter_position += 1 == num_counters { - break; - } else { - counters[counter_position] = 1; - is_white = !is_white; - } - } - i += 1; - } - // the last counter but ran off the side of the image, OK. Otherwise, a problem. - if !(counter_position == num_counters || (counter_position == num_counters - 1 && i == end)) { - throw NotFoundException::get_not_found_instance(); - } - } - - pub fn record_pattern_in_reverse( row: &BitArray, start: i32, counters: &Vec) -> /* throws NotFoundException */Result> { - // This could be more efficient I guess - let num_transitions_left: i32 = counters.len(); - let mut last: bool = row.get(start); - while start > 0 && num_transitions_left >= 0 { - if row.get(start -= 1) != last { - num_transitions_left -= 1; - last = !last; - } - } - if num_transitions_left >= 0 { - throw NotFoundException::get_not_found_instance(); - } - ::record_pattern(row, start + 1, &counters); - } - - /** - * Determines how closely a set of observed counts of runs of black/white values matches a given - * target pattern. This is reported as the ratio of the total variance from the expected pattern - * proportions across all pattern elements, to the length of the pattern. - * - * @param counters observed counters - * @param pattern expected pattern - * @param maxIndividualVariance The most any counter can differ before we give up - * @return ratio of total variance between counters and pattern compared to total pattern size - */ - pub fn pattern_match_variance( counters: &Vec, pattern: &Vec, max_individual_variance: f32) -> f32 { - let num_counters: i32 = counters.len(); - let mut total: i32 = 0; - let pattern_length: i32 = 0; - { - let mut i: i32 = 0; - while i < num_counters { - { - total += counters[i]; - pattern_length += pattern[i]; - } - i += 1; - } - } - - if total < pattern_length { - // to reliably match, so fail: - return Float::POSITIVE_INFINITY; - } - let unit_bar_width: f32 = total as f32 / pattern_length; - max_individual_variance *= unit_bar_width; - let total_variance: f32 = 0.0f; - { - let mut x: i32 = 0; - while x < num_counters { - { - let counter: i32 = counters[x]; - let scaled_pattern: f32 = pattern[x] * unit_bar_width; - let variance: f32 = if counter > scaled_pattern { counter - scaled_pattern } else { scaled_pattern - counter }; - if variance > max_individual_variance { - return Float::POSITIVE_INFINITY; - } - total_variance += variance; - } - x += 1; - } - } - - return total_variance / total; - } - - /** - *

Attempts to decode a one-dimensional barcode format given a single row of - * an image.

- * - * @param rowNumber row number from top of the row - * @param row the black/white pixel data of the row - * @param hints decode hints - * @return {@link Result} containing encoded string and start/end of barcode - * @throws NotFoundException if no potential barcode is found - * @throws ChecksumException if a potential barcode is found but does not pass its checksum - * @throws FormatException if a potential barcode is found but format is invalid - */ - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> ; -} - diff --git a/port_src/output/zxing/oned/one_dimensional_code_writer.rs b/port_src/output/zxing/oned/one_dimensional_code_writer.rs deleted file mode 100644 index 2247765..0000000 --- a/port_src/output/zxing/oned/one_dimensional_code_writer.rs +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2011 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::oned; - -/** - *

Encapsulates functionality and implementation that is common to one-dimensional barcodes.

- * - * @author dsbnatut@gmail.com (Kazuki Nishiura) - */ - - const NUMERIC: Pattern = Pattern::compile("[0-9]+"); -#[derive(Writer)] -pub struct OneDimensionalCodeWriter { -} - -impl OneDimensionalCodeWriter { - - /** - * Encode the contents to boolean array expression of one-dimensional barcode. - * Start code and end code should be included in result, and side margins should not be included. - * - * @param contents barcode contents to encode - * @return a {@code boolean[]} of horizontal pixels (false = white, true = black) - */ - pub fn encode(&self, contents: &String) -> Vec ; - - /** - * Can be overwritten if the encode requires to read the hints map. Otherwise it defaults to {@code encode}. - * @param contents barcode contents to encode - * @param hints encoding hints - * @return a {@code boolean[]} of horizontal pixels (false = white, true = black) - */ - pub fn encode(&self, contents: &String, hints: &Map) -> Vec { - return self.encode(&contents); - } - - pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32) -> BitMatrix { - return self.encode(&contents, format, width, height, null); - } - - /** - * Encode the contents following specified format. - * {@code width} and {@code height} are required size. This method may return bigger size - * {@code BitMatrix} when specified size is too small. The user can set both {@code width} and - * {@code height} to zero to get minimum size barcode. If negative value is set to {@code width} - * or {@code height}, {@code IllegalArgumentException} is thrown. - */ - 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 width < 0 || height < 0 { - throw IllegalArgumentException::new(format!("Negative size is not allowed. Input: {}x{}", width, height)); - } - let supported_formats: Collection = self.get_supported_write_formats(); - if supported_formats != null && !supported_formats.contains(format) { - throw IllegalArgumentException::new(format!("Can only encode {}, but got {}", supported_formats, format)); - } - let sides_margin: i32 = self.get_default_margin(); - if hints != null && hints.contains_key(EncodeHintType::MARGIN) { - sides_margin = Integer::parse_int(&hints.get(EncodeHintType::MARGIN).to_string()); - } - let code: Vec = self.encode(&contents, &hints); - return ::render_result(&code, width, height, sides_margin); - } - - pub fn get_supported_write_formats(&self) -> Collection { - return null; - } - - /** - * @return a byte array of horizontal pixels (0 = white, 1 = black) - */ - fn render_result( code: &Vec, width: i32, height: i32, sides_margin: i32) -> BitMatrix { - let input_width: i32 = code.len(); - // Add quiet zone on both sides. - let full_width: i32 = input_width + sides_margin; - let output_width: i32 = Math::max(width, full_width); - let output_height: i32 = Math::max(1, height); - let multiple: i32 = output_width / full_width; - let left_padding: i32 = (output_width - (input_width * multiple)) / 2; - let output: BitMatrix = BitMatrix::new(output_width, output_height); - { - let input_x: i32 = 0, let output_x: i32 = left_padding; - while input_x < input_width { - { - if code[input_x] { - output.set_region(output_x, 0, multiple, output_height); - } - } - input_x += 1; - output_x += multiple; - } - } - - return output; - } - - /** - * @param contents string to check for numeric characters - * @throws IllegalArgumentException if input contains characters other than digits 0-9. - */ - pub fn check_numeric( contents: &String) { - if !NUMERIC::matcher(&contents)::matches() { - throw IllegalArgumentException::new("Input should only contain digits 0-9"); - } - } - - /** - * @param target encode black/white pattern into this array - * @param pos position to start encoding at in {@code target} - * @param pattern lengths of black/white runs to encode - * @param startColor starting color - false for white, true for black - * @return the number of elements added to target. - */ - pub fn append_pattern( target: &Vec, pos: i32, pattern: &Vec, start_color: bool) -> i32 { - let mut color: bool = start_color; - let num_added: i32 = 0; - for let len: i32 in pattern { - { - let mut j: i32 = 0; - while j < len { - { - target[pos += 1 !!!check!!! post increment] = color; - } - j += 1; - } - } - - num_added += len; - // flip color after each segment - color = !color; - } - return num_added; - } - - pub fn get_default_margin(&self) -> i32 { - // This seems like a decent idea for a default for all formats. - return 10; - } -} - diff --git a/port_src/output/zxing/oned/rss/abstract_r_s_s_reader.rs b/port_src/output/zxing/oned/rss/abstract_r_s_s_reader.rs deleted file mode 100644 index 81d14fb..0000000 --- a/port_src/output/zxing/oned/rss/abstract_r_s_s_reader.rs +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss; - -/** - * Superclass of {@link OneDReader} implementations that read barcodes in the RSS family - * of formats. - */ - - const MAX_AVG_VARIANCE: f32 = 0.2f; - - const MAX_INDIVIDUAL_VARIANCE: f32 = 0.45f; - - const MIN_FINDER_PATTERN_RATIO: f32 = 9.5f / 12.0f; - - const MAX_FINDER_PATTERN_RATIO: f32 = 12.5f / 14.0f; -pub struct AbstractRSSReader { - super: OneDReader; - - let decode_finder_counters: Vec; - - let data_character_counters: Vec; - - let odd_rounding_errors: Vec; - - let even_rounding_errors: Vec; - - let odd_counts: Vec; - - let even_counts: Vec; -} - -impl AbstractRSSReader { - - pub fn new() -> AbstractRSSReader { - decode_finder_counters = : [i32; 4] = [0; 4]; - data_character_counters = : [i32; 8] = [0; 8]; - odd_rounding_errors = : [f32; 4.0] = [0.0; 4.0]; - even_rounding_errors = : [f32; 4.0] = [0.0; 4.0]; - odd_counts = : [i32; data_character_counters.len() / 2] = [0; data_character_counters.len() / 2]; - even_counts = : [i32; data_character_counters.len() / 2] = [0; data_character_counters.len() / 2]; - } - - pub fn get_decode_finder_counters(&self) -> Vec { - return self.decode_finder_counters; - } - - pub fn get_data_character_counters(&self) -> Vec { - return self.data_character_counters; - } - - pub fn get_odd_rounding_errors(&self) -> Vec { - return self.odd_rounding_errors; - } - - pub fn get_even_rounding_errors(&self) -> Vec { - return self.even_rounding_errors; - } - - pub fn get_odd_counts(&self) -> Vec { - return self.odd_counts; - } - - pub fn get_even_counts(&self) -> Vec { - return self.even_counts; - } - - pub fn parse_finder_value( counters: &Vec, finder_patterns: &Vec>) -> /* throws NotFoundException */Result> { - { - let mut value: i32 = 0; - while value < finder_patterns.len() { - { - if pattern_match_variance(&counters, finder_patterns[value], MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE { - return Ok(value); - } - } - value += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - /** - * @param array values to sum - * @return sum of values - * @deprecated call {@link MathUtils#sum(int[])} - */ - pub fn count( array: &Vec) -> i32 { - return MathUtils::sum(&array); - } - - pub fn increment( array: &Vec, errors: &Vec) { - let mut index: i32 = 0; - let biggest_error: f32 = errors[0]; - { - let mut i: i32 = 1; - while i < array.len() { - { - if errors[i] > biggest_error { - biggest_error = errors[i]; - index = i; - } - } - i += 1; - } - } - - array[index] += 1; - } - - pub fn decrement( array: &Vec, errors: &Vec) { - let mut index: i32 = 0; - let biggest_error: f32 = errors[0]; - { - let mut i: i32 = 1; - while i < array.len() { - { - if errors[i] < biggest_error { - biggest_error = errors[i]; - index = i; - } - } - i += 1; - } - } - - array[index] -= 1; - } - - pub fn is_finder_pattern( counters: &Vec) -> bool { - let first_two_sum: i32 = counters[0] + counters[1]; - let sum: i32 = first_two_sum + counters[2] + counters[3]; - let ratio: f32 = first_two_sum / sum as f32; - if ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO { - // passes ratio test in spec, but see if the counts are unreasonable - let min_counter: i32 = Integer::MAX_VALUE; - let max_counter: i32 = Integer::MIN_VALUE; - for let counter: i32 in counters { - if counter > max_counter { - max_counter = counter; - } - if counter < min_counter { - min_counter = counter; - } - } - return max_counter < 10 * min_counter; - } - return false; - } -} - diff --git a/port_src/output/zxing/oned/rss/data_character.rs b/port_src/output/zxing/oned/rss/data_character.rs deleted file mode 100644 index d39f939..0000000 --- a/port_src/output/zxing/oned/rss/data_character.rs +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2009 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::oned::rss; - -/** - * Encapsulates a since character value in an RSS barcode, including its checksum information. - */ -pub struct DataCharacter { - - let value: i32; - - let checksum_portion: i32; -} - -impl DataCharacter { - - pub fn new( value: i32, checksum_portion: i32) -> DataCharacter { - let .value = value; - let .checksumPortion = checksum_portion; - } - - pub fn get_value(&self) -> i32 { - return self.value; - } - - pub fn get_checksum_portion(&self) -> i32 { - return self.checksum_portion; - } - - pub fn to_string(&self) -> String { - return format!("{}({})", self.value, self.checksum_portion); - } - - pub fn equals(&self, o: &Object) -> bool { - if !(o instanceof DataCharacter) { - return false; - } - let that: DataCharacter = o as DataCharacter; - return self.value == that.value && self.checksum_portion == that.checksumPortion; - } - - pub fn hash_code(&self) -> i32 { - return self.value ^ self.checksum_portion; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/bit_array_builder.rs b/port_src/output/zxing/oned/rss/expanded/bit_array_builder.rs deleted file mode 100644 index 5f5b12f..0000000 --- a/port_src/output/zxing/oned/rss/expanded/bit_array_builder.rs +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ -struct BitArrayBuilder { -} - -impl BitArrayBuilder { - - fn new() -> BitArrayBuilder { - } - - fn build_bit_array( pairs: &List) -> BitArray { - let char_number: i32 = (pairs.size() * 2) - 1; - if pairs.get(pairs.size() - 1).get_right_char() == null { - char_number -= 1; - } - let size: i32 = 12 * char_number; - let binary: BitArray = BitArray::new(size); - let acc_pos: i32 = 0; - let first_pair: ExpandedPair = pairs.get(0); - let first_value: i32 = first_pair.get_right_char().get_value(); - { - let mut i: i32 = 11; - while i >= 0 { - { - if (first_value & (1 << i)) != 0 { - binary.set(acc_pos); - } - acc_pos += 1; - } - i -= 1; - } - } - - { - let mut i: i32 = 1; - while i < pairs.size() { - { - let current_pair: ExpandedPair = pairs.get(i); - let left_value: i32 = current_pair.get_left_char().get_value(); - { - let mut j: i32 = 11; - while j >= 0 { - { - if (left_value & (1 << j)) != 0 { - binary.set(acc_pos); - } - acc_pos += 1; - } - j -= 1; - } - } - - if current_pair.get_right_char() != null { - let right_value: i32 = current_pair.get_right_char().get_value(); - { - let mut j: i32 = 11; - while j >= 0 { - { - if (right_value & (1 << j)) != 0 { - binary.set(acc_pos); - } - acc_pos += 1; - } - j -= 1; - } - } - - } - } - i += 1; - } - } - - return binary; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i013103decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i013103decoder.rs deleted file mode 100644 index 5e96dfd..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i013103decoder.rs +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ -struct AI013103decoder { - super: AI013x0xDecoder; -} - -impl AI013103decoder { - - fn new( information: &BitArray) -> AI013103decoder { - super(information); - } - - pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) { - buf.append("(3103)"); - } - - pub fn check_weight(&self, weight: i32) -> i32 { - return weight; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01320x_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i01320x_decoder.rs deleted file mode 100644 index fdc1c8e..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01320x_decoder.rs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ -struct AI01320xDecoder { - super: AI013x0xDecoder; -} - -impl AI01320xDecoder { - - fn new( information: &BitArray) -> AI01320xDecoder { - super(information); - } - - pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) { - if weight < 10000 { - buf.append("(3202)"); - } else { - buf.append("(3203)"); - } - } - - pub fn check_weight(&self, weight: i32) -> i32 { - if weight < 10000 { - return weight; - } - return weight - 10000; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01392x_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i01392x_decoder.rs deleted file mode 100644 index ea5fd97..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01392x_decoder.rs +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ - - const HEADER_SIZE: i32 = 5 + 1 + 2; - - const LAST_DIGIT_SIZE: i32 = 2; -struct AI01392xDecoder { - super: AI01decoder; -} - -impl AI01392xDecoder { - - fn new( information: &BitArray) -> AI01392xDecoder { - super(information); - } - - pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { - if self.get_information().get_size() < HEADER_SIZE + GTIN_SIZE { - throw NotFoundException::get_not_found_instance(); - } - let buf: StringBuilder = StringBuilder::new(); - encode_compressed_gtin(&buf, HEADER_SIZE); - let last_a_idigit: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE); - buf.append("(392"); - buf.append(last_a_idigit); - buf.append(')'); - let decoded_information: DecodedInformation = self.get_general_decoder().decode_general_purpose_field(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, null); - buf.append(&decoded_information.get_new_string()); - return Ok(buf.to_string()); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01393x_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i01393x_decoder.rs deleted file mode 100644 index 2f13441..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01393x_decoder.rs +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ -/* - * These authors would like to acknowledge the Spanish Ministry of Industry, - * Tourism and Trade, for the support in the project TSI020301-2008-2 - * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled - * Mobile Dynamic Environments", led by Treelogic - * ( http://www.treelogic.com/ ): - * - * http://www.piramidepse.com/ - */ -// package com::google::zxing::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ - - const HEADER_SIZE: i32 = 5 + 1 + 2; - - const LAST_DIGIT_SIZE: i32 = 2; - - const FIRST_THREE_DIGITS_SIZE: i32 = 10; -struct AI01393xDecoder { - super: AI01decoder; -} - -impl AI01393xDecoder { - - fn new( information: &BitArray) -> AI01393xDecoder { - super(information); - } - - pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { - if self.get_information().get_size() < HEADER_SIZE + GTIN_SIZE { - throw NotFoundException::get_not_found_instance(); - } - let buf: StringBuilder = StringBuilder::new(); - encode_compressed_gtin(&buf, HEADER_SIZE); - let last_a_idigit: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE); - buf.append("(393"); - buf.append(last_a_idigit); - buf.append(')'); - let first_three_digits: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, FIRST_THREE_DIGITS_SIZE); - if first_three_digits / 100 == 0 { - buf.append('0'); - } - if first_three_digits / 10 == 0 { - buf.append('0'); - } - buf.append(first_three_digits); - let general_information: DecodedInformation = self.get_general_decoder().decode_general_purpose_field(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE + FIRST_THREE_DIGITS_SIZE, null); - buf.append(&general_information.get_new_string()); - return Ok(buf.to_string()); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i013x0x1x_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i013x0x1x_decoder.rs deleted file mode 100644 index 7dd43d0..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i013x0x1x_decoder.rs +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - - const HEADER_SIZE: i32 = 7 + 1; - - const WEIGHT_SIZE: i32 = 20; - - const DATE_SIZE: i32 = 16; -struct AI013x0x1xDecoder { - super: AI01weightDecoder; - - let date_code: String; - - let first_a_idigits: String; -} - -impl AI013x0x1xDecoder { - - fn new( information: &BitArray, first_a_idigits: &String, date_code: &String) -> AI013x0x1xDecoder { - super(information); - let .dateCode = date_code; - let .firstAIdigits = first_a_idigits; - } - - pub fn parse_information(&self) -> /* throws NotFoundException */Result> { - if self.get_information().get_size() != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE { - throw NotFoundException::get_not_found_instance(); - } - let buf: StringBuilder = StringBuilder::new(); - encode_compressed_gtin(&buf, HEADER_SIZE); - encode_compressed_weight(&buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE); - self.encode_compressed_date(&buf, HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE); - return Ok(buf.to_string()); - } - - fn encode_compressed_date(&self, buf: &StringBuilder, current_pos: i32) { - let numeric_date: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(current_pos, DATE_SIZE); - if numeric_date == 38400 { - return; - } - buf.append('('); - buf.append(self.dateCode); - buf.append(')'); - let day: i32 = numeric_date % 32; - numeric_date /= 32; - let month: i32 = numeric_date % 12 + 1; - numeric_date /= 12; - let year: i32 = numeric_date; - if year / 10 == 0 { - buf.append('0'); - } - buf.append(year); - if month / 10 == 0 { - buf.append('0'); - } - buf.append(month); - if day / 10 == 0 { - buf.append('0'); - } - buf.append(day); - } - - pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) { - buf.append('('); - buf.append(self.firstAIdigits); - buf.append(weight / 100000); - buf.append(')'); - } - - pub fn check_weight(&self, weight: i32) -> i32 { - return weight % 100000; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i013x0x_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i013x0x_decoder.rs deleted file mode 100644 index a136c55..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i013x0x_decoder.rs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ - - const HEADER_SIZE: i32 = 4 + 1; - - const WEIGHT_SIZE: i32 = 15; -struct AI013x0xDecoder { - super: AI01weightDecoder; -} - -impl AI013x0xDecoder { - - fn new( information: &BitArray) -> AI013x0xDecoder { - super(information); - } - - pub fn parse_information(&self) -> /* throws NotFoundException */Result> { - if self.get_information().get_size() != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE { - throw NotFoundException::get_not_found_instance(); - } - let buf: StringBuilder = StringBuilder::new(); - encode_compressed_gtin(&buf, HEADER_SIZE); - encode_compressed_weight(&buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE); - return Ok(buf.to_string()); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01_and_other_a_is.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i01_and_other_a_is.rs deleted file mode 100644 index 0a1dd02..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01_and_other_a_is.rs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - -//first bit encodes the linkage flag, - const HEADER_SIZE: i32 = 1 + 1 + 2; -struct AI01AndOtherAIs { - super: AI01decoder; -} - -impl AI01AndOtherAIs { - - //the second one is the encodation method, and the other two are for the variable length - fn new( information: &BitArray) -> AI01AndOtherAIs { - super(information); - } - - pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { - let buff: StringBuilder = StringBuilder::new(); - buff.append("(01)"); - let initial_gtin_position: i32 = buff.length(); - let first_gtin_digit: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE, 4); - buff.append(first_gtin_digit); - self.encode_compressed_gtin_without_a_i(&buff, HEADER_SIZE + 4, initial_gtin_position); - return Ok(self.get_general_decoder().decode_all_codes(&buff, HEADER_SIZE + 44)); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i01decoder.rs deleted file mode 100644 index 88bdbf0..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01decoder.rs +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - - const GTIN_SIZE: i32 = 40; -struct AI01decoder { - super: AbstractExpandedDecoder; -} - -impl AI01decoder { - - fn new( information: &BitArray) -> AI01decoder { - super(information); - } - - fn encode_compressed_gtin(&self, buf: &StringBuilder, current_pos: i32) { - buf.append("(01)"); - let initial_position: i32 = buf.length(); - buf.append('9'); - self.encode_compressed_gtin_without_a_i(&buf, current_pos, initial_position); - } - - fn encode_compressed_gtin_without_a_i(&self, buf: &StringBuilder, current_pos: i32, initial_buffer_position: i32) { - { - let mut i: i32 = 0; - while i < 4 { - { - let current_block: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(current_pos + 10 * i, 10); - if current_block / 100 == 0 { - buf.append('0'); - } - if current_block / 10 == 0 { - buf.append('0'); - } - buf.append(current_block); - } - i += 1; - } - } - - ::append_check_digit(&buf, initial_buffer_position); - } - - fn append_check_digit( buf: &StringBuilder, current_pos: i32) { - let check_digit: i32 = 0; - { - let mut i: i32 = 0; - while i < 13 { - { - let digit: i32 = buf.char_at(i + current_pos) - '0'; - check_digit += if (i & 0x01) == 0 { 3 * digit } else { digit }; - } - i += 1; - } - } - - check_digit = 10 - (check_digit % 10); - if check_digit == 10 { - check_digit = 0; - } - buf.append(check_digit); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01weight_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/a_i01weight_decoder.rs deleted file mode 100644 index ea18c8d..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/a_i01weight_decoder.rs +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ -struct AI01weightDecoder { - super: AI01decoder; -} - -impl AI01weightDecoder { - - fn new( information: &BitArray) -> AI01weightDecoder { - super(information); - } - - fn encode_compressed_weight(&self, buf: &StringBuilder, current_pos: i32, weight_size: i32) { - let original_weight_numeric: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(current_pos, weight_size); - self.add_weight_code(&buf, original_weight_numeric); - let weight_numeric: i32 = self.check_weight(original_weight_numeric); - let current_divisor: i32 = 100000; - { - let mut i: i32 = 0; - while i < 5 { - { - if weight_numeric / current_divisor == 0 { - buf.append('0'); - } - current_divisor /= 10; - } - i += 1; - } - } - - buf.append(weight_numeric); - } - - pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) ; - - pub fn check_weight(&self, weight: i32) -> i32 ; -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/abstract_expanded_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/abstract_expanded_decoder.rs deleted file mode 100644 index d84d869..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/abstract_expanded_decoder.rs +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ -pub struct AbstractExpandedDecoder { - - let information: BitArray; - - let general_decoder: GeneralAppIdDecoder; -} - -impl AbstractExpandedDecoder { - - fn new( information: &BitArray) -> AbstractExpandedDecoder { - let .information = information; - let .generalDecoder = GeneralAppIdDecoder::new(information); - } - - pub fn get_information(&self) -> BitArray { - return self.information; - } - - pub fn get_general_decoder(&self) -> GeneralAppIdDecoder { - return self.general_decoder; - } - - pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> ; - - pub fn create_decoder( information: &BitArray) -> AbstractExpandedDecoder { - if information.get(1) { - return AI01AndOtherAIs::new(information); - } - if !information.get(2) { - return AnyAIDecoder::new(information); - } - let four_bit_encodation_method: i32 = GeneralAppIdDecoder::extract_numeric_value_from_bit_array(information, 1, 4); - match four_bit_encodation_method { - 4 => - { - return AI013103decoder::new(information); - } - 5 => - { - return AI01320xDecoder::new(information); - } - } - let five_bit_encodation_method: i32 = GeneralAppIdDecoder::extract_numeric_value_from_bit_array(information, 1, 5); - match five_bit_encodation_method { - 12 => - { - return AI01392xDecoder::new(information); - } - 13 => - { - return AI01393xDecoder::new(information); - } - } - let seven_bit_encodation_method: i32 = GeneralAppIdDecoder::extract_numeric_value_from_bit_array(information, 1, 7); - match seven_bit_encodation_method { - 56 => - { - return AI013x0x1xDecoder::new(information, "310", "11"); - } - 57 => - { - return AI013x0x1xDecoder::new(information, "320", "11"); - } - 58 => - { - return AI013x0x1xDecoder::new(information, "310", "13"); - } - 59 => - { - return AI013x0x1xDecoder::new(information, "320", "13"); - } - 60 => - { - return AI013x0x1xDecoder::new(information, "310", "15"); - } - 61 => - { - return AI013x0x1xDecoder::new(information, "320", "15"); - } - 62 => - { - return AI013x0x1xDecoder::new(information, "310", "17"); - } - 63 => - { - return AI013x0x1xDecoder::new(information, "320", "17"); - } - } - throw IllegalStateException::new(format!("unknown decoder: {}", information)); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/any_a_i_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/any_a_i_decoder.rs deleted file mode 100644 index 077cc5d..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/any_a_i_decoder.rs +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - - const HEADER_SIZE: i32 = 2 + 1 + 2; -struct AnyAIDecoder { - super: AbstractExpandedDecoder; -} - -impl AnyAIDecoder { - - fn new( information: &BitArray) -> AnyAIDecoder { - super(information); - } - - pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { - let buf: StringBuilder = StringBuilder::new(); - return Ok(self.get_general_decoder().decode_all_codes(&buf, HEADER_SIZE)); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/block_parsed_result.rs b/port_src/output/zxing/oned/rss/expanded/decoders/block_parsed_result.rs deleted file mode 100644 index a82f356..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/block_parsed_result.rs +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ -struct BlockParsedResult { - - let decoded_information: DecodedInformation; - - let finished: bool; -} - -impl BlockParsedResult { - - fn new() -> BlockParsedResult { - this(null, false); - } - - fn new( information: &DecodedInformation, finished: bool) -> BlockParsedResult { - let .finished = finished; - let .decodedInformation = information; - } - - fn get_decoded_information(&self) -> DecodedInformation { - return self.decodedInformation; - } - - fn is_finished(&self) -> bool { - return self.finished; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/current_parsing_state.rs b/port_src/output/zxing/oned/rss/expanded/decoders/current_parsing_state.rs deleted file mode 100644 index cfda228..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/current_parsing_state.rs +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ -struct CurrentParsingState { - - let mut position: i32; - - let mut encoding: State; -} - -impl CurrentParsingState { - - enum State { - - NUMERIC(), ALPHA(), ISO_IEC_646() - } - - fn new() -> CurrentParsingState { - let .position = 0; - let .encoding = State::NUMERIC; - } - - fn get_position(&self) -> i32 { - return self.position; - } - - fn set_position(&self, position: i32) { - self.position = position; - } - - fn increment_position(&self, delta: i32) { - self.position += delta; - } - - fn is_alpha(&self) -> bool { - return self.encoding == State::ALPHA; - } - - fn is_numeric(&self) -> bool { - return self.encoding == State::NUMERIC; - } - - fn is_iso_iec646(&self) -> bool { - return self.encoding == State::ISO_IEC_646; - } - - fn set_numeric(&self) { - self.encoding = State::NUMERIC; - } - - fn set_alpha(&self) { - self.encoding = State::ALPHA; - } - - fn set_iso_iec646(&self) { - self.encoding = State::ISO_IEC_646; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_char.rs b/port_src/output/zxing/oned/rss/expanded/decoders/decoded_char.rs deleted file mode 100644 index 95e64e9..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_char.rs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - -// It's not in Alphanumeric neither in ISO/IEC 646 charset - const FNC1: char = '$'; -struct DecodedChar { - super: DecodedObject; - - let value: char; -} - -impl DecodedChar { - - fn new( new_position: i32, value: char) -> DecodedChar { - super(new_position); - let .value = value; - } - - fn get_value(&self) -> char { - return self.value; - } - - fn is_f_n_c1(&self) -> bool { - return self.value == FNC1; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_information.rs b/port_src/output/zxing/oned/rss/expanded/decoders/decoded_information.rs deleted file mode 100644 index 90d02de..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_information.rs +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ -struct DecodedInformation { - super: DecodedObject; - - let new_string: String; - - let remaining_value: i32; - - let mut remaining: bool; -} - -impl DecodedInformation { - - fn new( new_position: i32, new_string: &String) -> DecodedInformation { - super(new_position); - let .newString = new_string; - let .remaining = false; - let .remainingValue = 0; - } - - fn new( new_position: i32, new_string: &String, remaining_value: i32) -> DecodedInformation { - super(new_position); - let .remaining = true; - let .remainingValue = remaining_value; - let .newString = new_string; - } - - fn get_new_string(&self) -> String { - return self.newString; - } - - fn is_remaining(&self) -> bool { - return self.remaining; - } - - fn get_remaining_value(&self) -> i32 { - return self.remainingValue; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_numeric.rs b/port_src/output/zxing/oned/rss/expanded/decoders/decoded_numeric.rs deleted file mode 100644 index 37bea05..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_numeric.rs +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - - const FNC1: i32 = 10; -struct DecodedNumeric { - super: DecodedObject; - - let first_digit: i32; - - let second_digit: i32; -} - -impl DecodedNumeric { - - fn new( new_position: i32, first_digit: i32, second_digit: i32) -> DecodedNumeric throws FormatException { - super(new_position); - if first_digit < 0 || first_digit > 10 || second_digit < 0 || second_digit > 10 { - throw FormatException::get_format_instance(); - } - let .firstDigit = first_digit; - let .secondDigit = second_digit; - } - - fn get_first_digit(&self) -> i32 { - return self.firstDigit; - } - - fn get_second_digit(&self) -> i32 { - return self.secondDigit; - } - - fn get_value(&self) -> i32 { - return self.firstDigit * 10 + self.secondDigit; - } - - fn is_first_digit_f_n_c1(&self) -> bool { - return self.firstDigit == FNC1; - } - - fn is_second_digit_f_n_c1(&self) -> bool { - return self.secondDigit == FNC1; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_object.rs b/port_src/output/zxing/oned/rss/expanded/decoders/decoded_object.rs deleted file mode 100644 index ed28cfd..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/decoded_object.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ -struct DecodedObject { - - let new_position: i32; -} - -impl DecodedObject { - - fn new( new_position: i32) -> DecodedObject { - let .newPosition = new_position; - } - - fn get_new_position(&self) -> i32 { - return self.newPosition; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/field_parser.rs b/port_src/output/zxing/oned/rss/expanded/decoders/field_parser.rs deleted file mode 100644 index 12df4e8..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/field_parser.rs +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - - const TWO_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); - - const THREE_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); - - const THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); - - const FOUR_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); -struct FieldParser { -} - -impl FieldParser { - - static { - TWO_DIGIT_DATA_LENGTH::put("00", &DataLength::fixed(18)); - TWO_DIGIT_DATA_LENGTH::put("01", &DataLength::fixed(14)); - TWO_DIGIT_DATA_LENGTH::put("02", &DataLength::fixed(14)); - TWO_DIGIT_DATA_LENGTH::put("10", &DataLength::variable(20)); - TWO_DIGIT_DATA_LENGTH::put("11", &DataLength::fixed(6)); - TWO_DIGIT_DATA_LENGTH::put("12", &DataLength::fixed(6)); - TWO_DIGIT_DATA_LENGTH::put("13", &DataLength::fixed(6)); - TWO_DIGIT_DATA_LENGTH::put("15", &DataLength::fixed(6)); - TWO_DIGIT_DATA_LENGTH::put("17", &DataLength::fixed(6)); - TWO_DIGIT_DATA_LENGTH::put("20", &DataLength::fixed(2)); - TWO_DIGIT_DATA_LENGTH::put("21", &DataLength::variable(20)); - TWO_DIGIT_DATA_LENGTH::put("22", &DataLength::variable(29)); - TWO_DIGIT_DATA_LENGTH::put("30", &DataLength::variable(8)); - TWO_DIGIT_DATA_LENGTH::put("37", &DataLength::variable(8)); - //internal company codes - { - let mut i: i32 = 90; - while i <= 99 { - { - TWO_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::variable(30)); - } - i += 1; - } - } - - } - - static { - THREE_DIGIT_DATA_LENGTH::put("240", &DataLength::variable(30)); - THREE_DIGIT_DATA_LENGTH::put("241", &DataLength::variable(30)); - THREE_DIGIT_DATA_LENGTH::put("242", &DataLength::variable(6)); - THREE_DIGIT_DATA_LENGTH::put("250", &DataLength::variable(30)); - THREE_DIGIT_DATA_LENGTH::put("251", &DataLength::variable(30)); - THREE_DIGIT_DATA_LENGTH::put("253", &DataLength::variable(17)); - THREE_DIGIT_DATA_LENGTH::put("254", &DataLength::variable(20)); - THREE_DIGIT_DATA_LENGTH::put("400", &DataLength::variable(30)); - THREE_DIGIT_DATA_LENGTH::put("401", &DataLength::variable(30)); - THREE_DIGIT_DATA_LENGTH::put("402", &DataLength::fixed(17)); - THREE_DIGIT_DATA_LENGTH::put("403", &DataLength::variable(30)); - THREE_DIGIT_DATA_LENGTH::put("410", &DataLength::fixed(13)); - THREE_DIGIT_DATA_LENGTH::put("411", &DataLength::fixed(13)); - THREE_DIGIT_DATA_LENGTH::put("412", &DataLength::fixed(13)); - THREE_DIGIT_DATA_LENGTH::put("413", &DataLength::fixed(13)); - THREE_DIGIT_DATA_LENGTH::put("414", &DataLength::fixed(13)); - THREE_DIGIT_DATA_LENGTH::put("420", &DataLength::variable(20)); - THREE_DIGIT_DATA_LENGTH::put("421", &DataLength::variable(15)); - THREE_DIGIT_DATA_LENGTH::put("422", &DataLength::fixed(3)); - THREE_DIGIT_DATA_LENGTH::put("423", &DataLength::variable(15)); - THREE_DIGIT_DATA_LENGTH::put("424", &DataLength::fixed(3)); - THREE_DIGIT_DATA_LENGTH::put("425", &DataLength::fixed(3)); - THREE_DIGIT_DATA_LENGTH::put("426", &DataLength::fixed(3)); - } - - static { - { - let mut i: i32 = 310; - while i <= 316 { - { - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); - } - i += 1; - } - } - - { - let mut i: i32 = 320; - while i <= 336 { - { - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); - } - i += 1; - } - } - - { - let mut i: i32 = 340; - while i <= 357 { - { - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); - } - i += 1; - } - } - - { - let mut i: i32 = 360; - while i <= 369 { - { - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); - } - i += 1; - } - } - - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("390", &DataLength::variable(15)); - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("391", &DataLength::variable(18)); - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("392", &DataLength::variable(15)); - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("393", &DataLength::variable(18)); - THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("703", &DataLength::variable(30)); - } - - static { - FOUR_DIGIT_DATA_LENGTH::put("7001", &DataLength::fixed(13)); - FOUR_DIGIT_DATA_LENGTH::put("7002", &DataLength::variable(30)); - FOUR_DIGIT_DATA_LENGTH::put("7003", &DataLength::fixed(10)); - FOUR_DIGIT_DATA_LENGTH::put("8001", &DataLength::fixed(14)); - FOUR_DIGIT_DATA_LENGTH::put("8002", &DataLength::variable(20)); - FOUR_DIGIT_DATA_LENGTH::put("8003", &DataLength::variable(30)); - FOUR_DIGIT_DATA_LENGTH::put("8004", &DataLength::variable(30)); - FOUR_DIGIT_DATA_LENGTH::put("8005", &DataLength::fixed(6)); - FOUR_DIGIT_DATA_LENGTH::put("8006", &DataLength::fixed(18)); - FOUR_DIGIT_DATA_LENGTH::put("8007", &DataLength::variable(30)); - FOUR_DIGIT_DATA_LENGTH::put("8008", &DataLength::variable(12)); - FOUR_DIGIT_DATA_LENGTH::put("8018", &DataLength::fixed(18)); - FOUR_DIGIT_DATA_LENGTH::put("8020", &DataLength::variable(25)); - FOUR_DIGIT_DATA_LENGTH::put("8100", &DataLength::fixed(6)); - FOUR_DIGIT_DATA_LENGTH::put("8101", &DataLength::fixed(10)); - FOUR_DIGIT_DATA_LENGTH::put("8102", &DataLength::fixed(2)); - FOUR_DIGIT_DATA_LENGTH::put("8110", &DataLength::variable(70)); - FOUR_DIGIT_DATA_LENGTH::put("8200", &DataLength::variable(70)); - } - - fn new() -> FieldParser { - } - - fn parse_fields_in_general_purpose( raw_information: &String) -> /* throws NotFoundException */Result> { - if raw_information.is_empty() { - return Ok(null); - } - if raw_information.length() < 2 { - throw NotFoundException::get_not_found_instance(); - } - let two_digit_data_length: DataLength = TWO_DIGIT_DATA_LENGTH::get(&raw_information.substring(0, 2)); - if two_digit_data_length != null { - if two_digit_data_length.variable { - return Ok(::process_variable_a_i(2, two_digit_data_length.len(), &raw_information)); - } - return Ok(::process_fixed_a_i(2, two_digit_data_length.len(), &raw_information)); - } - if raw_information.length() < 3 { - throw NotFoundException::get_not_found_instance(); - } - let first_three_digits: String = raw_information.substring(0, 3); - let three_digit_data_length: DataLength = THREE_DIGIT_DATA_LENGTH::get(&first_three_digits); - if three_digit_data_length != null { - if three_digit_data_length.variable { - return Ok(::process_variable_a_i(3, three_digit_data_length.len(), &raw_information)); - } - return Ok(::process_fixed_a_i(3, three_digit_data_length.len(), &raw_information)); - } - if raw_information.length() < 4 { - throw NotFoundException::get_not_found_instance(); - } - let three_digit_plus_digit_data_length: DataLength = THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::get(&first_three_digits); - if three_digit_plus_digit_data_length != null { - if three_digit_plus_digit_data_length.variable { - return Ok(::process_variable_a_i(4, three_digit_plus_digit_data_length.len(), &raw_information)); - } - return Ok(::process_fixed_a_i(4, three_digit_plus_digit_data_length.len(), &raw_information)); - } - let first_four_digit_length: DataLength = FOUR_DIGIT_DATA_LENGTH::get(&raw_information.substring(0, 4)); - if first_four_digit_length != null { - if first_four_digit_length.variable { - return Ok(::process_variable_a_i(4, first_four_digit_length.len(), &raw_information)); - } - return Ok(::process_fixed_a_i(4, first_four_digit_length.len(), &raw_information)); - } - throw NotFoundException::get_not_found_instance(); - } - - fn process_fixed_a_i( ai_size: i32, field_size: i32, raw_information: &String) -> /* throws NotFoundException */Result> { - if raw_information.length() < ai_size { - throw NotFoundException::get_not_found_instance(); - } - let ai: String = raw_information.substring(0, ai_size); - if raw_information.length() < ai_size + field_size { - throw NotFoundException::get_not_found_instance(); - } - let field: String = raw_information.substring(ai_size, ai_size + field_size); - let remaining: String = raw_information.substring(ai_size + field_size); - let result: String = format!("({}){}", ai, field); - let parsed_a_i: String = ::parse_fields_in_general_purpose(&remaining); - return Ok( if parsed_a_i == null { result } else { format!("{}{}", result, parsed_a_i) }); - } - - fn process_variable_a_i( ai_size: i32, variable_field_size: i32, raw_information: &String) -> /* throws NotFoundException */Result> { - let ai: String = raw_information.substring(0, ai_size); - let max_size: i32 = Math::min(&raw_information.length(), ai_size + variable_field_size); - let field: String = raw_information.substring(ai_size, max_size); - let remaining: String = raw_information.substring(max_size); - let result: String = format!("({}){}", ai, field); - let parsed_a_i: String = ::parse_fields_in_general_purpose(&remaining); - return Ok( if parsed_a_i == null { result } else { format!("{}{}", result, parsed_a_i) }); - } - - struct DataLength { - - let variable: bool; - - let length: i32; - } - - impl DataLength { - - fn new( variable: bool, length: i32) -> DataLength { - let .variable = variable; - let .len() = length; - } - - fn fixed( length: i32) -> DataLength { - return DataLength::new(false, length); - } - - fn variable( length: i32) -> DataLength { - return DataLength::new(true, length); - } - } - -} - diff --git a/port_src/output/zxing/oned/rss/expanded/decoders/general_app_id_decoder.rs b/port_src/output/zxing/oned/rss/expanded/decoders/general_app_id_decoder.rs deleted file mode 100644 index cb5cce9..0000000 --- a/port_src/output/zxing/oned/rss/expanded/decoders/general_app_id_decoder.rs +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded::decoders; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ -struct GeneralAppIdDecoder { - - let information: BitArray; - - let current: CurrentParsingState = CurrentParsingState::new(); - - let buffer: StringBuilder = StringBuilder::new(); -} - -impl GeneralAppIdDecoder { - - fn new( information: &BitArray) -> GeneralAppIdDecoder { - let .information = information; - } - - fn decode_all_codes(&self, buff: &StringBuilder, initial_position: i32) -> /* throws NotFoundException, FormatException */Result> { - let current_position: i32 = initial_position; - let mut remaining: String = null; - loop { { - let info: DecodedInformation = self.decode_general_purpose_field(current_position, &remaining); - let parsed_fields: String = FieldParser::parse_fields_in_general_purpose(&info.get_new_string()); - if parsed_fields != null { - buff.append(&parsed_fields); - } - if info.is_remaining() { - remaining = String::value_of(&info.get_remaining_value()); - } else { - remaining = null; - } - if current_position == info.get_new_position() { - // No step forward! - break; - } - current_position = info.get_new_position(); - }if !(true) break;} - return Ok(buff.to_string()); - } - - fn is_still_numeric(&self, pos: i32) -> bool { - // and one of the first 4 bits is "1". - if pos + 7 > self.information.get_size() { - return pos + 4 <= self.information.get_size(); - } - { - let mut i: i32 = pos; - while i < pos + 3 { - { - if self.information.get(i) { - return true; - } - } - i += 1; - } - } - - return self.information.get(pos + 3); - } - - fn decode_numeric(&self, pos: i32) -> /* throws FormatException */Result> { - if pos + 7 > self.information.get_size() { - let numeric: i32 = ::extract_numeric_value_from_bit_array(pos, 4); - if numeric == 0 { - return Ok(DecodedNumeric::new(&self.information.get_size(), DecodedNumeric::FNC1, DecodedNumeric::FNC1)); - } - return Ok(DecodedNumeric::new(&self.information.get_size(), numeric - 1, DecodedNumeric::FNC1)); - } - let numeric: i32 = ::extract_numeric_value_from_bit_array(pos, 7); - let digit1: i32 = (numeric - 8) / 11; - let digit2: i32 = (numeric - 8) % 11; - return Ok(DecodedNumeric::new(pos + 7, digit1, digit2)); - } - - fn extract_numeric_value_from_bit_array(&self, pos: i32, bits: i32) -> i32 { - return ::extract_numeric_value_from_bit_array(self.information, pos, bits); - } - - fn extract_numeric_value_from_bit_array( information: &BitArray, pos: i32, bits: i32) -> i32 { - let mut value: i32 = 0; - { - let mut i: i32 = 0; - while i < bits { - { - if information.get(pos + i) { - value |= 1 << (bits - i - 1); - } - } - i += 1; - } - } - - return value; - } - - fn decode_general_purpose_field(&self, pos: i32, remaining: &String) -> /* throws FormatException */Result> { - self.buffer.set_length(0); - if remaining != null { - self.buffer.append(&remaining); - } - self.current.set_position(pos); - let last_decoded: DecodedInformation = self.parse_blocks(); - if last_decoded != null && last_decoded.is_remaining() { - return Ok(DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string(), &last_decoded.get_remaining_value())); - } - return Ok(DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string())); - } - - fn parse_blocks(&self) -> /* throws FormatException */Result> { - let is_finished: bool; - let mut result: BlockParsedResult; - loop { { - let initial_position: i32 = self.current.get_position(); - if self.current.is_alpha() { - result = self.parse_alpha_block(); - is_finished = result.is_finished(); - } else if self.current.is_iso_iec646() { - result = self.parse_iso_iec646_block(); - is_finished = result.is_finished(); - } else { - // it must be numeric - result = self.parse_numeric_block(); - is_finished = result.is_finished(); - } - let position_changed: bool = initial_position != self.current.get_position(); - if !position_changed && !is_finished { - break; - } - }if !(!is_finished) break;} - return Ok(result.get_decoded_information()); - } - - fn parse_numeric_block(&self) -> /* throws FormatException */Result> { - while self.is_still_numeric(&self.current.get_position()) { - let numeric: DecodedNumeric = self.decode_numeric(&self.current.get_position()); - self.current.set_position(&numeric.get_new_position()); - if numeric.is_first_digit_f_n_c1() { - let mut information: DecodedInformation; - if numeric.is_second_digit_f_n_c1() { - information = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); - } else { - information = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string(), &numeric.get_second_digit()); - } - return Ok(BlockParsedResult::new(information, true)); - } - self.buffer.append(&numeric.get_first_digit()); - if numeric.is_second_digit_f_n_c1() { - let information: DecodedInformation = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); - return Ok(BlockParsedResult::new(information, true)); - } - self.buffer.append(&numeric.get_second_digit()); - } - if self.is_numeric_to_alpha_numeric_latch(&self.current.get_position()) { - self.current.set_alpha(); - self.current.increment_position(4); - } - return Ok(BlockParsedResult::new()); - } - - fn parse_iso_iec646_block(&self) -> /* throws FormatException */Result> { - while self.is_still_iso_iec646(&self.current.get_position()) { - let iso: DecodedChar = self.decode_iso_iec646(&self.current.get_position()); - self.current.set_position(&iso.get_new_position()); - if iso.is_f_n_c1() { - let information: DecodedInformation = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); - return Ok(BlockParsedResult::new(information, true)); - } - self.buffer.append(&iso.get_value()); - } - if self.is_alpha_or646_to_numeric_latch(&self.current.get_position()) { - self.current.increment_position(3); - self.current.set_numeric(); - } else if self.is_alpha_to646_to_alpha_latch(&self.current.get_position()) { - if self.current.get_position() + 5 < self.information.get_size() { - self.current.increment_position(5); - } else { - self.current.set_position(&self.information.get_size()); - } - self.current.set_alpha(); - } - return Ok(BlockParsedResult::new()); - } - - fn parse_alpha_block(&self) -> BlockParsedResult { - while self.is_still_alpha(&self.current.get_position()) { - let alpha: DecodedChar = self.decode_alphanumeric(&self.current.get_position()); - self.current.set_position(&alpha.get_new_position()); - if alpha.is_f_n_c1() { - let information: DecodedInformation = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); - //end of the char block - return BlockParsedResult::new(information, true); - } - self.buffer.append(&alpha.get_value()); - } - if self.is_alpha_or646_to_numeric_latch(&self.current.get_position()) { - self.current.increment_position(3); - self.current.set_numeric(); - } else if self.is_alpha_to646_to_alpha_latch(&self.current.get_position()) { - if self.current.get_position() + 5 < self.information.get_size() { - self.current.increment_position(5); - } else { - self.current.set_position(&self.information.get_size()); - } - self.current.set_iso_iec646(); - } - return BlockParsedResult::new(); - } - - fn is_still_iso_iec646(&self, pos: i32) -> bool { - if pos + 5 > self.information.get_size() { - return false; - } - let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); - if five_bit_value >= 5 && five_bit_value < 16 { - return true; - } - if pos + 7 > self.information.get_size() { - return false; - } - let seven_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 7); - if seven_bit_value >= 64 && seven_bit_value < 116 { - return true; - } - if pos + 8 > self.information.get_size() { - return false; - } - let eight_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 8); - return eight_bit_value >= 232 && eight_bit_value < 253; - } - - fn decode_iso_iec646(&self, pos: i32) -> /* throws FormatException */Result> { - let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); - if five_bit_value == 15 { - return Ok(DecodedChar::new(pos + 5, DecodedChar::FNC1)); - } - if five_bit_value >= 5 && five_bit_value < 15 { - return Ok(DecodedChar::new(pos + 5, ('0' + five_bit_value - 5) as char)); - } - let seven_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 7); - if seven_bit_value >= 64 && seven_bit_value < 90 { - return Ok(DecodedChar::new(pos + 7, (seven_bit_value + 1) as char)); - } - if seven_bit_value >= 90 && seven_bit_value < 116 { - return Ok(DecodedChar::new(pos + 7, (seven_bit_value + 7) as char)); - } - let eight_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 8); - let mut c: char; - match eight_bit_value { - 232 => - { - c = '!'; - break; - } - 233 => - { - c = '"'; - break; - } - 234 => - { - c = '%'; - break; - } - 235 => - { - c = '&'; - break; - } - 236 => - { - c = '\''; - break; - } - 237 => - { - c = '('; - break; - } - 238 => - { - c = ')'; - break; - } - 239 => - { - c = '*'; - break; - } - 240 => - { - c = '+'; - break; - } - 241 => - { - c = ','; - break; - } - 242 => - { - c = '-'; - break; - } - 243 => - { - c = '.'; - break; - } - 244 => - { - c = '/'; - break; - } - 245 => - { - c = ':'; - break; - } - 246 => - { - c = ';'; - break; - } - 247 => - { - c = '<'; - break; - } - 248 => - { - c = '='; - break; - } - 249 => - { - c = '>'; - break; - } - 250 => - { - c = '?'; - break; - } - 251 => - { - c = '_'; - break; - } - 252 => - { - c = ' '; - break; - } - _ => - { - throw FormatException::get_format_instance(); - } - } - return Ok(DecodedChar::new(pos + 8, c)); - } - - fn is_still_alpha(&self, pos: i32) -> bool { - if pos + 5 > self.information.get_size() { - return false; - } - // We now check if it's a valid 5-bit value (0..9 and FNC1) - let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); - if five_bit_value >= 5 && five_bit_value < 16 { - return true; - } - if pos + 6 > self.information.get_size() { - return false; - } - let six_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 6); - // 63 not included - return six_bit_value >= 16 && six_bit_value < 63; - } - - fn decode_alphanumeric(&self, pos: i32) -> DecodedChar { - let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); - if five_bit_value == 15 { - return DecodedChar::new(pos + 5, DecodedChar::FNC1); - } - if five_bit_value >= 5 && five_bit_value < 15 { - return DecodedChar::new(pos + 5, ('0' + five_bit_value - 5) as char); - } - let six_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 6); - if six_bit_value >= 32 && six_bit_value < 58 { - return DecodedChar::new(pos + 6, (six_bit_value + 33) as char); - } - let mut c: char; - match six_bit_value { - 58 => - { - c = '*'; - break; - } - 59 => - { - c = ','; - break; - } - 60 => - { - c = '-'; - break; - } - 61 => - { - c = '.'; - break; - } - 62 => - { - c = '/'; - break; - } - _ => - { - throw IllegalStateException::new(format!("Decoding invalid alphanumeric value: {}", six_bit_value)); - } - } - return DecodedChar::new(pos + 6, c); - } - - fn is_alpha_to646_to_alpha_latch(&self, pos: i32) -> bool { - if pos + 1 > self.information.get_size() { - return false; - } - { - let mut i: i32 = 0; - while i < 5 && i + pos < self.information.get_size() { - { - if i == 2 { - if !self.information.get(pos + 2) { - return false; - } - } else if self.information.get(pos + i) { - return false; - } - } - i += 1; - } - } - - return true; - } - - fn is_alpha_or646_to_numeric_latch(&self, pos: i32) -> bool { - // Next is alphanumeric if there are 3 positions and they are all zeros - if pos + 3 > self.information.get_size() { - return false; - } - { - let mut i: i32 = pos; - while i < pos + 3 { - { - if self.information.get(i) { - return false; - } - } - i += 1; - } - } - - return true; - } - - fn is_numeric_to_alpha_numeric_latch(&self, pos: i32) -> bool { - // if there is a subset of this just before the end of the symbol - if pos + 1 > self.information.get_size() { - return false; - } - { - let mut i: i32 = 0; - while i < 4 && i + pos < self.information.get_size() { - { - if self.information.get(pos + i) { - return false; - } - } - i += 1; - } - } - - return true; - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/expanded_pair.rs b/port_src/output/zxing/oned/rss/expanded/expanded_pair.rs deleted file mode 100644 index e730d6b..0000000 --- a/port_src/output/zxing/oned/rss/expanded/expanded_pair.rs +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - */ -struct ExpandedPair { - - let left_char: DataCharacter; - - let right_char: DataCharacter; - - let finder_pattern: FinderPattern; -} - -impl ExpandedPair { - - fn new( left_char: &DataCharacter, right_char: &DataCharacter, finder_pattern: &FinderPattern) -> ExpandedPair { - let .leftChar = left_char; - let .rightChar = right_char; - let .finderPattern = finder_pattern; - } - - fn get_left_char(&self) -> DataCharacter { - return self.leftChar; - } - - fn get_right_char(&self) -> DataCharacter { - return self.rightChar; - } - - fn get_finder_pattern(&self) -> FinderPattern { - return self.finderPattern; - } - - fn must_be_last(&self) -> bool { - return self.rightChar == null; - } - - pub fn to_string(&self) -> String { - return format!("[ {} , {} : {} ]", self.left_char, self.right_char, ( if self.finder_pattern == null { "null" } else { self.finder_pattern.get_value() })); - } - - pub fn equals(&self, o: &Object) -> bool { - if !(o instanceof ExpandedPair) { - return false; - } - let that: ExpandedPair = o as ExpandedPair; - return Objects::equals(self.left_char, that.leftChar) && Objects::equals(self.right_char, that.rightChar) && Objects::equals(self.finder_pattern, that.finderPattern); - } - - pub fn hash_code(&self) -> i32 { - return Objects::hash_code(self.left_char) ^ Objects::hash_code(self.right_char) ^ Objects::hash_code(self.finder_pattern); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/expanded_row.rs b/port_src/output/zxing/oned/rss/expanded/expanded_row.rs deleted file mode 100644 index f0c03bf..0000000 --- a/port_src/output/zxing/oned/rss/expanded/expanded_row.rs +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded; - -/** - * One row of an RSS Expanded Stacked symbol, consisting of 1+ expanded pairs. - */ -struct ExpandedRow { - - let pairs: List; - - let row_number: i32; -} - -impl ExpandedRow { - - fn new( pairs: &List, row_number: i32) -> ExpandedRow { - let .pairs = ArrayList<>::new(&pairs); - let .rowNumber = row_number; - } - - fn get_pairs(&self) -> List { - return self.pairs; - } - - fn get_row_number(&self) -> i32 { - return self.rowNumber; - } - - fn is_equivalent(&self, other_pairs: &List) -> bool { - return self.pairs.equals(&other_pairs); - } - - pub fn to_string(&self) -> String { - return format!("{ {} }", self.pairs); - } - - /** - * Two rows are equal if they contain the same pairs in the same order. - */ - pub fn equals(&self, o: &Object) -> bool { - if !(o instanceof ExpandedRow) { - return false; - } - let that: ExpandedRow = o as ExpandedRow; - return self.pairs.equals(that.pairs); - } - - pub fn hash_code(&self) -> i32 { - return self.pairs.hash_code(); - } -} - diff --git a/port_src/output/zxing/oned/rss/expanded/r_s_s_expanded_reader.rs b/port_src/output/zxing/oned/rss/expanded/r_s_s_expanded_reader.rs deleted file mode 100644 index e67e071..0000000 --- a/port_src/output/zxing/oned/rss/expanded/r_s_s_expanded_reader.rs +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Copyright (C) 2010 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::oned::rss::expanded; - -/** - * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) - * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) - */ - - const SYMBOL_WIDEST: vec![Vec; 5] = vec![7, 5, 4, 3, 1, ] -; - - const EVEN_TOTAL_SUBSET: vec![Vec; 5] = vec![4, 20, 52, 104, 204, ] -; - - const GSUM: vec![Vec; 5] = vec![0, 348, 1388, 2948, 3988, ] -; - - const FINDER_PATTERNS: vec![vec![Vec>; 4]; 6] = vec![// A -vec![1, 8, 4, 1, ] -, // B -vec![3, 6, 4, 1, ] -, // C -vec![3, 4, 6, 1, ] -, // D -vec![3, 2, 8, 1, ] -, // E -vec![2, 6, 5, 1, ] -, // F -vec![2, 2, 9, 1, ] -, ] -; - - const WEIGHTS: vec![vec![Vec>; 8]; 23] = vec![vec![1, 3, 9, 27, 81, 32, 96, 77, ] -, vec![20, 60, 180, 118, 143, 7, 21, 63, ] -, vec![189, 145, 13, 39, 117, 140, 209, 205, ] -, vec![193, 157, 49, 147, 19, 57, 171, 91, ] -, vec![62, 186, 136, 197, 169, 85, 44, 132, ] -, vec![185, 133, 188, 142, 4, 12, 36, 108, ] -, vec![113, 128, 173, 97, 80, 29, 87, 50, ] -, vec![150, 28, 84, 41, 123, 158, 52, 156, ] -, vec![46, 138, 203, 187, 139, 206, 196, 166, ] -, vec![76, 17, 51, 153, 37, 111, 122, 155, ] -, vec![43, 129, 176, 106, 107, 110, 119, 146, ] -, vec![16, 48, 144, 10, 30, 90, 59, 177, ] -, vec![109, 116, 137, 200, 178, 112, 125, 164, ] -, vec![70, 210, 208, 202, 184, 130, 179, 115, ] -, vec![134, 191, 151, 31, 93, 68, 204, 190, ] -, vec![148, 22, 66, 198, 172, 94, 71, 2, ] -, vec![6, 18, 54, 162, 64, 192, 154, 40, ] -, vec![120, 149, 25, 75, 14, 42, 126, 167, ] -, vec![79, 26, 78, 23, 69, 207, 199, 175, ] -, vec![103, 98, 83, 38, 114, 131, 182, 124, ] -, vec![161, 61, 183, 127, 170, 88, 53, 159, ] -, vec![55, 165, 73, 8, 24, 72, 5, 15, ] -, vec![45, 135, 194, 160, 58, 174, 100, 89, ] -, ] -; - - const FINDER_PAT_A: i32 = 0; - - const FINDER_PAT_B: i32 = 1; - - const FINDER_PAT_C: i32 = 2; - - const FINDER_PAT_D: i32 = 3; - - const FINDER_PAT_E: i32 = 4; - - const FINDER_PAT_F: i32 = 5; - - const FINDER_PATTERN_SEQUENCES: vec![vec![Vec>; 11]; 10] = vec![vec![FINDER_PAT_A, FINDER_PAT_A, ] -, vec![FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, ] -, vec![FINDER_PAT_A, FINDER_PAT_C, FINDER_PAT_B, FINDER_PAT_D, ] -, vec![FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_C, ] -, vec![FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_F, ] -, vec![FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F, ] -, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D, ] -, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E, ] -, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F, ] -, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F, ] -, ] -; - - const MAX_PAIRS: i32 = 11; -pub struct RSSExpandedReader { - super: AbstractRSSReader; - - let pairs: List = ArrayList<>::new(MAX_PAIRS); - - let rows: List = ArrayList<>::new(); - - let start_end: [i32; 2] = [0; 2]; - - let start_from_even: bool; -} - -impl RSSExpandedReader { - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, FormatException */Result> { - // Rows can start with even pattern in case in prev rows there where odd number of patters. - // So lets try twice - self.pairs.clear(); - self.startFromEven = false; - let tryResult1 = 0; - 'try1: loop { - { - return Ok(::construct_result(&self.decode_row2pairs(row_number, row))); - } - break 'try1 - } - match tryResult1 { - catch ( e: &NotFoundException) { - } 0 => break - } - - self.pairs.clear(); - self.startFromEven = true; - return Ok(::construct_result(&self.decode_row2pairs(row_number, row))); - } - - pub fn reset(&self) { - self.pairs.clear(); - self.rows.clear(); - } - - // Not private for testing - fn decode_row2pairs(&self, row_number: i32, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { - let mut done: bool = false; - while !done { - let tryResult1 = 0; - 'try1: loop { - { - self.pairs.add(&self.retrieve_next_pair(row, self.pairs, row_number)); - } - break 'try1 - } - match tryResult1 { - catch ( nfe: &NotFoundException) { - if self.pairs.is_empty() { - throw nfe; - } - done = true; - } 0 => break - } - - } - // TODO: verify sequence of finder patterns as in checkPairSequence() - if self.check_checksum() { - return Ok(self.pairs); - } - let try_stacked_decode: bool = !self.rows.is_empty(); - // TODO: deal with reversed rows - self.store_row(row_number); - if try_stacked_decode { - // When the image is 180-rotated, then rows are sorted in wrong direction. - // Try twice with both the directions. - let mut ps: List = self.check_rows(false); - if ps != null { - return Ok(ps); - } - ps = self.check_rows(true); - if ps != null { - return Ok(ps); - } - } - throw NotFoundException::get_not_found_instance(); - } - - fn check_rows(&self, reverse: bool) -> List { - // Stacked barcode can have up to 11 rows, so 25 seems reasonable enough - if self.rows.size() > 25 { - // We will never have a chance to get result, so clear it - self.rows.clear(); - return Ok(null); - } - self.pairs.clear(); - if reverse { - Collections::reverse(self.rows); - } - let mut ps: List = null; - let tryResult1 = 0; - 'try1: loop { - { - ps = self.check_rows(ArrayList<>::new(), 0); - } - break 'try1 - } - match tryResult1 { - catch ( e: &NotFoundException) { - } 0 => break - } - - if reverse { - Collections::reverse(self.rows); - } - return Ok(ps); - } - - // Try to construct a valid rows sequence - // Recursion is used to implement backtracking - fn check_rows(&self, collected_rows: &List, current_row: i32) -> /* throws NotFoundException */Result, Rc> { - { - let mut i: i32 = current_row; - while i < self.rows.size() { - { - let row: ExpandedRow = self.rows.get(i); - self.pairs.clear(); - for let collected_row: ExpandedRow in collected_rows { - self.pairs.add_all(&collected_row.get_pairs()); - } - self.pairs.add_all(&row.get_pairs()); - if ::is_valid_sequence(self.pairs) { - if self.check_checksum() { - return Ok(self.pairs); - } - let rs: List = ArrayList<>::new(&collected_rows); - rs.add(row); - let tryResult1 = 0; - 'try1: loop { - { - // Recursion: try to add more rows - return Ok(self.check_rows(&rs, i + 1)); - } - break 'try1 - } - match tryResult1 { - catch ( e: &NotFoundException) { - } 0 => break - } - - } - } - i += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - // Whether the pairs form a valid find pattern sequence, - // either complete or a prefix - fn is_valid_sequence( pairs: &List) -> bool { - for let sequence: Vec in FINDER_PATTERN_SEQUENCES { - if pairs.size() <= sequence.len() { - let mut stop: bool = true; - { - let mut j: i32 = 0; - while j < pairs.size() { - { - if pairs.get(j).get_finder_pattern().get_value() != sequence[j] { - stop = false; - break; - } - } - j += 1; - } - } - - if stop { - return true; - } - } - } - return false; - } - - fn store_row(&self, row_number: i32) { - // Discard if duplicate above or below; otherwise insert in order by row number. - let insert_pos: i32 = 0; - let prev_is_same: bool = false; - let next_is_same: bool = false; - while insert_pos < self.rows.size() { - let erow: ExpandedRow = self.rows.get(insert_pos); - if erow.get_row_number() > row_number { - next_is_same = erow.is_equivalent(self.pairs); - break; - } - prev_is_same = erow.is_equivalent(self.pairs); - insert_pos += 1; - } - if next_is_same || prev_is_same { - return; - } - // Check whether the row is part of an already detected row - if ::is_partial_row(self.pairs, self.rows) { - return; - } - self.rows.add(insert_pos, ExpandedRow::new(self.pairs, row_number)); - ::remove_partial_rows(self.pairs, self.rows); - } - - // Remove all the rows that contains only specified pairs - fn remove_partial_rows( pairs: &Collection, rows: &Collection) { - { - let iterator: Iterator = rows.iterator(); - while iterator.has_next(){ - let r: ExpandedRow = iterator.next(); - if r.get_pairs().size() != pairs.size() { - let all_found: bool = true; - for let p: ExpandedPair in r.get_pairs() { - if !pairs.contains(p) { - all_found = false; - break; - } - } - if all_found { - // 'pairs' contains all the pairs from the row 'r' - iterator.remove(); - } - } - } - } - - } - - // Returns true when one of the rows already contains all the pairs - fn is_partial_row( pairs: &Iterable, rows: &Iterable) -> bool { - for let r: ExpandedRow in rows { - let all_found: bool = true; - for let p: ExpandedPair in pairs { - let mut found: bool = false; - for let pp: ExpandedPair in r.get_pairs() { - if p.equals(pp) { - found = true; - break; - } - } - if !found { - all_found = false; - break; - } - } - if all_found { - // the row 'r' contain all the pairs from 'pairs' - return true; - } - } - return false; - } - - // Only used for unit testing - fn get_rows(&self) -> List { - return self.rows; - } - - // Not private for unit testing - fn construct_result( pairs: &List) -> /* throws NotFoundException, FormatException */Result> { - let binary: BitArray = BitArrayBuilder::build_bit_array(&pairs); - let decoder: AbstractExpandedDecoder = AbstractExpandedDecoder::create_decoder(binary); - let resulting_string: String = decoder.parse_information(); - let first_points: Vec = pairs.get(0).get_finder_pattern().get_result_points(); - let last_points: Vec = pairs.get(pairs.size() - 1).get_finder_pattern().get_result_points(); - let result: Result = Result::new(&resulting_string, null, : vec![ResultPoint; 4] = vec![first_points[0], first_points[1], last_points[0], last_points[1], ] - , BarcodeFormat::RSS_EXPANDED); - result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]e0"); - return Ok(result); - } - - fn check_checksum(&self) -> bool { - let first_pair: ExpandedPair = self.pairs.get(0); - let check_character: DataCharacter = first_pair.get_left_char(); - let first_character: DataCharacter = first_pair.get_right_char(); - if first_character == null { - return false; - } - let mut checksum: i32 = first_character.get_checksum_portion(); - let mut s: i32 = 2; - { - let mut i: i32 = 1; - while i < self.pairs.size() { - { - let current_pair: ExpandedPair = self.pairs.get(i); - checksum += current_pair.get_left_char().get_checksum_portion(); - s += 1; - let current_right_char: DataCharacter = current_pair.get_right_char(); - if current_right_char != null { - checksum += current_right_char.get_checksum_portion(); - s += 1; - } - } - i += 1; - } - } - - checksum %= 211; - let check_character_value: i32 = 211 * (s - 4) + checksum; - return check_character_value == check_character.get_value(); - } - - fn get_next_second_bar( row: &BitArray, initial_pos: i32) -> i32 { - let current_pos: i32; - if row.get(initial_pos) { - current_pos = row.get_next_unset(initial_pos); - current_pos = row.get_next_set(current_pos); - } else { - current_pos = row.get_next_set(initial_pos); - current_pos = row.get_next_unset(current_pos); - } - return current_pos; - } - - // not private for testing - fn retrieve_next_pair(&self, row: &BitArray, previous_pairs: &List, row_number: i32) -> /* throws NotFoundException */Result> { - let is_odd_pattern: bool = previous_pairs.size() % 2 == 0; - if self.start_from_even { - is_odd_pattern = !is_odd_pattern; - } - let mut pattern: FinderPattern; - let keep_finding: bool = true; - let forced_offset: i32 = -1; - loop { { - self.find_next_pair(row, &previous_pairs, forced_offset); - pattern = self.parse_found_finder_pattern(row, row_number, is_odd_pattern); - if pattern == null { - forced_offset = ::get_next_second_bar(row, self.startEnd[0]); - } else { - keep_finding = false; - } - }if !(keep_finding) break;} - // When stacked symbol is split over multiple rows, there's no way to guess if this pair can be last or not. - // boolean mayBeLast = checkPairSequence(previousPairs, pattern); - let left_char: DataCharacter = self.decode_data_character(row, pattern, is_odd_pattern, true); - if !previous_pairs.is_empty() && previous_pairs.get(previous_pairs.size() - 1).must_be_last() { - throw NotFoundException::get_not_found_instance(); - } - let right_char: DataCharacter; - let tryResult1 = 0; - 'try1: loop { - { - right_char = self.decode_data_character(row, pattern, is_odd_pattern, false); - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &NotFoundException) { - right_char = null; - } 0 => break - } - - return Ok(ExpandedPair::new(left_char, right_char, pattern)); - } - - fn find_next_pair(&self, row: &BitArray, previous_pairs: &List, forced_offset: i32) -> /* throws NotFoundException */Result> { - let mut counters: Vec = self.get_decode_finder_counters(); - counters[0] = 0; - counters[1] = 0; - counters[2] = 0; - counters[3] = 0; - let width: i32 = row.get_size(); - let row_offset: i32; - if forced_offset >= 0 { - row_offset = forced_offset; - } else if previous_pairs.is_empty() { - row_offset = 0; - } else { - let last_pair: ExpandedPair = previous_pairs.get(previous_pairs.size() - 1); - row_offset = last_pair.get_finder_pattern().get_start_end()[1]; - } - let searching_even_pair: bool = previous_pairs.size() % 2 != 0; - if self.start_from_even { - searching_even_pair = !searching_even_pair; - } - let is_white: bool = false; - while row_offset < width { - is_white = !row.get(row_offset); - if !is_white { - break; - } - row_offset += 1; - } - let counter_position: i32 = 0; - let pattern_start: i32 = row_offset; - { - let mut x: i32 = row_offset; - while x < width { - { - if row.get(x) != is_white { - counters[counter_position] += 1; - } else { - if counter_position == 3 { - if searching_even_pair { - ::reverse_counters(&counters); - } - if is_finder_pattern(&counters) { - self.startEnd[0] = pattern_start; - self.startEnd[1] = x; - return; - } - if searching_even_pair { - ::reverse_counters(&counters); - } - pattern_start += counters[0] + counters[1]; - counters[0] = counters[2]; - counters[1] = counters[3]; - counters[2] = 0; - counters[3] = 0; - counter_position -= 1; - } else { - counter_position += 1; - } - counters[counter_position] = 1; - is_white = !is_white; - } - } - x += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - fn reverse_counters( counters: &Vec) { - let mut length: i32 = counters.len(); - { - let mut i: i32 = 0; - while i < length / 2 { - { - let tmp: i32 = counters[i]; - counters[i] = counters[length - i - 1]; - counters[length - i - 1] = tmp; - } - i += 1; - } - } - - } - - fn parse_found_finder_pattern(&self, row: &BitArray, row_number: i32, odd_pattern: bool) -> FinderPattern { - // Actually we found elements 2-5. - let first_counter: i32; - let mut start: i32; - let mut end: i32; - if odd_pattern { - // If pattern number is odd, we need to locate element 1 *before* the current block. - let first_element_start: i32 = self.startEnd[0] - 1; - // Locate element 1 - while first_element_start >= 0 && !row.get(first_element_start) { - first_element_start -= 1; - } - first_element_start += 1; - first_counter = self.startEnd[0] - first_element_start; - start = first_element_start; - end = self.startEnd[1]; - } else { - // If pattern number is even, the pattern is reversed, so we need to locate element 1 *after* the current block. - start = self.startEnd[0]; - end = row.get_next_unset(self.startEnd[1] + 1); - first_counter = end - self.startEnd[1]; - } - // Make 'counters' hold 1-4 - let mut counters: Vec = self.get_decode_finder_counters(); - System::arraycopy(&counters, 0, &counters, 1, counters.len() - 1); - counters[0] = first_counter; - let mut value: i32; - let tryResult1 = 0; - 'try1: loop { - { - value = parse_finder_value(&counters, &FINDER_PATTERNS); - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &NotFoundException) { - return null; - } 0 => break - } - - return FinderPattern::new(value, : vec![i32; 2] = vec![start, end, ] - , start, end, row_number); - } - - fn decode_data_character(&self, row: &BitArray, pattern: &FinderPattern, is_odd_pattern: bool, left_char: bool) -> /* throws NotFoundException */Result> { - let mut counters: Vec = self.get_data_character_counters(); - Arrays::fill(&counters, 0); - if left_char { - record_pattern_in_reverse(row, pattern.get_start_end()[0], &counters); - } else { - record_pattern(row, pattern.get_start_end()[1], &counters); - // reverse it - { - let mut i: i32 = 0, let mut j: i32 = counters.len() - 1; - while i < j { - { - let temp: i32 = counters[i]; - counters[i] = counters[j]; - counters[j] = temp; - } - i += 1; - j -= 1; - } - } - - } - //counters[] has the pixels of the module - //left and right data characters have all the same length - let num_modules: i32 = 17; - let element_width: f32 = MathUtils::sum(&counters) / num_modules as f32; - // Sanity check: element width for pattern and the character should match - let expected_element_width: f32 = (pattern.get_start_end()[1] - pattern.get_start_end()[0]) / 15.0f; - if Math::abs(element_width - expected_element_width) / expected_element_width > 0.3f { - throw NotFoundException::get_not_found_instance(); - } - let odd_counts: Vec = self.get_odd_counts(); - let even_counts: Vec = self.get_even_counts(); - let odd_rounding_errors: Vec = self.get_odd_rounding_errors(); - let even_rounding_errors: Vec = self.get_even_rounding_errors(); - { - let mut i: i32 = 0; - while i < counters.len() { - { - let value: f32 = 1.0f * counters[i] / element_width; - // Round - let mut count: i32 = (value + 0.5f) as i32; - if count < 1 { - if value < 0.3f { - throw NotFoundException::get_not_found_instance(); - } - count = 1; - } else if count > 8 { - if value > 8.7f { - throw NotFoundException::get_not_found_instance(); - } - count = 8; - } - let mut offset: i32 = i / 2; - if (i & 0x01) == 0 { - odd_counts[offset] = count; - odd_rounding_errors[offset] = value - count; - } else { - even_counts[offset] = count; - even_rounding_errors[offset] = value - count; - } - } - i += 1; - } - } - - self.adjust_odd_even_counts(num_modules); - let weight_row_number: i32 = 4 * pattern.get_value() + ( if is_odd_pattern { 0 } else { 2 }) + ( if left_char { 0 } else { 1 }) - 1; - let odd_sum: i32 = 0; - let odd_checksum_portion: i32 = 0; - { - let mut i: i32 = odd_counts.len() - 1; - while i >= 0 { - { - if ::is_not_a1left(pattern, is_odd_pattern, left_char) { - let weight: i32 = WEIGHTS[weight_row_number][2 * i]; - odd_checksum_portion += odd_counts[i] * weight; - } - odd_sum += odd_counts[i]; - } - i -= 1; - } - } - - let even_checksum_portion: i32 = 0; - { - let mut i: i32 = even_counts.len() - 1; - while i >= 0 { - { - if ::is_not_a1left(pattern, is_odd_pattern, left_char) { - let weight: i32 = WEIGHTS[weight_row_number][2 * i + 1]; - even_checksum_portion += even_counts[i] * weight; - } - } - i -= 1; - } - } - - let checksum_portion: i32 = odd_checksum_portion + even_checksum_portion; - if (odd_sum & 0x01) != 0 || odd_sum > 13 || odd_sum < 4 { - throw NotFoundException::get_not_found_instance(); - } - let group: i32 = (13 - odd_sum) / 2; - let odd_widest: i32 = SYMBOL_WIDEST[group]; - let even_widest: i32 = 9 - odd_widest; - let v_odd: i32 = RSSUtils::get_r_s_svalue(&odd_counts, odd_widest, true); - let v_even: i32 = RSSUtils::get_r_s_svalue(&even_counts, even_widest, false); - let t_even: i32 = EVEN_TOTAL_SUBSET[group]; - let g_sum: i32 = GSUM[group]; - let value: i32 = v_odd * t_even + v_even + g_sum; - return Ok(DataCharacter::new(value, checksum_portion)); - } - - fn is_not_a1left( pattern: &FinderPattern, is_odd_pattern: bool, left_char: bool) -> bool { - // A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char - return !(pattern.get_value() == 0 && is_odd_pattern && left_char); - } - - fn adjust_odd_even_counts(&self, num_modules: i32) -> /* throws NotFoundException */Result> { - let odd_sum: i32 = MathUtils::sum(&self.get_odd_counts()); - let even_sum: i32 = MathUtils::sum(&self.get_even_counts()); - let increment_odd: bool = false; - let decrement_odd: bool = false; - if odd_sum > 13 { - decrement_odd = true; - } else if odd_sum < 4 { - increment_odd = true; - } - let increment_even: bool = false; - let decrement_even: bool = false; - if even_sum > 13 { - decrement_even = true; - } else if even_sum < 4 { - increment_even = true; - } - let mismatch: i32 = odd_sum + even_sum - num_modules; - let odd_parity_bad: bool = (odd_sum & 0x01) == 1; - let even_parity_bad: bool = (even_sum & 0x01) == 0; - match mismatch { - 1 => - { - if odd_parity_bad { - if even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - decrement_odd = true; - } else { - if !even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - decrement_even = true; - } - break; - } - -1 => - { - if odd_parity_bad { - if even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - increment_odd = true; - } else { - if !even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - increment_even = true; - } - break; - } - 0 => - { - if odd_parity_bad { - if !even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - // Both bad - if odd_sum < even_sum { - increment_odd = true; - decrement_even = true; - } else { - decrement_odd = true; - increment_even = true; - } - } else { - if even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - // Nothing to do! - } - break; - } - _ => - { - throw NotFoundException::get_not_found_instance(); - } - } - if increment_odd { - if decrement_odd { - throw NotFoundException::get_not_found_instance(); - } - increment(&self.get_odd_counts(), &self.get_odd_rounding_errors()); - } - if decrement_odd { - decrement(&self.get_odd_counts(), &self.get_odd_rounding_errors()); - } - if increment_even { - if decrement_even { - throw NotFoundException::get_not_found_instance(); - } - increment(&self.get_even_counts(), &self.get_odd_rounding_errors()); - } - if decrement_even { - decrement(&self.get_even_counts(), &self.get_even_rounding_errors()); - } - } -} - diff --git a/port_src/output/zxing/oned/rss/finder_pattern.rs b/port_src/output/zxing/oned/rss/finder_pattern.rs deleted file mode 100644 index f362f3d..0000000 --- a/port_src/output/zxing/oned/rss/finder_pattern.rs +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2009 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::oned::rss; - -/** - * Encapsulates an RSS barcode finder pattern, including its start/end position and row. - */ -pub struct FinderPattern { - - let value: i32; - - let start_end: Vec; - - let result_points: Vec; -} - -impl FinderPattern { - - pub fn new( value: i32, start_end: &Vec, start: i32, end: i32, row_number: i32) -> FinderPattern { - let .value = value; - let .startEnd = start_end; - let .resultPoints = : vec![ResultPoint; 2] = vec![ResultPoint::new(start, row_number), ResultPoint::new(end, row_number), ] - ; - } - - pub fn get_value(&self) -> i32 { - return self.value; - } - - pub fn get_start_end(&self) -> Vec { - return self.start_end; - } - - pub fn get_result_points(&self) -> Vec { - return self.result_points; - } - - pub fn equals(&self, o: &Object) -> bool { - if !(o instanceof FinderPattern) { - return false; - } - let that: FinderPattern = o as FinderPattern; - return self.value == that.value; - } - - pub fn hash_code(&self) -> i32 { - return self.value; - } -} - diff --git a/port_src/output/zxing/oned/rss/pair.rs b/port_src/output/zxing/oned/rss/pair.rs deleted file mode 100644 index 219903f..0000000 --- a/port_src/output/zxing/oned/rss/pair.rs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2009 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::oned::rss; - -struct Pair { - super: DataCharacter; - - let finder_pattern: FinderPattern; - - let mut count: i32; -} - -impl Pair { - - fn new( value: i32, checksum_portion: i32, finder_pattern: &FinderPattern) -> Pair { - super(value, checksum_portion); - let .finderPattern = finder_pattern; - } - - fn get_finder_pattern(&self) -> FinderPattern { - return self.finder_pattern; - } - - fn get_count(&self) -> i32 { - return self.count; - } - - fn increment_count(&self) { - self.count += 1; - } -} - diff --git a/port_src/output/zxing/oned/rss/r_s_s14_reader.rs b/port_src/output/zxing/oned/rss/r_s_s14_reader.rs deleted file mode 100644 index fb2fe82..0000000 --- a/port_src/output/zxing/oned/rss/r_s_s14_reader.rs +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright 2009 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::oned::rss; - -/** - * Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006. - */ - - const OUTSIDE_EVEN_TOTAL_SUBSET: vec![Vec; 5] = vec![1, 10, 34, 70, 126, ] -; - - const INSIDE_ODD_TOTAL_SUBSET: vec![Vec; 4] = vec![4, 20, 48, 81, ] -; - - const OUTSIDE_GSUM: vec![Vec; 5] = vec![0, 161, 961, 2015, 2715, ] -; - - const INSIDE_GSUM: vec![Vec; 4] = vec![0, 336, 1036, 1516, ] -; - - const OUTSIDE_ODD_WIDEST: vec![Vec; 5] = vec![8, 6, 4, 3, 1, ] -; - - const INSIDE_ODD_WIDEST: vec![Vec; 4] = vec![2, 4, 6, 8, ] -; - - const FINDER_PATTERNS: vec![vec![Vec>; 4]; 9] = vec![vec![3, 8, 2, 1, ] -, vec![3, 5, 5, 1, ] -, vec![3, 3, 7, 1, ] -, vec![3, 1, 9, 1, ] -, vec![2, 7, 4, 1, ] -, vec![2, 5, 6, 1, ] -, vec![2, 3, 8, 1, ] -, vec![1, 5, 7, 1, ] -, vec![1, 3, 9, 1, ] -, ] -; -pub struct RSS14Reader { - super: AbstractRSSReader; - - let possible_left_pairs: List; - - let possible_right_pairs: List; -} - -impl RSS14Reader { - - pub fn new() -> RSS14Reader { - possible_left_pairs = ArrayList<>::new(); - possible_right_pairs = ArrayList<>::new(); - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { - let left_pair: Pair = self.decode_pair(row, false, row_number, &hints); - ::add_or_tally(&self.possible_left_pairs, left_pair); - row.reverse(); - let right_pair: Pair = self.decode_pair(row, true, row_number, &hints); - ::add_or_tally(&self.possible_right_pairs, right_pair); - row.reverse(); - for let left: Pair in self.possible_left_pairs { - if left.get_count() > 1 { - for let right: Pair in self.possible_right_pairs { - if right.get_count() > 1 && ::check_checksum(left, right) { - return Ok(::construct_result(left, right)); - } - } - } - } - throw NotFoundException::get_not_found_instance(); - } - - fn add_or_tally( possible_pairs: &Collection, pair: &Pair) { - if pair == null { - return; - } - let mut found: bool = false; - for let other: Pair in possible_pairs { - if other.get_value() == pair.get_value() { - other.increment_count(); - found = true; - break; - } - } - if !found { - possible_pairs.add(pair); - } - } - - pub fn reset(&self) { - self.possible_left_pairs.clear(); - self.possible_right_pairs.clear(); - } - - fn construct_result( left_pair: &Pair, right_pair: &Pair) -> Result { - let symbol_value: i64 = 4537077 * left_pair.get_value() + right_pair.get_value(); - let text: String = String::value_of(symbol_value); - let buffer: StringBuilder = StringBuilder::new(14); - { - let mut i: i32 = 13 - text.length(); - while i > 0 { - { - buffer.append('0'); - } - i -= 1; - } - } - - buffer.append(&text); - let check_digit: i32 = 0; - { - let mut i: i32 = 0; - while i < 13 { - { - let digit: i32 = buffer.char_at(i) - '0'; - check_digit += if (i & 0x01) == 0 { 3 * digit } else { digit }; - } - i += 1; - } - } - - check_digit = 10 - (check_digit % 10); - if check_digit == 10 { - check_digit = 0; - } - buffer.append(check_digit); - let left_points: Vec = left_pair.get_finder_pattern().get_result_points(); - let right_points: Vec = right_pair.get_finder_pattern().get_result_points(); - let result: Result = Result::new(&buffer.to_string(), null, : vec![ResultPoint; 4] = vec![left_points[0], left_points[1], right_points[0], right_points[1], ] - , BarcodeFormat::RSS_14); - result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]e0"); - return result; - } - - fn check_checksum( left_pair: &Pair, right_pair: &Pair) -> bool { - let check_value: i32 = (left_pair.get_checksum_portion() + 16 * right_pair.get_checksum_portion()) % 79; - let target_check_value: i32 = 9 * left_pair.get_finder_pattern().get_value() + right_pair.get_finder_pattern().get_value(); - if target_check_value > 72 { - target_check_value -= 1; - } - if target_check_value > 8 { - target_check_value -= 1; - } - return check_value == target_check_value; - } - - fn decode_pair(&self, row: &BitArray, right: bool, row_number: i32, hints: &Map) -> Pair { - let tryResult1 = 0; - 'try1: loop { - { - let start_end: Vec = self.find_finder_pattern(row, right); - let pattern: FinderPattern = self.parse_found_finder_pattern(row, row_number, right, &start_end); - let result_point_callback: ResultPointCallback = if hints == null { null } else { hints.get(DecodeHintType::NEED_RESULT_POINT_CALLBACK) as ResultPointCallback }; - if result_point_callback != null { - start_end = pattern.get_start_end(); - let mut center: f32 = (start_end[0] + start_end[1] - 1.0) / 2.0f; - if right { - // row is actually reversed - center = row.get_size() - 1.0 - center; - } - result_point_callback.found_possible_result_point(ResultPoint::new(center, row_number)); - } - let outside: DataCharacter = self.decode_data_character(row, pattern, true); - let inside: DataCharacter = self.decode_data_character(row, pattern, false); - return Pair::new(1597 * outside.get_value() + inside.get_value(), outside.get_checksum_portion() + 4 * inside.get_checksum_portion(), pattern); - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &NotFoundException) { - return null; - } 0 => break - } - - } - - fn decode_data_character(&self, row: &BitArray, pattern: &FinderPattern, outside_char: bool) -> /* throws NotFoundException */Result> { - let mut counters: Vec = get_data_character_counters(); - Arrays::fill(&counters, 0); - if outside_char { - record_pattern_in_reverse(row, pattern.get_start_end()[0], &counters); - } else { - record_pattern(row, pattern.get_start_end()[1], &counters); - // reverse it - { - let mut i: i32 = 0, let mut j: i32 = counters.len() - 1; - while i < j { - { - let temp: i32 = counters[i]; - counters[i] = counters[j]; - counters[j] = temp; - } - i += 1; - j -= 1; - } - } - - } - let num_modules: i32 = if outside_char { 16 } else { 15 }; - let element_width: f32 = MathUtils::sum(&counters) / num_modules as f32; - let odd_counts: Vec = self.get_odd_counts(); - let even_counts: Vec = self.get_even_counts(); - let odd_rounding_errors: Vec = self.get_odd_rounding_errors(); - let even_rounding_errors: Vec = self.get_even_rounding_errors(); - { - let mut i: i32 = 0; - while i < counters.len() { - { - let value: f32 = counters[i] / element_width; - // Round - let mut count: i32 = (value + 0.5f) as i32; - if count < 1 { - count = 1; - } else if count > 8 { - count = 8; - } - let mut offset: i32 = i / 2; - if (i & 0x01) == 0 { - odd_counts[offset] = count; - odd_rounding_errors[offset] = value - count; - } else { - even_counts[offset] = count; - even_rounding_errors[offset] = value - count; - } - } - i += 1; - } - } - - self.adjust_odd_even_counts(outside_char, num_modules); - let odd_sum: i32 = 0; - let odd_checksum_portion: i32 = 0; - { - let mut i: i32 = odd_counts.len() - 1; - while i >= 0 { - { - odd_checksum_portion *= 9; - odd_checksum_portion += odd_counts[i]; - odd_sum += odd_counts[i]; - } - i -= 1; - } - } - - let even_checksum_portion: i32 = 0; - let even_sum: i32 = 0; - { - let mut i: i32 = even_counts.len() - 1; - while i >= 0 { - { - even_checksum_portion *= 9; - even_checksum_portion += even_counts[i]; - even_sum += even_counts[i]; - } - i -= 1; - } - } - - let checksum_portion: i32 = odd_checksum_portion + 3 * even_checksum_portion; - if outside_char { - if (odd_sum & 0x01) != 0 || odd_sum > 12 || odd_sum < 4 { - throw NotFoundException::get_not_found_instance(); - } - let group: i32 = (12 - odd_sum) / 2; - let odd_widest: i32 = OUTSIDE_ODD_WIDEST[group]; - let even_widest: i32 = 9 - odd_widest; - let v_odd: i32 = RSSUtils::get_r_s_svalue(&odd_counts, odd_widest, false); - let v_even: i32 = RSSUtils::get_r_s_svalue(&even_counts, even_widest, true); - let t_even: i32 = OUTSIDE_EVEN_TOTAL_SUBSET[group]; - let g_sum: i32 = OUTSIDE_GSUM[group]; - return Ok(DataCharacter::new(v_odd * t_even + v_even + g_sum, checksum_portion)); - } else { - if (even_sum & 0x01) != 0 || even_sum > 10 || even_sum < 4 { - throw NotFoundException::get_not_found_instance(); - } - let group: i32 = (10 - even_sum) / 2; - let odd_widest: i32 = INSIDE_ODD_WIDEST[group]; - let even_widest: i32 = 9 - odd_widest; - let v_odd: i32 = RSSUtils::get_r_s_svalue(&odd_counts, odd_widest, true); - let v_even: i32 = RSSUtils::get_r_s_svalue(&even_counts, even_widest, false); - let t_odd: i32 = INSIDE_ODD_TOTAL_SUBSET[group]; - let g_sum: i32 = INSIDE_GSUM[group]; - return Ok(DataCharacter::new(v_even * t_odd + v_odd + g_sum, checksum_portion)); - } - } - - fn find_finder_pattern(&self, row: &BitArray, right_finder_pattern: bool) -> /* throws NotFoundException */Result, Rc> { - let mut counters: Vec = get_decode_finder_counters(); - counters[0] = 0; - counters[1] = 0; - counters[2] = 0; - counters[3] = 0; - let width: i32 = row.get_size(); - let is_white: bool = false; - let row_offset: i32 = 0; - while row_offset < width { - is_white = !row.get(row_offset); - if right_finder_pattern == is_white { - // Will encounter white first when searching for right finder pattern - break; - } - row_offset += 1; - } - let counter_position: i32 = 0; - let pattern_start: i32 = row_offset; - { - let mut x: i32 = row_offset; - while x < width { - { - if row.get(x) != is_white { - counters[counter_position] += 1; - } else { - if counter_position == 3 { - if is_finder_pattern(&counters) { - return Ok( : vec![i32; 2] = vec![pattern_start, x, ] - ); - } - pattern_start += counters[0] + counters[1]; - counters[0] = counters[2]; - counters[1] = counters[3]; - counters[2] = 0; - counters[3] = 0; - counter_position -= 1; - } else { - counter_position += 1; - } - counters[counter_position] = 1; - is_white = !is_white; - } - } - x += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - fn parse_found_finder_pattern(&self, row: &BitArray, row_number: i32, right: bool, start_end: &Vec) -> /* throws NotFoundException */Result> { - // Actually we found elements 2-5 - let first_is_black: bool = row.get(start_end[0]); - let first_element_start: i32 = start_end[0] - 1; - // Locate element 1 - while first_element_start >= 0 && first_is_black != row.get(first_element_start) { - first_element_start -= 1; - } - first_element_start += 1; - let first_counter: i32 = start_end[0] - first_element_start; - // Make 'counters' hold 1-4 - let mut counters: Vec = get_decode_finder_counters(); - System::arraycopy(&counters, 0, &counters, 1, counters.len() - 1); - counters[0] = first_counter; - let value: i32 = parse_finder_value(&counters, &FINDER_PATTERNS); - let mut start: i32 = first_element_start; - let mut end: i32 = start_end[1]; - if right { - // row is actually reversed - start = row.get_size() - 1 - start; - end = row.get_size() - 1 - end; - } - return Ok(FinderPattern::new(value, : vec![i32; 2] = vec![first_element_start, start_end[1], ] - , start, end, row_number)); - } - - fn adjust_odd_even_counts(&self, outside_char: bool, num_modules: i32) -> /* throws NotFoundException */Result> { - let odd_sum: i32 = MathUtils::sum(&get_odd_counts()); - let even_sum: i32 = MathUtils::sum(&get_even_counts()); - let increment_odd: bool = false; - let decrement_odd: bool = false; - let increment_even: bool = false; - let decrement_even: bool = false; - if outside_char { - if odd_sum > 12 { - decrement_odd = true; - } else if odd_sum < 4 { - increment_odd = true; - } - if even_sum > 12 { - decrement_even = true; - } else if even_sum < 4 { - increment_even = true; - } - } else { - if odd_sum > 11 { - decrement_odd = true; - } else if odd_sum < 5 { - increment_odd = true; - } - if even_sum > 10 { - decrement_even = true; - } else if even_sum < 4 { - increment_even = true; - } - } - let mismatch: i32 = odd_sum + even_sum - num_modules; - let odd_parity_bad: bool = (odd_sum & 0x01) == ( if outside_char { 1 } else { 0 }); - let even_parity_bad: bool = (even_sum & 0x01) == 1; - /*if (mismatch == 2) { - if (!(oddParityBad && evenParityBad)) { - throw ReaderException.getInstance(); - } - decrementOdd = true; - decrementEven = true; - } else if (mismatch == -2) { - if (!(oddParityBad && evenParityBad)) { - throw ReaderException.getInstance(); - } - incrementOdd = true; - incrementEven = true; - } else */ - match mismatch { - 1 => - { - if odd_parity_bad { - if even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - decrement_odd = true; - } else { - if !even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - decrement_even = true; - } - break; - } - -1 => - { - if odd_parity_bad { - if even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - increment_odd = true; - } else { - if !even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - increment_even = true; - } - break; - } - 0 => - { - if odd_parity_bad { - if !even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - // Both bad - if odd_sum < even_sum { - increment_odd = true; - decrement_even = true; - } else { - decrement_odd = true; - increment_even = true; - } - } else { - if even_parity_bad { - throw NotFoundException::get_not_found_instance(); - } - // Nothing to do! - } - break; - } - _ => - { - throw NotFoundException::get_not_found_instance(); - } - } - if increment_odd { - if decrement_odd { - throw NotFoundException::get_not_found_instance(); - } - increment(&get_odd_counts(), &get_odd_rounding_errors()); - } - if decrement_odd { - decrement(&get_odd_counts(), &get_odd_rounding_errors()); - } - if increment_even { - if decrement_even { - throw NotFoundException::get_not_found_instance(); - } - increment(&get_even_counts(), &get_odd_rounding_errors()); - } - if decrement_even { - decrement(&get_even_counts(), &get_even_rounding_errors()); - } - } -} - diff --git a/port_src/output/zxing/oned/rss/r_s_s_utils.rs b/port_src/output/zxing/oned/rss/r_s_s_utils.rs deleted file mode 100644 index 078a6fc..0000000 --- a/port_src/output/zxing/oned/rss/r_s_s_utils.rs +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2009 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::oned::rss; - -/** Adapted from listings in ISO/IEC 24724 Appendix B and Appendix G. */ -pub struct RSSUtils { -} - -impl RSSUtils { - - fn new() -> RSSUtils { - } - - pub fn get_r_s_svalue( widths: &Vec, max_width: i32, no_narrow: bool) -> i32 { - let mut n: i32 = 0; - for let width: i32 in widths { - n += width; - } - let mut val: i32 = 0; - let narrow_mask: i32 = 0; - let elements: i32 = widths.len(); - { - let mut bar: i32 = 0; - while bar < elements - 1 { - { - let elm_width: i32; - { - elm_width = 1; - narrow_mask |= 1 << bar; - while elm_width < widths[bar] { - { - let sub_val: i32 = ::combins(n - elm_width - 1, elements - bar - 2); - if no_narrow && (narrow_mask == 0) && (n - elm_width - (elements - bar - 1) >= elements - bar - 1) { - sub_val -= ::combins(n - elm_width - (elements - bar), elements - bar - 2); - } - if elements - bar - 1 > 1 { - let less_val: i32 = 0; - { - let mxw_element: i32 = n - elm_width - (elements - bar - 2); - while mxw_element > max_width { - { - less_val += ::combins(n - elm_width - mxw_element - 1, elements - bar - 3); - } - mxw_element -= 1; - } - } - - sub_val -= less_val * (elements - 1 - bar); - } else if n - elm_width > max_width { - sub_val -= 1; - } - val += sub_val; - } - elm_width += 1; - narrow_mask &= ~(1 << bar); - } - } - - n -= elm_width; - } - bar += 1; - } - } - - return val; - } - - fn combins( n: i32, r: i32) -> i32 { - let max_denom: i32; - let min_denom: i32; - if n - r > r { - min_denom = r; - max_denom = n - r; - } else { - min_denom = n - r; - max_denom = r; - } - let mut val: i32 = 1; - let mut j: i32 = 1; - { - let mut i: i32 = n; - while i > max_denom { - { - val *= i; - if j <= min_denom { - val /= j; - j += 1; - } - } - i -= 1; - } - } - - while j <= min_denom { - val /= j; - j += 1; - } - return val; - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_a_reader.rs b/port_src/output/zxing/oned/u_p_c_a_reader.rs deleted file mode 100644 index 79d7d5b..0000000 --- a/port_src/output/zxing/oned/u_p_c_a_reader.rs +++ /dev/null @@ -1,69 +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::oned; - -/** - *

Implements decoding of the UPC-A format.

- * - * @author dswitkin@google.com (Daniel Switkin) - * @author Sean Owen - */ -pub struct UPCAReader { - super: UPCEANReader; - - let ean13_reader: UPCEANReader = EAN13Reader::new(); -} - -impl UPCAReader { - - pub fn decode_row(&self, row_number: i32, row: &BitArray, start_guard_range: &Vec, hints: &Map) -> /* throws NotFoundException, FormatException, ChecksumException */Result> { - return Ok(::maybe_return_result(&self.ean13_reader.decode_row(row_number, row, &start_guard_range, &hints))); - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, FormatException, ChecksumException */Result> { - return Ok(::maybe_return_result(&self.ean13_reader.decode_row(row_number, row, &hints))); - } - - pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, FormatException */Result> { - return Ok(::maybe_return_result(&self.ean13_reader.decode(image))); - } - - pub fn decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException, FormatException */Result> { - return Ok(::maybe_return_result(&self.ean13_reader.decode(image, &hints))); - } - - fn get_barcode_format(&self) -> BarcodeFormat { - return BarcodeFormat::UPC_A; - } - - pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { - return Ok(self.ean13_reader.decode_middle(row, &start_range, &result_string)); - } - - fn maybe_return_result( result: &Result) -> /* throws FormatException */Result> { - let text: String = result.get_text(); - if text.char_at(0) == '0' { - let upca_result: Result = Result::new(&text.substring(1), null, &result.get_result_points(), BarcodeFormat::UPC_A); - if result.get_result_metadata() != null { - upca_result.put_all_metadata(&result.get_result_metadata()); - } - return Ok(upca_result); - } else { - throw FormatException::get_format_instance(); - } - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_a_writer.rs b/port_src/output/zxing/oned/u_p_c_a_writer.rs deleted file mode 100644 index d073dee..0000000 --- a/port_src/output/zxing/oned/u_p_c_a_writer.rs +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010 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::oned; - -/** - * This object renders a UPC-A code as a {@link BitMatrix}. - * - * @author qwandor@google.com (Andrew Walbran) - */ -#[derive(Writer)] -pub struct UPCAWriter { - - let sub_writer: EAN13Writer = EAN13Writer::new(); -} - -impl UPCAWriter { - - 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 format != BarcodeFormat::UPC_A { - throw IllegalArgumentException::new(format!("Can only encode UPC-A, but got {}", format)); - } - // Transform a UPC-A code into the equivalent EAN-13 code and write it that way - return self.sub_writer.encode(format!("0{}", contents), BarcodeFormat::EAN_13, width, height, &hints); - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_e_a_n_extension2_support.rs b/port_src/output/zxing/oned/u_p_c_e_a_n_extension2_support.rs deleted file mode 100644 index 7a340e7..0000000 --- a/port_src/output/zxing/oned/u_p_c_e_a_n_extension2_support.rs +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2012 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::oned; - -/** - * @see UPCEANExtension5Support - */ -struct UPCEANExtension2Support { - - let decode_middle_counters: [i32; 4] = [0; 4]; - - let decode_row_string_buffer: StringBuilder = StringBuilder::new(); -} - -impl UPCEANExtension2Support { - - fn decode_row(&self, row_number: i32, row: &BitArray, extension_start_range: &Vec) -> /* throws NotFoundException */Result> { - let result: StringBuilder = self.decode_row_string_buffer; - result.set_length(0); - let end: i32 = self.decode_middle(row, &extension_start_range, &result); - let result_string: String = result.to_string(); - let extension_data: Map = ::parse_extension_string(&result_string); - let extension_result: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new((extension_start_range[0] + extension_start_range[1]) / 2.0f, row_number), ResultPoint::new(end, row_number), ] - , BarcodeFormat::UPC_EAN_EXTENSION); - if extension_data != null { - extension_result.put_all_metadata(&extension_data); - } - return Ok(extension_result); - } - - fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { - let mut counters: Vec = self.decode_middle_counters; - counters[0] = 0; - counters[1] = 0; - counters[2] = 0; - counters[3] = 0; - let end: i32 = row.get_size(); - let row_offset: i32 = start_range[1]; - let check_parity: i32 = 0; - { - let mut x: i32 = 0; - while x < 2 && row_offset < end { - { - let best_match: i32 = UPCEANReader::decode_digit(row, &counters, row_offset, UPCEANReader.L_AND_G_PATTERNS); - result_string.append(('0' + best_match % 10) as char); - for let counter: i32 in counters { - row_offset += counter; - } - if best_match >= 10 { - check_parity |= 1 << (1 - x); - } - if x != 1 { - // Read off separator if not last - row_offset = row.get_next_set(row_offset); - row_offset = row.get_next_unset(row_offset); - } - } - x += 1; - } - } - - if result_string.length() != 2 { - throw NotFoundException::get_not_found_instance(); - } - if Integer::parse_int(&result_string.to_string()) % 4 != check_parity { - throw NotFoundException::get_not_found_instance(); - } - return Ok(row_offset); - } - - /** - * @param raw raw content of extension - * @return formatted interpretation of raw content as a {@link Map} mapping - * one {@link ResultMetadataType} to appropriate value, or {@code null} if not known - */ - fn parse_extension_string( raw: &String) -> Map { - if raw.length() != 2 { - return null; - } - let result: Map = EnumMap<>::new(ResultMetadataType.class); - result.put(ResultMetadataType::ISSUE_NUMBER, &Integer::value_of(&raw)); - return result; - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_e_a_n_extension5_support.rs b/port_src/output/zxing/oned/u_p_c_e_a_n_extension5_support.rs deleted file mode 100644 index 07973e2..0000000 --- a/port_src/output/zxing/oned/u_p_c_e_a_n_extension5_support.rs +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2010 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::oned; - -/** - * @see UPCEANExtension2Support - */ - - const CHECK_DIGIT_ENCODINGS: vec![Vec; 10] = vec![0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05, ] -; -struct UPCEANExtension5Support { - - let decode_middle_counters: [i32; 4] = [0; 4]; - - let decode_row_string_buffer: StringBuilder = StringBuilder::new(); -} - -impl UPCEANExtension5Support { - - fn decode_row(&self, row_number: i32, row: &BitArray, extension_start_range: &Vec) -> /* throws NotFoundException */Result> { - let result: StringBuilder = self.decode_row_string_buffer; - result.set_length(0); - let end: i32 = self.decode_middle(row, &extension_start_range, &result); - let result_string: String = result.to_string(); - let extension_data: Map = ::parse_extension_string(&result_string); - let extension_result: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new((extension_start_range[0] + extension_start_range[1]) / 2.0f, row_number), ResultPoint::new(end, row_number), ] - , BarcodeFormat::UPC_EAN_EXTENSION); - if extension_data != null { - extension_result.put_all_metadata(&extension_data); - } - return Ok(extension_result); - } - - fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { - let mut counters: Vec = self.decode_middle_counters; - counters[0] = 0; - counters[1] = 0; - counters[2] = 0; - counters[3] = 0; - let end: i32 = row.get_size(); - let row_offset: i32 = start_range[1]; - let lg_pattern_found: i32 = 0; - { - let mut x: i32 = 0; - while x < 5 && row_offset < end { - { - let best_match: i32 = UPCEANReader::decode_digit(row, &counters, row_offset, UPCEANReader.L_AND_G_PATTERNS); - result_string.append(('0' + best_match % 10) as char); - for let counter: i32 in counters { - row_offset += counter; - } - if best_match >= 10 { - lg_pattern_found |= 1 << (4 - x); - } - if x != 4 { - // Read off separator if not last - row_offset = row.get_next_set(row_offset); - row_offset = row.get_next_unset(row_offset); - } - } - x += 1; - } - } - - if result_string.length() != 5 { - throw NotFoundException::get_not_found_instance(); - } - let check_digit: i32 = ::determine_check_digit(lg_pattern_found); - if ::extension_checksum(&result_string.to_string()) != check_digit { - throw NotFoundException::get_not_found_instance(); - } - return Ok(row_offset); - } - - fn extension_checksum( s: &CharSequence) -> i32 { - let length: i32 = s.length(); - let mut sum: i32 = 0; - { - let mut i: i32 = length - 2; - while i >= 0 { - { - sum += s.char_at(i) - '0'; - } - i -= 2; - } - } - - sum *= 3; - { - let mut i: i32 = length - 1; - while i >= 0 { - { - sum += s.char_at(i) - '0'; - } - i -= 2; - } - } - - sum *= 3; - return sum % 10; - } - - fn determine_check_digit( lg_pattern_found: i32) -> /* throws NotFoundException */Result> { - { - let mut d: i32 = 0; - while d < 10 { - { - if lg_pattern_found == CHECK_DIGIT_ENCODINGS[d] { - return Ok(d); - } - } - d += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - /** - * @param raw raw content of extension - * @return formatted interpretation of raw content as a {@link Map} mapping - * one {@link ResultMetadataType} to appropriate value, or {@code null} if not known - */ - fn parse_extension_string( raw: &String) -> Map { - if raw.length() != 5 { - return null; - } - let value: Object = ::parse_extension5_string(&raw); - if value == null { - return null; - } - let result: Map = EnumMap<>::new(ResultMetadataType.class); - result.put(ResultMetadataType::SUGGESTED_PRICE, &value); - return result; - } - - fn parse_extension5_string( raw: &String) -> String { - let mut currency: String; - match raw.char_at(0) { - '0' => - { - currency = "£"; - break; - } - '5' => - { - currency = "$"; - break; - } - '9' => - { - // Reference: http://www.jollytech.com - match raw { - "90000" => - { - // No suggested retail price - return null; - } - "99991" => - { - // Complementary - return "0.00"; - } - "99990" => - { - return "Used"; - } - } - // Otherwise... unknown currency? - currency = ""; - break; - } - _ => - { - currency = ""; - break; - } - } - let raw_amount: i32 = Integer::parse_int(&raw.substring(1)); - let units_string: String = String::value_of(raw_amount / 100); - let hundredths: i32 = raw_amount % 100; - let hundredths_string: String = if hundredths < 10 { format!("0{}", hundredths) } else { String::value_of(hundredths) }; - return format!("{}{}.{}", currency, units_string, hundredths_string); - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_e_a_n_extension_support.rs b/port_src/output/zxing/oned/u_p_c_e_a_n_extension_support.rs deleted file mode 100644 index a495ac3..0000000 --- a/port_src/output/zxing/oned/u_p_c_e_a_n_extension_support.rs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2010 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::oned; - - - const EXTENSION_START_PATTERN: vec![Vec; 3] = vec![1, 1, 2, ] -; -struct UPCEANExtensionSupport { - - let two_support: UPCEANExtension2Support = UPCEANExtension2Support::new(); - - let five_support: UPCEANExtension5Support = UPCEANExtension5Support::new(); -} - -impl UPCEANExtensionSupport { - - fn decode_row(&self, row_number: i32, row: &BitArray, row_offset: i32) -> /* throws NotFoundException */Result> { - let extension_start_range: Vec = UPCEANReader::find_guard_pattern(row, row_offset, false, &EXTENSION_START_PATTERN); - let tryResult1 = 0; - 'try1: loop { - { - return Ok(self.five_support.decode_row(row_number, row, &extension_start_range)); - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &ReaderException) { - return Ok(self.two_support.decode_row(row_number, row, &extension_start_range)); - } 0 => break - } - - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_e_a_n_reader.rs b/port_src/output/zxing/oned/u_p_c_e_a_n_reader.rs deleted file mode 100644 index 65f60b9..0000000 --- a/port_src/output/zxing/oned/u_p_c_e_a_n_reader.rs +++ /dev/null @@ -1,423 +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::oned; - -/** - *

Encapsulates functionality and implementation that is common to UPC and EAN families - * of one-dimensional barcodes.

- * - * @author dswitkin@google.com (Daniel Switkin) - * @author Sean Owen - * @author alasdair@google.com (Alasdair Mackintosh) - */ - -// These two values are critical for determining how permissive the decoding will be. -// We've arrived at these values through a lot of trial and error. Setting them any higher -// lets false positives creep in quickly. - const MAX_AVG_VARIANCE: f32 = 0.48f; - - const MAX_INDIVIDUAL_VARIANCE: f32 = 0.7f; - -/** - * Start/end guard pattern. - */ - const START_END_PATTERN: vec![Vec; 3] = vec![1, 1, 1, ] -; - -/** - * Pattern marking the middle of a UPC/EAN pattern, separating the two halves. - */ - const MIDDLE_PATTERN: vec![Vec; 5] = vec![1, 1, 1, 1, 1, ] -; - -/** - * end guard pattern. - */ - const END_PATTERN: vec![Vec; 6] = vec![1, 1, 1, 1, 1, 1, ] -; - -/** - * "Odd", or "L" patterns used to encode UPC/EAN digits. - */ - const L_PATTERNS: vec![vec![Vec>; 4]; 10] = vec![// 0 -vec![3, 2, 1, 1, ] -, // 1 -vec![2, 2, 2, 1, ] -, // 2 -vec![2, 1, 2, 2, ] -, // 3 -vec![1, 4, 1, 1, ] -, // 4 -vec![1, 1, 3, 2, ] -, // 5 -vec![1, 2, 3, 1, ] -, // 6 -vec![1, 1, 1, 4, ] -, // 7 -vec![1, 3, 1, 2, ] -, // 8 -vec![1, 2, 1, 3, ] -, // 9 -vec![3, 1, 1, 2, ] -, ] -; - -/** - * As above but also including the "even", or "G" patterns used to encode UPC/EAN digits. - */ - const L_AND_G_PATTERNS: Vec>; -pub struct UPCEANReader { - super: OneDReader; - - let decode_row_string_buffer: StringBuilder; - - let extension_reader: UPCEANExtensionSupport; - - let ean_man_support: EANManufacturerOrgSupport; -} - -impl UPCEANReader { - - static { - L_AND_G_PATTERNS = : [i32; 20] = [0; 20]; - System::arraycopy(&L_PATTERNS, 0, &L_AND_G_PATTERNS, 0, 10); - { - let mut i: i32 = 10; - while i < 20 { - { - let widths: Vec = L_PATTERNS[i - 10]; - let reversed_widths: [i32; widths.len()] = [0; widths.len()]; - { - let mut j: i32 = 0; - while j < widths.len() { - { - reversed_widths[j] = widths[widths.len() - j - 1]; - } - j += 1; - } - } - - L_AND_G_PATTERNS[i] = reversed_widths; - } - i += 1; - } - } - - } - - pub fn new() -> UPCEANReader { - decode_row_string_buffer = StringBuilder::new(20); - extension_reader = UPCEANExtensionSupport::new(); - ean_man_support = EANManufacturerOrgSupport::new(); - } - - fn find_start_guard_pattern( row: &BitArray) -> /* throws NotFoundException */Result, Rc> { - let found_start: bool = false; - let start_range: Vec = null; - let next_start: i32 = 0; - let counters: [i32; START_END_PATTERN.len()] = [0; START_END_PATTERN.len()]; - while !found_start { - Arrays::fill(&counters, 0, START_END_PATTERN.len(), 0); - start_range = ::find_guard_pattern(row, next_start, false, &START_END_PATTERN, &counters); - let start: i32 = start_range[0]; - next_start = start_range[1]; - // Make sure there is a quiet zone at least as big as the start pattern before the barcode. - // If this check would run off the left edge of the image, do not accept this barcode, - // as it is very likely to be a false positive. - let quiet_start: i32 = start - (next_start - start); - if quiet_start >= 0 { - found_start = row.is_range(quiet_start, start, false); - } - } - return Ok(start_range); - } - - pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { - return Ok(self.decode_row(row_number, row, &::find_start_guard_pattern(row), &hints)); - } - - /** - *

Like {@link #decodeRow(int, BitArray, Map)}, but - * allows caller to inform method about where the UPC/EAN start pattern is - * found. This allows this to be computed once and reused across many implementations.

- * - * @param rowNumber row index into the image - * @param row encoding of the row of the barcode image - * @param startGuardRange start/end column where the opening start pattern was found - * @param hints optional hints that influence decoding - * @return {@link Result} encapsulating the result of decoding a barcode in the row - * @throws NotFoundException if no potential barcode is found - * @throws ChecksumException if a potential barcode is found but does not pass its checksum - * @throws FormatException if a potential barcode is found but format is invalid - */ - pub fn decode_row(&self, row_number: i32, row: &BitArray, start_guard_range: &Vec, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { - let result_point_callback: ResultPointCallback = if hints == null { null } else { hints.get(DecodeHintType::NEED_RESULT_POINT_CALLBACK) as ResultPointCallback }; - let symbology_identifier: i32 = 0; - if result_point_callback != null { - result_point_callback.found_possible_result_point(ResultPoint::new((start_guard_range[0] + start_guard_range[1]) / 2.0f, row_number)); - } - let result: StringBuilder = self.decode_row_string_buffer; - result.set_length(0); - let end_start: i32 = self.decode_middle(row, &start_guard_range, &result); - if result_point_callback != null { - result_point_callback.found_possible_result_point(ResultPoint::new(end_start, row_number)); - } - let end_range: Vec = self.decode_end(row, end_start); - if result_point_callback != null { - result_point_callback.found_possible_result_point(ResultPoint::new((end_range[0] + end_range[1]) / 2.0f, row_number)); - } - // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The - // spec might want more whitespace, but in practice this is the maximum we can count on. - let end: i32 = end_range[1]; - let quiet_end: i32 = end + (end - end_range[0]); - if quiet_end >= row.get_size() || !row.is_range(end, quiet_end, false) { - throw NotFoundException::get_not_found_instance(); - } - let result_string: String = result.to_string(); - // UPC/EAN should never be less than 8 chars anyway - if result_string.length() < 8 { - throw FormatException::get_format_instance(); - } - if !self.check_checksum(&result_string) { - throw ChecksumException::get_checksum_instance(); - } - let left: f32 = (start_guard_range[1] + start_guard_range[0]) / 2.0f; - let right: f32 = (end_range[1] + end_range[0]) / 2.0f; - let format: BarcodeFormat = self.get_barcode_format(); - let decode_result: Result = Result::new(&result_string, // no natural byte representation for these barcodes - null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] - , format); - let extension_length: i32 = 0; - let tryResult1 = 0; - 'try1: loop { - { - let extension_result: Result = self.extension_reader.decode_row(row_number, row, end_range[1]); - decode_result.put_metadata(ResultMetadataType::UPC_EAN_EXTENSION, &extension_result.get_text()); - decode_result.put_all_metadata(&extension_result.get_result_metadata()); - decode_result.add_result_points(&extension_result.get_result_points()); - extension_length = extension_result.get_text().length(); - } - break 'try1 - } - match tryResult1 { - catch ( re: &ReaderException) { - } 0 => break - } - - let allowed_extensions: Vec = if hints == null { null } else { hints.get(DecodeHintType::ALLOWED_EAN_EXTENSIONS) as Vec }; - if allowed_extensions != null { - let mut valid: bool = false; - for let length: i32 in allowed_extensions { - if extension_length == length { - valid = true; - break; - } - } - if !valid { - throw NotFoundException::get_not_found_instance(); - } - } - if format == BarcodeFormat::EAN_13 || format == BarcodeFormat::UPC_A { - let country_i_d: String = self.ean_man_support.lookup_country_identifier(&result_string); - if country_i_d != null { - decode_result.put_metadata(ResultMetadataType::POSSIBLE_COUNTRY, &country_i_d); - } - } - if format == BarcodeFormat::EAN_8 { - symbology_identifier = 4; - } - decode_result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]E{}", symbology_identifier)); - return Ok(decode_result); - } - - /** - * @param s string of digits to check - * @return {@link #checkStandardUPCEANChecksum(CharSequence)} - * @throws FormatException if the string does not contain only digits - */ - fn check_checksum(&self, s: &String) -> /* throws FormatException */Result> { - return Ok(::check_standard_u_p_c_e_a_n_checksum(&s)); - } - - /** - * Computes the UPC/EAN checksum on a string of digits, and reports - * whether the checksum is correct or not. - * - * @param s string of digits to check - * @return true iff string of digits passes the UPC/EAN checksum algorithm - * @throws FormatException if the string does not contain only digits - */ - fn check_standard_u_p_c_e_a_n_checksum( s: &CharSequence) -> /* throws FormatException */Result> { - let length: i32 = s.length(); - if length == 0 { - return Ok(false); - } - let check: i32 = Character::digit(&s.char_at(length - 1), 10); - return Ok(::get_standard_u_p_c_e_a_n_checksum(&s.sub_sequence(0, length - 1)) == check); - } - - fn get_standard_u_p_c_e_a_n_checksum( s: &CharSequence) -> /* throws FormatException */Result> { - let length: i32 = s.length(); - let mut sum: i32 = 0; - { - let mut i: i32 = length - 1; - while i >= 0 { - { - let digit: i32 = s.char_at(i) - '0'; - if digit < 0 || digit > 9 { - throw FormatException::get_format_instance(); - } - sum += digit; - } - i -= 2; - } - } - - sum *= 3; - { - let mut i: i32 = length - 2; - while i >= 0 { - { - let digit: i32 = s.char_at(i) - '0'; - if digit < 0 || digit > 9 { - throw FormatException::get_format_instance(); - } - sum += digit; - } - i -= 2; - } - } - - return Ok((1000 - sum) % 10); - } - - fn decode_end(&self, row: &BitArray, end_start: i32) -> /* throws NotFoundException */Result, Rc> { - return Ok(::find_guard_pattern(row, end_start, false, &START_END_PATTERN)); - } - - fn find_guard_pattern( row: &BitArray, row_offset: i32, white_first: bool, pattern: &Vec) -> /* throws NotFoundException */Result, Rc> { - return Ok(::find_guard_pattern(row, row_offset, white_first, &pattern, : [i32; pattern.len()] = [0; pattern.len()])); - } - - /** - * @param row row of black/white values to search - * @param rowOffset position to start search - * @param whiteFirst if true, indicates that the pattern specifies white/black/white/... - * pixel counts, otherwise, it is interpreted as black/white/black/... - * @param pattern pattern of counts of number of black and white pixels that are being - * searched for as a pattern - * @param counters array of counters, as long as pattern, to re-use - * @return start/end horizontal offset of guard pattern, as an array of two ints - * @throws NotFoundException if pattern is not found - */ - fn find_guard_pattern( row: &BitArray, row_offset: i32, white_first: bool, pattern: &Vec, counters: &Vec) -> /* throws NotFoundException */Result, Rc> { - let width: i32 = row.get_size(); - row_offset = if white_first { row.get_next_unset(row_offset) } else { row.get_next_set(row_offset) }; - let counter_position: i32 = 0; - let pattern_start: i32 = row_offset; - let pattern_length: i32 = pattern.len(); - let is_white: bool = white_first; - { - let mut x: i32 = row_offset; - while x < width { - { - if row.get(x) != is_white { - counters[counter_position] += 1; - } else { - if counter_position == pattern_length - 1 { - if pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE { - return Ok( : vec![i32; 2] = vec![pattern_start, x, ] - ); - } - pattern_start += counters[0] + counters[1]; - System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); - counters[counter_position - 1] = 0; - counters[counter_position] = 0; - counter_position -= 1; - } else { - counter_position += 1; - } - counters[counter_position] = 1; - is_white = !is_white; - } - } - x += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - /** - * Attempts to decode a single UPC/EAN-encoded digit. - * - * @param row row of black/white values to decode - * @param counters the counts of runs of observed black/white/black/... values - * @param rowOffset horizontal offset to start decoding from - * @param patterns the set of patterns to use to decode -- sometimes different encodings - * for the digits 0-9 are used, and this indicates the encodings for 0 to 9 that should - * be used - * @return horizontal offset of first pixel beyond the decoded digit - * @throws NotFoundException if digit cannot be decoded - */ - fn decode_digit( row: &BitArray, counters: &Vec, row_offset: i32, patterns: &Vec>) -> /* throws NotFoundException */Result> { - record_pattern(row, row_offset, &counters); - // worst variance we'll accept - let best_variance: f32 = MAX_AVG_VARIANCE; - let best_match: i32 = -1; - let max: i32 = patterns.len(); - { - let mut i: i32 = 0; - while i < max { - { - let pattern: Vec = patterns[i]; - let variance: f32 = pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE); - if variance < best_variance { - best_variance = variance; - best_match = i; - } - } - i += 1; - } - } - - if best_match >= 0 { - return Ok(best_match); - } else { - throw NotFoundException::get_not_found_instance(); - } - } - - /** - * Get the format of this decoder. - * - * @return The 1D format. - */ - fn get_barcode_format(&self) -> BarcodeFormat ; - - /** - * Subclasses override this to decode the portion of a barcode between the start - * and end guard patterns. - * - * @param row row of black/white values to search - * @param startRange start/end offset of start guard pattern - * @param resultString {@link StringBuilder} to append decoded chars to - * @return horizontal offset of first pixel after the "middle" that was decoded - * @throws NotFoundException if decoding could not complete successfully - */ - pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> ; -} - diff --git a/port_src/output/zxing/oned/u_p_c_e_a_n_writer.rs b/port_src/output/zxing/oned/u_p_c_e_a_n_writer.rs deleted file mode 100644 index a0452c8..0000000 --- a/port_src/output/zxing/oned/u_p_c_e_a_n_writer.rs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2009 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::oned; - -/** - *

Encapsulates functionality and implementation that is common to UPC and EAN families - * of one-dimensional barcodes.

- * - * @author aripollak@gmail.com (Ari Pollak) - * @author dsbnatut@gmail.com (Kazuki Nishiura) - */ -pub struct UPCEANWriter { - super: OneDimensionalCodeWriter; -} - -impl UPCEANWriter { - - pub fn get_default_margin(&self) -> i32 { - // Use a different default more appropriate for UPC/EAN - return 9; - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_e_reader.rs b/port_src/output/zxing/oned/u_p_c_e_reader.rs deleted file mode 100644 index dbafc7f..0000000 --- a/port_src/output/zxing/oned/u_p_c_e_reader.rs +++ /dev/null @@ -1,202 +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::oned; - -/** - *

Implements decoding of the UPC-E format.

- *

This is a great reference for - * UPC-E information.

- * - * @author Sean Owen - */ - -/** - * The pattern that marks the middle, and end, of a UPC-E pattern. - * There is no "second half" to a UPC-E barcode. - */ - const MIDDLE_END_PATTERN: vec![Vec; 6] = vec![1, 1, 1, 1, 1, 1, ] -; - -// For an UPC-E barcode, the final digit is represented by the parities used -// to encode the middle six digits, according to the table below. -// -// Parity of next 6 digits -// Digit 0 1 2 3 4 5 -// 0 Even Even Even Odd Odd Odd -// 1 Even Even Odd Even Odd Odd -// 2 Even Even Odd Odd Even Odd -// 3 Even Even Odd Odd Odd Even -// 4 Even Odd Even Even Odd Odd -// 5 Even Odd Odd Even Even Odd -// 6 Even Odd Odd Odd Even Even -// 7 Even Odd Even Odd Even Odd -// 8 Even Odd Even Odd Odd Even -// 9 Even Odd Odd Even Odd Even -// -// The encoding is represented by the following array, which is a bit pattern -// using Odd = 0 and Even = 1. For example, 5 is represented by: -// -// Odd Even Even Odd Odd Even -// in binary: -// 0 1 1 0 0 1 == 0x19 -// -/** - * See {@link #L_AND_G_PATTERNS}; these values similarly represent patterns of - * even-odd parity encodings of digits that imply both the number system (0 or 1) - * used, and the check digit. - */ - const NUMSYS_AND_CHECK_DIGIT_PATTERNS: vec![vec![Vec>; 10]; 2] = vec![vec![0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25, ] -, vec![0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A, ] -, ] -; -pub struct UPCEReader { - super: UPCEANReader; - - let decode_middle_counters: Vec; -} - -impl UPCEReader { - - pub fn new() -> UPCEReader { - decode_middle_counters = : [i32; 4] = [0; 4]; - } - - pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result: &StringBuilder) -> /* throws NotFoundException */Result> { - let mut counters: Vec = self.decode_middle_counters; - counters[0] = 0; - counters[1] = 0; - counters[2] = 0; - counters[3] = 0; - let end: i32 = row.get_size(); - let row_offset: i32 = start_range[1]; - let lg_pattern_found: i32 = 0; - { - let mut x: i32 = 0; - while x < 6 && row_offset < end { - { - let best_match: i32 = decode_digit(row, &counters, row_offset, L_AND_G_PATTERNS); - result.append(('0' + best_match % 10) as char); - for let counter: i32 in counters { - row_offset += counter; - } - if best_match >= 10 { - lg_pattern_found |= 1 << (5 - x); - } - } - x += 1; - } - } - - ::determine_num_sys_and_check_digit(&result, lg_pattern_found); - return Ok(row_offset); - } - - pub fn decode_end(&self, row: &BitArray, end_start: i32) -> /* throws NotFoundException */Result, Rc> { - return Ok(find_guard_pattern(row, end_start, true, &MIDDLE_END_PATTERN)); - } - - pub fn check_checksum(&self, s: &String) -> /* throws FormatException */Result> { - return Ok(super.check_checksum(&::convert_u_p_c_eto_u_p_c_a(&s))); - } - - fn determine_num_sys_and_check_digit( result_string: &StringBuilder, lg_pattern_found: i32) -> /* throws NotFoundException */Result> { - { - let num_sys: i32 = 0; - while num_sys <= 1 { - { - { - let mut d: i32 = 0; - while d < 10 { - { - if lg_pattern_found == NUMSYS_AND_CHECK_DIGIT_PATTERNS[num_sys][d] { - result_string.insert(0, ('0' + num_sys) as char); - result_string.append(('0' + d) as char); - return; - } - } - d += 1; - } - } - - } - num_sys += 1; - } - } - - throw NotFoundException::get_not_found_instance(); - } - - fn get_barcode_format(&self) -> BarcodeFormat { - return BarcodeFormat::UPC_E; - } - - /** - * Expands a UPC-E value back into its full, equivalent UPC-A code value. - * - * @param upce UPC-E code as string of digits - * @return equivalent UPC-A code as string of digits - */ - pub fn convert_u_p_c_eto_u_p_c_a( upce: &String) -> String { - let upce_chars: [Option; 6] = [None; 6]; - upce.get_chars(1, 7, &upce_chars, 0); - let result: StringBuilder = StringBuilder::new(12); - result.append(&upce.char_at(0)); - let last_char: char = upce_chars[5]; - match last_char { - '0' => - { - } - '1' => - { - } - '2' => - { - result.append(&upce_chars, 0, 2); - result.append(last_char); - result.append("0000"); - result.append(&upce_chars, 2, 3); - break; - } - '3' => - { - result.append(&upce_chars, 0, 3); - result.append("00000"); - result.append(&upce_chars, 3, 2); - break; - } - '4' => - { - result.append(&upce_chars, 0, 4); - result.append("00000"); - result.append(upce_chars[4]); - break; - } - _ => - { - result.append(&upce_chars, 0, 5); - result.append("0000"); - result.append(last_char); - break; - } - } - // Only append check digit in conversion if supplied - if upce.length() >= 8 { - result.append(&upce.char_at(7)); - } - return result.to_string(); - } -} - diff --git a/port_src/output/zxing/oned/u_p_c_e_writer.rs b/port_src/output/zxing/oned/u_p_c_e_writer.rs deleted file mode 100644 index 77985b1..0000000 --- a/port_src/output/zxing/oned/u_p_c_e_writer.rs +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2009 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::oned; - -/** - * This object renders an UPC-E code as a {@link BitMatrix}. - * - * @author 0979097955s@gmail.com (RX) - */ - - const CODE_WIDTH: i32 = // start guard -3 + // bars -(7 * 6) + // end guard -6; -pub struct UPCEWriter { - super: UPCEANWriter; -} - -impl UPCEWriter { - - pub fn get_supported_write_formats(&self) -> Collection { - return Collections::singleton(BarcodeFormat::UPC_E); - } - - pub fn encode(&self, contents: &String) -> Vec { - let length: i32 = contents.length(); - match length { - 7 => - { - // No check digit present, calculate it and add it - let mut check: i32; - let tryResult1 = 0; - 'try1: loop { - { - check = UPCEANReader::get_standard_u_p_c_e_a_n_checksum(&UPCEReader::convert_u_p_c_eto_u_p_c_a(&contents)); - } - break 'try1 - } - match tryResult1 { - catch ( fe: &FormatException) { - throw IllegalArgumentException::new(fe); - } 0 => break - } - - contents += check; - break; - } - 8 => - { - let tryResult1 = 0; - 'try1: loop { - { - if !UPCEANReader::check_standard_u_p_c_e_a_n_checksum(&UPCEReader::convert_u_p_c_eto_u_p_c_a(&contents)) { - throw IllegalArgumentException::new("Contents do not pass checksum"); - } - } - break 'try1 - } - match tryResult1 { - catch ( ignored: &FormatException) { - throw IllegalArgumentException::new("Illegal contents"); - } 0 => break - } - - break; - } - _ => - { - throw IllegalArgumentException::new(format!("Requested contents should be 7 or 8 digits long, but got {}", length)); - } - } - check_numeric(&contents); - let first_digit: i32 = Character::digit(&contents.char_at(0), 10); - if first_digit != 0 && first_digit != 1 { - throw IllegalArgumentException::new("Number system must be 0 or 1"); - } - let check_digit: i32 = Character::digit(&contents.char_at(7), 10); - let parities: i32 = UPCEReader.NUMSYS_AND_CHECK_DIGIT_PATTERNS[first_digit][check_digit]; - let result: [bool; CODE_WIDTH] = [false; CODE_WIDTH]; - let mut pos: i32 = append_pattern(&result, 0, UPCEANReader.START_END_PATTERN, true); - { - let mut i: i32 = 1; - while i <= 6 { - { - let mut digit: i32 = Character::digit(&contents.char_at(i), 10); - if (parities >> (6 - i) & 1) == 1 { - digit += 10; - } - pos += append_pattern(&result, pos, UPCEANReader.L_AND_G_PATTERNS[digit], false); - } - i += 1; - } - } - - append_pattern(&result, pos, UPCEANReader.END_PATTERN, false); - return result; - } -} - diff --git a/src/oned.rs b/src/oned.rs index e69de29..d46e26c 100644 --- a/src/oned.rs +++ b/src/oned.rs @@ -0,0 +1,6397 @@ +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.ChecksumException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.ChecksumException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.ChecksumException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.NotFoundException; +import com.google.zxing.common.BitArray; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.FormatException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.NotFoundException; +import com.google.zxing.common.BitArray; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.FormatException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.common.BitMatrix; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.NotFoundException; +import com.google.zxing.Reader; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; +import com.google.zxing.common.BitArray; +import com.google.zxing.oned.rss.RSS14Reader; +import com.google.zxing.oned.rss.expanded.RSSExpandedReader; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.NotFoundException; +import com.google.zxing.Reader; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; +import com.google.zxing.common.BitArray; + +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.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.ReaderException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; + +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.Result; +import com.google.zxing.common.BitArray; + +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.BarcodeFormat; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; + + +import com.google.zxing.NotFoundException; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; +import com.google.zxing.common.BitArray; + + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.ChecksumException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.ResultPointCallback; +import com.google.zxing.common.BitArray; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.common.BitArray; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.FormatException; +import com.google.zxing.common.BitMatrix; + +// NEW FILE: coda_bar_reader.rs +/* + * 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::oned; + +/** + *

Decodes Codabar barcodes.

+ * + * @author Bas Vijfwinkel + * @author David Walker + */ + +// These values are critical for determining how permissive the decoding +// will be. All stripe sizes must be within the window these define, as +// compared to the average stripe size. + const MAX_ACCEPTABLE: f32 = 2.0f; + + const PADDING: f32 = 1.5f; + + const ALPHABET_STRING: &'static str = "0123456789-$:/.+ABCD"; + + const ALPHABET: Vec = ALPHABET_STRING::to_char_array(); + +/** + * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of + * each int correspond to the pattern of wide and narrow, with 1s representing "wide" and 0s representing narrow. + */ + const CHARACTER_ENCODINGS: vec![Vec; 20] = vec![// 0-9 +0x003, // 0-9 +0x006, // 0-9 +0x009, // 0-9 +0x060, // 0-9 +0x012, // 0-9 +0x042, // 0-9 +0x021, // 0-9 +0x024, // 0-9 +0x030, // 0-9 +0x048, // -$:/.+ABCD +0x00c, // -$:/.+ABCD +0x018, // -$:/.+ABCD +0x045, // -$:/.+ABCD +0x051, // -$:/.+ABCD +0x054, // -$:/.+ABCD +0x015, // -$:/.+ABCD +0x01A, // -$:/.+ABCD +0x029, // -$:/.+ABCD +0x00B, // -$:/.+ABCD +0x00E, ] +; + +// minimal number of characters that should be present (including start and stop characters) +// under normal circumstances this should be set to 3, but can be set higher +// as a last-ditch attempt to reduce false positives. + const MIN_CHARACTER_LENGTH: i32 = 3; + +// official start and end patterns + const STARTEND_ENCODING: vec![Vec; 4] = vec!['A', 'B', 'C', 'D', ] +; +pub struct CodaBarReader { + super: OneDReader; + + // some Codabar generator allow the Codabar string to be closed by every + // character. This will cause lots of false positives! + // some industries use a checksum standard but this is not part of the original Codabar standard + // for more information see : http://www.mecsw.com/specs/codabar.html + // Keep some instance variables to avoid reallocations + let decode_row_result: StringBuilder; + + let mut counters: Vec; + + let counter_length: i32; +} + +impl CodaBarReader { + + pub fn new() -> CodaBarReader { + decode_row_result = StringBuilder::new(20); + counters = : [i32; 80] = [0; 80]; + counter_length = 0; + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { + Arrays::fill(&self.counters, 0); + self.set_counters(row); + let start_offset: i32 = self.find_start_pattern(); + let next_start: i32 = start_offset; + self.decode_row_result.set_length(0); + loop { { + let char_offset: i32 = self.to_narrow_wide_pattern(next_start); + if char_offset == -1 { + throw NotFoundException::get_not_found_instance(); + } + // Hack: We store the position in the alphabet table into a + // StringBuilder, so that we can access the decoded patterns in + // validatePattern. We'll translate to the actual characters later. + self.decode_row_result.append(char_offset as char); + next_start += 8; + // Stop as soon as we see the end character. + if self.decode_row_result.length() > 1 && ::array_contains(&STARTEND_ENCODING, ALPHABET[char_offset]) { + break; + } + }if !(// no fixed end pattern so keep on reading while data is available + next_start < self.counter_length) break;} + // Look for whitespace after pattern: + let trailing_whitespace: i32 = self.counters[next_start - 1]; + let last_pattern_size: i32 = 0; + { + let mut i: i32 = -8; + while i < -1 { + { + last_pattern_size += self.counters[next_start + i]; + } + i += 1; + } + } + + // at the end of the row. (I.e. the barcode barely fits.) + if next_start < self.counter_length && trailing_whitespace < last_pattern_size / 2 { + throw NotFoundException::get_not_found_instance(); + } + self.validate_pattern(start_offset); + // Translate character table offsets to actual characters. + { + let mut i: i32 = 0; + while i < self.decode_row_result.length() { + { + self.decode_row_result.set_char_at(i, ALPHABET[self.decode_row_result.char_at(i)]); + } + i += 1; + } + } + + // Ensure a valid start and end character + let startchar: char = self.decode_row_result.char_at(0); + if !::array_contains(&STARTEND_ENCODING, startchar) { + throw NotFoundException::get_not_found_instance(); + } + let endchar: char = self.decode_row_result.char_at(self.decode_row_result.length() - 1); + if !::array_contains(&STARTEND_ENCODING, endchar) { + throw NotFoundException::get_not_found_instance(); + } + // remove stop/start characters character and check if a long enough string is contained + if self.decode_row_result.length() <= MIN_CHARACTER_LENGTH { + // Almost surely a false positive ( start + stop + at least 1 character) + throw NotFoundException::get_not_found_instance(); + } + if hints == null || !hints.contains_key(DecodeHintType::RETURN_CODABAR_START_END) { + self.decode_row_result.delete_char_at(self.decode_row_result.length() - 1); + self.decode_row_result.delete_char_at(0); + } + let running_count: i32 = 0; + { + let mut i: i32 = 0; + while i < start_offset { + { + running_count += self.counters[i]; + } + i += 1; + } + } + + let left: f32 = running_count; + { + let mut i: i32 = start_offset; + while i < next_start - 1 { + { + running_count += self.counters[i]; + } + i += 1; + } + } + + let right: f32 = running_count; + let result: Result = Result::new(&self.decode_row_result.to_string(), null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] + , BarcodeFormat::CODABAR); + result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]F0"); + return Ok(result); + } + + fn validate_pattern(&self, start: i32) -> /* throws NotFoundException */Result> { + // First, sum up the total size of our four categories of stripe sizes; + let mut sizes: vec![Vec; 4] = vec![0, 0, 0, 0, ] + ; + let mut counts: vec![Vec; 4] = vec![0, 0, 0, 0, ] + ; + let end: i32 = self.decode_row_result.length() - 1; + // We break out of this loop in the middle, in order to handle + // inter-character spaces properly. + let mut pos: i32 = start; + { + let mut i: i32 = 0; + while i <= end { + { + let mut pattern: i32 = CHARACTER_ENCODINGS[self.decode_row_result.char_at(i)]; + { + let mut j: i32 = 6; + while j >= 0 { + { + // Even j = bars, while odd j = spaces. Categories 2 and 3 are for + // long stripes, while 0 and 1 are for short stripes. + let mut category: i32 = (j & 1) + (pattern & 1) * 2; + sizes[category] += self.counters[pos + j]; + counts[category] += 1; + pattern >>= 1; + } + j -= 1; + } + } + + // We ignore the inter-character space - it could be of any size. + pos += 8; + } + i += 1; + } + } + + // Calculate our allowable size thresholds using fixed-point math. + let mut maxes: [f32; 4.0] = [0.0; 4.0]; + let mut mins: [f32; 4.0] = [0.0; 4.0]; + // should be on the "wrong" side of that line. + { + let mut i: i32 = 0; + while i < 2 { + { + // Accept arbitrarily small "short" stripes. + mins[i] = 0.0f; + mins[i + 2] = (sizes[i] as f32 / counts[i] + sizes[i + 2] as f32 / counts[i + 2]) / 2.0f; + maxes[i] = mins[i + 2]; + maxes[i + 2] = (sizes[i + 2] * MAX_ACCEPTABLE + PADDING) / counts[i + 2]; + } + i += 1; + } + } + + // Now verify that all of the stripes are within the thresholds. + pos = start; + { + let mut i: i32 = 0; + while i <= end { + { + let mut pattern: i32 = CHARACTER_ENCODINGS[self.decode_row_result.char_at(i)]; + { + let mut j: i32 = 6; + while j >= 0 { + { + // Even j = bars, while odd j = spaces. Categories 2 and 3 are for + // long stripes, while 0 and 1 are for short stripes. + let category: i32 = (j & 1) + (pattern & 1) * 2; + let size: i32 = self.counters[pos + j]; + if size < mins[category] || size > maxes[category] { + throw NotFoundException::get_not_found_instance(); + } + pattern >>= 1; + } + j -= 1; + } + } + + pos += 8; + } + i += 1; + } + } + + } + + /** + * Records the size of all runs of white and black pixels, starting with white. + * This is just like recordPattern, except it records all the counters, and + * uses our builtin "counters" member for storage. + * @param row row to count from + */ + fn set_counters(&self, row: &BitArray) -> /* throws NotFoundException */Result> { + self.counter_length = 0; + // Start from the first white bit. + let mut i: i32 = row.get_next_unset(0); + let end: i32 = row.get_size(); + if i >= end { + throw NotFoundException::get_not_found_instance(); + } + let is_white: bool = true; + let mut count: i32 = 0; + while i < end { + if row.get(i) != is_white { + count += 1; + } else { + self.counter_append(count); + count = 1; + is_white = !is_white; + } + i += 1; + } + self.counter_append(count); + } + + fn counter_append(&self, e: i32) { + self.counters[self.counter_length] = e; + self.counter_length += 1; + if self.counter_length >= self.counters.len() { + let temp: [i32; self.counter_length * 2] = [0; self.counter_length * 2]; + System::arraycopy(&self.counters, 0, &temp, 0, self.counter_length); + self.counters = temp; + } + } + + fn find_start_pattern(&self) -> /* throws NotFoundException */Result> { + { + let mut i: i32 = 1; + while i < self.counter_length { + { + let char_offset: i32 = self.to_narrow_wide_pattern(i); + if char_offset != -1 && ::array_contains(&STARTEND_ENCODING, ALPHABET[char_offset]) { + // Look for whitespace before start pattern, >= 50% of width of start pattern + // We make an exception if the whitespace is the first element. + let pattern_size: i32 = 0; + { + let mut j: i32 = i; + while j < i + 7 { + { + pattern_size += self.counters[j]; + } + j += 1; + } + } + + if i == 1 || self.counters[i - 1] >= pattern_size / 2 { + return Ok(i); + } + } + } + i += 2; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + fn array_contains( array: &Vec, key: char) -> bool { + if array != null { + for let c: char in array { + if c == key { + return true; + } + } + } + return false; + } + + // Assumes that counters[position] is a bar. + fn to_narrow_wide_pattern(&self, position: i32) -> i32 { + let end: i32 = position + 7; + if end >= self.counter_length { + return -1; + } + let the_counters: Vec = self.counters; + let max_bar: i32 = 0; + let min_bar: i32 = Integer::MAX_VALUE; + { + let mut j: i32 = position; + while j < end { + { + let current_counter: i32 = the_counters[j]; + if current_counter < min_bar { + min_bar = current_counter; + } + if current_counter > max_bar { + max_bar = current_counter; + } + } + j += 2; + } + } + + let threshold_bar: i32 = (min_bar + max_bar) / 2; + let max_space: i32 = 0; + let min_space: i32 = Integer::MAX_VALUE; + { + let mut j: i32 = position + 1; + while j < end { + { + let current_counter: i32 = the_counters[j]; + if current_counter < min_space { + min_space = current_counter; + } + if current_counter > max_space { + max_space = current_counter; + } + } + j += 2; + } + } + + let threshold_space: i32 = (min_space + max_space) / 2; + let mut bitmask: i32 = 1 << 7; + let mut pattern: i32 = 0; + { + let mut i: i32 = 0; + while i < 7 { + { + let threshold: i32 = if (i & 1) == 0 { threshold_bar } else { threshold_space }; + bitmask >>= 1; + if the_counters[position + i] > threshold { + pattern |= bitmask; + } + } + i += 1; + } + } + + { + let mut i: i32 = 0; + while i < CHARACTER_ENCODINGS.len() { + { + if CHARACTER_ENCODINGS[i] == pattern { + return i; + } + } + i += 1; + } + } + + return -1; + } +} + +// NEW FILE: coda_bar_writer.rs +/* + * Copyright 2011 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::oned; + +/** + * This class renders CodaBar as {@code boolean[]}. + * + * @author dsbnatut@gmail.com (Kazuki Nishiura) + */ + + const START_END_CHARS: vec![Vec; 4] = vec!['A', 'B', 'C', 'D', ] +; + + const ALT_START_END_CHARS: vec![Vec; 4] = vec!['T', 'N', '*', 'E', ] +; + + const CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED: vec![Vec; 4] = vec!['/', ':', '+', '.', ] +; + + const DEFAULT_GUARD: char = START_END_CHARS[0]; +pub struct CodaBarWriter { + super: OneDimensionalCodeWriter; +} + +impl CodaBarWriter { + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::CODABAR); + } + + pub fn encode(&self, contents: &String) -> Vec { + if contents.length() < 2 { + // Can't have a start/end guard, so tentatively add default guards + contents = format!("{}{}{}", DEFAULT_GUARD, contents, DEFAULT_GUARD); + } else { + // Verify input and calculate decoded length. + let first_char: char = Character::to_upper_case(&contents.char_at(0)); + let last_char: char = Character::to_upper_case(&contents.char_at(contents.length() - 1)); + let starts_normal: bool = CodaBarReader::array_contains(&START_END_CHARS, first_char); + let ends_normal: bool = CodaBarReader::array_contains(&START_END_CHARS, last_char); + let starts_alt: bool = CodaBarReader::array_contains(&ALT_START_END_CHARS, first_char); + let ends_alt: bool = CodaBarReader::array_contains(&ALT_START_END_CHARS, last_char); + if starts_normal { + if !ends_normal { + throw IllegalArgumentException::new(format!("Invalid start/end guards: {}", contents)); + } + // else already has valid start/end + } else if starts_alt { + if !ends_alt { + throw IllegalArgumentException::new(format!("Invalid start/end guards: {}", contents)); + } + // else already has valid start/end + } else { + // Doesn't start with a guard + if ends_normal || ends_alt { + throw IllegalArgumentException::new(format!("Invalid start/end guards: {}", contents)); + } + // else doesn't end with guard either, so add a default + contents = format!("{}{}{}", DEFAULT_GUARD, contents, DEFAULT_GUARD); + } + } + // The start character and the end character are decoded to 10 length each. + let result_length: i32 = 20; + { + let mut i: i32 = 1; + while i < contents.length() - 1 { + { + if Character::is_digit(&contents.char_at(i)) || contents.char_at(i) == '-' || contents.char_at(i) == '$' { + result_length += 9; + } else if CodaBarReader::array_contains(&CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED, &contents.char_at(i)) { + result_length += 10; + } else { + throw IllegalArgumentException::new(format!("Cannot encode : '{}\'", contents.char_at(i))); + } + } + i += 1; + } + } + + // A blank is placed between each character. + result_length += contents.length() - 1; + let mut result: [bool; result_length] = [false; result_length]; + let mut position: i32 = 0; + { + let mut index: i32 = 0; + while index < contents.length() { + { + let mut c: char = Character::to_upper_case(&contents.char_at(index)); + if index == 0 || index == contents.length() - 1 { + // The start/end chars are not in the CodaBarReader.ALPHABET. + match c { + 'T' => + { + c = 'A'; + break; + } + 'N' => + { + c = 'B'; + break; + } + '*' => + { + c = 'C'; + break; + } + 'E' => + { + c = 'D'; + break; + } + } + } + let mut code: i32 = 0; + { + let mut i: i32 = 0; + while i < CodaBarReader::ALPHABET::len() { + { + // Found any, because I checked above. + if c == CodaBarReader::ALPHABET[i] { + code = CodaBarReader::CHARACTER_ENCODINGS[i]; + break; + } + } + i += 1; + } + } + + let mut color: bool = true; + let mut counter: i32 = 0; + let mut bit: i32 = 0; + while bit < 7 { + // A character consists of 7 digit. + result[position] = color; + position += 1; + if ((code >> (6 - bit)) & 1) == 0 || counter == 1 { + // Flip the color. + color = !color; + bit += 1; + counter = 0; + } else { + counter += 1; + } + } + if index < contents.length() - 1 { + result[position] = false; + position += 1; + } + } + index += 1; + } + } + + return result; + } +} + +// NEW FILE: code128_reader.rs +/* + * 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::oned; + +/** + *

Decodes Code 128 barcodes.

+ * + * @author Sean Owen + */ + + const CODE_PATTERNS: vec![vec![Vec>; 7]; 107] = vec![// 0 +vec![2, 1, 2, 2, 2, 2, ] +, vec![2, 2, 2, 1, 2, 2, ] +, vec![2, 2, 2, 2, 2, 1, ] +, vec![1, 2, 1, 2, 2, 3, ] +, vec![1, 2, 1, 3, 2, 2, ] +, // 5 +vec![1, 3, 1, 2, 2, 2, ] +, vec![1, 2, 2, 2, 1, 3, ] +, vec![1, 2, 2, 3, 1, 2, ] +, vec![1, 3, 2, 2, 1, 2, ] +, vec![2, 2, 1, 2, 1, 3, ] +, // 10 +vec![2, 2, 1, 3, 1, 2, ] +, vec![2, 3, 1, 2, 1, 2, ] +, vec![1, 1, 2, 2, 3, 2, ] +, vec![1, 2, 2, 1, 3, 2, ] +, vec![1, 2, 2, 2, 3, 1, ] +, // 15 +vec![1, 1, 3, 2, 2, 2, ] +, vec![1, 2, 3, 1, 2, 2, ] +, vec![1, 2, 3, 2, 2, 1, ] +, vec![2, 2, 3, 2, 1, 1, ] +, vec![2, 2, 1, 1, 3, 2, ] +, // 20 +vec![2, 2, 1, 2, 3, 1, ] +, vec![2, 1, 3, 2, 1, 2, ] +, vec![2, 2, 3, 1, 1, 2, ] +, vec![3, 1, 2, 1, 3, 1, ] +, vec![3, 1, 1, 2, 2, 2, ] +, // 25 +vec![3, 2, 1, 1, 2, 2, ] +, vec![3, 2, 1, 2, 2, 1, ] +, vec![3, 1, 2, 2, 1, 2, ] +, vec![3, 2, 2, 1, 1, 2, ] +, vec![3, 2, 2, 2, 1, 1, ] +, // 30 +vec![2, 1, 2, 1, 2, 3, ] +, vec![2, 1, 2, 3, 2, 1, ] +, vec![2, 3, 2, 1, 2, 1, ] +, vec![1, 1, 1, 3, 2, 3, ] +, vec![1, 3, 1, 1, 2, 3, ] +, // 35 +vec![1, 3, 1, 3, 2, 1, ] +, vec![1, 1, 2, 3, 1, 3, ] +, vec![1, 3, 2, 1, 1, 3, ] +, vec![1, 3, 2, 3, 1, 1, ] +, vec![2, 1, 1, 3, 1, 3, ] +, // 40 +vec![2, 3, 1, 1, 1, 3, ] +, vec![2, 3, 1, 3, 1, 1, ] +, vec![1, 1, 2, 1, 3, 3, ] +, vec![1, 1, 2, 3, 3, 1, ] +, vec![1, 3, 2, 1, 3, 1, ] +, // 45 +vec![1, 1, 3, 1, 2, 3, ] +, vec![1, 1, 3, 3, 2, 1, ] +, vec![1, 3, 3, 1, 2, 1, ] +, vec![3, 1, 3, 1, 2, 1, ] +, vec![2, 1, 1, 3, 3, 1, ] +, // 50 +vec![2, 3, 1, 1, 3, 1, ] +, vec![2, 1, 3, 1, 1, 3, ] +, vec![2, 1, 3, 3, 1, 1, ] +, vec![2, 1, 3, 1, 3, 1, ] +, vec![3, 1, 1, 1, 2, 3, ] +, // 55 +vec![3, 1, 1, 3, 2, 1, ] +, vec![3, 3, 1, 1, 2, 1, ] +, vec![3, 1, 2, 1, 1, 3, ] +, vec![3, 1, 2, 3, 1, 1, ] +, vec![3, 3, 2, 1, 1, 1, ] +, // 60 +vec![3, 1, 4, 1, 1, 1, ] +, vec![2, 2, 1, 4, 1, 1, ] +, vec![4, 3, 1, 1, 1, 1, ] +, vec![1, 1, 1, 2, 2, 4, ] +, vec![1, 1, 1, 4, 2, 2, ] +, // 65 +vec![1, 2, 1, 1, 2, 4, ] +, vec![1, 2, 1, 4, 2, 1, ] +, vec![1, 4, 1, 1, 2, 2, ] +, vec![1, 4, 1, 2, 2, 1, ] +, vec![1, 1, 2, 2, 1, 4, ] +, // 70 +vec![1, 1, 2, 4, 1, 2, ] +, vec![1, 2, 2, 1, 1, 4, ] +, vec![1, 2, 2, 4, 1, 1, ] +, vec![1, 4, 2, 1, 1, 2, ] +, vec![1, 4, 2, 2, 1, 1, ] +, // 75 +vec![2, 4, 1, 2, 1, 1, ] +, vec![2, 2, 1, 1, 1, 4, ] +, vec![4, 1, 3, 1, 1, 1, ] +, vec![2, 4, 1, 1, 1, 2, ] +, vec![1, 3, 4, 1, 1, 1, ] +, // 80 +vec![1, 1, 1, 2, 4, 2, ] +, vec![1, 2, 1, 1, 4, 2, ] +, vec![1, 2, 1, 2, 4, 1, ] +, vec![1, 1, 4, 2, 1, 2, ] +, vec![1, 2, 4, 1, 1, 2, ] +, // 85 +vec![1, 2, 4, 2, 1, 1, ] +, vec![4, 1, 1, 2, 1, 2, ] +, vec![4, 2, 1, 1, 1, 2, ] +, vec![4, 2, 1, 2, 1, 1, ] +, vec![2, 1, 2, 1, 4, 1, ] +, // 90 +vec![2, 1, 4, 1, 2, 1, ] +, vec![4, 1, 2, 1, 2, 1, ] +, vec![1, 1, 1, 1, 4, 3, ] +, vec![1, 1, 1, 3, 4, 1, ] +, vec![1, 3, 1, 1, 4, 1, ] +, // 95 +vec![1, 1, 4, 1, 1, 3, ] +, vec![1, 1, 4, 3, 1, 1, ] +, vec![4, 1, 1, 1, 1, 3, ] +, vec![4, 1, 1, 3, 1, 1, ] +, vec![1, 1, 3, 1, 4, 1, ] +, // 100 +vec![1, 1, 4, 1, 3, 1, ] +, vec![3, 1, 1, 1, 4, 1, ] +, vec![4, 1, 1, 1, 3, 1, ] +, vec![2, 1, 1, 4, 1, 2, ] +, vec![2, 1, 1, 2, 1, 4, ] +, // 105 +vec![2, 1, 1, 2, 3, 2, ] +, vec![2, 3, 3, 1, 1, 1, 2, ] +, ] +; + + const MAX_AVG_VARIANCE: f32 = 0.25f; + + const MAX_INDIVIDUAL_VARIANCE: f32 = 0.7f; + + const CODE_SHIFT: i32 = 98; + + const CODE_CODE_C: i32 = 99; + + const CODE_CODE_B: i32 = 100; + + const CODE_CODE_A: i32 = 101; + + const CODE_FNC_1: i32 = 102; + + const CODE_FNC_2: i32 = 97; + + const CODE_FNC_3: i32 = 96; + + const CODE_FNC_4_A: i32 = 101; + + const CODE_FNC_4_B: i32 = 100; + + const CODE_START_A: i32 = 103; + + const CODE_START_B: i32 = 104; + + const CODE_START_C: i32 = 105; + + const CODE_STOP: i32 = 106; +pub struct Code128Reader { + super: OneDReader; +} + +impl Code128Reader { + + fn find_start_pattern( row: &BitArray) -> /* throws NotFoundException */Result, Rc> { + let width: i32 = row.get_size(); + let row_offset: i32 = row.get_next_set(0); + let counter_position: i32 = 0; + let mut counters: [i32; 6] = [0; 6]; + let pattern_start: i32 = row_offset; + let is_white: bool = false; + let pattern_length: i32 = counters.len(); + { + let mut i: i32 = row_offset; + while i < width { + { + if row.get(i) != is_white { + counters[counter_position] += 1; + } else { + if counter_position == pattern_length - 1 { + let best_variance: f32 = MAX_AVG_VARIANCE; + let best_match: i32 = -1; + { + let start_code: i32 = CODE_START_A; + while start_code <= CODE_START_C { + { + let variance: f32 = pattern_match_variance(&counters, CODE_PATTERNS[start_code], MAX_INDIVIDUAL_VARIANCE); + if variance < best_variance { + best_variance = variance; + best_match = start_code; + } + } + start_code += 1; + } + } + + // Look for whitespace before start pattern, >= 50% of width of start pattern + if best_match >= 0 && row.is_range(&Math::max(0, pattern_start - (i - pattern_start) / 2), pattern_start, false) { + return Ok( : vec![i32; 3] = vec![pattern_start, i, best_match, ] + ); + } + pattern_start += counters[0] + counters[1]; + System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); + counters[counter_position - 1] = 0; + counters[counter_position] = 0; + counter_position -= 1; + } else { + counter_position += 1; + } + counters[counter_position] = 1; + is_white = !is_white; + } + } + i += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + fn decode_code( row: &BitArray, counters: &Vec, row_offset: i32) -> /* throws NotFoundException */Result> { + record_pattern(row, row_offset, &counters); + // worst variance we'll accept + let best_variance: f32 = MAX_AVG_VARIANCE; + let best_match: i32 = -1; + { + let mut d: i32 = 0; + while d < CODE_PATTERNS.len() { + { + let pattern: Vec = CODE_PATTERNS[d]; + let variance: f32 = pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE); + if variance < best_variance { + best_variance = variance; + best_match = d; + } + } + d += 1; + } + } + + // TODO We're overlooking the fact that the STOP pattern has 7 values, not 6. + if best_match >= 0 { + return Ok(best_match); + } else { + throw NotFoundException::get_not_found_instance(); + } + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, FormatException, ChecksumException */Result> { + let convert_f_n_c1: bool = hints != null && hints.contains_key(DecodeHintType::ASSUME_GS1); + let symbology_modifier: i32 = 0; + let start_pattern_info: Vec = ::find_start_pattern(row); + let start_code: i32 = start_pattern_info[2]; + let raw_codes: List = ArrayList<>::new(20); + raw_codes.add(start_code as i8); + let code_set: i32; + match start_code { + CODE_START_A => + { + code_set = CODE_CODE_A; + break; + } + CODE_START_B => + { + code_set = CODE_CODE_B; + break; + } + CODE_START_C => + { + code_set = CODE_CODE_C; + break; + } + _ => + { + throw FormatException::get_format_instance(); + } + } + let mut done: bool = false; + let is_next_shifted: bool = false; + let result: StringBuilder = StringBuilder::new(20); + let last_start: i32 = start_pattern_info[0]; + let next_start: i32 = start_pattern_info[1]; + let counters: [i32; 6] = [0; 6]; + let last_code: i32 = 0; + let mut code: i32 = 0; + let checksum_total: i32 = start_code; + let mut multiplier: i32 = 0; + let last_character_was_printable: bool = true; + let upper_mode: bool = false; + let shift_upper_mode: bool = false; + while !done { + let unshift: bool = is_next_shifted; + is_next_shifted = false; + // Save off last code + last_code = code; + // Decode another code from image + code = ::decode_code(row, &counters, next_start); + raw_codes.add(code as i8); + // Remember whether the last code was printable or not (excluding CODE_STOP) + if code != CODE_STOP { + last_character_was_printable = true; + } + // Add to checksum computation (if not CODE_STOP of course) + if code != CODE_STOP { + multiplier += 1; + checksum_total += multiplier * code; + } + // Advance to where the next code will to start + last_start = next_start; + for let counter: i32 in counters { + next_start += counter; + } + // Take care of illegal start codes + match code { + CODE_START_A => + { + } + CODE_START_B => + { + } + CODE_START_C => + { + throw FormatException::get_format_instance(); + } + } + match code_set { + CODE_CODE_A => + { + if code < 64 { + if shift_upper_mode == upper_mode { + result.append((' ' + code) as char); + } else { + result.append((' ' + code + 128) as char); + } + shift_upper_mode = false; + } else if code < 96 { + if shift_upper_mode == upper_mode { + result.append((code - 64) as char); + } else { + result.append((code + 64) as char); + } + shift_upper_mode = false; + } else { + // code was printable or not. + if code != CODE_STOP { + last_character_was_printable = false; + } + match code { + CODE_FNC_1 => + { + if result.length() == 0 { + // FNC1 at first or second character determines the symbology + symbology_modifier = 1; + } else if result.length() == 1 { + symbology_modifier = 2; + } + if convert_f_n_c1 { + if result.length() == 0 { + // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code + // is FNC1 then this is GS1-128. We add the symbology identifier. + result.append("]C1"); + } else { + // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) + result.append(29 as char); + } + } + break; + } + CODE_FNC_2 => + { + symbology_modifier = 4; + break; + } + CODE_FNC_3 => + { + // do nothing? + break; + } + CODE_FNC_4_A => + { + if !upper_mode && shift_upper_mode { + upper_mode = true; + shift_upper_mode = false; + } else if upper_mode && shift_upper_mode { + upper_mode = false; + shift_upper_mode = false; + } else { + shift_upper_mode = true; + } + break; + } + CODE_SHIFT => + { + is_next_shifted = true; + code_set = CODE_CODE_B; + break; + } + CODE_CODE_B => + { + code_set = CODE_CODE_B; + break; + } + CODE_CODE_C => + { + code_set = CODE_CODE_C; + break; + } + CODE_STOP => + { + done = true; + break; + } + } + } + break; + } + CODE_CODE_B => + { + if code < 96 { + if shift_upper_mode == upper_mode { + result.append((' ' + code) as char); + } else { + result.append((' ' + code + 128) as char); + } + shift_upper_mode = false; + } else { + if code != CODE_STOP { + last_character_was_printable = false; + } + match code { + CODE_FNC_1 => + { + if result.length() == 0 { + // FNC1 at first or second character determines the symbology + symbology_modifier = 1; + } else if result.length() == 1 { + symbology_modifier = 2; + } + if convert_f_n_c1 { + if result.length() == 0 { + // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code + // is FNC1 then this is GS1-128. We add the symbology identifier. + result.append("]C1"); + } else { + // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) + result.append(29 as char); + } + } + break; + } + CODE_FNC_2 => + { + symbology_modifier = 4; + break; + } + CODE_FNC_3 => + { + // do nothing? + break; + } + CODE_FNC_4_B => + { + if !upper_mode && shift_upper_mode { + upper_mode = true; + shift_upper_mode = false; + } else if upper_mode && shift_upper_mode { + upper_mode = false; + shift_upper_mode = false; + } else { + shift_upper_mode = true; + } + break; + } + CODE_SHIFT => + { + is_next_shifted = true; + code_set = CODE_CODE_A; + break; + } + CODE_CODE_A => + { + code_set = CODE_CODE_A; + break; + } + CODE_CODE_C => + { + code_set = CODE_CODE_C; + break; + } + CODE_STOP => + { + done = true; + break; + } + } + } + break; + } + CODE_CODE_C => + { + if code < 100 { + if code < 10 { + result.append('0'); + } + result.append(code); + } else { + if code != CODE_STOP { + last_character_was_printable = false; + } + match code { + CODE_FNC_1 => + { + if result.length() == 0 { + // FNC1 at first or second character determines the symbology + symbology_modifier = 1; + } else if result.length() == 1 { + symbology_modifier = 2; + } + if convert_f_n_c1 { + if result.length() == 0 { + // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code + // is FNC1 then this is GS1-128. We add the symbology identifier. + result.append("]C1"); + } else { + // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS) + result.append(29 as char); + } + } + break; + } + CODE_CODE_A => + { + code_set = CODE_CODE_A; + break; + } + CODE_CODE_B => + { + code_set = CODE_CODE_B; + break; + } + CODE_STOP => + { + done = true; + break; + } + } + } + break; + } + } + // Unshift back to another code set if we were shifted + if unshift { + code_set = if code_set == CODE_CODE_A { CODE_CODE_B } else { CODE_CODE_A }; + } + } + let last_pattern_size: i32 = next_start - last_start; + // Check for ample whitespace following pattern, but, to do this we first need to remember that + // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left + // to read off. Would be slightly better to properly read. Here we just skip it: + next_start = row.get_next_unset(next_start); + if !row.is_range(next_start, &Math::min(&row.get_size(), next_start + (next_start - last_start) / 2), false) { + throw NotFoundException::get_not_found_instance(); + } + // Pull out from sum the value of the penultimate check code + checksum_total -= multiplier * last_code; + // lastCode is the checksum then: + if checksum_total % 103 != last_code { + throw ChecksumException::get_checksum_instance(); + } + // Need to pull out the check digits from string + let result_length: i32 = result.length(); + if result_length == 0 { + // false positive + throw NotFoundException::get_not_found_instance(); + } + // be a printable character. If it was just interpreted as a control code, nothing to remove. + if result_length > 0 && last_character_was_printable { + if code_set == CODE_CODE_C { + result.delete(result_length - 2, result_length); + } else { + result.delete(result_length - 1, result_length); + } + } + let left: f32 = (start_pattern_info[1] + start_pattern_info[0]) / 2.0f; + let right: f32 = last_start + last_pattern_size / 2.0f; + let raw_codes_size: i32 = raw_codes.size(); + let raw_bytes: [i8; raw_codes_size] = [0; raw_codes_size]; + { + let mut i: i32 = 0; + while i < raw_codes_size { + { + raw_bytes[i] = raw_codes.get(i); + } + i += 1; + } + } + + let result_object: Result = Result::new(&result.to_string(), &raw_bytes, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] + , BarcodeFormat::CODE_128); + result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]C{}", symbology_modifier)); + return Ok(result_object); + } +} + +// NEW FILE: code128_writer.rs +/* + * Copyright 2010 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::oned; + +/** + * This object renders a CODE128 code as a {@link BitMatrix}. + * + * @author erik.barbara@gmail.com (Erik Barbara) + */ + + const CODE_START_A: i32 = 103; + + const CODE_START_B: i32 = 104; + + const CODE_START_C: i32 = 105; + + const CODE_CODE_A: i32 = 101; + + const CODE_CODE_B: i32 = 100; + + const CODE_CODE_C: i32 = 99; + + const CODE_STOP: i32 = 106; + +// Dummy characters used to specify control characters in input + const ESCAPE_FNC_1: char = 'ñ'; + + const ESCAPE_FNC_2: char = 'ò'; + + const ESCAPE_FNC_3: char = 'ó'; + + const ESCAPE_FNC_4: char = 'ô'; + +// Code A, Code B, Code C + const CODE_FNC_1: i32 = 102; + +// Code A, Code B + const CODE_FNC_2: i32 = 97; + +// Code A, Code B + const CODE_FNC_3: i32 = 96; + +// Code A + const CODE_FNC_4_A: i32 = 101; + +// Code B + const CODE_FNC_4_B: i32 = 100; +pub struct Code128Writer { + super: OneDimensionalCodeWriter; +} + +impl Code128Writer { + + // Results of minimal lookahead for code C + enum CType { + + UNCODABLE(), ONE_DIGIT(), TWO_DIGITS(), FNC_1() + } + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::CODE_128); + } + + pub fn encode(&self, contents: &String) -> Vec { + return self.encode(&contents, null); + } + + pub fn encode(&self, contents: &String, hints: &Map) -> Vec { + let forced_code_set: i32 = ::check(&contents, &hints); + let has_compaction_hint: bool = hints != null && hints.contains_key(EncodeHintType::CODE128_COMPACT) && Boolean::parse_boolean(&hints.get(EncodeHintType::CODE128_COMPACT).to_string()); + return if has_compaction_hint { MinimalEncoder::new().encode(&contents) } else { ::encode_fast(&contents, forced_code_set) }; + } + + fn check( contents: &String, hints: &Map) -> i32 { + let length: i32 = contents.length(); + // Check length + if length < 1 || length > 80 { + throw IllegalArgumentException::new(format!("Contents length should be between 1 and 80 characters, but got {}", length)); + } + // Check for forced code set hint. + let forced_code_set: i32 = -1; + if hints != null && hints.contains_key(EncodeHintType::FORCE_CODE_SET) { + let code_set_hint: String = hints.get(EncodeHintType::FORCE_CODE_SET).to_string(); + match code_set_hint { + "A" => + { + forced_code_set = CODE_CODE_A; + break; + } + "B" => + { + forced_code_set = CODE_CODE_B; + break; + } + "C" => + { + forced_code_set = CODE_CODE_C; + break; + } + _ => + { + throw IllegalArgumentException::new(format!("Unsupported code set hint: {}", code_set_hint)); + } + } + } + // Check content + { + let mut i: i32 = 0; + while i < length { + { + let c: char = contents.char_at(i); + // check for non ascii characters that are not special GS1 characters + match c { + // special function characters + ESCAPE_FNC_1 => + { + } + ESCAPE_FNC_2 => + { + } + ESCAPE_FNC_3 => + { + } + ESCAPE_FNC_4 => + { + break; + } + // non ascii characters + _ => + { + if c > 127 { + // shift and manual code change are not supported + throw IllegalArgumentException::new(format!("Bad character in input: ASCII value={}", c as i32)); + } + } + } + // check characters for compatibility with forced code set + match forced_code_set { + CODE_CODE_A => + { + // allows no ascii above 95 (no lower caps, no special symbols) + if c > 95 && c <= 127 { + throw IllegalArgumentException::new(format!("Bad character in input for forced code set A: ASCII value={}", c as i32)); + } + break; + } + CODE_CODE_B => + { + // allows no ascii below 32 (terminal symbols) + if c <= 32 { + throw IllegalArgumentException::new(format!("Bad character in input for forced code set B: ASCII value={}", c as i32)); + } + break; + } + CODE_CODE_C => + { + // allows only numbers and no FNC 2/3/4 + if c < 48 || (c > 57 && c <= 127) || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 { + throw IllegalArgumentException::new(format!("Bad character in input for forced code set C: ASCII value={}", c as i32)); + } + break; + } + } + } + i += 1; + } + } + + return forced_code_set; + } + + fn encode_fast( contents: &String, forced_code_set: i32) -> Vec { + let length: i32 = contents.length(); + // temporary storage for patterns + let patterns: Collection> = ArrayList<>::new(); + let check_sum: i32 = 0; + let check_weight: i32 = 1; + // selected code (CODE_CODE_B or CODE_CODE_C) + let code_set: i32 = 0; + // position in contents + let mut position: i32 = 0; + while position < length { + //Select code to use + let new_code_set: i32; + if forced_code_set == -1 { + new_code_set = ::choose_code(&contents, position, code_set); + } else { + new_code_set = forced_code_set; + } + //Get the pattern index + let pattern_index: i32; + if new_code_set == code_set { + // First handle escapes + match contents.char_at(position) { + ESCAPE_FNC_1 => + { + pattern_index = CODE_FNC_1; + break; + } + ESCAPE_FNC_2 => + { + pattern_index = CODE_FNC_2; + break; + } + ESCAPE_FNC_3 => + { + pattern_index = CODE_FNC_3; + break; + } + ESCAPE_FNC_4 => + { + if code_set == CODE_CODE_A { + pattern_index = CODE_FNC_4_A; + } else { + pattern_index = CODE_FNC_4_B; + } + break; + } + _ => + { + // Then handle normal characters otherwise + match code_set { + CODE_CODE_A => + { + pattern_index = contents.char_at(position) - ' '; + if pattern_index < 0 { + // everything below a space character comes behind the underscore in the code patterns table + pattern_index += '`'; + } + break; + } + CODE_CODE_B => + { + pattern_index = contents.char_at(position) - ' '; + break; + } + _ => + { + // CODE_CODE_C + if position + 1 == length { + // this is the last character, but the encoding is C, which always encodes two characers + throw IllegalArgumentException::new("Bad number of characters for digit only encoding."); + } + pattern_index = Integer::parse_int(&contents.substring(position, position + 2)); + // Also incremented below + position += 1; + break; + } + } + } + } + position += 1; + } else { + // Do we have a code set? + if code_set == 0 { + // No, we don't have a code set + match new_code_set { + CODE_CODE_A => + { + pattern_index = CODE_START_A; + break; + } + CODE_CODE_B => + { + pattern_index = CODE_START_B; + break; + } + _ => + { + pattern_index = CODE_START_C; + break; + } + } + } else { + // Yes, we have a code set + pattern_index = new_code_set; + } + code_set = new_code_set; + } + // Get the pattern + patterns.add(Code128Reader::CODE_PATTERNS[pattern_index]); + // Compute checksum + check_sum += pattern_index * check_weight; + if position != 0 { + check_weight += 1; + } + } + return ::produce_result(&patterns, check_sum); + } + + fn produce_result( patterns: &Collection>, check_sum: i32) -> Vec { + // Compute and append checksum + check_sum %= 103; + patterns.add(Code128Reader::CODE_PATTERNS[check_sum]); + // Append stop code + patterns.add(Code128Reader::CODE_PATTERNS[CODE_STOP]); + // Compute code width + let code_width: i32 = 0; + for let pattern: Vec in patterns { + for let width: i32 in pattern { + code_width += width; + } + } + // Compute result + let result: [bool; code_width] = [false; code_width]; + let mut pos: i32 = 0; + for let pattern: Vec in patterns { + pos += append_pattern(&result, pos, &pattern, true); + } + return result; + } + + fn find_c_type( value: &CharSequence, start: i32) -> CType { + let last: i32 = value.length(); + if start >= last { + return CType.UNCODABLE; + } + let mut c: char = value.char_at(start); + if c == ESCAPE_FNC_1 { + return CType.FNC_1; + } + if c < '0' || c > '9' { + return CType.UNCODABLE; + } + if start + 1 >= last { + return CType.ONE_DIGIT; + } + c = value.char_at(start + 1); + if c < '0' || c > '9' { + return CType.ONE_DIGIT; + } + return CType.TWO_DIGITS; + } + + fn choose_code( value: &CharSequence, start: i32, old_code: i32) -> i32 { + let mut lookahead: CType = ::find_c_type(&value, start); + if lookahead == CType.ONE_DIGIT { + if old_code == CODE_CODE_A { + return CODE_CODE_A; + } + return CODE_CODE_B; + } + if lookahead == CType.UNCODABLE { + if start < value.length() { + let c: char = value.char_at(start); + if c < ' ' || (old_code == CODE_CODE_A && (c < '`' || (c >= ESCAPE_FNC_1 && c <= ESCAPE_FNC_4))) { + // can continue in code A, encodes ASCII 0 to 95 or FNC1 to FNC4 + return CODE_CODE_A; + } + } + // no choice + return CODE_CODE_B; + } + if old_code == CODE_CODE_A && lookahead == CType.FNC_1 { + return CODE_CODE_A; + } + if old_code == CODE_CODE_C { + // can continue in code C + return CODE_CODE_C; + } + if old_code == CODE_CODE_B { + if lookahead == CType.FNC_1 { + // can continue in code B + return CODE_CODE_B; + } + // Seen two consecutive digits, see what follows + lookahead = ::find_c_type(&value, start + 2); + if lookahead == CType.UNCODABLE || lookahead == CType.ONE_DIGIT { + // not worth switching now + return CODE_CODE_B; + } + if lookahead == CType.FNC_1 { + // two digits, then FNC_1... + lookahead = ::find_c_type(&value, start + 3); + if lookahead == CType.TWO_DIGITS { + // then two more digits, switch + return CODE_CODE_C; + } else { + // otherwise not worth switching + return CODE_CODE_B; + } + } + // At this point, there are at least 4 consecutive digits. + // Look ahead to choose whether to switch now or on the next round. + let mut index: i32 = start + 4; + while (lookahead = ::find_c_type(&value, index)) == CType.TWO_DIGITS { + index += 2; + } + if lookahead == CType.ONE_DIGIT { + // odd number of digits, switch later + return CODE_CODE_B; + } + // even number of digits, switch now + return CODE_CODE_C; + } + // Here oldCode == 0, which means we are choosing the initial code + if lookahead == CType.FNC_1 { + // ignore FNC_1 + lookahead = ::find_c_type(&value, start + 1); + } + if lookahead == CType.TWO_DIGITS { + // at least two digits, start in code C + return CODE_CODE_C; + } + return CODE_CODE_B; + } + + /** + * Encodes minimally using Divide-And-Conquer with Memoization + **/ + + const A: &'static str = format!(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ \n \rÿ"); + + const B: &'static str = format!(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÿ"); + + const CODE_SHIFT: i32 = 98; + struct MinimalEncoder { + + let memoized_cost: Vec>; + + let min_path: Vec>; + } + + impl MinimalEncoder { + + enum Charset { + + A(), B(), C(), NONE() + } + + enum Latch { + + A(), B(), C(), SHIFT(), NONE() + } + + fn encode(&self, contents: &String) -> Vec { + self.memoized_cost = : [[i32; contents.length()]; 4] = [[0; contents.length()]; 4]; + self.min_path = : [[Option; contents.length()]; 4] = [[None; contents.length()]; 4]; + self.encode(&contents, Charset::NONE, 0); + let patterns: Collection> = ArrayList<>::new(); + let check_sum : vec![i32; 1] = vec![0, ] + ; + let check_weight : vec![i32; 1] = vec![1, ] + ; + let length: i32 = contents.length(); + let mut charset: Charset = Charset::NONE; + { + let mut i: i32 = 0; + while i < length { + { + let latch: Latch = self.min_path[charset.ordinal()][i]; + match latch { + A => + { + charset = Charset::A; + ::add_pattern(&patterns, if i == 0 { CODE_START_A } else { CODE_CODE_A }, &check_sum, &check_weight, i); + break; + } + B => + { + charset = Charset::B; + ::add_pattern(&patterns, if i == 0 { CODE_START_B } else { CODE_CODE_B }, &check_sum, &check_weight, i); + break; + } + C => + { + charset = Charset::C; + ::add_pattern(&patterns, if i == 0 { CODE_START_C } else { CODE_CODE_C }, &check_sum, &check_weight, i); + break; + } + SHIFT => + { + ::add_pattern(&patterns, CODE_SHIFT, &check_sum, &check_weight, i); + break; + } + } + if charset == Charset::C { + if contents.char_at(i) == ESCAPE_FNC_1 { + ::add_pattern(&patterns, CODE_FNC_1, &check_sum, &check_weight, i); + } else { + ::add_pattern(&patterns, &Integer::parse_int(&contents.substring(i, i + 2)), &check_sum, &check_weight, i); + //the algorithm never leads to a single trailing digit in character set C + assert!( i + 1 < length); + if i + 1 < length { + i += 1; + } + } + } else { + // charset A or B + let pattern_index: i32; + match contents.char_at(i) { + ESCAPE_FNC_1 => + { + pattern_index = CODE_FNC_1; + break; + } + ESCAPE_FNC_2 => + { + pattern_index = CODE_FNC_2; + break; + } + ESCAPE_FNC_3 => + { + pattern_index = CODE_FNC_3; + break; + } + ESCAPE_FNC_4 => + { + if (charset == Charset::A && latch != Latch::SHIFT) || (charset == Charset::B && latch == Latch::SHIFT) { + pattern_index = CODE_FNC_4_A; + } else { + pattern_index = CODE_FNC_4_B; + } + break; + } + _ => + { + pattern_index = contents.char_at(i) - ' '; + } + } + if (charset == Charset::A && latch != Latch::SHIFT) || (charset == Charset::B && latch == Latch::SHIFT) { + if pattern_index < 0 { + pattern_index += '`'; + } + } + ::add_pattern(&patterns, pattern_index, &check_sum, &check_weight, i); + } + } + i += 1; + } + } + + self.memoized_cost = null; + self.min_path = null; + return ::produce_result(&patterns, check_sum[0]); + } + + fn add_pattern( patterns: &Collection>, pattern_index: i32, check_sum: &Vec, check_weight: &Vec, position: i32) { + patterns.add(Code128Reader::CODE_PATTERNS[pattern_index]); + if position != 0 { + check_weight[0] += 1; + } + check_sum[0] += pattern_index * check_weight[0]; + } + + fn is_digit( c: char) -> bool { + return c >= '0' && c <= '9'; + } + + fn can_encode(&self, contents: &CharSequence, charset: &Charset, position: i32) -> bool { + let c: char = contents.char_at(position); + match charset { + A => + { + return c == ESCAPE_FNC_1 || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 || A::index_of(c) >= 0; + } + B => + { + return c == ESCAPE_FNC_1 || c == ESCAPE_FNC_2 || c == ESCAPE_FNC_3 || c == ESCAPE_FNC_4 || B::index_of(c) >= 0; + } + C => + { + return c == ESCAPE_FNC_1 || (position + 1 < contents.length() && ::is_digit(c) && ::is_digit(&contents.char_at(position + 1))); + } + _ => + { + return false; + } + } + } + + /** + * Encode the string starting at position position starting with the character set charset + **/ + fn encode(&self, contents: &CharSequence, charset: &Charset, position: i32) -> i32 { + assert!( position < contents.length()); + let m_cost: i32 = self.memoized_cost[charset.ordinal()][position]; + if m_cost > 0 { + return m_cost; + } + let min_cost: i32 = Integer::MAX_VALUE; + let min_latch: Latch = Latch::NONE; + let at_end: bool = position + 1 >= contents.length(); + let sets : vec![Charset; 2] = vec![Charset::A, Charset::B, ] + ; + { + let mut i: i32 = 0; + while i <= 1 { + { + if self.can_encode(&contents, sets[i], position) { + let mut cost: i32 = 1; + let mut latch: Latch = Latch::NONE; + if charset != sets[i] { + cost += 1; + latch = Latch::value_of(&sets[i].to_string()); + } + if !at_end { + cost += self.encode(&contents, sets[i], position + 1); + } + if cost < min_cost { + min_cost = cost; + min_latch = latch; + } + cost = 1; + if charset == sets[(i + 1) % 2] { + cost += 1; + latch = Latch::SHIFT; + if !at_end { + cost += self.encode(&contents, charset, position + 1); + } + if cost < min_cost { + min_cost = cost; + min_latch = latch; + } + } + } + } + i += 1; + } + } + + if self.can_encode(&contents, Charset::C, position) { + let mut cost: i32 = 1; + let mut latch: Latch = Latch::NONE; + if charset != Charset::C { + cost += 1; + latch = Latch::C; + } + let advance: i32 = if contents.char_at(position) == ESCAPE_FNC_1 { 1 } else { 2 }; + if position + advance < contents.length() { + cost += self.encode(&contents, Charset::C, position + advance); + } + if cost < min_cost { + min_cost = cost; + min_latch = latch; + } + } + if min_cost == Integer::MAX_VALUE { + throw IllegalArgumentException::new(format!("Bad character in input: ASCII value={}", contents.char_at(position) as i32)); + } + self.memoized_cost[charset.ordinal()][position] = min_cost; + self.min_path[charset.ordinal()][position] = min_latch; + return min_cost; + } + } + +} + +// NEW FILE: code39_reader.rs +/* + * 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::oned; + +/** + *

Decodes Code 39 barcodes. Supports "Full ASCII Code 39" if USE_CODE_39_EXTENDED_MODE is set.

+ * + * @author Sean Owen + * @see Code93Reader + */ + + const ALPHABET_STRING: &'static str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; + +/** + * These represent the encodings of characters, as patterns of wide and narrow bars. + * The 9 least-significant bits of each int correspond to the pattern of wide and narrow, + * with 1s representing "wide" and 0s representing narrow. + */ + const CHARACTER_ENCODINGS: vec![Vec; 43] = vec![// 0-9 +0x034, // 0-9 +0x121, // 0-9 +0x061, // 0-9 +0x160, // 0-9 +0x031, // 0-9 +0x130, // 0-9 +0x070, // 0-9 +0x025, // 0-9 +0x124, // 0-9 +0x064, // A-J +0x109, // A-J +0x049, // A-J +0x148, // A-J +0x019, // A-J +0x118, // A-J +0x058, // A-J +0x00D, // A-J +0x10C, // A-J +0x04C, // A-J +0x01C, // K-T +0x103, // K-T +0x043, // K-T +0x142, // K-T +0x013, // K-T +0x112, // K-T +0x052, // K-T +0x007, // K-T +0x106, // K-T +0x046, // K-T +0x016, // U-$ +0x181, // U-$ +0x0C1, // U-$ +0x1C0, // U-$ +0x091, // U-$ +0x190, // U-$ +0x0D0, // U-$ +0x085, // U-$ +0x184, // U-$ +0x0C4, // U-$ +0x0A8, // /-% +0x0A2, // /-% +0x08A, // /-% +0x02A, ] +; + + const ASTERISK_ENCODING: i32 = 0x094; +pub struct Code39Reader { + super: OneDReader; + + let using_check_digit: bool; + + let extended_mode: bool; + + let decode_row_result: StringBuilder; + + let mut counters: Vec; +} + +impl Code39Reader { + + /** + * Creates a reader that assumes all encoded data is data, and does not treat the final + * character as a check digit. It will not decoded "extended Code 39" sequences. + */ + pub fn new() -> Code39Reader { + this(false); + } + + /** + * Creates a reader that can be configured to check the last character as a check digit. + * It will not decoded "extended Code 39" sequences. + * + * @param usingCheckDigit if true, treat the last data character as a check digit, not + * data, and verify that the checksum passes. + */ + pub fn new( using_check_digit: bool) -> Code39Reader { + this(using_check_digit, false); + } + + /** + * Creates a reader that can be configured to check the last character as a check digit, + * or optionally attempt to decode "extended Code 39" sequences that are used to encode + * the full ASCII character set. + * + * @param usingCheckDigit if true, treat the last data character as a check digit, not + * data, and verify that the checksum passes. + * @param extendedMode if true, will attempt to decode extended Code 39 sequences in the + * text. + */ + pub fn new( using_check_digit: bool, extended_mode: bool) -> Code39Reader { + let .usingCheckDigit = using_check_digit; + let .extendedMode = extended_mode; + decode_row_result = StringBuilder::new(20); + counters = : [i32; 9] = [0; 9]; + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { + let the_counters: Vec = self.counters; + Arrays::fill(&the_counters, 0); + let result: StringBuilder = self.decode_row_result; + result.set_length(0); + let start: Vec = ::find_asterisk_pattern(row, &the_counters); + // Read off white space + let next_start: i32 = row.get_next_set(start[1]); + let end: i32 = row.get_size(); + let decoded_char: char; + let last_start: i32; + loop { { + record_pattern(row, next_start, &the_counters); + let pattern: i32 = ::to_narrow_wide_pattern(&the_counters); + if pattern < 0 { + throw NotFoundException::get_not_found_instance(); + } + decoded_char = ::pattern_to_char(pattern); + result.append(decoded_char); + last_start = next_start; + for let counter: i32 in the_counters { + next_start += counter; + } + // Read off white space + next_start = row.get_next_set(next_start); + }if !(decoded_char != '*') break;} + // remove asterisk + result.set_length(result.length() - 1); + // Look for whitespace after pattern: + let last_pattern_size: i32 = 0; + for let counter: i32 in the_counters { + last_pattern_size += counter; + } + let white_space_after_end: i32 = next_start - last_start - last_pattern_size; + // (but if it's whitespace to the very end of the image, that's OK) + if next_start != end && (white_space_after_end * 2) < last_pattern_size { + throw NotFoundException::get_not_found_instance(); + } + if self.using_check_digit { + let max: i32 = result.length() - 1; + let mut total: i32 = 0; + { + let mut i: i32 = 0; + while i < max { + { + total += ALPHABET_STRING::index_of(&self.decode_row_result.char_at(i)); + } + i += 1; + } + } + + if result.char_at(max) != ALPHABET_STRING::char_at(total % 43) { + throw ChecksumException::get_checksum_instance(); + } + result.set_length(max); + } + if result.length() == 0 { + // false positive + throw NotFoundException::get_not_found_instance(); + } + let result_string: String; + if self.extended_mode { + result_string = ::decode_extended(&result); + } else { + result_string = result.to_string(); + } + let left: f32 = (start[1] + start[0]) / 2.0f; + let right: f32 = last_start + last_pattern_size / 2.0f; + let result_object: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] + , BarcodeFormat::CODE_39); + result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]A0"); + return Ok(result_object); + } + + fn find_asterisk_pattern( row: &BitArray, counters: &Vec) -> /* throws NotFoundException */Result, Rc> { + let width: i32 = row.get_size(); + let row_offset: i32 = row.get_next_set(0); + let counter_position: i32 = 0; + let pattern_start: i32 = row_offset; + let is_white: bool = false; + let pattern_length: i32 = counters.len(); + { + let mut i: i32 = row_offset; + while i < width { + { + if row.get(i) != is_white { + counters[counter_position] += 1; + } else { + if counter_position == pattern_length - 1 { + // Look for whitespace before start pattern, >= 50% of width of start pattern + if ::to_narrow_wide_pattern(&counters) == ASTERISK_ENCODING && row.is_range(&Math::max(0, pattern_start - ((i - pattern_start) / 2)), pattern_start, false) { + return Ok( : vec![i32; 2] = vec![pattern_start, i, ] + ); + } + pattern_start += counters[0] + counters[1]; + System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); + counters[counter_position - 1] = 0; + counters[counter_position] = 0; + counter_position -= 1; + } else { + counter_position += 1; + } + counters[counter_position] = 1; + is_white = !is_white; + } + } + i += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + // For efficiency, returns -1 on failure. Not throwing here saved as many as 700 exceptions + // per image when using some of our blackbox images. + fn to_narrow_wide_pattern( counters: &Vec) -> i32 { + let num_counters: i32 = counters.len(); + let max_narrow_counter: i32 = 0; + let wide_counters: i32; + loop { { + let min_counter: i32 = Integer::MAX_VALUE; + for let counter: i32 in counters { + if counter < min_counter && counter > max_narrow_counter { + min_counter = counter; + } + } + max_narrow_counter = min_counter; + wide_counters = 0; + let total_wide_counters_width: i32 = 0; + let mut pattern: i32 = 0; + { + let mut i: i32 = 0; + while i < num_counters { + { + let counter: i32 = counters[i]; + if counter > max_narrow_counter { + pattern |= 1 << (num_counters - 1 - i); + wide_counters += 1; + total_wide_counters_width += counter; + } + } + i += 1; + } + } + + if wide_counters == 3 { + // counter is more than 1.5 times the average: + { + let mut i: i32 = 0; + while i < num_counters && wide_counters > 0 { + { + let counter: i32 = counters[i]; + if counter > max_narrow_counter { + wide_counters -= 1; + // totalWideCountersWidth = 3 * average, so this checks if counter >= 3/2 * average + if (counter * 2) >= total_wide_counters_width { + return -1; + } + } + } + i += 1; + } + } + + return pattern; + } + }if !(wide_counters > 3) break;} + return -1; + } + + fn pattern_to_char( pattern: i32) -> /* throws NotFoundException */Result> { + { + let mut i: i32 = 0; + while i < CHARACTER_ENCODINGS.len() { + { + if CHARACTER_ENCODINGS[i] == pattern { + return Ok(ALPHABET_STRING::char_at(i)); + } + } + i += 1; + } + } + + if pattern == ASTERISK_ENCODING { + return Ok('*'); + } + throw NotFoundException::get_not_found_instance(); + } + + fn decode_extended( encoded: &CharSequence) -> /* throws FormatException */Result> { + let length: i32 = encoded.length(); + let decoded: StringBuilder = StringBuilder::new(length); + { + let mut i: i32 = 0; + while i < length { + { + let c: char = encoded.char_at(i); + if c == '+' || c == '$' || c == '%' || c == '/' { + let next: char = encoded.char_at(i + 1); + let decoded_char: char = '\0'; + match c { + '+' => + { + // +A to +Z map to a to z + if next >= 'A' && next <= 'Z' { + decoded_char = (next + 32) as char; + } else { + throw FormatException::get_format_instance(); + } + break; + } + '$' => + { + // $A to $Z map to control codes SH to SB + if next >= 'A' && next <= 'Z' { + decoded_char = (next - 64) as char; + } else { + throw FormatException::get_format_instance(); + } + break; + } + '%' => + { + // %A to %E map to control codes ESC to US + if next >= 'A' && next <= 'E' { + decoded_char = (next - 38) as char; + } else if next >= 'F' && next <= 'J' { + decoded_char = (next - 11) as char; + } else if next >= 'K' && next <= 'O' { + decoded_char = (next + 16) as char; + } else if next >= 'P' && next <= 'T' { + decoded_char = (next + 43) as char; + } else if next == 'U' { + decoded_char = 0 as char; + } else if next == 'V' { + decoded_char = '@'; + } else if next == 'W' { + decoded_char = '`'; + } else if next == 'X' || next == 'Y' || next == 'Z' { + decoded_char = 127 as char; + } else { + throw FormatException::get_format_instance(); + } + break; + } + '/' => + { + // /A to /O map to ! to , and /Z maps to : + if next >= 'A' && next <= 'O' { + decoded_char = (next - 32) as char; + } else if next == 'Z' { + decoded_char = ':'; + } else { + throw FormatException::get_format_instance(); + } + break; + } + } + decoded.append(decoded_char); + // bump up i again since we read two characters + i += 1; + } else { + decoded.append(c); + } + } + i += 1; + } + } + + return Ok(decoded.to_string()); + } +} + +// NEW FILE: code39_writer.rs +/* + * Copyright 2010 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::oned; + +/** + * This object renders a CODE39 code as a {@link BitMatrix}. + * + * @author erik.barbara@gmail.com (Erik Barbara) + */ +pub struct Code39Writer { + super: OneDimensionalCodeWriter; +} + +impl Code39Writer { + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::CODE_39); + } + + pub fn encode(&self, contents: &String) -> Vec { + let mut length: i32 = contents.length(); + if length > 80 { + throw IllegalArgumentException::new(format!("Requested contents should be less than 80 digits long, but got {}", length)); + } + { + let mut i: i32 = 0; + while i < length { + { + let index_in_string: i32 = Code39Reader::ALPHABET_STRING::index_of(&contents.char_at(i)); + if index_in_string < 0 { + contents = ::try_to_convert_to_extended_mode(&contents); + length = contents.length(); + if length > 80 { + throw IllegalArgumentException::new(format!("Requested contents should be less than 80 digits long, but got {} (extended full ASCII mode)", length)); + } + break; + } + } + i += 1; + } + } + + let widths: [i32; 9] = [0; 9]; + let code_width: i32 = 24 + 1 + (13 * length); + let result: [bool; code_width] = [false; code_width]; + ::to_int_array(Code39Reader::ASTERISK_ENCODING, &widths); + let mut pos: i32 = append_pattern(&result, 0, &widths, true); + let narrow_white: vec![Vec; 1] = vec![1, ] + ; + pos += append_pattern(&result, pos, &narrow_white, false); + //append next character to byte matrix + { + let mut i: i32 = 0; + while i < length { + { + let index_in_string: i32 = Code39Reader::ALPHABET_STRING::index_of(&contents.char_at(i)); + ::to_int_array(Code39Reader::CHARACTER_ENCODINGS[index_in_string], &widths); + pos += append_pattern(&result, pos, &widths, true); + pos += append_pattern(&result, pos, &narrow_white, false); + } + i += 1; + } + } + + ::to_int_array(Code39Reader::ASTERISK_ENCODING, &widths); + append_pattern(&result, pos, &widths, true); + return result; + } + + fn to_int_array( a: i32, to_return: &Vec) { + { + let mut i: i32 = 0; + while i < 9 { + { + let temp: i32 = a & (1 << (8 - i)); + to_return[i] = if temp == 0 { 1 } else { 2 }; + } + i += 1; + } + } + + } + + fn try_to_convert_to_extended_mode( contents: &String) -> String { + let length: i32 = contents.length(); + let extended_content: StringBuilder = StringBuilder::new(); + { + let mut i: i32 = 0; + while i < length { + { + let character: char = contents.char_at(i); + match character { + '' => + { + extended_content.append("%U"); + break; + } + ' ' => + { + } + '-' => + { + } + '.' => + { + extended_content.append(character); + break; + } + '@' => + { + extended_content.append("%V"); + break; + } + '`' => + { + extended_content.append("%W"); + break; + } + _ => + { + if character <= 26 { + extended_content.append('$'); + extended_content.append(('A' + (character - 1)) as char); + } else if character < ' ' { + extended_content.append('%'); + extended_content.append(('A' + (character - 27)) as char); + } else if character <= ',' || character == '/' || character == ':' { + extended_content.append('/'); + extended_content.append(('A' + (character - 33)) as char); + } else if character <= '9' { + extended_content.append(('0' + (character - 48)) as char); + } else if character <= '?' { + extended_content.append('%'); + extended_content.append(('F' + (character - 59)) as char); + } else if character <= 'Z' { + extended_content.append(('A' + (character - 65)) as char); + } else if character <= '_' { + extended_content.append('%'); + extended_content.append(('K' + (character - 91)) as char); + } else if character <= 'z' { + extended_content.append('+'); + extended_content.append(('A' + (character - 97)) as char); + } else if character <= 127 { + extended_content.append('%'); + extended_content.append(('P' + (character - 123)) as char); + } else { + throw IllegalArgumentException::new(format!("Requested content contains a non-encodable character: '{}'", contents.char_at(i))); + } + break; + } + } + } + i += 1; + } + } + + return extended_content.to_string(); + } +} + +// NEW FILE: code93_reader.rs +/* + * Copyright 2010 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::oned; + +/** + *

Decodes Code 93 barcodes.

+ * + * @author Sean Owen + * @see Code39Reader + */ + +// Note that 'abcd' are dummy characters in place of control characters. + const ALPHABET_STRING: &'static str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*"; + + const ALPHABET: Vec = ALPHABET_STRING::to_char_array(); + +/** + * These represent the encodings of characters, as patterns of wide and narrow bars. + * The 9 least-significant bits of each int correspond to the pattern of wide and narrow. + */ + const CHARACTER_ENCODINGS: vec![Vec; 48] = vec![// 0-9 +0x114, // 0-9 +0x148, // 0-9 +0x144, // 0-9 +0x142, // 0-9 +0x128, // 0-9 +0x124, // 0-9 +0x122, // 0-9 +0x150, // 0-9 +0x112, // 0-9 +0x10A, // A-J +0x1A8, // A-J +0x1A4, // A-J +0x1A2, // A-J +0x194, // A-J +0x192, // A-J +0x18A, // A-J +0x168, // A-J +0x164, // A-J +0x162, // A-J +0x134, // K-T +0x11A, // K-T +0x158, // K-T +0x14C, // K-T +0x146, // K-T +0x12C, // K-T +0x116, // K-T +0x1B4, // K-T +0x1B2, // K-T +0x1AC, // K-T +0x1A6, // U-Z +0x196, // U-Z +0x19A, // U-Z +0x16C, // U-Z +0x166, // U-Z +0x136, // U-Z +0x13A, // - - % +0x12E, // - - % +0x1D4, // - - % +0x1D2, // - - % +0x1CA, // - - % +0x16E, // - - % +0x176, // - - % +0x1AE, // Control chars? $-* +0x126, // Control chars? $-* +0x1DA, // Control chars? $-* +0x1D6, // Control chars? $-* +0x132, // Control chars? $-* +0x15E, ] +; + + const ASTERISK_ENCODING: i32 = CHARACTER_ENCODINGS[47]; +pub struct Code93Reader { + super: OneDReader; + + let decode_row_result: StringBuilder; + + let mut counters: Vec; +} + +impl Code93Reader { + + pub fn new() -> Code93Reader { + decode_row_result = StringBuilder::new(20); + counters = : [i32; 6] = [0; 6]; + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { + let start: Vec = self.find_asterisk_pattern(row); + // Read off white space + let next_start: i32 = row.get_next_set(start[1]); + let end: i32 = row.get_size(); + let the_counters: Vec = self.counters; + Arrays::fill(&the_counters, 0); + let result: StringBuilder = self.decode_row_result; + result.set_length(0); + let decoded_char: char; + let last_start: i32; + loop { { + record_pattern(row, next_start, &the_counters); + let pattern: i32 = ::to_pattern(&the_counters); + if pattern < 0 { + throw NotFoundException::get_not_found_instance(); + } + decoded_char = ::pattern_to_char(pattern); + result.append(decoded_char); + last_start = next_start; + for let counter: i32 in the_counters { + next_start += counter; + } + // Read off white space + next_start = row.get_next_set(next_start); + }if !(decoded_char != '*') break;} + // remove asterisk + result.delete_char_at(result.length() - 1); + let last_pattern_size: i32 = 0; + for let counter: i32 in the_counters { + last_pattern_size += counter; + } + // Should be at least one more black module + if next_start == end || !row.get(next_start) { + throw NotFoundException::get_not_found_instance(); + } + if result.length() < 2 { + // false positive -- need at least 2 checksum digits + throw NotFoundException::get_not_found_instance(); + } + ::check_checksums(&result); + // Remove checksum digits + result.set_length(result.length() - 2); + let result_string: String = ::decode_extended(&result); + let left: f32 = (start[1] + start[0]) / 2.0f; + let right: f32 = last_start + last_pattern_size / 2.0f; + let result_object: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] + , BarcodeFormat::CODE_93); + result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]G0"); + return Ok(result_object); + } + + fn find_asterisk_pattern(&self, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { + let width: i32 = row.get_size(); + let row_offset: i32 = row.get_next_set(0); + Arrays::fill(&self.counters, 0); + let the_counters: Vec = self.counters; + let pattern_start: i32 = row_offset; + let is_white: bool = false; + let pattern_length: i32 = the_counters.len(); + let counter_position: i32 = 0; + { + let mut i: i32 = row_offset; + while i < width { + { + if row.get(i) != is_white { + the_counters[counter_position] += 1; + } else { + if counter_position == pattern_length - 1 { + if ::to_pattern(&the_counters) == ASTERISK_ENCODING { + return Ok( : vec![i32; 2] = vec![pattern_start, i, ] + ); + } + pattern_start += the_counters[0] + the_counters[1]; + System::arraycopy(&the_counters, 2, &the_counters, 0, counter_position - 1); + the_counters[counter_position - 1] = 0; + the_counters[counter_position] = 0; + counter_position -= 1; + } else { + counter_position += 1; + } + the_counters[counter_position] = 1; + is_white = !is_white; + } + } + i += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + fn to_pattern( counters: &Vec) -> i32 { + let mut sum: i32 = 0; + for let counter: i32 in counters { + sum += counter; + } + let mut pattern: i32 = 0; + let max: i32 = counters.len(); + { + let mut i: i32 = 0; + while i < max { + { + let scaled: i32 = Math::round(counters[i] * 9.0f / sum); + if scaled < 1 || scaled > 4 { + return -1; + } + if (i & 0x01) == 0 { + { + let mut j: i32 = 0; + while j < scaled { + { + pattern = (pattern << 1) | 0x01; + } + j += 1; + } + } + + } else { + pattern <<= scaled; + } + } + i += 1; + } + } + + return pattern; + } + + fn pattern_to_char( pattern: i32) -> /* throws NotFoundException */Result> { + { + let mut i: i32 = 0; + while i < CHARACTER_ENCODINGS.len() { + { + if CHARACTER_ENCODINGS[i] == pattern { + return Ok(ALPHABET[i]); + } + } + i += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + fn decode_extended( encoded: &CharSequence) -> /* throws FormatException */Result> { + let length: i32 = encoded.length(); + let decoded: StringBuilder = StringBuilder::new(length); + { + let mut i: i32 = 0; + while i < length { + { + let c: char = encoded.char_at(i); + if c >= 'a' && c <= 'd' { + if i >= length - 1 { + throw FormatException::get_format_instance(); + } + let next: char = encoded.char_at(i + 1); + let decoded_char: char = '\0'; + match c { + 'd' => + { + // +A to +Z map to a to z + if next >= 'A' && next <= 'Z' { + decoded_char = (next + 32) as char; + } else { + throw FormatException::get_format_instance(); + } + break; + } + 'a' => + { + // $A to $Z map to control codes SH to SB + if next >= 'A' && next <= 'Z' { + decoded_char = (next - 64) as char; + } else { + throw FormatException::get_format_instance(); + } + break; + } + 'b' => + { + if next >= 'A' && next <= 'E' { + // %A to %E map to control codes ESC to USep + decoded_char = (next - 38) as char; + } else if next >= 'F' && next <= 'J' { + // %F to %J map to ; < = > ? + decoded_char = (next - 11) as char; + } else if next >= 'K' && next <= 'O' { + // %K to %O map to [ \ ] ^ _ + decoded_char = (next + 16) as char; + } else if next >= 'P' && next <= 'T' { + // %P to %T map to { | } ~ DEL + decoded_char = (next + 43) as char; + } else if next == 'U' { + // %U map to NUL + decoded_char = '\0'; + } else if next == 'V' { + // %V map to @ + decoded_char = '@'; + } else if next == 'W' { + // %W map to ` + decoded_char = '`'; + } else if next >= 'X' && next <= 'Z' { + // %X to %Z all map to DEL (127) + decoded_char = 127; + } else { + throw FormatException::get_format_instance(); + } + break; + } + 'c' => + { + // /A to /O map to ! to , and /Z maps to : + if next >= 'A' && next <= 'O' { + decoded_char = (next - 32) as char; + } else if next == 'Z' { + decoded_char = ':'; + } else { + throw FormatException::get_format_instance(); + } + break; + } + } + decoded.append(decoded_char); + // bump up i again since we read two characters + i += 1; + } else { + decoded.append(c); + } + } + i += 1; + } + } + + return Ok(decoded.to_string()); + } + + fn check_checksums( result: &CharSequence) -> /* throws ChecksumException */Result> { + let length: i32 = result.length(); + ::check_one_checksum(&result, length - 2, 20); + ::check_one_checksum(&result, length - 1, 15); + } + + fn check_one_checksum( result: &CharSequence, check_position: i32, weight_max: i32) -> /* throws ChecksumException */Result> { + let mut weight: i32 = 1; + let mut total: i32 = 0; + { + let mut i: i32 = check_position - 1; + while i >= 0 { + { + total += weight * ALPHABET_STRING::index_of(&result.char_at(i)); + if weight += 1 > weight_max { + weight = 1; + } + } + i -= 1; + } + } + + if result.char_at(check_position) != ALPHABET[total % 47] { + throw ChecksumException::get_checksum_instance(); + } + } +} + +// NEW FILE: code93_writer.rs +/* + * Copyright 2015 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::oned; + +/** + * This object renders a CODE93 code as a BitMatrix + */ +pub struct Code93Writer { + super: OneDimensionalCodeWriter; +} + +impl Code93Writer { + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::CODE_93); + } + + /** + * @param contents barcode contents to encode. It should not be encoded for extended characters. + * @return a {@code boolean[]} of horizontal pixels (false = white, true = black) + */ + pub fn encode(&self, contents: &String) -> Vec { + contents = ::convert_to_extended(&contents); + let length: i32 = contents.length(); + if length > 80 { + throw IllegalArgumentException::new(format!("Requested contents should be less than 80 digits long after converting to extended encoding, but got {}", length)); + } + //length of code + 2 start/stop characters + 2 checksums, each of 9 bits, plus a termination bar + let code_width: i32 = (contents.length() + 2 + 2) * 9 + 1; + let mut result: [bool; code_width] = [false; code_width]; + //start character (*) + let mut pos: i32 = ::append_pattern(&result, 0, Code93Reader::ASTERISK_ENCODING); + { + let mut i: i32 = 0; + while i < length { + { + let index_in_string: i32 = Code93Reader::ALPHABET_STRING::index_of(&contents.char_at(i)); + pos += ::append_pattern(&result, pos, Code93Reader::CHARACTER_ENCODINGS[index_in_string]); + } + i += 1; + } + } + + //add two checksums + let check1: i32 = ::compute_checksum_index(&contents, 20); + pos += ::append_pattern(&result, pos, Code93Reader::CHARACTER_ENCODINGS[check1]); + //append the contents to reflect the first checksum added + contents += Code93Reader::ALPHABET_STRING::char_at(check1); + let check2: i32 = ::compute_checksum_index(&contents, 15); + pos += ::append_pattern(&result, pos, Code93Reader::CHARACTER_ENCODINGS[check2]); + //end character (*) + pos += ::append_pattern(&result, pos, Code93Reader::ASTERISK_ENCODING); + //termination bar (single black bar) + result[pos] = true; + return result; + } + + /** + * @param target output to append to + * @param pos start position + * @param pattern pattern to append + * @param startColor unused + * @return 9 + * @deprecated without replacement; intended as an internal-only method + */ + pub fn append_pattern( target: &Vec, pos: i32, pattern: &Vec, start_color: bool) -> i32 { + for let bit: i32 in pattern { + target[pos += 1 !!!check!!! post increment] = bit != 0; + } + return 9; + } + + fn append_pattern( target: &Vec, pos: i32, a: i32) -> i32 { + { + let mut i: i32 = 0; + while i < 9 { + { + let temp: i32 = a & (1 << (8 - i)); + target[pos + i] = temp != 0; + } + i += 1; + } + } + + return 9; + } + + fn compute_checksum_index( contents: &String, max_weight: i32) -> i32 { + let mut weight: i32 = 1; + let mut total: i32 = 0; + { + let mut i: i32 = contents.length() - 1; + while i >= 0 { + { + let index_in_string: i32 = Code93Reader::ALPHABET_STRING::index_of(&contents.char_at(i)); + total += index_in_string * weight; + if weight += 1 > max_weight { + weight = 1; + } + } + i -= 1; + } + } + + return total % 47; + } + + fn convert_to_extended( contents: &String) -> String { + let length: i32 = contents.length(); + let extended_content: StringBuilder = StringBuilder::new(length * 2); + { + let mut i: i32 = 0; + while i < length { + { + let character: char = contents.char_at(i); + // ($)=a, (%)=b, (/)=c, (+)=d. see Code93Reader.ALPHABET_STRING + if character == 0 { + // NUL: (%)U + extended_content.append("bU"); + } else if character <= 26 { + // SOH - SUB: ($)A - ($)Z + extended_content.append('a'); + extended_content.append(('A' + character - 1) as char); + } else if character <= 31 { + // ESC - US: (%)A - (%)E + extended_content.append('b'); + extended_content.append(('A' + character - 27) as char); + } else if character == ' ' || character == '$' || character == '%' || character == '+' { + // space $ % + + extended_content.append(character); + } else if character <= ',' { + // ! " # & ' ( ) * ,: (/)A - (/)L + extended_content.append('c'); + extended_content.append(('A' + character - '!') as char); + } else if character <= '9' { + extended_content.append(character); + } else if character == ':' { + // :: (/)Z + extended_content.append("cZ"); + } else if character <= '?' { + // ; - ?: (%)F - (%)J + extended_content.append('b'); + extended_content.append(('F' + character - ';') as char); + } else if character == '@' { + // @: (%)V + extended_content.append("bV"); + } else if character <= 'Z' { + // A - Z + extended_content.append(character); + } else if character <= '_' { + // [ - _: (%)K - (%)O + extended_content.append('b'); + extended_content.append(('K' + character - '[') as char); + } else if character == '`' { + // `: (%)W + extended_content.append("bW"); + } else if character <= 'z' { + // a - z: (*)A - (*)Z + extended_content.append('d'); + extended_content.append(('A' + character - 'a') as char); + } else if character <= 127 { + // { - DEL: (%)P - (%)T + extended_content.append('b'); + extended_content.append(('P' + character - '{') as char); + } else { + throw IllegalArgumentException::new(format!("Requested content contains a non-encodable character: '{}'", character)); + } + } + i += 1; + } + } + + return extended_content.to_string(); + } +} + +// NEW FILE: e_a_n13_reader.rs +/* + * 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::oned; + +/** + *

Implements decoding of the EAN-13 format.

+ * + * @author dswitkin@google.com (Daniel Switkin) + * @author Sean Owen + * @author alasdair@google.com (Alasdair Mackintosh) + */ + +// For an EAN-13 barcode, the first digit is represented by the parities used +// to encode the next six digits, according to the table below. For example, +// if the barcode is 5 123456 789012 then the value of the first digit is +// signified by using odd for '1', even for '2', even for '3', odd for '4', +// odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13 +// +// Parity of next 6 digits +// Digit 0 1 2 3 4 5 +// 0 Odd Odd Odd Odd Odd Odd +// 1 Odd Odd Even Odd Even Even +// 2 Odd Odd Even Even Odd Even +// 3 Odd Odd Even Even Even Odd +// 4 Odd Even Odd Odd Even Even +// 5 Odd Even Even Odd Odd Even +// 6 Odd Even Even Even Odd Odd +// 7 Odd Even Odd Even Odd Even +// 8 Odd Even Odd Even Even Odd +// 9 Odd Even Even Odd Even Odd +// +// Note that the encoding for '0' uses the same parity as a UPC barcode. Hence +// a UPC barcode can be converted to an EAN-13 barcode by prepending a 0. +// +// The encoding is represented by the following array, which is a bit pattern +// using Odd = 0 and Even = 1. For example, 5 is represented by: +// +// Odd Even Even Odd Odd Even +// in binary: +// 0 1 1 0 0 1 == 0x19 +// + const FIRST_DIGIT_ENCODINGS: vec![Vec; 10] = vec![0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A, ] +; +pub struct EAN13Reader { + super: UPCEANReader; + + let decode_middle_counters: Vec; +} + +impl EAN13Reader { + + pub fn new() -> EAN13Reader { + decode_middle_counters = : [i32; 4] = [0; 4]; + } + + pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { + let mut counters: Vec = self.decode_middle_counters; + counters[0] = 0; + counters[1] = 0; + counters[2] = 0; + counters[3] = 0; + let end: i32 = row.get_size(); + let row_offset: i32 = start_range[1]; + let lg_pattern_found: i32 = 0; + { + let mut x: i32 = 0; + while x < 6 && row_offset < end { + { + let best_match: i32 = decode_digit(row, &counters, row_offset, L_AND_G_PATTERNS); + result_string.append(('0' + best_match % 10) as char); + for let counter: i32 in counters { + row_offset += counter; + } + if best_match >= 10 { + lg_pattern_found |= 1 << (5 - x); + } + } + x += 1; + } + } + + ::determine_first_digit(&result_string, lg_pattern_found); + let middle_range: Vec = find_guard_pattern(row, row_offset, true, MIDDLE_PATTERN); + row_offset = middle_range[1]; + { + let mut x: i32 = 0; + while x < 6 && row_offset < end { + { + let best_match: i32 = decode_digit(row, &counters, row_offset, L_PATTERNS); + result_string.append(('0' + best_match) as char); + for let counter: i32 in counters { + row_offset += counter; + } + } + x += 1; + } + } + + return Ok(row_offset); + } + + fn get_barcode_format(&self) -> BarcodeFormat { + return BarcodeFormat::EAN_13; + } + + /** + * Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded + * digits in a barcode, determines the implicitly encoded first digit and adds it to the + * result string. + * + * @param resultString string to insert decoded first digit into + * @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to + * encode digits + * @throws NotFoundException if first digit cannot be determined + */ + fn determine_first_digit( result_string: &StringBuilder, lg_pattern_found: i32) -> /* throws NotFoundException */Result> { + { + let mut d: i32 = 0; + while d < 10 { + { + if lg_pattern_found == FIRST_DIGIT_ENCODINGS[d] { + result_string.insert(0, ('0' + d) as char); + return; + } + } + d += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } +} + +// NEW FILE: e_a_n13_writer.rs +/* + * Copyright 2009 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::oned; + +/** + * This object renders an EAN13 code as a {@link BitMatrix}. + * + * @author aripollak@gmail.com (Ari Pollak) + */ + + const CODE_WIDTH: i32 = // start guard +3 + // left bars +(7 * 6) + // middle guard +5 + // right bars +(7 * 6) + // end guard +3; +pub struct EAN13Writer { + super: UPCEANWriter; +} + +impl EAN13Writer { + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::EAN_13); + } + + pub fn encode(&self, contents: &String) -> Vec { + let length: i32 = contents.length(); + match length { + 12 => + { + // No check digit present, calculate it and add it + let mut check: i32; + let tryResult1 = 0; + 'try1: loop { + { + check = UPCEANReader::get_standard_u_p_c_e_a_n_checksum(&contents); + } + break 'try1 + } + match tryResult1 { + catch ( fe: &FormatException) { + throw IllegalArgumentException::new(fe); + } 0 => break + } + + contents += check; + break; + } + 13 => + { + let tryResult1 = 0; + 'try1: loop { + { + if !UPCEANReader::check_standard_u_p_c_e_a_n_checksum(&contents) { + throw IllegalArgumentException::new("Contents do not pass checksum"); + } + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &FormatException) { + throw IllegalArgumentException::new("Illegal contents"); + } 0 => break + } + + break; + } + _ => + { + throw IllegalArgumentException::new(format!("Requested contents should be 12 or 13 digits long, but got {}", length)); + } + } + check_numeric(&contents); + let first_digit: i32 = Character::digit(&contents.char_at(0), 10); + let parities: i32 = EAN13Reader.FIRST_DIGIT_ENCODINGS[first_digit]; + let result: [bool; CODE_WIDTH] = [false; CODE_WIDTH]; + let mut pos: i32 = 0; + pos += append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); + // See EAN13Reader for a description of how the first digit & left bars are encoded + { + let mut i: i32 = 1; + while i <= 6 { + { + let mut digit: i32 = Character::digit(&contents.char_at(i), 10); + if (parities >> (6 - i) & 1) == 1 { + digit += 10; + } + pos += append_pattern(&result, pos, UPCEANReader.L_AND_G_PATTERNS[digit], false); + } + i += 1; + } + } + + pos += append_pattern(&result, pos, UPCEANReader.MIDDLE_PATTERN, false); + { + let mut i: i32 = 7; + while i <= 12 { + { + let digit: i32 = Character::digit(&contents.char_at(i), 10); + pos += append_pattern(&result, pos, UPCEANReader.L_PATTERNS[digit], true); + } + i += 1; + } + } + + append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); + return result; + } +} + +// NEW FILE: e_a_n8_reader.rs +/* + * 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::oned; + +/** + *

Implements decoding of the EAN-8 format.

+ * + * @author Sean Owen + */ +pub struct EAN8Reader { + super: UPCEANReader; + + let decode_middle_counters: Vec; +} + +impl EAN8Reader { + + pub fn new() -> EAN8Reader { + decode_middle_counters = : [i32; 4] = [0; 4]; + } + + pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result: &StringBuilder) -> /* throws NotFoundException */Result> { + let mut counters: Vec = self.decode_middle_counters; + counters[0] = 0; + counters[1] = 0; + counters[2] = 0; + counters[3] = 0; + let end: i32 = row.get_size(); + let row_offset: i32 = start_range[1]; + { + let mut x: i32 = 0; + while x < 4 && row_offset < end { + { + let best_match: i32 = decode_digit(row, &counters, row_offset, L_PATTERNS); + result.append(('0' + best_match) as char); + for let counter: i32 in counters { + row_offset += counter; + } + } + x += 1; + } + } + + let middle_range: Vec = find_guard_pattern(row, row_offset, true, MIDDLE_PATTERN); + row_offset = middle_range[1]; + { + let mut x: i32 = 0; + while x < 4 && row_offset < end { + { + let best_match: i32 = decode_digit(row, &counters, row_offset, L_PATTERNS); + result.append(('0' + best_match) as char); + for let counter: i32 in counters { + row_offset += counter; + } + } + x += 1; + } + } + + return Ok(row_offset); + } + + fn get_barcode_format(&self) -> BarcodeFormat { + return BarcodeFormat::EAN_8; + } +} + +// NEW FILE: e_a_n8_writer.rs +/* + * Copyright 2009 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::oned; + +/** + * This object renders an EAN8 code as a {@link BitMatrix}. + * + * @author aripollak@gmail.com (Ari Pollak) + */ + + const CODE_WIDTH: i32 = // start guard +3 + // left bars +(7 * 4) + // middle guard +5 + // right bars +(7 * 4) + // end guard +3; +pub struct EAN8Writer { + super: UPCEANWriter; +} + +impl EAN8Writer { + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::EAN_8); + } + + /** + * @return a byte array of horizontal pixels (false = white, true = black) + */ + pub fn encode(&self, contents: &String) -> Vec { + let length: i32 = contents.length(); + match length { + 7 => + { + // No check digit present, calculate it and add it + let mut check: i32; + let tryResult1 = 0; + 'try1: loop { + { + check = UPCEANReader::get_standard_u_p_c_e_a_n_checksum(&contents); + } + break 'try1 + } + match tryResult1 { + catch ( fe: &FormatException) { + throw IllegalArgumentException::new(fe); + } 0 => break + } + + contents += check; + break; + } + 8 => + { + let tryResult1 = 0; + 'try1: loop { + { + if !UPCEANReader::check_standard_u_p_c_e_a_n_checksum(&contents) { + throw IllegalArgumentException::new("Contents do not pass checksum"); + } + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &FormatException) { + throw IllegalArgumentException::new("Illegal contents"); + } 0 => break + } + + break; + } + _ => + { + throw IllegalArgumentException::new(format!("Requested contents should be 7 or 8 digits long, but got {}", length)); + } + } + check_numeric(&contents); + let result: [bool; CODE_WIDTH] = [false; CODE_WIDTH]; + let mut pos: i32 = 0; + pos += append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); + { + let mut i: i32 = 0; + while i <= 3 { + { + let digit: i32 = Character::digit(&contents.char_at(i), 10); + pos += append_pattern(&result, pos, UPCEANReader.L_PATTERNS[digit], false); + } + i += 1; + } + } + + pos += append_pattern(&result, pos, UPCEANReader.MIDDLE_PATTERN, false); + { + let mut i: i32 = 4; + while i <= 7 { + { + let digit: i32 = Character::digit(&contents.char_at(i), 10); + pos += append_pattern(&result, pos, UPCEANReader.L_PATTERNS[digit], true); + } + i += 1; + } + } + + append_pattern(&result, pos, UPCEANReader.START_END_PATTERN, true); + return result; + } +} + +// NEW FILE: e_a_n_manufacturer_org_support.rs +/* + * Copyright (C) 2010 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::oned; + +/** + * Records EAN prefix to GS1 Member Organization, where the member organization + * correlates strongly with a country. This is an imperfect means of identifying + * a country of origin by EAN-13 barcode value. See + * + * http://en.wikipedia.org/wiki/List_of_GS1_country_codes. + * + * @author Sean Owen + */ +struct EANManufacturerOrgSupport { + + let ranges: List> = ArrayList<>::new(); + + let country_identifiers: List = ArrayList<>::new(); +} + +impl EANManufacturerOrgSupport { + + fn lookup_country_identifier(&self, product_code: &String) -> String { + self.init_if_needed(); + let prefix: i32 = Integer::parse_int(&product_code.substring(0, 3)); + let max: i32 = self.ranges.size(); + { + let mut i: i32 = 0; + while i < max { + { + let range: Vec = self.ranges.get(i); + let start: i32 = range[0]; + if prefix < start { + return null; + } + let end: i32 = if range.len() == 1 { start } else { range[1] }; + if prefix <= end { + return self.country_identifiers.get(i); + } + } + i += 1; + } + } + + return null; + } + + fn add(&self, range: &Vec, id: &String) { + self.ranges.add(&range); + self.country_identifiers.add(&id); + } + + fn init_if_needed(&self) { + if !self.ranges.is_empty() { + return; + } + self.add( : vec![i32; 2] = vec![0, 19, ] + , "US/CA"); + self.add( : vec![i32; 2] = vec![30, 39, ] + , "US"); + self.add( : vec![i32; 2] = vec![60, 139, ] + , "US/CA"); + self.add( : vec![i32; 2] = vec![300, 379, ] + , "FR"); + self.add( : vec![i32; 1] = vec![380, ] + , "BG"); + self.add( : vec![i32; 1] = vec![383, ] + , "SI"); + self.add( : vec![i32; 1] = vec![385, ] + , "HR"); + self.add( : vec![i32; 1] = vec![387, ] + , "BA"); + self.add( : vec![i32; 2] = vec![400, 440, ] + , "DE"); + self.add( : vec![i32; 2] = vec![450, 459, ] + , "JP"); + self.add( : vec![i32; 2] = vec![460, 469, ] + , "RU"); + self.add( : vec![i32; 1] = vec![471, ] + , "TW"); + self.add( : vec![i32; 1] = vec![474, ] + , "EE"); + self.add( : vec![i32; 1] = vec![475, ] + , "LV"); + self.add( : vec![i32; 1] = vec![476, ] + , "AZ"); + self.add( : vec![i32; 1] = vec![477, ] + , "LT"); + self.add( : vec![i32; 1] = vec![478, ] + , "UZ"); + self.add( : vec![i32; 1] = vec![479, ] + , "LK"); + self.add( : vec![i32; 1] = vec![480, ] + , "PH"); + self.add( : vec![i32; 1] = vec![481, ] + , "BY"); + self.add( : vec![i32; 1] = vec![482, ] + , "UA"); + self.add( : vec![i32; 1] = vec![484, ] + , "MD"); + self.add( : vec![i32; 1] = vec![485, ] + , "AM"); + self.add( : vec![i32; 1] = vec![486, ] + , "GE"); + self.add( : vec![i32; 1] = vec![487, ] + , "KZ"); + self.add( : vec![i32; 1] = vec![489, ] + , "HK"); + self.add( : vec![i32; 2] = vec![490, 499, ] + , "JP"); + self.add( : vec![i32; 2] = vec![500, 509, ] + , "GB"); + self.add( : vec![i32; 1] = vec![520, ] + , "GR"); + self.add( : vec![i32; 1] = vec![528, ] + , "LB"); + self.add( : vec![i32; 1] = vec![529, ] + , "CY"); + self.add( : vec![i32; 1] = vec![531, ] + , "MK"); + self.add( : vec![i32; 1] = vec![535, ] + , "MT"); + self.add( : vec![i32; 1] = vec![539, ] + , "IE"); + self.add( : vec![i32; 2] = vec![540, 549, ] + , "BE/LU"); + self.add( : vec![i32; 1] = vec![560, ] + , "PT"); + self.add( : vec![i32; 1] = vec![569, ] + , "IS"); + self.add( : vec![i32; 2] = vec![570, 579, ] + , "DK"); + self.add( : vec![i32; 1] = vec![590, ] + , "PL"); + self.add( : vec![i32; 1] = vec![594, ] + , "RO"); + self.add( : vec![i32; 1] = vec![599, ] + , "HU"); + self.add( : vec![i32; 2] = vec![600, 601, ] + , "ZA"); + self.add( : vec![i32; 1] = vec![603, ] + , "GH"); + self.add( : vec![i32; 1] = vec![608, ] + , "BH"); + self.add( : vec![i32; 1] = vec![609, ] + , "MU"); + self.add( : vec![i32; 1] = vec![611, ] + , "MA"); + self.add( : vec![i32; 1] = vec![613, ] + , "DZ"); + self.add( : vec![i32; 1] = vec![616, ] + , "KE"); + self.add( : vec![i32; 1] = vec![618, ] + , "CI"); + self.add( : vec![i32; 1] = vec![619, ] + , "TN"); + self.add( : vec![i32; 1] = vec![621, ] + , "SY"); + self.add( : vec![i32; 1] = vec![622, ] + , "EG"); + self.add( : vec![i32; 1] = vec![624, ] + , "LY"); + self.add( : vec![i32; 1] = vec![625, ] + , "JO"); + self.add( : vec![i32; 1] = vec![626, ] + , "IR"); + self.add( : vec![i32; 1] = vec![627, ] + , "KW"); + self.add( : vec![i32; 1] = vec![628, ] + , "SA"); + self.add( : vec![i32; 1] = vec![629, ] + , "AE"); + self.add( : vec![i32; 2] = vec![640, 649, ] + , "FI"); + self.add( : vec![i32; 2] = vec![690, 695, ] + , "CN"); + self.add( : vec![i32; 2] = vec![700, 709, ] + , "NO"); + self.add( : vec![i32; 1] = vec![729, ] + , "IL"); + self.add( : vec![i32; 2] = vec![730, 739, ] + , "SE"); + self.add( : vec![i32; 1] = vec![740, ] + , "GT"); + self.add( : vec![i32; 1] = vec![741, ] + , "SV"); + self.add( : vec![i32; 1] = vec![742, ] + , "HN"); + self.add( : vec![i32; 1] = vec![743, ] + , "NI"); + self.add( : vec![i32; 1] = vec![744, ] + , "CR"); + self.add( : vec![i32; 1] = vec![745, ] + , "PA"); + self.add( : vec![i32; 1] = vec![746, ] + , "DO"); + self.add( : vec![i32; 1] = vec![750, ] + , "MX"); + self.add( : vec![i32; 2] = vec![754, 755, ] + , "CA"); + self.add( : vec![i32; 1] = vec![759, ] + , "VE"); + self.add( : vec![i32; 2] = vec![760, 769, ] + , "CH"); + self.add( : vec![i32; 1] = vec![770, ] + , "CO"); + self.add( : vec![i32; 1] = vec![773, ] + , "UY"); + self.add( : vec![i32; 1] = vec![775, ] + , "PE"); + self.add( : vec![i32; 1] = vec![777, ] + , "BO"); + self.add( : vec![i32; 1] = vec![779, ] + , "AR"); + self.add( : vec![i32; 1] = vec![780, ] + , "CL"); + self.add( : vec![i32; 1] = vec![784, ] + , "PY"); + self.add( : vec![i32; 1] = vec![785, ] + , "PE"); + self.add( : vec![i32; 1] = vec![786, ] + , "EC"); + self.add( : vec![i32; 2] = vec![789, 790, ] + , "BR"); + self.add( : vec![i32; 2] = vec![800, 839, ] + , "IT"); + self.add( : vec![i32; 2] = vec![840, 849, ] + , "ES"); + self.add( : vec![i32; 1] = vec![850, ] + , "CU"); + self.add( : vec![i32; 1] = vec![858, ] + , "SK"); + self.add( : vec![i32; 1] = vec![859, ] + , "CZ"); + self.add( : vec![i32; 1] = vec![860, ] + , "YU"); + self.add( : vec![i32; 1] = vec![865, ] + , "MN"); + self.add( : vec![i32; 1] = vec![867, ] + , "KP"); + self.add( : vec![i32; 2] = vec![868, 869, ] + , "TR"); + self.add( : vec![i32; 2] = vec![870, 879, ] + , "NL"); + self.add( : vec![i32; 1] = vec![880, ] + , "KR"); + self.add( : vec![i32; 1] = vec![885, ] + , "TH"); + self.add( : vec![i32; 1] = vec![888, ] + , "SG"); + self.add( : vec![i32; 1] = vec![890, ] + , "IN"); + self.add( : vec![i32; 1] = vec![893, ] + , "VN"); + self.add( : vec![i32; 1] = vec![896, ] + , "PK"); + self.add( : vec![i32; 1] = vec![899, ] + , "ID"); + self.add( : vec![i32; 2] = vec![900, 919, ] + , "AT"); + self.add( : vec![i32; 2] = vec![930, 939, ] + , "AU"); + self.add( : vec![i32; 2] = vec![940, 949, ] + , "AZ"); + self.add( : vec![i32; 1] = vec![955, ] + , "MY"); + self.add( : vec![i32; 1] = vec![958, ] + , "MO"); + } +} + +// NEW FILE: i_t_f_reader.rs +/* + * 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::oned; + +/** + *

Implements decoding of the ITF format, or Interleaved Two of Five.

+ * + *

This Reader will scan ITF barcodes of certain lengths only. + * At the moment it reads length 6, 8, 10, 12, 14, 16, 18, 20, 24, and 44 as these have appeared "in the wild". Not all + * lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of + * required checksum function.

+ * + *

The checksum is optional and is not applied by this Reader. The consumer of the decoded + * value will have to apply a checksum if required.

+ * + *

http://en.wikipedia.org/wiki/Interleaved_2_of_5 + * is a great reference for Interleaved 2 of 5 information.

+ * + * @author kevin.osullivan@sita.aero, SITA Lab. + */ + + const MAX_AVG_VARIANCE: f32 = 0.38f; + + const MAX_INDIVIDUAL_VARIANCE: f32 = 0.5f; + +// Pixel width of a 3x wide line + const W: i32 = 3; + +// Pixel width of a 2x wide line + let w: i32 = 2; + +// Pixed width of a narrow line + const N: i32 = 1; + +/** Valid ITF lengths. Anything longer than the largest value is also allowed. */ + const DEFAULT_ALLOWED_LENGTHS: vec![Vec; 5] = vec![6, 8, 10, 12, 14, ] +; + +/** + * Start/end guard pattern. + * + * Note: The end pattern is reversed because the row is reversed before + * searching for the END_PATTERN + */ + const START_PATTERN: vec![Vec; 4] = vec![N, N, N, N, ] +; + + const END_PATTERN_REVERSED: vec![vec![Vec>; 3]; 2] = vec![// 2x +vec![N, N, w, ] +, // 3x +vec![N, N, W, ] +, ] +; + +// See ITFWriter.PATTERNS +/** + * Patterns of Wide / Narrow lines to indicate each digit + */ + const PATTERNS: vec![vec![Vec>; 5]; 20] = vec![// 0 +vec![N, N, w, w, N, ] +, // 1 +vec![w, N, N, N, w, ] +, // 2 +vec![N, w, N, N, w, ] +, // 3 +vec![w, w, N, N, N, ] +, // 4 +vec![N, N, w, N, w, ] +, // 5 +vec![w, N, w, N, N, ] +, // 6 +vec![N, w, w, N, N, ] +, // 7 +vec![N, N, N, w, w, ] +, // 8 +vec![w, N, N, w, N, ] +, // 9 +vec![N, w, N, w, N, ] +, // 0 +vec![N, N, W, W, N, ] +, // 1 +vec![W, N, N, N, W, ] +, // 2 +vec![N, W, N, N, W, ] +, // 3 +vec![W, W, N, N, N, ] +, // 4 +vec![N, N, W, N, W, ] +, // 5 +vec![W, N, W, N, N, ] +, // 6 +vec![N, W, W, N, N, ] +, // 7 +vec![N, N, N, W, W, ] +, // 8 +vec![W, N, N, W, N, ] +, // 9 +vec![N, W, N, W, N, ] +, ] +; +pub struct ITFReader { + super: OneDReader; + + // Stores the actual narrow line width of the image being decoded. + let narrow_line_width: i32 = -1; +} + +impl ITFReader { + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws FormatException, NotFoundException */Result> { + // Find out where the Middle section (payload) starts & ends + let start_range: Vec = self.decode_start(row); + let end_range: Vec = self.decode_end(row); + let result: StringBuilder = StringBuilder::new(20); + ::decode_middle(row, start_range[1], end_range[0], &result); + let result_string: String = result.to_string(); + let allowed_lengths: Vec = null; + if hints != null { + allowed_lengths = hints.get(DecodeHintType::ALLOWED_LENGTHS) as Vec; + } + if allowed_lengths == null { + allowed_lengths = DEFAULT_ALLOWED_LENGTHS; + } + // To avoid false positives with 2D barcodes (and other patterns), make + // an assumption that the decoded string must be a 'standard' length if it's short + let length: i32 = result_string.length(); + let length_o_k: bool = false; + let max_allowed_length: i32 = 0; + for let allowed_length: i32 in allowed_lengths { + if length == allowed_length { + length_o_k = true; + break; + } + if allowed_length > max_allowed_length { + max_allowed_length = allowed_length; + } + } + if !length_o_k && length > max_allowed_length { + length_o_k = true; + } + if !length_o_k { + throw FormatException::get_format_instance(); + } + let result_object: Result = Result::new(&result_string, // no natural byte representation for these barcodes + null, : vec![ResultPoint; 2] = vec![ResultPoint::new(start_range[1], row_number), ResultPoint::new(end_range[0], row_number), ] + , BarcodeFormat::ITF); + result_object.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]I0"); + return Ok(result_object); + } + + /** + * @param row row of black/white values to search + * @param payloadStart offset of start pattern + * @param resultString {@link StringBuilder} to append decoded chars to + * @throws NotFoundException if decoding could not complete successfully + */ + fn decode_middle( row: &BitArray, payload_start: i32, payload_end: i32, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { + // Digits are interleaved in pairs - 5 black lines for one digit, and the + // 5 + // interleaved white lines for the second digit. + // Therefore, need to scan 10 lines and then + // split these into two arrays + let counter_digit_pair: [i32; 10] = [0; 10]; + let counter_black: [i32; 5] = [0; 5]; + let counter_white: [i32; 5] = [0; 5]; + while payload_start < payload_end { + // Get 10 runs of black/white. + record_pattern(row, payload_start, &counter_digit_pair); + // Split them into each array + { + let mut k: i32 = 0; + while k < 5 { + { + let two_k: i32 = 2 * k; + counter_black[k] = counter_digit_pair[two_k]; + counter_white[k] = counter_digit_pair[two_k + 1]; + } + k += 1; + } + } + + let best_match: i32 = ::decode_digit(&counter_black); + result_string.append(('0' + best_match) as char); + best_match = ::decode_digit(&counter_white); + result_string.append(('0' + best_match) as char); + for let counter_digit: i32 in counter_digit_pair { + payload_start += counter_digit; + } + } + } + + /** + * Identify where the start of the middle / payload section starts. + * + * @param row row of black/white values to search + * @return Array, containing index of start of 'start block' and end of + * 'start block' + */ + fn decode_start(&self, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { + let end_start: i32 = ::skip_white_space(row); + let start_pattern: Vec = ::find_guard_pattern(row, end_start, &START_PATTERN); + // Determine the width of a narrow line in pixels. We can do this by + // getting the width of the start pattern and dividing by 4 because its + // made up of 4 narrow lines. + self.narrowLineWidth = (start_pattern[1] - start_pattern[0]) / 4; + self.validate_quiet_zone(row, start_pattern[0]); + return Ok(start_pattern); + } + + /** + * The start & end patterns must be pre/post fixed by a quiet zone. This + * zone must be at least 10 times the width of a narrow line. Scan back until + * we either get to the start of the barcode or match the necessary number of + * quiet zone pixels. + * + * Note: Its assumed the row is reversed when using this method to find + * quiet zone after the end pattern. + * + * ref: http://www.barcode-1.net/i25code.html + * + * @param row bit array representing the scanned barcode. + * @param startPattern index into row of the start or end pattern. + * @throws NotFoundException if the quiet zone cannot be found + */ + fn validate_quiet_zone(&self, row: &BitArray, start_pattern: i32) -> /* throws NotFoundException */Result> { + // expect to find this many pixels of quiet zone + let quiet_count: i32 = self.narrowLineWidth * 10; + // if there are not so many pixel at all let's try as many as possible + quiet_count = Math::min(quiet_count, start_pattern); + { + let mut i: i32 = start_pattern - 1; + while quiet_count > 0 && i >= 0 { + { + if row.get(i) { + break; + } + quiet_count -= 1; + } + i -= 1; + } + } + + if quiet_count != 0 { + // Unable to find the necessary number of quiet zone pixels. + throw NotFoundException::get_not_found_instance(); + } + } + + /** + * Skip all whitespace until we get to the first black line. + * + * @param row row of black/white values to search + * @return index of the first black line. + * @throws NotFoundException Throws exception if no black lines are found in the row + */ + fn skip_white_space( row: &BitArray) -> /* throws NotFoundException */Result> { + let width: i32 = row.get_size(); + let end_start: i32 = row.get_next_set(0); + if end_start == width { + throw NotFoundException::get_not_found_instance(); + } + return Ok(end_start); + } + + /** + * Identify where the end of the middle / payload section ends. + * + * @param row row of black/white values to search + * @return Array, containing index of start of 'end block' and end of 'end + * block' + */ + fn decode_end(&self, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { + // For convenience, reverse the row and then + // search from 'the start' for the end block + row.reverse(); + let tryResult1 = 0; + 'try1: loop { + { + let end_start: i32 = ::skip_white_space(row); + let end_pattern: Vec; + let tryResult2 = 0; + 'try2: loop { + { + end_pattern = ::find_guard_pattern(row, end_start, END_PATTERN_REVERSED[0]); + } + break 'try2 + } + match tryResult2 { + catch ( nfe: &NotFoundException) { + end_pattern = ::find_guard_pattern(row, end_start, END_PATTERN_REVERSED[1]); + } 0 => break + } + + // The start & end patterns must be pre/post fixed by a quiet zone. This + // zone must be at least 10 times the width of a narrow line. + // ref: http://www.barcode-1.net/i25code.html + self.validate_quiet_zone(row, end_pattern[0]); + // Now recalculate the indices of where the 'endblock' starts & stops to + // accommodate + // the reversed nature of the search + let temp: i32 = end_pattern[0]; + end_pattern[0] = row.get_size() - end_pattern[1]; + end_pattern[1] = row.get_size() - temp; + return Ok(end_pattern); + } + break 'try1 + } + match tryResult1 { + 0 => break + } + finally { + // Put the row back the right way. + row.reverse(); + } + } + + /** + * @param row row of black/white values to search + * @param rowOffset position to start search + * @param pattern pattern of counts of number of black and white pixels that are + * being searched for as a pattern + * @return start/end horizontal offset of guard pattern, as an array of two + * ints + * @throws NotFoundException if pattern is not found + */ + fn find_guard_pattern( row: &BitArray, row_offset: i32, pattern: &Vec) -> /* throws NotFoundException */Result, Rc> { + let pattern_length: i32 = pattern.len(); + let mut counters: [i32; pattern_length] = [0; pattern_length]; + let width: i32 = row.get_size(); + let is_white: bool = false; + let counter_position: i32 = 0; + let pattern_start: i32 = row_offset; + { + let mut x: i32 = row_offset; + while x < width { + { + if row.get(x) != is_white { + counters[counter_position] += 1; + } else { + if counter_position == pattern_length - 1 { + if pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE { + return Ok( : vec![i32; 2] = vec![pattern_start, x, ] + ); + } + pattern_start += counters[0] + counters[1]; + System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); + counters[counter_position - 1] = 0; + counters[counter_position] = 0; + counter_position -= 1; + } else { + counter_position += 1; + } + counters[counter_position] = 1; + is_white = !is_white; + } + } + x += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + /** + * Attempts to decode a sequence of ITF black/white lines into single + * digit. + * + * @param counters the counts of runs of observed black/white/black/... values + * @return The decoded digit + * @throws NotFoundException if digit cannot be decoded + */ + fn decode_digit( counters: &Vec) -> /* throws NotFoundException */Result> { + // worst variance we'll accept + let best_variance: f32 = MAX_AVG_VARIANCE; + let best_match: i32 = -1; + let max: i32 = PATTERNS.len(); + { + let mut i: i32 = 0; + while i < max { + { + let pattern: Vec = PATTERNS[i]; + let variance: f32 = pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE); + if variance < best_variance { + best_variance = variance; + best_match = i; + } else if variance == best_variance { + // if we find a second 'best match' with the same variance, we can not reliably report to have a suitable match + best_match = -1; + } + } + i += 1; + } + } + + if best_match >= 0 { + return Ok(best_match % 10); + } else { + throw NotFoundException::get_not_found_instance(); + } + } +} + +// NEW FILE: i_t_f_writer.rs +/* + * Copyright 2010 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::oned; + +/** + * This object renders a ITF code as a {@link BitMatrix}. + * + * @author erik.barbara@gmail.com (Erik Barbara) + */ + + const START_PATTERN: vec![Vec; 4] = vec![1, 1, 1, 1, ] +; + + const END_PATTERN: vec![Vec; 3] = vec![3, 1, 1, ] +; + +// Pixel width of a 3x wide line + const W: i32 = 3; + +// Pixed width of a narrow line + const N: i32 = 1; + +// See ITFReader.PATTERNS + const PATTERNS: vec![vec![Vec>; 5]; 10] = vec![// 0 +vec![N, N, W, W, N, ] +, // 1 +vec![W, N, N, N, W, ] +, // 2 +vec![N, W, N, N, W, ] +, // 3 +vec![W, W, N, N, N, ] +, // 4 +vec![N, N, W, N, W, ] +, // 5 +vec![W, N, W, N, N, ] +, // 6 +vec![N, W, W, N, N, ] +, // 7 +vec![N, N, N, W, W, ] +, // 8 +vec![W, N, N, W, N, ] +, // 9 +vec![N, W, N, W, N, ] +, ] +; +pub struct ITFWriter { + super: OneDimensionalCodeWriter; +} + +impl ITFWriter { + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::ITF); + } + + pub fn encode(&self, contents: &String) -> Vec { + let length: i32 = contents.length(); + if length % 2 != 0 { + throw IllegalArgumentException::new("The length of the input should be even"); + } + if length > 80 { + throw IllegalArgumentException::new(format!("Requested contents should be less than 80 digits long, but got {}", length)); + } + check_numeric(&contents); + let result: [bool; 9 + 9 * length] = [false; 9 + 9 * length]; + let mut pos: i32 = append_pattern(&result, 0, &START_PATTERN, true); + { + let mut i: i32 = 0; + while i < length { + { + let one: i32 = Character::digit(&contents.char_at(i), 10); + let two: i32 = Character::digit(&contents.char_at(i + 1), 10); + let mut encoding: [i32; 10] = [0; 10]; + { + let mut j: i32 = 0; + while j < 5 { + { + encoding[2 * j] = PATTERNS[one][j]; + encoding[2 * j + 1] = PATTERNS[two][j]; + } + j += 1; + } + } + + pos += append_pattern(&result, pos, &encoding, true); + } + i += 2; + } + } + + append_pattern(&result, pos, &END_PATTERN, true); + return result; + } +} + +// NEW FILE: multi_format_one_d_reader.rs +/* + * 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::oned; + +/** + * @author dswitkin@google.com (Daniel Switkin) + * @author Sean Owen + */ + + const EMPTY_ONED_ARRAY: [Option; 0] = [None; 0]; +pub struct MultiFormatOneDReader { + super: OneDReader; + + let readers: Vec; +} + +impl MultiFormatOneDReader { + + pub fn new( hints: &Map) -> MultiFormatOneDReader { + let possible_formats: Collection = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection }; + let use_code39_check_digit: bool = hints != null && hints.get(DecodeHintType::ASSUME_CODE_39_CHECK_DIGIT) != null; + let mut readers: Collection = ArrayList<>::new(); + if possible_formats != null { + if possible_formats.contains(BarcodeFormat::EAN_13) || possible_formats.contains(BarcodeFormat::UPC_A) || possible_formats.contains(BarcodeFormat::EAN_8) || possible_formats.contains(BarcodeFormat::UPC_E) { + readers.add(MultiFormatUPCEANReader::new(&hints)); + } + if possible_formats.contains(BarcodeFormat::CODE_39) { + readers.add(Code39Reader::new(use_code39_check_digit)); + } + if possible_formats.contains(BarcodeFormat::CODE_93) { + readers.add(Code93Reader::new()); + } + if possible_formats.contains(BarcodeFormat::CODE_128) { + readers.add(Code128Reader::new()); + } + if possible_formats.contains(BarcodeFormat::ITF) { + readers.add(ITFReader::new()); + } + if possible_formats.contains(BarcodeFormat::CODABAR) { + readers.add(CodaBarReader::new()); + } + if possible_formats.contains(BarcodeFormat::RSS_14) { + readers.add(RSS14Reader::new()); + } + if possible_formats.contains(BarcodeFormat::RSS_EXPANDED) { + readers.add(RSSExpandedReader::new()); + } + } + if readers.is_empty() { + readers.add(MultiFormatUPCEANReader::new(&hints)); + readers.add(Code39Reader::new()); + readers.add(CodaBarReader::new()); + readers.add(Code93Reader::new()); + readers.add(Code128Reader::new()); + readers.add(ITFReader::new()); + readers.add(RSS14Reader::new()); + readers.add(RSSExpandedReader::new()); + } + let .readers = readers.to_array(EMPTY_ONED_ARRAY); + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { + for let reader: OneDReader in self.readers { + let tryResult1 = 0; + 'try1: loop { + { + return Ok(reader.decode_row(row_number, row, &hints)); + } + break 'try1 + } + match tryResult1 { + catch ( re: &ReaderException) { + } 0 => break + } + + } + throw NotFoundException::get_not_found_instance(); + } + + pub fn reset(&self) { + for let reader: Reader in self.readers { + reader.reset(); + } + } +} + +// NEW FILE: multi_format_u_p_c_e_a_n_reader.rs +/* + * 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::oned; + +/** + *

A reader that can read all available UPC/EAN formats. If a caller wants to try to + * read all such formats, it is most efficient to use this implementation rather than invoke + * individual readers.

+ * + * @author Sean Owen + */ + + const EMPTY_READER_ARRAY: [Option; 0] = [None; 0]; +pub struct MultiFormatUPCEANReader { + super: OneDReader; + + let readers: Vec; +} + +impl MultiFormatUPCEANReader { + + pub fn new( hints: &Map) -> MultiFormatUPCEANReader { + let possible_formats: Collection = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection }; + let mut readers: Collection = ArrayList<>::new(); + if possible_formats != null { + if possible_formats.contains(BarcodeFormat::EAN_13) { + readers.add(EAN13Reader::new()); + } else if possible_formats.contains(BarcodeFormat::UPC_A) { + readers.add(UPCAReader::new()); + } + if possible_formats.contains(BarcodeFormat::EAN_8) { + readers.add(EAN8Reader::new()); + } + if possible_formats.contains(BarcodeFormat::UPC_E) { + readers.add(UPCEReader::new()); + } + } + if readers.is_empty() { + readers.add(EAN13Reader::new()); + // UPC-A is covered by EAN-13 + readers.add(EAN8Reader::new()); + readers.add(UPCEReader::new()); + } + let .readers = readers.to_array(EMPTY_READER_ARRAY); + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { + // Compute this location once and reuse it on multiple implementations + let start_guard_pattern: Vec = UPCEANReader::find_start_guard_pattern(row); + for let reader: UPCEANReader in self.readers { + let tryResult1 = 0; + 'try1: loop { + { + let result: Result = reader.decode_row(row_number, row, &start_guard_pattern, &hints); + // Special case: a 12-digit code encoded in UPC-A is identical to a "0" + // followed by those 12 digits encoded as EAN-13. Each will recognize such a code, + // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0". + // Individually these are correct and their readers will both read such a code + // and correctly call it EAN-13, or UPC-A, respectively. + // + // In this case, if we've been looking for both types, we'd like to call it + // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read + // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A + // result if appropriate. + // + // But, don't return UPC-A if UPC-A was not a requested format! + let ean13_may_be_u_p_c_a: bool = result.get_barcode_format() == BarcodeFormat::EAN_13 && result.get_text().char_at(0) == '0'; + let possible_formats: Collection = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection }; + let can_return_u_p_c_a: bool = possible_formats == null || possible_formats.contains(BarcodeFormat::UPC_A); + if ean13_may_be_u_p_c_a && can_return_u_p_c_a { + // Transfer the metadata across + let result_u_p_c_a: Result = Result::new(&result.get_text().substring(1), &result.get_raw_bytes(), &result.get_result_points(), BarcodeFormat::UPC_A); + result_u_p_c_a.put_all_metadata(&result.get_result_metadata()); + return Ok(result_u_p_c_a); + } + return Ok(result); + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &ReaderException) { + } 0 => break + } + + } + throw NotFoundException::get_not_found_instance(); + } + + pub fn reset(&self) { + for let reader: Reader in self.readers { + reader.reset(); + } + } +} + +// NEW FILE: one_d_reader.rs +/* + * 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::oned; + +/** + * Encapsulates functionality and implementation that is common to all families + * of one-dimensional barcodes. + * + * @author dswitkin@google.com (Daniel Switkin) + * @author Sean Owen + */ +#[derive(Reader)] +pub struct OneDReader { +} + +impl OneDReader { + + pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, FormatException */Result> { + return Ok(self.decode(image, null)); + } + + // Note that we don't try rotation without the try harder flag, even if rotation was supported. + pub fn decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException, FormatException */Result> { + let tryResult1 = 0; + 'try1: loop { + { + return Ok(self.do_decode(image, &hints)); + } + break 'try1 + } + match tryResult1 { + catch ( nfe: &NotFoundException) { + let try_harder: bool = hints != null && hints.contains_key(DecodeHintType::TRY_HARDER); + if try_harder && image.is_rotate_supported() { + let rotated_image: BinaryBitmap = image.rotate_counter_clockwise(); + let result: Result = self.do_decode(rotated_image, &hints); + let metadata: Map = result.get_result_metadata(); + let mut orientation: i32 = 270; + if metadata != null && metadata.contains_key(ResultMetadataType::ORIENTATION) { + orientation = (orientation + metadata.get(ResultMetadataType::ORIENTATION) as Integer) % 360; + } + result.put_metadata(ResultMetadataType::ORIENTATION, orientation); + let mut points: Vec = result.get_result_points(); + if points != null { + let height: i32 = rotated_image.get_height(); + { + let mut i: i32 = 0; + while i < points.len() { + { + points[i] = ResultPoint::new(height - points[i].get_y() - 1, &points[i].get_x()); + } + i += 1; + } + } + + } + return Ok(result); + } else { + throw nfe; + } + } 0 => break + } + + } + + pub fn reset(&self) { + // do nothing + } + + /** + * We're going to examine rows from the middle outward, searching alternately above and below the + * middle, and farther out each time. rowStep is the number of rows between each successive + * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then + * middle + rowStep, then middle - (2 * rowStep), etc. + * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily + * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the + * image if "trying harder". + * + * @param image The image to decode + * @param hints Any hints that were requested + * @return The contents of the decoded barcode + * @throws NotFoundException Any spontaneous errors which occur + */ + fn do_decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException */Result> { + let width: i32 = image.get_width(); + let height: i32 = image.get_height(); + let mut row: BitArray = BitArray::new(width); + let try_harder: bool = hints != null && hints.contains_key(DecodeHintType::TRY_HARDER); + let row_step: i32 = Math::max(1, height >> ( if try_harder { 8 } else { 5 })); + let max_lines: i32; + if try_harder { + // Look at the whole image, not just the center + max_lines = height; + } else { + // 15 rows spaced 1/32 apart is roughly the middle half of the image + max_lines = 15; + } + let middle: i32 = height / 2; + { + let mut x: i32 = 0; + while x < max_lines { + { + // Scanning from the middle out. Determine which row we're looking at next: + let row_steps_above_or_below: i32 = (x + 1) / 2; + // i.e. is x even? + let is_above: bool = (x & 0x01) == 0; + let row_number: i32 = middle + row_step * ( if is_above { row_steps_above_or_below } else { -row_steps_above_or_below }); + if row_number < 0 || row_number >= height { + // Oops, if we run off the top or bottom, stop + break; + } + // Estimate black point for this row and load it: + let tryResult1 = 0; + 'try1: loop { + { + row = image.get_black_row(row_number, row); + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &NotFoundException) { + continue; + } 0 => break + } + + // handle decoding upside down barcodes. + { + let mut attempt: i32 = 0; + while attempt < 2 { + { + if attempt == 1 { + // trying again? + // reverse the row and continue + row.reverse(); + // that start on the center line. + if hints != null && hints.contains_key(DecodeHintType::NEED_RESULT_POINT_CALLBACK) { + let new_hints: Map = EnumMap<>::new(DecodeHintType.class); + new_hints.put_all(&hints); + new_hints.remove(DecodeHintType::NEED_RESULT_POINT_CALLBACK); + hints = new_hints; + } + } + let tryResult1 = 0; + 'try1: loop { + { + // Look for a barcode + let result: Result = self.decode_row(row_number, row, &hints); + // We found our barcode + if attempt == 1 { + // But it was upside down, so note that + result.put_metadata(ResultMetadataType::ORIENTATION, 180); + // And remember to flip the result points horizontally. + let mut points: Vec = result.get_result_points(); + if points != null { + points[0] = ResultPoint::new(width - points[0].get_x() - 1, &points[0].get_y()); + points[1] = ResultPoint::new(width - points[1].get_x() - 1, &points[1].get_y()); + } + } + return Ok(result); + } + break 'try1 + } + match tryResult1 { + catch ( re: &ReaderException) { + } 0 => break + } + + } + attempt += 1; + } + } + + } + x += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + /** + * Records the size of successive runs of white and black pixels in a row, starting at a given point. + * The values are recorded in the given array, and the number of runs recorded is equal to the size + * of the array. If the row starts on a white pixel at the given start point, then the first count + * recorded is the run of white pixels starting from that point; likewise it is the count of a run + * of black pixels if the row begin on a black pixels at that point. + * + * @param row row to count from + * @param start offset into row to start at + * @param counters array into which to record counts + * @throws NotFoundException if counters cannot be filled entirely from row before running out + * of pixels + */ + pub fn record_pattern( row: &BitArray, start: i32, counters: &Vec) -> /* throws NotFoundException */Result> { + let num_counters: i32 = counters.len(); + Arrays::fill(&counters, 0, num_counters, 0); + let end: i32 = row.get_size(); + if start >= end { + throw NotFoundException::get_not_found_instance(); + } + let is_white: bool = !row.get(start); + let counter_position: i32 = 0; + let mut i: i32 = start; + while i < end { + if row.get(i) != is_white { + counters[counter_position] += 1; + } else { + if counter_position += 1 == num_counters { + break; + } else { + counters[counter_position] = 1; + is_white = !is_white; + } + } + i += 1; + } + // the last counter but ran off the side of the image, OK. Otherwise, a problem. + if !(counter_position == num_counters || (counter_position == num_counters - 1 && i == end)) { + throw NotFoundException::get_not_found_instance(); + } + } + + pub fn record_pattern_in_reverse( row: &BitArray, start: i32, counters: &Vec) -> /* throws NotFoundException */Result> { + // This could be more efficient I guess + let num_transitions_left: i32 = counters.len(); + let mut last: bool = row.get(start); + while start > 0 && num_transitions_left >= 0 { + if row.get(start -= 1) != last { + num_transitions_left -= 1; + last = !last; + } + } + if num_transitions_left >= 0 { + throw NotFoundException::get_not_found_instance(); + } + ::record_pattern(row, start + 1, &counters); + } + + /** + * Determines how closely a set of observed counts of runs of black/white values matches a given + * target pattern. This is reported as the ratio of the total variance from the expected pattern + * proportions across all pattern elements, to the length of the pattern. + * + * @param counters observed counters + * @param pattern expected pattern + * @param maxIndividualVariance The most any counter can differ before we give up + * @return ratio of total variance between counters and pattern compared to total pattern size + */ + pub fn pattern_match_variance( counters: &Vec, pattern: &Vec, max_individual_variance: f32) -> f32 { + let num_counters: i32 = counters.len(); + let mut total: i32 = 0; + let pattern_length: i32 = 0; + { + let mut i: i32 = 0; + while i < num_counters { + { + total += counters[i]; + pattern_length += pattern[i]; + } + i += 1; + } + } + + if total < pattern_length { + // to reliably match, so fail: + return Float::POSITIVE_INFINITY; + } + let unit_bar_width: f32 = total as f32 / pattern_length; + max_individual_variance *= unit_bar_width; + let total_variance: f32 = 0.0f; + { + let mut x: i32 = 0; + while x < num_counters { + { + let counter: i32 = counters[x]; + let scaled_pattern: f32 = pattern[x] * unit_bar_width; + let variance: f32 = if counter > scaled_pattern { counter - scaled_pattern } else { scaled_pattern - counter }; + if variance > max_individual_variance { + return Float::POSITIVE_INFINITY; + } + total_variance += variance; + } + x += 1; + } + } + + return total_variance / total; + } + + /** + *

Attempts to decode a one-dimensional barcode format given a single row of + * an image.

+ * + * @param rowNumber row number from top of the row + * @param row the black/white pixel data of the row + * @param hints decode hints + * @return {@link Result} containing encoded string and start/end of barcode + * @throws NotFoundException if no potential barcode is found + * @throws ChecksumException if a potential barcode is found but does not pass its checksum + * @throws FormatException if a potential barcode is found but format is invalid + */ + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> ; +} + +// NEW FILE: one_dimensional_code_writer.rs +/* + * Copyright 2011 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::oned; + +/** + *

Encapsulates functionality and implementation that is common to one-dimensional barcodes.

+ * + * @author dsbnatut@gmail.com (Kazuki Nishiura) + */ + + const NUMERIC: Pattern = Pattern::compile("[0-9]+"); +#[derive(Writer)] +pub struct OneDimensionalCodeWriter { +} + +impl OneDimensionalCodeWriter { + + /** + * Encode the contents to boolean array expression of one-dimensional barcode. + * Start code and end code should be included in result, and side margins should not be included. + * + * @param contents barcode contents to encode + * @return a {@code boolean[]} of horizontal pixels (false = white, true = black) + */ + pub fn encode(&self, contents: &String) -> Vec ; + + /** + * Can be overwritten if the encode requires to read the hints map. Otherwise it defaults to {@code encode}. + * @param contents barcode contents to encode + * @param hints encoding hints + * @return a {@code boolean[]} of horizontal pixels (false = white, true = black) + */ + pub fn encode(&self, contents: &String, hints: &Map) -> Vec { + return self.encode(&contents); + } + + pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32) -> BitMatrix { + return self.encode(&contents, format, width, height, null); + } + + /** + * Encode the contents following specified format. + * {@code width} and {@code height} are required size. This method may return bigger size + * {@code BitMatrix} when specified size is too small. The user can set both {@code width} and + * {@code height} to zero to get minimum size barcode. If negative value is set to {@code width} + * or {@code height}, {@code IllegalArgumentException} is thrown. + */ + 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 width < 0 || height < 0 { + throw IllegalArgumentException::new(format!("Negative size is not allowed. Input: {}x{}", width, height)); + } + let supported_formats: Collection = self.get_supported_write_formats(); + if supported_formats != null && !supported_formats.contains(format) { + throw IllegalArgumentException::new(format!("Can only encode {}, but got {}", supported_formats, format)); + } + let sides_margin: i32 = self.get_default_margin(); + if hints != null && hints.contains_key(EncodeHintType::MARGIN) { + sides_margin = Integer::parse_int(&hints.get(EncodeHintType::MARGIN).to_string()); + } + let code: Vec = self.encode(&contents, &hints); + return ::render_result(&code, width, height, sides_margin); + } + + pub fn get_supported_write_formats(&self) -> Collection { + return null; + } + + /** + * @return a byte array of horizontal pixels (0 = white, 1 = black) + */ + fn render_result( code: &Vec, width: i32, height: i32, sides_margin: i32) -> BitMatrix { + let input_width: i32 = code.len(); + // Add quiet zone on both sides. + let full_width: i32 = input_width + sides_margin; + let output_width: i32 = Math::max(width, full_width); + let output_height: i32 = Math::max(1, height); + let multiple: i32 = output_width / full_width; + let left_padding: i32 = (output_width - (input_width * multiple)) / 2; + let output: BitMatrix = BitMatrix::new(output_width, output_height); + { + let input_x: i32 = 0, let output_x: i32 = left_padding; + while input_x < input_width { + { + if code[input_x] { + output.set_region(output_x, 0, multiple, output_height); + } + } + input_x += 1; + output_x += multiple; + } + } + + return output; + } + + /** + * @param contents string to check for numeric characters + * @throws IllegalArgumentException if input contains characters other than digits 0-9. + */ + pub fn check_numeric( contents: &String) { + if !NUMERIC::matcher(&contents)::matches() { + throw IllegalArgumentException::new("Input should only contain digits 0-9"); + } + } + + /** + * @param target encode black/white pattern into this array + * @param pos position to start encoding at in {@code target} + * @param pattern lengths of black/white runs to encode + * @param startColor starting color - false for white, true for black + * @return the number of elements added to target. + */ + pub fn append_pattern( target: &Vec, pos: i32, pattern: &Vec, start_color: bool) -> i32 { + let mut color: bool = start_color; + let num_added: i32 = 0; + for let len: i32 in pattern { + { + let mut j: i32 = 0; + while j < len { + { + target[pos += 1 !!!check!!! post increment] = color; + } + j += 1; + } + } + + num_added += len; + // flip color after each segment + color = !color; + } + return num_added; + } + + pub fn get_default_margin(&self) -> i32 { + // This seems like a decent idea for a default for all formats. + return 10; + } +} + +// NEW FILE: u_p_c_a_reader.rs +/* + * 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::oned; + +/** + *

Implements decoding of the UPC-A format.

+ * + * @author dswitkin@google.com (Daniel Switkin) + * @author Sean Owen + */ +pub struct UPCAReader { + super: UPCEANReader; + + let ean13_reader: UPCEANReader = EAN13Reader::new(); +} + +impl UPCAReader { + + pub fn decode_row(&self, row_number: i32, row: &BitArray, start_guard_range: &Vec, hints: &Map) -> /* throws NotFoundException, FormatException, ChecksumException */Result> { + return Ok(::maybe_return_result(&self.ean13_reader.decode_row(row_number, row, &start_guard_range, &hints))); + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, FormatException, ChecksumException */Result> { + return Ok(::maybe_return_result(&self.ean13_reader.decode_row(row_number, row, &hints))); + } + + pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, FormatException */Result> { + return Ok(::maybe_return_result(&self.ean13_reader.decode(image))); + } + + pub fn decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException, FormatException */Result> { + return Ok(::maybe_return_result(&self.ean13_reader.decode(image, &hints))); + } + + fn get_barcode_format(&self) -> BarcodeFormat { + return BarcodeFormat::UPC_A; + } + + pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { + return Ok(self.ean13_reader.decode_middle(row, &start_range, &result_string)); + } + + fn maybe_return_result( result: &Result) -> /* throws FormatException */Result> { + let text: String = result.get_text(); + if text.char_at(0) == '0' { + let upca_result: Result = Result::new(&text.substring(1), null, &result.get_result_points(), BarcodeFormat::UPC_A); + if result.get_result_metadata() != null { + upca_result.put_all_metadata(&result.get_result_metadata()); + } + return Ok(upca_result); + } else { + throw FormatException::get_format_instance(); + } + } +} + +// NEW FILE: u_p_c_a_writer.rs +/* + * Copyright 2010 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::oned; + +/** + * This object renders a UPC-A code as a {@link BitMatrix}. + * + * @author qwandor@google.com (Andrew Walbran) + */ +#[derive(Writer)] +pub struct UPCAWriter { + + let sub_writer: EAN13Writer = EAN13Writer::new(); +} + +impl UPCAWriter { + + 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 format != BarcodeFormat::UPC_A { + throw IllegalArgumentException::new(format!("Can only encode UPC-A, but got {}", format)); + } + // Transform a UPC-A code into the equivalent EAN-13 code and write it that way + return self.sub_writer.encode(format!("0{}", contents), BarcodeFormat::EAN_13, width, height, &hints); + } +} + +// NEW FILE: u_p_c_e_a_n_extension2_support.rs +/* + * Copyright (C) 2012 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::oned; + +/** + * @see UPCEANExtension5Support + */ +struct UPCEANExtension2Support { + + let decode_middle_counters: [i32; 4] = [0; 4]; + + let decode_row_string_buffer: StringBuilder = StringBuilder::new(); +} + +impl UPCEANExtension2Support { + + fn decode_row(&self, row_number: i32, row: &BitArray, extension_start_range: &Vec) -> /* throws NotFoundException */Result> { + let result: StringBuilder = self.decode_row_string_buffer; + result.set_length(0); + let end: i32 = self.decode_middle(row, &extension_start_range, &result); + let result_string: String = result.to_string(); + let extension_data: Map = ::parse_extension_string(&result_string); + let extension_result: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new((extension_start_range[0] + extension_start_range[1]) / 2.0f, row_number), ResultPoint::new(end, row_number), ] + , BarcodeFormat::UPC_EAN_EXTENSION); + if extension_data != null { + extension_result.put_all_metadata(&extension_data); + } + return Ok(extension_result); + } + + fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { + let mut counters: Vec = self.decode_middle_counters; + counters[0] = 0; + counters[1] = 0; + counters[2] = 0; + counters[3] = 0; + let end: i32 = row.get_size(); + let row_offset: i32 = start_range[1]; + let check_parity: i32 = 0; + { + let mut x: i32 = 0; + while x < 2 && row_offset < end { + { + let best_match: i32 = UPCEANReader::decode_digit(row, &counters, row_offset, UPCEANReader.L_AND_G_PATTERNS); + result_string.append(('0' + best_match % 10) as char); + for let counter: i32 in counters { + row_offset += counter; + } + if best_match >= 10 { + check_parity |= 1 << (1 - x); + } + if x != 1 { + // Read off separator if not last + row_offset = row.get_next_set(row_offset); + row_offset = row.get_next_unset(row_offset); + } + } + x += 1; + } + } + + if result_string.length() != 2 { + throw NotFoundException::get_not_found_instance(); + } + if Integer::parse_int(&result_string.to_string()) % 4 != check_parity { + throw NotFoundException::get_not_found_instance(); + } + return Ok(row_offset); + } + + /** + * @param raw raw content of extension + * @return formatted interpretation of raw content as a {@link Map} mapping + * one {@link ResultMetadataType} to appropriate value, or {@code null} if not known + */ + fn parse_extension_string( raw: &String) -> Map { + if raw.length() != 2 { + return null; + } + let result: Map = EnumMap<>::new(ResultMetadataType.class); + result.put(ResultMetadataType::ISSUE_NUMBER, &Integer::value_of(&raw)); + return result; + } +} + +// NEW FILE: u_p_c_e_a_n_extension5_support.rs +/* + * Copyright (C) 2010 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::oned; + +/** + * @see UPCEANExtension2Support + */ + + const CHECK_DIGIT_ENCODINGS: vec![Vec; 10] = vec![0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05, ] +; +struct UPCEANExtension5Support { + + let decode_middle_counters: [i32; 4] = [0; 4]; + + let decode_row_string_buffer: StringBuilder = StringBuilder::new(); +} + +impl UPCEANExtension5Support { + + fn decode_row(&self, row_number: i32, row: &BitArray, extension_start_range: &Vec) -> /* throws NotFoundException */Result> { + let result: StringBuilder = self.decode_row_string_buffer; + result.set_length(0); + let end: i32 = self.decode_middle(row, &extension_start_range, &result); + let result_string: String = result.to_string(); + let extension_data: Map = ::parse_extension_string(&result_string); + let extension_result: Result = Result::new(&result_string, null, : vec![ResultPoint; 2] = vec![ResultPoint::new((extension_start_range[0] + extension_start_range[1]) / 2.0f, row_number), ResultPoint::new(end, row_number), ] + , BarcodeFormat::UPC_EAN_EXTENSION); + if extension_data != null { + extension_result.put_all_metadata(&extension_data); + } + return Ok(extension_result); + } + + fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> { + let mut counters: Vec = self.decode_middle_counters; + counters[0] = 0; + counters[1] = 0; + counters[2] = 0; + counters[3] = 0; + let end: i32 = row.get_size(); + let row_offset: i32 = start_range[1]; + let lg_pattern_found: i32 = 0; + { + let mut x: i32 = 0; + while x < 5 && row_offset < end { + { + let best_match: i32 = UPCEANReader::decode_digit(row, &counters, row_offset, UPCEANReader.L_AND_G_PATTERNS); + result_string.append(('0' + best_match % 10) as char); + for let counter: i32 in counters { + row_offset += counter; + } + if best_match >= 10 { + lg_pattern_found |= 1 << (4 - x); + } + if x != 4 { + // Read off separator if not last + row_offset = row.get_next_set(row_offset); + row_offset = row.get_next_unset(row_offset); + } + } + x += 1; + } + } + + if result_string.length() != 5 { + throw NotFoundException::get_not_found_instance(); + } + let check_digit: i32 = ::determine_check_digit(lg_pattern_found); + if ::extension_checksum(&result_string.to_string()) != check_digit { + throw NotFoundException::get_not_found_instance(); + } + return Ok(row_offset); + } + + fn extension_checksum( s: &CharSequence) -> i32 { + let length: i32 = s.length(); + let mut sum: i32 = 0; + { + let mut i: i32 = length - 2; + while i >= 0 { + { + sum += s.char_at(i) - '0'; + } + i -= 2; + } + } + + sum *= 3; + { + let mut i: i32 = length - 1; + while i >= 0 { + { + sum += s.char_at(i) - '0'; + } + i -= 2; + } + } + + sum *= 3; + return sum % 10; + } + + fn determine_check_digit( lg_pattern_found: i32) -> /* throws NotFoundException */Result> { + { + let mut d: i32 = 0; + while d < 10 { + { + if lg_pattern_found == CHECK_DIGIT_ENCODINGS[d] { + return Ok(d); + } + } + d += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + /** + * @param raw raw content of extension + * @return formatted interpretation of raw content as a {@link Map} mapping + * one {@link ResultMetadataType} to appropriate value, or {@code null} if not known + */ + fn parse_extension_string( raw: &String) -> Map { + if raw.length() != 5 { + return null; + } + let value: Object = ::parse_extension5_string(&raw); + if value == null { + return null; + } + let result: Map = EnumMap<>::new(ResultMetadataType.class); + result.put(ResultMetadataType::SUGGESTED_PRICE, &value); + return result; + } + + fn parse_extension5_string( raw: &String) -> String { + let mut currency: String; + match raw.char_at(0) { + '0' => + { + currency = "£"; + break; + } + '5' => + { + currency = "$"; + break; + } + '9' => + { + // Reference: http://www.jollytech.com + match raw { + "90000" => + { + // No suggested retail price + return null; + } + "99991" => + { + // Complementary + return "0.00"; + } + "99990" => + { + return "Used"; + } + } + // Otherwise... unknown currency? + currency = ""; + break; + } + _ => + { + currency = ""; + break; + } + } + let raw_amount: i32 = Integer::parse_int(&raw.substring(1)); + let units_string: String = String::value_of(raw_amount / 100); + let hundredths: i32 = raw_amount % 100; + let hundredths_string: String = if hundredths < 10 { format!("0{}", hundredths) } else { String::value_of(hundredths) }; + return format!("{}{}.{}", currency, units_string, hundredths_string); + } +} + +// NEW FILE: u_p_c_e_a_n_extension_support.rs +/* + * Copyright (C) 2010 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::oned; + + + const EXTENSION_START_PATTERN: vec![Vec; 3] = vec![1, 1, 2, ] +; +struct UPCEANExtensionSupport { + + let two_support: UPCEANExtension2Support = UPCEANExtension2Support::new(); + + let five_support: UPCEANExtension5Support = UPCEANExtension5Support::new(); +} + +impl UPCEANExtensionSupport { + + fn decode_row(&self, row_number: i32, row: &BitArray, row_offset: i32) -> /* throws NotFoundException */Result> { + let extension_start_range: Vec = UPCEANReader::find_guard_pattern(row, row_offset, false, &EXTENSION_START_PATTERN); + let tryResult1 = 0; + 'try1: loop { + { + return Ok(self.five_support.decode_row(row_number, row, &extension_start_range)); + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &ReaderException) { + return Ok(self.two_support.decode_row(row_number, row, &extension_start_range)); + } 0 => break + } + + } +} + +// NEW FILE: u_p_c_e_a_n_reader.rs +/* + * 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::oned; + +/** + *

Encapsulates functionality and implementation that is common to UPC and EAN families + * of one-dimensional barcodes.

+ * + * @author dswitkin@google.com (Daniel Switkin) + * @author Sean Owen + * @author alasdair@google.com (Alasdair Mackintosh) + */ + +// These two values are critical for determining how permissive the decoding will be. +// We've arrived at these values through a lot of trial and error. Setting them any higher +// lets false positives creep in quickly. + const MAX_AVG_VARIANCE: f32 = 0.48f; + + const MAX_INDIVIDUAL_VARIANCE: f32 = 0.7f; + +/** + * Start/end guard pattern. + */ + const START_END_PATTERN: vec![Vec; 3] = vec![1, 1, 1, ] +; + +/** + * Pattern marking the middle of a UPC/EAN pattern, separating the two halves. + */ + const MIDDLE_PATTERN: vec![Vec; 5] = vec![1, 1, 1, 1, 1, ] +; + +/** + * end guard pattern. + */ + const END_PATTERN: vec![Vec; 6] = vec![1, 1, 1, 1, 1, 1, ] +; + +/** + * "Odd", or "L" patterns used to encode UPC/EAN digits. + */ + const L_PATTERNS: vec![vec![Vec>; 4]; 10] = vec![// 0 +vec![3, 2, 1, 1, ] +, // 1 +vec![2, 2, 2, 1, ] +, // 2 +vec![2, 1, 2, 2, ] +, // 3 +vec![1, 4, 1, 1, ] +, // 4 +vec![1, 1, 3, 2, ] +, // 5 +vec![1, 2, 3, 1, ] +, // 6 +vec![1, 1, 1, 4, ] +, // 7 +vec![1, 3, 1, 2, ] +, // 8 +vec![1, 2, 1, 3, ] +, // 9 +vec![3, 1, 1, 2, ] +, ] +; + +/** + * As above but also including the "even", or "G" patterns used to encode UPC/EAN digits. + */ + const L_AND_G_PATTERNS: Vec>; +pub struct UPCEANReader { + super: OneDReader; + + let decode_row_string_buffer: StringBuilder; + + let extension_reader: UPCEANExtensionSupport; + + let ean_man_support: EANManufacturerOrgSupport; +} + +impl UPCEANReader { + + static { + L_AND_G_PATTERNS = : [i32; 20] = [0; 20]; + System::arraycopy(&L_PATTERNS, 0, &L_AND_G_PATTERNS, 0, 10); + { + let mut i: i32 = 10; + while i < 20 { + { + let widths: Vec = L_PATTERNS[i - 10]; + let reversed_widths: [i32; widths.len()] = [0; widths.len()]; + { + let mut j: i32 = 0; + while j < widths.len() { + { + reversed_widths[j] = widths[widths.len() - j - 1]; + } + j += 1; + } + } + + L_AND_G_PATTERNS[i] = reversed_widths; + } + i += 1; + } + } + + } + + pub fn new() -> UPCEANReader { + decode_row_string_buffer = StringBuilder::new(20); + extension_reader = UPCEANExtensionSupport::new(); + ean_man_support = EANManufacturerOrgSupport::new(); + } + + fn find_start_guard_pattern( row: &BitArray) -> /* throws NotFoundException */Result, Rc> { + let found_start: bool = false; + let start_range: Vec = null; + let next_start: i32 = 0; + let counters: [i32; START_END_PATTERN.len()] = [0; START_END_PATTERN.len()]; + while !found_start { + Arrays::fill(&counters, 0, START_END_PATTERN.len(), 0); + start_range = ::find_guard_pattern(row, next_start, false, &START_END_PATTERN, &counters); + let start: i32 = start_range[0]; + next_start = start_range[1]; + // Make sure there is a quiet zone at least as big as the start pattern before the barcode. + // If this check would run off the left edge of the image, do not accept this barcode, + // as it is very likely to be a false positive. + let quiet_start: i32 = start - (next_start - start); + if quiet_start >= 0 { + found_start = row.is_range(quiet_start, start, false); + } + } + return Ok(start_range); + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { + return Ok(self.decode_row(row_number, row, &::find_start_guard_pattern(row), &hints)); + } + + /** + *

Like {@link #decodeRow(int, BitArray, Map)}, but + * allows caller to inform method about where the UPC/EAN start pattern is + * found. This allows this to be computed once and reused across many implementations.

+ * + * @param rowNumber row index into the image + * @param row encoding of the row of the barcode image + * @param startGuardRange start/end column where the opening start pattern was found + * @param hints optional hints that influence decoding + * @return {@link Result} encapsulating the result of decoding a barcode in the row + * @throws NotFoundException if no potential barcode is found + * @throws ChecksumException if a potential barcode is found but does not pass its checksum + * @throws FormatException if a potential barcode is found but format is invalid + */ + pub fn decode_row(&self, row_number: i32, row: &BitArray, start_guard_range: &Vec, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> { + let result_point_callback: ResultPointCallback = if hints == null { null } else { hints.get(DecodeHintType::NEED_RESULT_POINT_CALLBACK) as ResultPointCallback }; + let symbology_identifier: i32 = 0; + if result_point_callback != null { + result_point_callback.found_possible_result_point(ResultPoint::new((start_guard_range[0] + start_guard_range[1]) / 2.0f, row_number)); + } + let result: StringBuilder = self.decode_row_string_buffer; + result.set_length(0); + let end_start: i32 = self.decode_middle(row, &start_guard_range, &result); + if result_point_callback != null { + result_point_callback.found_possible_result_point(ResultPoint::new(end_start, row_number)); + } + let end_range: Vec = self.decode_end(row, end_start); + if result_point_callback != null { + result_point_callback.found_possible_result_point(ResultPoint::new((end_range[0] + end_range[1]) / 2.0f, row_number)); + } + // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The + // spec might want more whitespace, but in practice this is the maximum we can count on. + let end: i32 = end_range[1]; + let quiet_end: i32 = end + (end - end_range[0]); + if quiet_end >= row.get_size() || !row.is_range(end, quiet_end, false) { + throw NotFoundException::get_not_found_instance(); + } + let result_string: String = result.to_string(); + // UPC/EAN should never be less than 8 chars anyway + if result_string.length() < 8 { + throw FormatException::get_format_instance(); + } + if !self.check_checksum(&result_string) { + throw ChecksumException::get_checksum_instance(); + } + let left: f32 = (start_guard_range[1] + start_guard_range[0]) / 2.0f; + let right: f32 = (end_range[1] + end_range[0]) / 2.0f; + let format: BarcodeFormat = self.get_barcode_format(); + let decode_result: Result = Result::new(&result_string, // no natural byte representation for these barcodes + null, : vec![ResultPoint; 2] = vec![ResultPoint::new(left, row_number), ResultPoint::new(right, row_number), ] + , format); + let extension_length: i32 = 0; + let tryResult1 = 0; + 'try1: loop { + { + let extension_result: Result = self.extension_reader.decode_row(row_number, row, end_range[1]); + decode_result.put_metadata(ResultMetadataType::UPC_EAN_EXTENSION, &extension_result.get_text()); + decode_result.put_all_metadata(&extension_result.get_result_metadata()); + decode_result.add_result_points(&extension_result.get_result_points()); + extension_length = extension_result.get_text().length(); + } + break 'try1 + } + match tryResult1 { + catch ( re: &ReaderException) { + } 0 => break + } + + let allowed_extensions: Vec = if hints == null { null } else { hints.get(DecodeHintType::ALLOWED_EAN_EXTENSIONS) as Vec }; + if allowed_extensions != null { + let mut valid: bool = false; + for let length: i32 in allowed_extensions { + if extension_length == length { + valid = true; + break; + } + } + if !valid { + throw NotFoundException::get_not_found_instance(); + } + } + if format == BarcodeFormat::EAN_13 || format == BarcodeFormat::UPC_A { + let country_i_d: String = self.ean_man_support.lookup_country_identifier(&result_string); + if country_i_d != null { + decode_result.put_metadata(ResultMetadataType::POSSIBLE_COUNTRY, &country_i_d); + } + } + if format == BarcodeFormat::EAN_8 { + symbology_identifier = 4; + } + decode_result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]E{}", symbology_identifier)); + return Ok(decode_result); + } + + /** + * @param s string of digits to check + * @return {@link #checkStandardUPCEANChecksum(CharSequence)} + * @throws FormatException if the string does not contain only digits + */ + fn check_checksum(&self, s: &String) -> /* throws FormatException */Result> { + return Ok(::check_standard_u_p_c_e_a_n_checksum(&s)); + } + + /** + * Computes the UPC/EAN checksum on a string of digits, and reports + * whether the checksum is correct or not. + * + * @param s string of digits to check + * @return true iff string of digits passes the UPC/EAN checksum algorithm + * @throws FormatException if the string does not contain only digits + */ + fn check_standard_u_p_c_e_a_n_checksum( s: &CharSequence) -> /* throws FormatException */Result> { + let length: i32 = s.length(); + if length == 0 { + return Ok(false); + } + let check: i32 = Character::digit(&s.char_at(length - 1), 10); + return Ok(::get_standard_u_p_c_e_a_n_checksum(&s.sub_sequence(0, length - 1)) == check); + } + + fn get_standard_u_p_c_e_a_n_checksum( s: &CharSequence) -> /* throws FormatException */Result> { + let length: i32 = s.length(); + let mut sum: i32 = 0; + { + let mut i: i32 = length - 1; + while i >= 0 { + { + let digit: i32 = s.char_at(i) - '0'; + if digit < 0 || digit > 9 { + throw FormatException::get_format_instance(); + } + sum += digit; + } + i -= 2; + } + } + + sum *= 3; + { + let mut i: i32 = length - 2; + while i >= 0 { + { + let digit: i32 = s.char_at(i) - '0'; + if digit < 0 || digit > 9 { + throw FormatException::get_format_instance(); + } + sum += digit; + } + i -= 2; + } + } + + return Ok((1000 - sum) % 10); + } + + fn decode_end(&self, row: &BitArray, end_start: i32) -> /* throws NotFoundException */Result, Rc> { + return Ok(::find_guard_pattern(row, end_start, false, &START_END_PATTERN)); + } + + fn find_guard_pattern( row: &BitArray, row_offset: i32, white_first: bool, pattern: &Vec) -> /* throws NotFoundException */Result, Rc> { + return Ok(::find_guard_pattern(row, row_offset, white_first, &pattern, : [i32; pattern.len()] = [0; pattern.len()])); + } + + /** + * @param row row of black/white values to search + * @param rowOffset position to start search + * @param whiteFirst if true, indicates that the pattern specifies white/black/white/... + * pixel counts, otherwise, it is interpreted as black/white/black/... + * @param pattern pattern of counts of number of black and white pixels that are being + * searched for as a pattern + * @param counters array of counters, as long as pattern, to re-use + * @return start/end horizontal offset of guard pattern, as an array of two ints + * @throws NotFoundException if pattern is not found + */ + fn find_guard_pattern( row: &BitArray, row_offset: i32, white_first: bool, pattern: &Vec, counters: &Vec) -> /* throws NotFoundException */Result, Rc> { + let width: i32 = row.get_size(); + row_offset = if white_first { row.get_next_unset(row_offset) } else { row.get_next_set(row_offset) }; + let counter_position: i32 = 0; + let pattern_start: i32 = row_offset; + let pattern_length: i32 = pattern.len(); + let is_white: bool = white_first; + { + let mut x: i32 = row_offset; + while x < width { + { + if row.get(x) != is_white { + counters[counter_position] += 1; + } else { + if counter_position == pattern_length - 1 { + if pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE { + return Ok( : vec![i32; 2] = vec![pattern_start, x, ] + ); + } + pattern_start += counters[0] + counters[1]; + System::arraycopy(&counters, 2, &counters, 0, counter_position - 1); + counters[counter_position - 1] = 0; + counters[counter_position] = 0; + counter_position -= 1; + } else { + counter_position += 1; + } + counters[counter_position] = 1; + is_white = !is_white; + } + } + x += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + /** + * Attempts to decode a single UPC/EAN-encoded digit. + * + * @param row row of black/white values to decode + * @param counters the counts of runs of observed black/white/black/... values + * @param rowOffset horizontal offset to start decoding from + * @param patterns the set of patterns to use to decode -- sometimes different encodings + * for the digits 0-9 are used, and this indicates the encodings for 0 to 9 that should + * be used + * @return horizontal offset of first pixel beyond the decoded digit + * @throws NotFoundException if digit cannot be decoded + */ + fn decode_digit( row: &BitArray, counters: &Vec, row_offset: i32, patterns: &Vec>) -> /* throws NotFoundException */Result> { + record_pattern(row, row_offset, &counters); + // worst variance we'll accept + let best_variance: f32 = MAX_AVG_VARIANCE; + let best_match: i32 = -1; + let max: i32 = patterns.len(); + { + let mut i: i32 = 0; + while i < max { + { + let pattern: Vec = patterns[i]; + let variance: f32 = pattern_match_variance(&counters, &pattern, MAX_INDIVIDUAL_VARIANCE); + if variance < best_variance { + best_variance = variance; + best_match = i; + } + } + i += 1; + } + } + + if best_match >= 0 { + return Ok(best_match); + } else { + throw NotFoundException::get_not_found_instance(); + } + } + + /** + * Get the format of this decoder. + * + * @return The 1D format. + */ + fn get_barcode_format(&self) -> BarcodeFormat ; + + /** + * Subclasses override this to decode the portion of a barcode between the start + * and end guard patterns. + * + * @param row row of black/white values to search + * @param startRange start/end offset of start guard pattern + * @param resultString {@link StringBuilder} to append decoded chars to + * @return horizontal offset of first pixel after the "middle" that was decoded + * @throws NotFoundException if decoding could not complete successfully + */ + pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result_string: &StringBuilder) -> /* throws NotFoundException */Result> ; +} + +// NEW FILE: u_p_c_e_a_n_writer.rs +/* + * Copyright 2009 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::oned; + +/** + *

Encapsulates functionality and implementation that is common to UPC and EAN families + * of one-dimensional barcodes.

+ * + * @author aripollak@gmail.com (Ari Pollak) + * @author dsbnatut@gmail.com (Kazuki Nishiura) + */ +pub struct UPCEANWriter { + super: OneDimensionalCodeWriter; +} + +impl UPCEANWriter { + + pub fn get_default_margin(&self) -> i32 { + // Use a different default more appropriate for UPC/EAN + return 9; + } +} + +// NEW FILE: u_p_c_e_reader.rs +/* + * 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::oned; + +/** + *

Implements decoding of the UPC-E format.

+ *

This is a great reference for + * UPC-E information.

+ * + * @author Sean Owen + */ + +/** + * The pattern that marks the middle, and end, of a UPC-E pattern. + * There is no "second half" to a UPC-E barcode. + */ + const MIDDLE_END_PATTERN: vec![Vec; 6] = vec![1, 1, 1, 1, 1, 1, ] +; + +// For an UPC-E barcode, the final digit is represented by the parities used +// to encode the middle six digits, according to the table below. +// +// Parity of next 6 digits +// Digit 0 1 2 3 4 5 +// 0 Even Even Even Odd Odd Odd +// 1 Even Even Odd Even Odd Odd +// 2 Even Even Odd Odd Even Odd +// 3 Even Even Odd Odd Odd Even +// 4 Even Odd Even Even Odd Odd +// 5 Even Odd Odd Even Even Odd +// 6 Even Odd Odd Odd Even Even +// 7 Even Odd Even Odd Even Odd +// 8 Even Odd Even Odd Odd Even +// 9 Even Odd Odd Even Odd Even +// +// The encoding is represented by the following array, which is a bit pattern +// using Odd = 0 and Even = 1. For example, 5 is represented by: +// +// Odd Even Even Odd Odd Even +// in binary: +// 0 1 1 0 0 1 == 0x19 +// +/** + * See {@link #L_AND_G_PATTERNS}; these values similarly represent patterns of + * even-odd parity encodings of digits that imply both the number system (0 or 1) + * used, and the check digit. + */ + const NUMSYS_AND_CHECK_DIGIT_PATTERNS: vec![vec![Vec>; 10]; 2] = vec![vec![0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25, ] +, vec![0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A, ] +, ] +; +pub struct UPCEReader { + super: UPCEANReader; + + let decode_middle_counters: Vec; +} + +impl UPCEReader { + + pub fn new() -> UPCEReader { + decode_middle_counters = : [i32; 4] = [0; 4]; + } + + pub fn decode_middle(&self, row: &BitArray, start_range: &Vec, result: &StringBuilder) -> /* throws NotFoundException */Result> { + let mut counters: Vec = self.decode_middle_counters; + counters[0] = 0; + counters[1] = 0; + counters[2] = 0; + counters[3] = 0; + let end: i32 = row.get_size(); + let row_offset: i32 = start_range[1]; + let lg_pattern_found: i32 = 0; + { + let mut x: i32 = 0; + while x < 6 && row_offset < end { + { + let best_match: i32 = decode_digit(row, &counters, row_offset, L_AND_G_PATTERNS); + result.append(('0' + best_match % 10) as char); + for let counter: i32 in counters { + row_offset += counter; + } + if best_match >= 10 { + lg_pattern_found |= 1 << (5 - x); + } + } + x += 1; + } + } + + ::determine_num_sys_and_check_digit(&result, lg_pattern_found); + return Ok(row_offset); + } + + pub fn decode_end(&self, row: &BitArray, end_start: i32) -> /* throws NotFoundException */Result, Rc> { + return Ok(find_guard_pattern(row, end_start, true, &MIDDLE_END_PATTERN)); + } + + pub fn check_checksum(&self, s: &String) -> /* throws FormatException */Result> { + return Ok(super.check_checksum(&::convert_u_p_c_eto_u_p_c_a(&s))); + } + + fn determine_num_sys_and_check_digit( result_string: &StringBuilder, lg_pattern_found: i32) -> /* throws NotFoundException */Result> { + { + let num_sys: i32 = 0; + while num_sys <= 1 { + { + { + let mut d: i32 = 0; + while d < 10 { + { + if lg_pattern_found == NUMSYS_AND_CHECK_DIGIT_PATTERNS[num_sys][d] { + result_string.insert(0, ('0' + num_sys) as char); + result_string.append(('0' + d) as char); + return; + } + } + d += 1; + } + } + + } + num_sys += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + fn get_barcode_format(&self) -> BarcodeFormat { + return BarcodeFormat::UPC_E; + } + + /** + * Expands a UPC-E value back into its full, equivalent UPC-A code value. + * + * @param upce UPC-E code as string of digits + * @return equivalent UPC-A code as string of digits + */ + pub fn convert_u_p_c_eto_u_p_c_a( upce: &String) -> String { + let upce_chars: [Option; 6] = [None; 6]; + upce.get_chars(1, 7, &upce_chars, 0); + let result: StringBuilder = StringBuilder::new(12); + result.append(&upce.char_at(0)); + let last_char: char = upce_chars[5]; + match last_char { + '0' => + { + } + '1' => + { + } + '2' => + { + result.append(&upce_chars, 0, 2); + result.append(last_char); + result.append("0000"); + result.append(&upce_chars, 2, 3); + break; + } + '3' => + { + result.append(&upce_chars, 0, 3); + result.append("00000"); + result.append(&upce_chars, 3, 2); + break; + } + '4' => + { + result.append(&upce_chars, 0, 4); + result.append("00000"); + result.append(upce_chars[4]); + break; + } + _ => + { + result.append(&upce_chars, 0, 5); + result.append("0000"); + result.append(last_char); + break; + } + } + // Only append check digit in conversion if supplied + if upce.length() >= 8 { + result.append(&upce.char_at(7)); + } + return result.to_string(); + } +} + +// NEW FILE: u_p_c_e_writer.rs +/* + * Copyright 2009 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::oned; + +/** + * This object renders an UPC-E code as a {@link BitMatrix}. + * + * @author 0979097955s@gmail.com (RX) + */ + + const CODE_WIDTH: i32 = // start guard +3 + // bars +(7 * 6) + // end guard +6; +pub struct UPCEWriter { + super: UPCEANWriter; +} + +impl UPCEWriter { + + pub fn get_supported_write_formats(&self) -> Collection { + return Collections::singleton(BarcodeFormat::UPC_E); + } + + pub fn encode(&self, contents: &String) -> Vec { + let length: i32 = contents.length(); + match length { + 7 => + { + // No check digit present, calculate it and add it + let mut check: i32; + let tryResult1 = 0; + 'try1: loop { + { + check = UPCEANReader::get_standard_u_p_c_e_a_n_checksum(&UPCEReader::convert_u_p_c_eto_u_p_c_a(&contents)); + } + break 'try1 + } + match tryResult1 { + catch ( fe: &FormatException) { + throw IllegalArgumentException::new(fe); + } 0 => break + } + + contents += check; + break; + } + 8 => + { + let tryResult1 = 0; + 'try1: loop { + { + if !UPCEANReader::check_standard_u_p_c_e_a_n_checksum(&UPCEReader::convert_u_p_c_eto_u_p_c_a(&contents)) { + throw IllegalArgumentException::new("Contents do not pass checksum"); + } + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &FormatException) { + throw IllegalArgumentException::new("Illegal contents"); + } 0 => break + } + + break; + } + _ => + { + throw IllegalArgumentException::new(format!("Requested contents should be 7 or 8 digits long, but got {}", length)); + } + } + check_numeric(&contents); + let first_digit: i32 = Character::digit(&contents.char_at(0), 10); + if first_digit != 0 && first_digit != 1 { + throw IllegalArgumentException::new("Number system must be 0 or 1"); + } + let check_digit: i32 = Character::digit(&contents.char_at(7), 10); + let parities: i32 = UPCEReader.NUMSYS_AND_CHECK_DIGIT_PATTERNS[first_digit][check_digit]; + let result: [bool; CODE_WIDTH] = [false; CODE_WIDTH]; + let mut pos: i32 = append_pattern(&result, 0, UPCEANReader.START_END_PATTERN, true); + { + let mut i: i32 = 1; + while i <= 6 { + { + let mut digit: i32 = Character::digit(&contents.char_at(i), 10); + if (parities >> (6 - i) & 1) == 1 { + digit += 10; + } + pos += append_pattern(&result, pos, UPCEANReader.L_AND_G_PATTERNS[digit], false); + } + i += 1; + } + } + + append_pattern(&result, pos, UPCEANReader.END_PATTERN, false); + return result; + } +} + diff --git a/src/oned/rss.rs b/src/oned/rss.rs index e69de29..8498a81 100644 --- a/src/oned/rss.rs +++ b/src/oned/rss.rs @@ -0,0 +1,970 @@ +import com.google.zxing.NotFoundException; +import com.google.zxing.common.detector.MathUtils; +import com.google.zxing.oned.OneDReader; + +import com.google.zxing.ResultPoint; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.ResultPointCallback; +import com.google.zxing.common.BitArray; +import com.google.zxing.common.detector.MathUtils; + + + +// NEW FILE: abstract_r_s_s_reader.rs +/* + * Copyright (C) 2010 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::oned::rss; + +/** + * Superclass of {@link OneDReader} implementations that read barcodes in the RSS family + * of formats. + */ + + const MAX_AVG_VARIANCE: f32 = 0.2f; + + const MAX_INDIVIDUAL_VARIANCE: f32 = 0.45f; + + const MIN_FINDER_PATTERN_RATIO: f32 = 9.5f / 12.0f; + + const MAX_FINDER_PATTERN_RATIO: f32 = 12.5f / 14.0f; +pub struct AbstractRSSReader { + super: OneDReader; + + let decode_finder_counters: Vec; + + let data_character_counters: Vec; + + let odd_rounding_errors: Vec; + + let even_rounding_errors: Vec; + + let odd_counts: Vec; + + let even_counts: Vec; +} + +impl AbstractRSSReader { + + pub fn new() -> AbstractRSSReader { + decode_finder_counters = : [i32; 4] = [0; 4]; + data_character_counters = : [i32; 8] = [0; 8]; + odd_rounding_errors = : [f32; 4.0] = [0.0; 4.0]; + even_rounding_errors = : [f32; 4.0] = [0.0; 4.0]; + odd_counts = : [i32; data_character_counters.len() / 2] = [0; data_character_counters.len() / 2]; + even_counts = : [i32; data_character_counters.len() / 2] = [0; data_character_counters.len() / 2]; + } + + pub fn get_decode_finder_counters(&self) -> Vec { + return self.decode_finder_counters; + } + + pub fn get_data_character_counters(&self) -> Vec { + return self.data_character_counters; + } + + pub fn get_odd_rounding_errors(&self) -> Vec { + return self.odd_rounding_errors; + } + + pub fn get_even_rounding_errors(&self) -> Vec { + return self.even_rounding_errors; + } + + pub fn get_odd_counts(&self) -> Vec { + return self.odd_counts; + } + + pub fn get_even_counts(&self) -> Vec { + return self.even_counts; + } + + pub fn parse_finder_value( counters: &Vec, finder_patterns: &Vec>) -> /* throws NotFoundException */Result> { + { + let mut value: i32 = 0; + while value < finder_patterns.len() { + { + if pattern_match_variance(&counters, finder_patterns[value], MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE { + return Ok(value); + } + } + value += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + /** + * @param array values to sum + * @return sum of values + * @deprecated call {@link MathUtils#sum(int[])} + */ + pub fn count( array: &Vec) -> i32 { + return MathUtils::sum(&array); + } + + pub fn increment( array: &Vec, errors: &Vec) { + let mut index: i32 = 0; + let biggest_error: f32 = errors[0]; + { + let mut i: i32 = 1; + while i < array.len() { + { + if errors[i] > biggest_error { + biggest_error = errors[i]; + index = i; + } + } + i += 1; + } + } + + array[index] += 1; + } + + pub fn decrement( array: &Vec, errors: &Vec) { + let mut index: i32 = 0; + let biggest_error: f32 = errors[0]; + { + let mut i: i32 = 1; + while i < array.len() { + { + if errors[i] < biggest_error { + biggest_error = errors[i]; + index = i; + } + } + i += 1; + } + } + + array[index] -= 1; + } + + pub fn is_finder_pattern( counters: &Vec) -> bool { + let first_two_sum: i32 = counters[0] + counters[1]; + let sum: i32 = first_two_sum + counters[2] + counters[3]; + let ratio: f32 = first_two_sum / sum as f32; + if ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO { + // passes ratio test in spec, but see if the counts are unreasonable + let min_counter: i32 = Integer::MAX_VALUE; + let max_counter: i32 = Integer::MIN_VALUE; + for let counter: i32 in counters { + if counter > max_counter { + max_counter = counter; + } + if counter < min_counter { + min_counter = counter; + } + } + return max_counter < 10 * min_counter; + } + return false; + } +} + +// NEW FILE: data_character.rs +/* + * Copyright 2009 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::oned::rss; + +/** + * Encapsulates a since character value in an RSS barcode, including its checksum information. + */ +pub struct DataCharacter { + + let value: i32; + + let checksum_portion: i32; +} + +impl DataCharacter { + + pub fn new( value: i32, checksum_portion: i32) -> DataCharacter { + let .value = value; + let .checksumPortion = checksum_portion; + } + + pub fn get_value(&self) -> i32 { + return self.value; + } + + pub fn get_checksum_portion(&self) -> i32 { + return self.checksum_portion; + } + + pub fn to_string(&self) -> String { + return format!("{}({})", self.value, self.checksum_portion); + } + + pub fn equals(&self, o: &Object) -> bool { + if !(o instanceof DataCharacter) { + return false; + } + let that: DataCharacter = o as DataCharacter; + return self.value == that.value && self.checksum_portion == that.checksumPortion; + } + + pub fn hash_code(&self) -> i32 { + return self.value ^ self.checksum_portion; + } +} + +// NEW FILE: finder_pattern.rs +/* + * Copyright 2009 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::oned::rss; + +/** + * Encapsulates an RSS barcode finder pattern, including its start/end position and row. + */ +pub struct FinderPattern { + + let value: i32; + + let start_end: Vec; + + let result_points: Vec; +} + +impl FinderPattern { + + pub fn new( value: i32, start_end: &Vec, start: i32, end: i32, row_number: i32) -> FinderPattern { + let .value = value; + let .startEnd = start_end; + let .resultPoints = : vec![ResultPoint; 2] = vec![ResultPoint::new(start, row_number), ResultPoint::new(end, row_number), ] + ; + } + + pub fn get_value(&self) -> i32 { + return self.value; + } + + pub fn get_start_end(&self) -> Vec { + return self.start_end; + } + + pub fn get_result_points(&self) -> Vec { + return self.result_points; + } + + pub fn equals(&self, o: &Object) -> bool { + if !(o instanceof FinderPattern) { + return false; + } + let that: FinderPattern = o as FinderPattern; + return self.value == that.value; + } + + pub fn hash_code(&self) -> i32 { + return self.value; + } +} + +// NEW FILE: pair.rs +/* + * Copyright 2009 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::oned::rss; + +struct Pair { + super: DataCharacter; + + let finder_pattern: FinderPattern; + + let mut count: i32; +} + +impl Pair { + + fn new( value: i32, checksum_portion: i32, finder_pattern: &FinderPattern) -> Pair { + super(value, checksum_portion); + let .finderPattern = finder_pattern; + } + + fn get_finder_pattern(&self) -> FinderPattern { + return self.finder_pattern; + } + + fn get_count(&self) -> i32 { + return self.count; + } + + fn increment_count(&self) { + self.count += 1; + } +} + +// NEW FILE: r_s_s14_reader.rs +/* + * Copyright 2009 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::oned::rss; + +/** + * Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006. + */ + + const OUTSIDE_EVEN_TOTAL_SUBSET: vec![Vec; 5] = vec![1, 10, 34, 70, 126, ] +; + + const INSIDE_ODD_TOTAL_SUBSET: vec![Vec; 4] = vec![4, 20, 48, 81, ] +; + + const OUTSIDE_GSUM: vec![Vec; 5] = vec![0, 161, 961, 2015, 2715, ] +; + + const INSIDE_GSUM: vec![Vec; 4] = vec![0, 336, 1036, 1516, ] +; + + const OUTSIDE_ODD_WIDEST: vec![Vec; 5] = vec![8, 6, 4, 3, 1, ] +; + + const INSIDE_ODD_WIDEST: vec![Vec; 4] = vec![2, 4, 6, 8, ] +; + + const FINDER_PATTERNS: vec![vec![Vec>; 4]; 9] = vec![vec![3, 8, 2, 1, ] +, vec![3, 5, 5, 1, ] +, vec![3, 3, 7, 1, ] +, vec![3, 1, 9, 1, ] +, vec![2, 7, 4, 1, ] +, vec![2, 5, 6, 1, ] +, vec![2, 3, 8, 1, ] +, vec![1, 5, 7, 1, ] +, vec![1, 3, 9, 1, ] +, ] +; +pub struct RSS14Reader { + super: AbstractRSSReader; + + let possible_left_pairs: List; + + let possible_right_pairs: List; +} + +impl RSS14Reader { + + pub fn new() -> RSS14Reader { + possible_left_pairs = ArrayList<>::new(); + possible_right_pairs = ArrayList<>::new(); + } + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException */Result> { + let left_pair: Pair = self.decode_pair(row, false, row_number, &hints); + ::add_or_tally(&self.possible_left_pairs, left_pair); + row.reverse(); + let right_pair: Pair = self.decode_pair(row, true, row_number, &hints); + ::add_or_tally(&self.possible_right_pairs, right_pair); + row.reverse(); + for let left: Pair in self.possible_left_pairs { + if left.get_count() > 1 { + for let right: Pair in self.possible_right_pairs { + if right.get_count() > 1 && ::check_checksum(left, right) { + return Ok(::construct_result(left, right)); + } + } + } + } + throw NotFoundException::get_not_found_instance(); + } + + fn add_or_tally( possible_pairs: &Collection, pair: &Pair) { + if pair == null { + return; + } + let mut found: bool = false; + for let other: Pair in possible_pairs { + if other.get_value() == pair.get_value() { + other.increment_count(); + found = true; + break; + } + } + if !found { + possible_pairs.add(pair); + } + } + + pub fn reset(&self) { + self.possible_left_pairs.clear(); + self.possible_right_pairs.clear(); + } + + fn construct_result( left_pair: &Pair, right_pair: &Pair) -> Result { + let symbol_value: i64 = 4537077 * left_pair.get_value() + right_pair.get_value(); + let text: String = String::value_of(symbol_value); + let buffer: StringBuilder = StringBuilder::new(14); + { + let mut i: i32 = 13 - text.length(); + while i > 0 { + { + buffer.append('0'); + } + i -= 1; + } + } + + buffer.append(&text); + let check_digit: i32 = 0; + { + let mut i: i32 = 0; + while i < 13 { + { + let digit: i32 = buffer.char_at(i) - '0'; + check_digit += if (i & 0x01) == 0 { 3 * digit } else { digit }; + } + i += 1; + } + } + + check_digit = 10 - (check_digit % 10); + if check_digit == 10 { + check_digit = 0; + } + buffer.append(check_digit); + let left_points: Vec = left_pair.get_finder_pattern().get_result_points(); + let right_points: Vec = right_pair.get_finder_pattern().get_result_points(); + let result: Result = Result::new(&buffer.to_string(), null, : vec![ResultPoint; 4] = vec![left_points[0], left_points[1], right_points[0], right_points[1], ] + , BarcodeFormat::RSS_14); + result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]e0"); + return result; + } + + fn check_checksum( left_pair: &Pair, right_pair: &Pair) -> bool { + let check_value: i32 = (left_pair.get_checksum_portion() + 16 * right_pair.get_checksum_portion()) % 79; + let target_check_value: i32 = 9 * left_pair.get_finder_pattern().get_value() + right_pair.get_finder_pattern().get_value(); + if target_check_value > 72 { + target_check_value -= 1; + } + if target_check_value > 8 { + target_check_value -= 1; + } + return check_value == target_check_value; + } + + fn decode_pair(&self, row: &BitArray, right: bool, row_number: i32, hints: &Map) -> Pair { + let tryResult1 = 0; + 'try1: loop { + { + let start_end: Vec = self.find_finder_pattern(row, right); + let pattern: FinderPattern = self.parse_found_finder_pattern(row, row_number, right, &start_end); + let result_point_callback: ResultPointCallback = if hints == null { null } else { hints.get(DecodeHintType::NEED_RESULT_POINT_CALLBACK) as ResultPointCallback }; + if result_point_callback != null { + start_end = pattern.get_start_end(); + let mut center: f32 = (start_end[0] + start_end[1] - 1.0) / 2.0f; + if right { + // row is actually reversed + center = row.get_size() - 1.0 - center; + } + result_point_callback.found_possible_result_point(ResultPoint::new(center, row_number)); + } + let outside: DataCharacter = self.decode_data_character(row, pattern, true); + let inside: DataCharacter = self.decode_data_character(row, pattern, false); + return Pair::new(1597 * outside.get_value() + inside.get_value(), outside.get_checksum_portion() + 4 * inside.get_checksum_portion(), pattern); + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &NotFoundException) { + return null; + } 0 => break + } + + } + + fn decode_data_character(&self, row: &BitArray, pattern: &FinderPattern, outside_char: bool) -> /* throws NotFoundException */Result> { + let mut counters: Vec = get_data_character_counters(); + Arrays::fill(&counters, 0); + if outside_char { + record_pattern_in_reverse(row, pattern.get_start_end()[0], &counters); + } else { + record_pattern(row, pattern.get_start_end()[1], &counters); + // reverse it + { + let mut i: i32 = 0, let mut j: i32 = counters.len() - 1; + while i < j { + { + let temp: i32 = counters[i]; + counters[i] = counters[j]; + counters[j] = temp; + } + i += 1; + j -= 1; + } + } + + } + let num_modules: i32 = if outside_char { 16 } else { 15 }; + let element_width: f32 = MathUtils::sum(&counters) / num_modules as f32; + let odd_counts: Vec = self.get_odd_counts(); + let even_counts: Vec = self.get_even_counts(); + let odd_rounding_errors: Vec = self.get_odd_rounding_errors(); + let even_rounding_errors: Vec = self.get_even_rounding_errors(); + { + let mut i: i32 = 0; + while i < counters.len() { + { + let value: f32 = counters[i] / element_width; + // Round + let mut count: i32 = (value + 0.5f) as i32; + if count < 1 { + count = 1; + } else if count > 8 { + count = 8; + } + let mut offset: i32 = i / 2; + if (i & 0x01) == 0 { + odd_counts[offset] = count; + odd_rounding_errors[offset] = value - count; + } else { + even_counts[offset] = count; + even_rounding_errors[offset] = value - count; + } + } + i += 1; + } + } + + self.adjust_odd_even_counts(outside_char, num_modules); + let odd_sum: i32 = 0; + let odd_checksum_portion: i32 = 0; + { + let mut i: i32 = odd_counts.len() - 1; + while i >= 0 { + { + odd_checksum_portion *= 9; + odd_checksum_portion += odd_counts[i]; + odd_sum += odd_counts[i]; + } + i -= 1; + } + } + + let even_checksum_portion: i32 = 0; + let even_sum: i32 = 0; + { + let mut i: i32 = even_counts.len() - 1; + while i >= 0 { + { + even_checksum_portion *= 9; + even_checksum_portion += even_counts[i]; + even_sum += even_counts[i]; + } + i -= 1; + } + } + + let checksum_portion: i32 = odd_checksum_portion + 3 * even_checksum_portion; + if outside_char { + if (odd_sum & 0x01) != 0 || odd_sum > 12 || odd_sum < 4 { + throw NotFoundException::get_not_found_instance(); + } + let group: i32 = (12 - odd_sum) / 2; + let odd_widest: i32 = OUTSIDE_ODD_WIDEST[group]; + let even_widest: i32 = 9 - odd_widest; + let v_odd: i32 = RSSUtils::get_r_s_svalue(&odd_counts, odd_widest, false); + let v_even: i32 = RSSUtils::get_r_s_svalue(&even_counts, even_widest, true); + let t_even: i32 = OUTSIDE_EVEN_TOTAL_SUBSET[group]; + let g_sum: i32 = OUTSIDE_GSUM[group]; + return Ok(DataCharacter::new(v_odd * t_even + v_even + g_sum, checksum_portion)); + } else { + if (even_sum & 0x01) != 0 || even_sum > 10 || even_sum < 4 { + throw NotFoundException::get_not_found_instance(); + } + let group: i32 = (10 - even_sum) / 2; + let odd_widest: i32 = INSIDE_ODD_WIDEST[group]; + let even_widest: i32 = 9 - odd_widest; + let v_odd: i32 = RSSUtils::get_r_s_svalue(&odd_counts, odd_widest, true); + let v_even: i32 = RSSUtils::get_r_s_svalue(&even_counts, even_widest, false); + let t_odd: i32 = INSIDE_ODD_TOTAL_SUBSET[group]; + let g_sum: i32 = INSIDE_GSUM[group]; + return Ok(DataCharacter::new(v_even * t_odd + v_odd + g_sum, checksum_portion)); + } + } + + fn find_finder_pattern(&self, row: &BitArray, right_finder_pattern: bool) -> /* throws NotFoundException */Result, Rc> { + let mut counters: Vec = get_decode_finder_counters(); + counters[0] = 0; + counters[1] = 0; + counters[2] = 0; + counters[3] = 0; + let width: i32 = row.get_size(); + let is_white: bool = false; + let row_offset: i32 = 0; + while row_offset < width { + is_white = !row.get(row_offset); + if right_finder_pattern == is_white { + // Will encounter white first when searching for right finder pattern + break; + } + row_offset += 1; + } + let counter_position: i32 = 0; + let pattern_start: i32 = row_offset; + { + let mut x: i32 = row_offset; + while x < width { + { + if row.get(x) != is_white { + counters[counter_position] += 1; + } else { + if counter_position == 3 { + if is_finder_pattern(&counters) { + return Ok( : vec![i32; 2] = vec![pattern_start, x, ] + ); + } + pattern_start += counters[0] + counters[1]; + counters[0] = counters[2]; + counters[1] = counters[3]; + counters[2] = 0; + counters[3] = 0; + counter_position -= 1; + } else { + counter_position += 1; + } + counters[counter_position] = 1; + is_white = !is_white; + } + } + x += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + fn parse_found_finder_pattern(&self, row: &BitArray, row_number: i32, right: bool, start_end: &Vec) -> /* throws NotFoundException */Result> { + // Actually we found elements 2-5 + let first_is_black: bool = row.get(start_end[0]); + let first_element_start: i32 = start_end[0] - 1; + // Locate element 1 + while first_element_start >= 0 && first_is_black != row.get(first_element_start) { + first_element_start -= 1; + } + first_element_start += 1; + let first_counter: i32 = start_end[0] - first_element_start; + // Make 'counters' hold 1-4 + let mut counters: Vec = get_decode_finder_counters(); + System::arraycopy(&counters, 0, &counters, 1, counters.len() - 1); + counters[0] = first_counter; + let value: i32 = parse_finder_value(&counters, &FINDER_PATTERNS); + let mut start: i32 = first_element_start; + let mut end: i32 = start_end[1]; + if right { + // row is actually reversed + start = row.get_size() - 1 - start; + end = row.get_size() - 1 - end; + } + return Ok(FinderPattern::new(value, : vec![i32; 2] = vec![first_element_start, start_end[1], ] + , start, end, row_number)); + } + + fn adjust_odd_even_counts(&self, outside_char: bool, num_modules: i32) -> /* throws NotFoundException */Result> { + let odd_sum: i32 = MathUtils::sum(&get_odd_counts()); + let even_sum: i32 = MathUtils::sum(&get_even_counts()); + let increment_odd: bool = false; + let decrement_odd: bool = false; + let increment_even: bool = false; + let decrement_even: bool = false; + if outside_char { + if odd_sum > 12 { + decrement_odd = true; + } else if odd_sum < 4 { + increment_odd = true; + } + if even_sum > 12 { + decrement_even = true; + } else if even_sum < 4 { + increment_even = true; + } + } else { + if odd_sum > 11 { + decrement_odd = true; + } else if odd_sum < 5 { + increment_odd = true; + } + if even_sum > 10 { + decrement_even = true; + } else if even_sum < 4 { + increment_even = true; + } + } + let mismatch: i32 = odd_sum + even_sum - num_modules; + let odd_parity_bad: bool = (odd_sum & 0x01) == ( if outside_char { 1 } else { 0 }); + let even_parity_bad: bool = (even_sum & 0x01) == 1; + /*if (mismatch == 2) { + if (!(oddParityBad && evenParityBad)) { + throw ReaderException.getInstance(); + } + decrementOdd = true; + decrementEven = true; + } else if (mismatch == -2) { + if (!(oddParityBad && evenParityBad)) { + throw ReaderException.getInstance(); + } + incrementOdd = true; + incrementEven = true; + } else */ + match mismatch { + 1 => + { + if odd_parity_bad { + if even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + decrement_odd = true; + } else { + if !even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + decrement_even = true; + } + break; + } + -1 => + { + if odd_parity_bad { + if even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + increment_odd = true; + } else { + if !even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + increment_even = true; + } + break; + } + 0 => + { + if odd_parity_bad { + if !even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + // Both bad + if odd_sum < even_sum { + increment_odd = true; + decrement_even = true; + } else { + decrement_odd = true; + increment_even = true; + } + } else { + if even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + // Nothing to do! + } + break; + } + _ => + { + throw NotFoundException::get_not_found_instance(); + } + } + if increment_odd { + if decrement_odd { + throw NotFoundException::get_not_found_instance(); + } + increment(&get_odd_counts(), &get_odd_rounding_errors()); + } + if decrement_odd { + decrement(&get_odd_counts(), &get_odd_rounding_errors()); + } + if increment_even { + if decrement_even { + throw NotFoundException::get_not_found_instance(); + } + increment(&get_even_counts(), &get_odd_rounding_errors()); + } + if decrement_even { + decrement(&get_even_counts(), &get_even_rounding_errors()); + } + } +} + +// NEW FILE: r_s_s_utils.rs +/* + * Copyright 2009 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::oned::rss; + +/** Adapted from listings in ISO/IEC 24724 Appendix B and Appendix G. */ +pub struct RSSUtils { +} + +impl RSSUtils { + + fn new() -> RSSUtils { + } + + pub fn get_r_s_svalue( widths: &Vec, max_width: i32, no_narrow: bool) -> i32 { + let mut n: i32 = 0; + for let width: i32 in widths { + n += width; + } + let mut val: i32 = 0; + let narrow_mask: i32 = 0; + let elements: i32 = widths.len(); + { + let mut bar: i32 = 0; + while bar < elements - 1 { + { + let elm_width: i32; + { + elm_width = 1; + narrow_mask |= 1 << bar; + while elm_width < widths[bar] { + { + let sub_val: i32 = ::combins(n - elm_width - 1, elements - bar - 2); + if no_narrow && (narrow_mask == 0) && (n - elm_width - (elements - bar - 1) >= elements - bar - 1) { + sub_val -= ::combins(n - elm_width - (elements - bar), elements - bar - 2); + } + if elements - bar - 1 > 1 { + let less_val: i32 = 0; + { + let mxw_element: i32 = n - elm_width - (elements - bar - 2); + while mxw_element > max_width { + { + less_val += ::combins(n - elm_width - mxw_element - 1, elements - bar - 3); + } + mxw_element -= 1; + } + } + + sub_val -= less_val * (elements - 1 - bar); + } else if n - elm_width > max_width { + sub_val -= 1; + } + val += sub_val; + } + elm_width += 1; + narrow_mask &= ~(1 << bar); + } + } + + n -= elm_width; + } + bar += 1; + } + } + + return val; + } + + fn combins( n: i32, r: i32) -> i32 { + let max_denom: i32; + let min_denom: i32; + if n - r > r { + min_denom = r; + max_denom = n - r; + } else { + min_denom = n - r; + max_denom = r; + } + let mut val: i32 = 1; + let mut j: i32 = 1; + { + let mut i: i32 = n; + while i > max_denom { + { + val *= i; + if j <= min_denom { + val /= j; + j += 1; + } + } + i -= 1; + } + } + + while j <= min_denom { + val /= j; + j += 1; + } + return val; + } +} + diff --git a/src/oned/rss/expanded.rs b/src/oned/rss/expanded.rs index e69de29..cf73a7e 100644 --- a/src/oned/rss/expanded.rs +++ b/src/oned/rss/expanded.rs @@ -0,0 +1,1058 @@ +import com.google.zxing.common.BitArray; + +import com.google.zxing.oned.rss.DataCharacter; +import com.google.zxing.oned.rss.FinderPattern; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; +import com.google.zxing.ResultPoint; +import com.google.zxing.common.BitArray; +import com.google.zxing.common.detector.MathUtils; +import com.google.zxing.oned.rss.AbstractRSSReader; +import com.google.zxing.oned.rss.DataCharacter; +import com.google.zxing.oned.rss.FinderPattern; +import com.google.zxing.oned.rss.RSSUtils; +import com.google.zxing.oned.rss.expanded.decoders.AbstractExpandedDecoder; + +// NEW FILE: bit_array_builder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ +struct BitArrayBuilder { +} + +impl BitArrayBuilder { + + fn new() -> BitArrayBuilder { + } + + fn build_bit_array( pairs: &List) -> BitArray { + let char_number: i32 = (pairs.size() * 2) - 1; + if pairs.get(pairs.size() - 1).get_right_char() == null { + char_number -= 1; + } + let size: i32 = 12 * char_number; + let binary: BitArray = BitArray::new(size); + let acc_pos: i32 = 0; + let first_pair: ExpandedPair = pairs.get(0); + let first_value: i32 = first_pair.get_right_char().get_value(); + { + let mut i: i32 = 11; + while i >= 0 { + { + if (first_value & (1 << i)) != 0 { + binary.set(acc_pos); + } + acc_pos += 1; + } + i -= 1; + } + } + + { + let mut i: i32 = 1; + while i < pairs.size() { + { + let current_pair: ExpandedPair = pairs.get(i); + let left_value: i32 = current_pair.get_left_char().get_value(); + { + let mut j: i32 = 11; + while j >= 0 { + { + if (left_value & (1 << j)) != 0 { + binary.set(acc_pos); + } + acc_pos += 1; + } + j -= 1; + } + } + + if current_pair.get_right_char() != null { + let right_value: i32 = current_pair.get_right_char().get_value(); + { + let mut j: i32 = 11; + while j >= 0 { + { + if (right_value & (1 << j)) != 0 { + binary.set(acc_pos); + } + acc_pos += 1; + } + j -= 1; + } + } + + } + } + i += 1; + } + } + + return binary; + } +} + +// NEW FILE: expanded_pair.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ +struct ExpandedPair { + + let left_char: DataCharacter; + + let right_char: DataCharacter; + + let finder_pattern: FinderPattern; +} + +impl ExpandedPair { + + fn new( left_char: &DataCharacter, right_char: &DataCharacter, finder_pattern: &FinderPattern) -> ExpandedPair { + let .leftChar = left_char; + let .rightChar = right_char; + let .finderPattern = finder_pattern; + } + + fn get_left_char(&self) -> DataCharacter { + return self.leftChar; + } + + fn get_right_char(&self) -> DataCharacter { + return self.rightChar; + } + + fn get_finder_pattern(&self) -> FinderPattern { + return self.finderPattern; + } + + fn must_be_last(&self) -> bool { + return self.rightChar == null; + } + + pub fn to_string(&self) -> String { + return format!("[ {} , {} : {} ]", self.left_char, self.right_char, ( if self.finder_pattern == null { "null" } else { self.finder_pattern.get_value() })); + } + + pub fn equals(&self, o: &Object) -> bool { + if !(o instanceof ExpandedPair) { + return false; + } + let that: ExpandedPair = o as ExpandedPair; + return Objects::equals(self.left_char, that.leftChar) && Objects::equals(self.right_char, that.rightChar) && Objects::equals(self.finder_pattern, that.finderPattern); + } + + pub fn hash_code(&self) -> i32 { + return Objects::hash_code(self.left_char) ^ Objects::hash_code(self.right_char) ^ Objects::hash_code(self.finder_pattern); + } +} + +// NEW FILE: expanded_row.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded; + +/** + * One row of an RSS Expanded Stacked symbol, consisting of 1+ expanded pairs. + */ +struct ExpandedRow { + + let pairs: List; + + let row_number: i32; +} + +impl ExpandedRow { + + fn new( pairs: &List, row_number: i32) -> ExpandedRow { + let .pairs = ArrayList<>::new(&pairs); + let .rowNumber = row_number; + } + + fn get_pairs(&self) -> List { + return self.pairs; + } + + fn get_row_number(&self) -> i32 { + return self.rowNumber; + } + + fn is_equivalent(&self, other_pairs: &List) -> bool { + return self.pairs.equals(&other_pairs); + } + + pub fn to_string(&self) -> String { + return format!("{ {} }", self.pairs); + } + + /** + * Two rows are equal if they contain the same pairs in the same order. + */ + pub fn equals(&self, o: &Object) -> bool { + if !(o instanceof ExpandedRow) { + return false; + } + let that: ExpandedRow = o as ExpandedRow; + return self.pairs.equals(that.pairs); + } + + pub fn hash_code(&self) -> i32 { + return self.pairs.hash_code(); + } +} + +// NEW FILE: r_s_s_expanded_reader.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + + const SYMBOL_WIDEST: vec![Vec; 5] = vec![7, 5, 4, 3, 1, ] +; + + const EVEN_TOTAL_SUBSET: vec![Vec; 5] = vec![4, 20, 52, 104, 204, ] +; + + const GSUM: vec![Vec; 5] = vec![0, 348, 1388, 2948, 3988, ] +; + + const FINDER_PATTERNS: vec![vec![Vec>; 4]; 6] = vec![// A +vec![1, 8, 4, 1, ] +, // B +vec![3, 6, 4, 1, ] +, // C +vec![3, 4, 6, 1, ] +, // D +vec![3, 2, 8, 1, ] +, // E +vec![2, 6, 5, 1, ] +, // F +vec![2, 2, 9, 1, ] +, ] +; + + const WEIGHTS: vec![vec![Vec>; 8]; 23] = vec![vec![1, 3, 9, 27, 81, 32, 96, 77, ] +, vec![20, 60, 180, 118, 143, 7, 21, 63, ] +, vec![189, 145, 13, 39, 117, 140, 209, 205, ] +, vec![193, 157, 49, 147, 19, 57, 171, 91, ] +, vec![62, 186, 136, 197, 169, 85, 44, 132, ] +, vec![185, 133, 188, 142, 4, 12, 36, 108, ] +, vec![113, 128, 173, 97, 80, 29, 87, 50, ] +, vec![150, 28, 84, 41, 123, 158, 52, 156, ] +, vec![46, 138, 203, 187, 139, 206, 196, 166, ] +, vec![76, 17, 51, 153, 37, 111, 122, 155, ] +, vec![43, 129, 176, 106, 107, 110, 119, 146, ] +, vec![16, 48, 144, 10, 30, 90, 59, 177, ] +, vec![109, 116, 137, 200, 178, 112, 125, 164, ] +, vec![70, 210, 208, 202, 184, 130, 179, 115, ] +, vec![134, 191, 151, 31, 93, 68, 204, 190, ] +, vec![148, 22, 66, 198, 172, 94, 71, 2, ] +, vec![6, 18, 54, 162, 64, 192, 154, 40, ] +, vec![120, 149, 25, 75, 14, 42, 126, 167, ] +, vec![79, 26, 78, 23, 69, 207, 199, 175, ] +, vec![103, 98, 83, 38, 114, 131, 182, 124, ] +, vec![161, 61, 183, 127, 170, 88, 53, 159, ] +, vec![55, 165, 73, 8, 24, 72, 5, 15, ] +, vec![45, 135, 194, 160, 58, 174, 100, 89, ] +, ] +; + + const FINDER_PAT_A: i32 = 0; + + const FINDER_PAT_B: i32 = 1; + + const FINDER_PAT_C: i32 = 2; + + const FINDER_PAT_D: i32 = 3; + + const FINDER_PAT_E: i32 = 4; + + const FINDER_PAT_F: i32 = 5; + + const FINDER_PATTERN_SEQUENCES: vec![vec![Vec>; 11]; 10] = vec![vec![FINDER_PAT_A, FINDER_PAT_A, ] +, vec![FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, ] +, vec![FINDER_PAT_A, FINDER_PAT_C, FINDER_PAT_B, FINDER_PAT_D, ] +, vec![FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_C, ] +, vec![FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_F, ] +, vec![FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F, ] +, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D, ] +, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E, ] +, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F, ] +, vec![FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F, ] +, ] +; + + const MAX_PAIRS: i32 = 11; +pub struct RSSExpandedReader { + super: AbstractRSSReader; + + let pairs: List = ArrayList<>::new(MAX_PAIRS); + + let rows: List = ArrayList<>::new(); + + let start_end: [i32; 2] = [0; 2]; + + let start_from_even: bool; +} + +impl RSSExpandedReader { + + pub fn decode_row(&self, row_number: i32, row: &BitArray, hints: &Map) -> /* throws NotFoundException, FormatException */Result> { + // Rows can start with even pattern in case in prev rows there where odd number of patters. + // So lets try twice + self.pairs.clear(); + self.startFromEven = false; + let tryResult1 = 0; + 'try1: loop { + { + return Ok(::construct_result(&self.decode_row2pairs(row_number, row))); + } + break 'try1 + } + match tryResult1 { + catch ( e: &NotFoundException) { + } 0 => break + } + + self.pairs.clear(); + self.startFromEven = true; + return Ok(::construct_result(&self.decode_row2pairs(row_number, row))); + } + + pub fn reset(&self) { + self.pairs.clear(); + self.rows.clear(); + } + + // Not private for testing + fn decode_row2pairs(&self, row_number: i32, row: &BitArray) -> /* throws NotFoundException */Result, Rc> { + let mut done: bool = false; + while !done { + let tryResult1 = 0; + 'try1: loop { + { + self.pairs.add(&self.retrieve_next_pair(row, self.pairs, row_number)); + } + break 'try1 + } + match tryResult1 { + catch ( nfe: &NotFoundException) { + if self.pairs.is_empty() { + throw nfe; + } + done = true; + } 0 => break + } + + } + // TODO: verify sequence of finder patterns as in checkPairSequence() + if self.check_checksum() { + return Ok(self.pairs); + } + let try_stacked_decode: bool = !self.rows.is_empty(); + // TODO: deal with reversed rows + self.store_row(row_number); + if try_stacked_decode { + // When the image is 180-rotated, then rows are sorted in wrong direction. + // Try twice with both the directions. + let mut ps: List = self.check_rows(false); + if ps != null { + return Ok(ps); + } + ps = self.check_rows(true); + if ps != null { + return Ok(ps); + } + } + throw NotFoundException::get_not_found_instance(); + } + + fn check_rows(&self, reverse: bool) -> List { + // Stacked barcode can have up to 11 rows, so 25 seems reasonable enough + if self.rows.size() > 25 { + // We will never have a chance to get result, so clear it + self.rows.clear(); + return Ok(null); + } + self.pairs.clear(); + if reverse { + Collections::reverse(self.rows); + } + let mut ps: List = null; + let tryResult1 = 0; + 'try1: loop { + { + ps = self.check_rows(ArrayList<>::new(), 0); + } + break 'try1 + } + match tryResult1 { + catch ( e: &NotFoundException) { + } 0 => break + } + + if reverse { + Collections::reverse(self.rows); + } + return Ok(ps); + } + + // Try to construct a valid rows sequence + // Recursion is used to implement backtracking + fn check_rows(&self, collected_rows: &List, current_row: i32) -> /* throws NotFoundException */Result, Rc> { + { + let mut i: i32 = current_row; + while i < self.rows.size() { + { + let row: ExpandedRow = self.rows.get(i); + self.pairs.clear(); + for let collected_row: ExpandedRow in collected_rows { + self.pairs.add_all(&collected_row.get_pairs()); + } + self.pairs.add_all(&row.get_pairs()); + if ::is_valid_sequence(self.pairs) { + if self.check_checksum() { + return Ok(self.pairs); + } + let rs: List = ArrayList<>::new(&collected_rows); + rs.add(row); + let tryResult1 = 0; + 'try1: loop { + { + // Recursion: try to add more rows + return Ok(self.check_rows(&rs, i + 1)); + } + break 'try1 + } + match tryResult1 { + catch ( e: &NotFoundException) { + } 0 => break + } + + } + } + i += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + // Whether the pairs form a valid find pattern sequence, + // either complete or a prefix + fn is_valid_sequence( pairs: &List) -> bool { + for let sequence: Vec in FINDER_PATTERN_SEQUENCES { + if pairs.size() <= sequence.len() { + let mut stop: bool = true; + { + let mut j: i32 = 0; + while j < pairs.size() { + { + if pairs.get(j).get_finder_pattern().get_value() != sequence[j] { + stop = false; + break; + } + } + j += 1; + } + } + + if stop { + return true; + } + } + } + return false; + } + + fn store_row(&self, row_number: i32) { + // Discard if duplicate above or below; otherwise insert in order by row number. + let insert_pos: i32 = 0; + let prev_is_same: bool = false; + let next_is_same: bool = false; + while insert_pos < self.rows.size() { + let erow: ExpandedRow = self.rows.get(insert_pos); + if erow.get_row_number() > row_number { + next_is_same = erow.is_equivalent(self.pairs); + break; + } + prev_is_same = erow.is_equivalent(self.pairs); + insert_pos += 1; + } + if next_is_same || prev_is_same { + return; + } + // Check whether the row is part of an already detected row + if ::is_partial_row(self.pairs, self.rows) { + return; + } + self.rows.add(insert_pos, ExpandedRow::new(self.pairs, row_number)); + ::remove_partial_rows(self.pairs, self.rows); + } + + // Remove all the rows that contains only specified pairs + fn remove_partial_rows( pairs: &Collection, rows: &Collection) { + { + let iterator: Iterator = rows.iterator(); + while iterator.has_next(){ + let r: ExpandedRow = iterator.next(); + if r.get_pairs().size() != pairs.size() { + let all_found: bool = true; + for let p: ExpandedPair in r.get_pairs() { + if !pairs.contains(p) { + all_found = false; + break; + } + } + if all_found { + // 'pairs' contains all the pairs from the row 'r' + iterator.remove(); + } + } + } + } + + } + + // Returns true when one of the rows already contains all the pairs + fn is_partial_row( pairs: &Iterable, rows: &Iterable) -> bool { + for let r: ExpandedRow in rows { + let all_found: bool = true; + for let p: ExpandedPair in pairs { + let mut found: bool = false; + for let pp: ExpandedPair in r.get_pairs() { + if p.equals(pp) { + found = true; + break; + } + } + if !found { + all_found = false; + break; + } + } + if all_found { + // the row 'r' contain all the pairs from 'pairs' + return true; + } + } + return false; + } + + // Only used for unit testing + fn get_rows(&self) -> List { + return self.rows; + } + + // Not private for unit testing + fn construct_result( pairs: &List) -> /* throws NotFoundException, FormatException */Result> { + let binary: BitArray = BitArrayBuilder::build_bit_array(&pairs); + let decoder: AbstractExpandedDecoder = AbstractExpandedDecoder::create_decoder(binary); + let resulting_string: String = decoder.parse_information(); + let first_points: Vec = pairs.get(0).get_finder_pattern().get_result_points(); + let last_points: Vec = pairs.get(pairs.size() - 1).get_finder_pattern().get_result_points(); + let result: Result = Result::new(&resulting_string, null, : vec![ResultPoint; 4] = vec![first_points[0], first_points[1], last_points[0], last_points[1], ] + , BarcodeFormat::RSS_EXPANDED); + result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, "]e0"); + return Ok(result); + } + + fn check_checksum(&self) -> bool { + let first_pair: ExpandedPair = self.pairs.get(0); + let check_character: DataCharacter = first_pair.get_left_char(); + let first_character: DataCharacter = first_pair.get_right_char(); + if first_character == null { + return false; + } + let mut checksum: i32 = first_character.get_checksum_portion(); + let mut s: i32 = 2; + { + let mut i: i32 = 1; + while i < self.pairs.size() { + { + let current_pair: ExpandedPair = self.pairs.get(i); + checksum += current_pair.get_left_char().get_checksum_portion(); + s += 1; + let current_right_char: DataCharacter = current_pair.get_right_char(); + if current_right_char != null { + checksum += current_right_char.get_checksum_portion(); + s += 1; + } + } + i += 1; + } + } + + checksum %= 211; + let check_character_value: i32 = 211 * (s - 4) + checksum; + return check_character_value == check_character.get_value(); + } + + fn get_next_second_bar( row: &BitArray, initial_pos: i32) -> i32 { + let current_pos: i32; + if row.get(initial_pos) { + current_pos = row.get_next_unset(initial_pos); + current_pos = row.get_next_set(current_pos); + } else { + current_pos = row.get_next_set(initial_pos); + current_pos = row.get_next_unset(current_pos); + } + return current_pos; + } + + // not private for testing + fn retrieve_next_pair(&self, row: &BitArray, previous_pairs: &List, row_number: i32) -> /* throws NotFoundException */Result> { + let is_odd_pattern: bool = previous_pairs.size() % 2 == 0; + if self.start_from_even { + is_odd_pattern = !is_odd_pattern; + } + let mut pattern: FinderPattern; + let keep_finding: bool = true; + let forced_offset: i32 = -1; + loop { { + self.find_next_pair(row, &previous_pairs, forced_offset); + pattern = self.parse_found_finder_pattern(row, row_number, is_odd_pattern); + if pattern == null { + forced_offset = ::get_next_second_bar(row, self.startEnd[0]); + } else { + keep_finding = false; + } + }if !(keep_finding) break;} + // When stacked symbol is split over multiple rows, there's no way to guess if this pair can be last or not. + // boolean mayBeLast = checkPairSequence(previousPairs, pattern); + let left_char: DataCharacter = self.decode_data_character(row, pattern, is_odd_pattern, true); + if !previous_pairs.is_empty() && previous_pairs.get(previous_pairs.size() - 1).must_be_last() { + throw NotFoundException::get_not_found_instance(); + } + let right_char: DataCharacter; + let tryResult1 = 0; + 'try1: loop { + { + right_char = self.decode_data_character(row, pattern, is_odd_pattern, false); + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &NotFoundException) { + right_char = null; + } 0 => break + } + + return Ok(ExpandedPair::new(left_char, right_char, pattern)); + } + + fn find_next_pair(&self, row: &BitArray, previous_pairs: &List, forced_offset: i32) -> /* throws NotFoundException */Result> { + let mut counters: Vec = self.get_decode_finder_counters(); + counters[0] = 0; + counters[1] = 0; + counters[2] = 0; + counters[3] = 0; + let width: i32 = row.get_size(); + let row_offset: i32; + if forced_offset >= 0 { + row_offset = forced_offset; + } else if previous_pairs.is_empty() { + row_offset = 0; + } else { + let last_pair: ExpandedPair = previous_pairs.get(previous_pairs.size() - 1); + row_offset = last_pair.get_finder_pattern().get_start_end()[1]; + } + let searching_even_pair: bool = previous_pairs.size() % 2 != 0; + if self.start_from_even { + searching_even_pair = !searching_even_pair; + } + let is_white: bool = false; + while row_offset < width { + is_white = !row.get(row_offset); + if !is_white { + break; + } + row_offset += 1; + } + let counter_position: i32 = 0; + let pattern_start: i32 = row_offset; + { + let mut x: i32 = row_offset; + while x < width { + { + if row.get(x) != is_white { + counters[counter_position] += 1; + } else { + if counter_position == 3 { + if searching_even_pair { + ::reverse_counters(&counters); + } + if is_finder_pattern(&counters) { + self.startEnd[0] = pattern_start; + self.startEnd[1] = x; + return; + } + if searching_even_pair { + ::reverse_counters(&counters); + } + pattern_start += counters[0] + counters[1]; + counters[0] = counters[2]; + counters[1] = counters[3]; + counters[2] = 0; + counters[3] = 0; + counter_position -= 1; + } else { + counter_position += 1; + } + counters[counter_position] = 1; + is_white = !is_white; + } + } + x += 1; + } + } + + throw NotFoundException::get_not_found_instance(); + } + + fn reverse_counters( counters: &Vec) { + let mut length: i32 = counters.len(); + { + let mut i: i32 = 0; + while i < length / 2 { + { + let tmp: i32 = counters[i]; + counters[i] = counters[length - i - 1]; + counters[length - i - 1] = tmp; + } + i += 1; + } + } + + } + + fn parse_found_finder_pattern(&self, row: &BitArray, row_number: i32, odd_pattern: bool) -> FinderPattern { + // Actually we found elements 2-5. + let first_counter: i32; + let mut start: i32; + let mut end: i32; + if odd_pattern { + // If pattern number is odd, we need to locate element 1 *before* the current block. + let first_element_start: i32 = self.startEnd[0] - 1; + // Locate element 1 + while first_element_start >= 0 && !row.get(first_element_start) { + first_element_start -= 1; + } + first_element_start += 1; + first_counter = self.startEnd[0] - first_element_start; + start = first_element_start; + end = self.startEnd[1]; + } else { + // If pattern number is even, the pattern is reversed, so we need to locate element 1 *after* the current block. + start = self.startEnd[0]; + end = row.get_next_unset(self.startEnd[1] + 1); + first_counter = end - self.startEnd[1]; + } + // Make 'counters' hold 1-4 + let mut counters: Vec = self.get_decode_finder_counters(); + System::arraycopy(&counters, 0, &counters, 1, counters.len() - 1); + counters[0] = first_counter; + let mut value: i32; + let tryResult1 = 0; + 'try1: loop { + { + value = parse_finder_value(&counters, &FINDER_PATTERNS); + } + break 'try1 + } + match tryResult1 { + catch ( ignored: &NotFoundException) { + return null; + } 0 => break + } + + return FinderPattern::new(value, : vec![i32; 2] = vec![start, end, ] + , start, end, row_number); + } + + fn decode_data_character(&self, row: &BitArray, pattern: &FinderPattern, is_odd_pattern: bool, left_char: bool) -> /* throws NotFoundException */Result> { + let mut counters: Vec = self.get_data_character_counters(); + Arrays::fill(&counters, 0); + if left_char { + record_pattern_in_reverse(row, pattern.get_start_end()[0], &counters); + } else { + record_pattern(row, pattern.get_start_end()[1], &counters); + // reverse it + { + let mut i: i32 = 0, let mut j: i32 = counters.len() - 1; + while i < j { + { + let temp: i32 = counters[i]; + counters[i] = counters[j]; + counters[j] = temp; + } + i += 1; + j -= 1; + } + } + + } + //counters[] has the pixels of the module + //left and right data characters have all the same length + let num_modules: i32 = 17; + let element_width: f32 = MathUtils::sum(&counters) / num_modules as f32; + // Sanity check: element width for pattern and the character should match + let expected_element_width: f32 = (pattern.get_start_end()[1] - pattern.get_start_end()[0]) / 15.0f; + if Math::abs(element_width - expected_element_width) / expected_element_width > 0.3f { + throw NotFoundException::get_not_found_instance(); + } + let odd_counts: Vec = self.get_odd_counts(); + let even_counts: Vec = self.get_even_counts(); + let odd_rounding_errors: Vec = self.get_odd_rounding_errors(); + let even_rounding_errors: Vec = self.get_even_rounding_errors(); + { + let mut i: i32 = 0; + while i < counters.len() { + { + let value: f32 = 1.0f * counters[i] / element_width; + // Round + let mut count: i32 = (value + 0.5f) as i32; + if count < 1 { + if value < 0.3f { + throw NotFoundException::get_not_found_instance(); + } + count = 1; + } else if count > 8 { + if value > 8.7f { + throw NotFoundException::get_not_found_instance(); + } + count = 8; + } + let mut offset: i32 = i / 2; + if (i & 0x01) == 0 { + odd_counts[offset] = count; + odd_rounding_errors[offset] = value - count; + } else { + even_counts[offset] = count; + even_rounding_errors[offset] = value - count; + } + } + i += 1; + } + } + + self.adjust_odd_even_counts(num_modules); + let weight_row_number: i32 = 4 * pattern.get_value() + ( if is_odd_pattern { 0 } else { 2 }) + ( if left_char { 0 } else { 1 }) - 1; + let odd_sum: i32 = 0; + let odd_checksum_portion: i32 = 0; + { + let mut i: i32 = odd_counts.len() - 1; + while i >= 0 { + { + if ::is_not_a1left(pattern, is_odd_pattern, left_char) { + let weight: i32 = WEIGHTS[weight_row_number][2 * i]; + odd_checksum_portion += odd_counts[i] * weight; + } + odd_sum += odd_counts[i]; + } + i -= 1; + } + } + + let even_checksum_portion: i32 = 0; + { + let mut i: i32 = even_counts.len() - 1; + while i >= 0 { + { + if ::is_not_a1left(pattern, is_odd_pattern, left_char) { + let weight: i32 = WEIGHTS[weight_row_number][2 * i + 1]; + even_checksum_portion += even_counts[i] * weight; + } + } + i -= 1; + } + } + + let checksum_portion: i32 = odd_checksum_portion + even_checksum_portion; + if (odd_sum & 0x01) != 0 || odd_sum > 13 || odd_sum < 4 { + throw NotFoundException::get_not_found_instance(); + } + let group: i32 = (13 - odd_sum) / 2; + let odd_widest: i32 = SYMBOL_WIDEST[group]; + let even_widest: i32 = 9 - odd_widest; + let v_odd: i32 = RSSUtils::get_r_s_svalue(&odd_counts, odd_widest, true); + let v_even: i32 = RSSUtils::get_r_s_svalue(&even_counts, even_widest, false); + let t_even: i32 = EVEN_TOTAL_SUBSET[group]; + let g_sum: i32 = GSUM[group]; + let value: i32 = v_odd * t_even + v_even + g_sum; + return Ok(DataCharacter::new(value, checksum_portion)); + } + + fn is_not_a1left( pattern: &FinderPattern, is_odd_pattern: bool, left_char: bool) -> bool { + // A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char + return !(pattern.get_value() == 0 && is_odd_pattern && left_char); + } + + fn adjust_odd_even_counts(&self, num_modules: i32) -> /* throws NotFoundException */Result> { + let odd_sum: i32 = MathUtils::sum(&self.get_odd_counts()); + let even_sum: i32 = MathUtils::sum(&self.get_even_counts()); + let increment_odd: bool = false; + let decrement_odd: bool = false; + if odd_sum > 13 { + decrement_odd = true; + } else if odd_sum < 4 { + increment_odd = true; + } + let increment_even: bool = false; + let decrement_even: bool = false; + if even_sum > 13 { + decrement_even = true; + } else if even_sum < 4 { + increment_even = true; + } + let mismatch: i32 = odd_sum + even_sum - num_modules; + let odd_parity_bad: bool = (odd_sum & 0x01) == 1; + let even_parity_bad: bool = (even_sum & 0x01) == 0; + match mismatch { + 1 => + { + if odd_parity_bad { + if even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + decrement_odd = true; + } else { + if !even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + decrement_even = true; + } + break; + } + -1 => + { + if odd_parity_bad { + if even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + increment_odd = true; + } else { + if !even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + increment_even = true; + } + break; + } + 0 => + { + if odd_parity_bad { + if !even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + // Both bad + if odd_sum < even_sum { + increment_odd = true; + decrement_even = true; + } else { + decrement_odd = true; + increment_even = true; + } + } else { + if even_parity_bad { + throw NotFoundException::get_not_found_instance(); + } + // Nothing to do! + } + break; + } + _ => + { + throw NotFoundException::get_not_found_instance(); + } + } + if increment_odd { + if decrement_odd { + throw NotFoundException::get_not_found_instance(); + } + increment(&self.get_odd_counts(), &self.get_odd_rounding_errors()); + } + if decrement_odd { + decrement(&self.get_odd_counts(), &self.get_odd_rounding_errors()); + } + if increment_even { + if decrement_even { + throw NotFoundException::get_not_found_instance(); + } + increment(&self.get_even_counts(), &self.get_odd_rounding_errors()); + } + if decrement_even { + decrement(&self.get_even_counts(), &self.get_even_rounding_errors()); + } + } +} + diff --git a/src/oned/rss/expanded/decoders.rs b/src/oned/rss/expanded/decoders.rs index e69de29..1e1dd9c 100644 --- a/src/oned/rss/expanded/decoders.rs +++ b/src/oned/rss/expanded/decoders.rs @@ -0,0 +1,1789 @@ +// NEW FILE: a_i013103decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ +struct AI013103decoder { + super: AI013x0xDecoder; +} + +impl AI013103decoder { + + fn new( information: &BitArray) -> AI013103decoder { + super(information); + } + + pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) { + buf.append("(3103)"); + } + + pub fn check_weight(&self, weight: i32) -> i32 { + return weight; + } +} + +// NEW FILE: a_i01320x_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ +struct AI01320xDecoder { + super: AI013x0xDecoder; +} + +impl AI01320xDecoder { + + fn new( information: &BitArray) -> AI01320xDecoder { + super(information); + } + + pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) { + if weight < 10000 { + buf.append("(3202)"); + } else { + buf.append("(3203)"); + } + } + + pub fn check_weight(&self, weight: i32) -> i32 { + if weight < 10000 { + return weight; + } + return weight - 10000; + } +} + +// NEW FILE: a_i01392x_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ + + const HEADER_SIZE: i32 = 5 + 1 + 2; + + const LAST_DIGIT_SIZE: i32 = 2; +struct AI01392xDecoder { + super: AI01decoder; +} + +impl AI01392xDecoder { + + fn new( information: &BitArray) -> AI01392xDecoder { + super(information); + } + + pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { + if self.get_information().get_size() < HEADER_SIZE + GTIN_SIZE { + throw NotFoundException::get_not_found_instance(); + } + let buf: StringBuilder = StringBuilder::new(); + encode_compressed_gtin(&buf, HEADER_SIZE); + let last_a_idigit: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE); + buf.append("(392"); + buf.append(last_a_idigit); + buf.append(')'); + let decoded_information: DecodedInformation = self.get_general_decoder().decode_general_purpose_field(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, null); + buf.append(&decoded_information.get_new_string()); + return Ok(buf.to_string()); + } +} + +// NEW FILE: a_i01393x_decoder.rs +/* + * Copyright (C) 2010 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. + */ +/* + * These authors would like to acknowledge the Spanish Ministry of Industry, + * Tourism and Trade, for the support in the project TSI020301-2008-2 + * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled + * Mobile Dynamic Environments", led by Treelogic + * ( http://www.treelogic.com/ ): + * + * http://www.piramidepse.com/ + */ +// package com::google::zxing::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ + + const HEADER_SIZE: i32 = 5 + 1 + 2; + + const LAST_DIGIT_SIZE: i32 = 2; + + const FIRST_THREE_DIGITS_SIZE: i32 = 10; +struct AI01393xDecoder { + super: AI01decoder; +} + +impl AI01393xDecoder { + + fn new( information: &BitArray) -> AI01393xDecoder { + super(information); + } + + pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { + if self.get_information().get_size() < HEADER_SIZE + GTIN_SIZE { + throw NotFoundException::get_not_found_instance(); + } + let buf: StringBuilder = StringBuilder::new(); + encode_compressed_gtin(&buf, HEADER_SIZE); + let last_a_idigit: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE); + buf.append("(393"); + buf.append(last_a_idigit); + buf.append(')'); + let first_three_digits: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, FIRST_THREE_DIGITS_SIZE); + if first_three_digits / 100 == 0 { + buf.append('0'); + } + if first_three_digits / 10 == 0 { + buf.append('0'); + } + buf.append(first_three_digits); + let general_information: DecodedInformation = self.get_general_decoder().decode_general_purpose_field(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE + FIRST_THREE_DIGITS_SIZE, null); + buf.append(&general_information.get_new_string()); + return Ok(buf.to_string()); + } +} + +// NEW FILE: a_i013x0x1x_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + + const HEADER_SIZE: i32 = 7 + 1; + + const WEIGHT_SIZE: i32 = 20; + + const DATE_SIZE: i32 = 16; +struct AI013x0x1xDecoder { + super: AI01weightDecoder; + + let date_code: String; + + let first_a_idigits: String; +} + +impl AI013x0x1xDecoder { + + fn new( information: &BitArray, first_a_idigits: &String, date_code: &String) -> AI013x0x1xDecoder { + super(information); + let .dateCode = date_code; + let .firstAIdigits = first_a_idigits; + } + + pub fn parse_information(&self) -> /* throws NotFoundException */Result> { + if self.get_information().get_size() != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE { + throw NotFoundException::get_not_found_instance(); + } + let buf: StringBuilder = StringBuilder::new(); + encode_compressed_gtin(&buf, HEADER_SIZE); + encode_compressed_weight(&buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE); + self.encode_compressed_date(&buf, HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE); + return Ok(buf.to_string()); + } + + fn encode_compressed_date(&self, buf: &StringBuilder, current_pos: i32) { + let numeric_date: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(current_pos, DATE_SIZE); + if numeric_date == 38400 { + return; + } + buf.append('('); + buf.append(self.dateCode); + buf.append(')'); + let day: i32 = numeric_date % 32; + numeric_date /= 32; + let month: i32 = numeric_date % 12 + 1; + numeric_date /= 12; + let year: i32 = numeric_date; + if year / 10 == 0 { + buf.append('0'); + } + buf.append(year); + if month / 10 == 0 { + buf.append('0'); + } + buf.append(month); + if day / 10 == 0 { + buf.append('0'); + } + buf.append(day); + } + + pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) { + buf.append('('); + buf.append(self.firstAIdigits); + buf.append(weight / 100000); + buf.append(')'); + } + + pub fn check_weight(&self, weight: i32) -> i32 { + return weight % 100000; + } +} + +// NEW FILE: a_i013x0x_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ + + const HEADER_SIZE: i32 = 4 + 1; + + const WEIGHT_SIZE: i32 = 15; +struct AI013x0xDecoder { + super: AI01weightDecoder; +} + +impl AI013x0xDecoder { + + fn new( information: &BitArray) -> AI013x0xDecoder { + super(information); + } + + pub fn parse_information(&self) -> /* throws NotFoundException */Result> { + if self.get_information().get_size() != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE { + throw NotFoundException::get_not_found_instance(); + } + let buf: StringBuilder = StringBuilder::new(); + encode_compressed_gtin(&buf, HEADER_SIZE); + encode_compressed_weight(&buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE); + return Ok(buf.to_string()); + } +} + +// NEW FILE: a_i01_and_other_a_is.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + +//first bit encodes the linkage flag, + const HEADER_SIZE: i32 = 1 + 1 + 2; +struct AI01AndOtherAIs { + super: AI01decoder; +} + +impl AI01AndOtherAIs { + + //the second one is the encodation method, and the other two are for the variable length + fn new( information: &BitArray) -> AI01AndOtherAIs { + super(information); + } + + pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { + let buff: StringBuilder = StringBuilder::new(); + buff.append("(01)"); + let initial_gtin_position: i32 = buff.length(); + let first_gtin_digit: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(HEADER_SIZE, 4); + buff.append(first_gtin_digit); + self.encode_compressed_gtin_without_a_i(&buff, HEADER_SIZE + 4, initial_gtin_position); + return Ok(self.get_general_decoder().decode_all_codes(&buff, HEADER_SIZE + 44)); + } +} + +// NEW FILE: a_i01decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + + const GTIN_SIZE: i32 = 40; +struct AI01decoder { + super: AbstractExpandedDecoder; +} + +impl AI01decoder { + + fn new( information: &BitArray) -> AI01decoder { + super(information); + } + + fn encode_compressed_gtin(&self, buf: &StringBuilder, current_pos: i32) { + buf.append("(01)"); + let initial_position: i32 = buf.length(); + buf.append('9'); + self.encode_compressed_gtin_without_a_i(&buf, current_pos, initial_position); + } + + fn encode_compressed_gtin_without_a_i(&self, buf: &StringBuilder, current_pos: i32, initial_buffer_position: i32) { + { + let mut i: i32 = 0; + while i < 4 { + { + let current_block: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(current_pos + 10 * i, 10); + if current_block / 100 == 0 { + buf.append('0'); + } + if current_block / 10 == 0 { + buf.append('0'); + } + buf.append(current_block); + } + i += 1; + } + } + + ::append_check_digit(&buf, initial_buffer_position); + } + + fn append_check_digit( buf: &StringBuilder, current_pos: i32) { + let check_digit: i32 = 0; + { + let mut i: i32 = 0; + while i < 13 { + { + let digit: i32 = buf.char_at(i + current_pos) - '0'; + check_digit += if (i & 0x01) == 0 { 3 * digit } else { digit }; + } + i += 1; + } + } + + check_digit = 10 - (check_digit % 10); + if check_digit == 10 { + check_digit = 0; + } + buf.append(check_digit); + } +} + +// NEW FILE: a_i01weight_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ +struct AI01weightDecoder { + super: AI01decoder; +} + +impl AI01weightDecoder { + + fn new( information: &BitArray) -> AI01weightDecoder { + super(information); + } + + fn encode_compressed_weight(&self, buf: &StringBuilder, current_pos: i32, weight_size: i32) { + let original_weight_numeric: i32 = self.get_general_decoder().extract_numeric_value_from_bit_array(current_pos, weight_size); + self.add_weight_code(&buf, original_weight_numeric); + let weight_numeric: i32 = self.check_weight(original_weight_numeric); + let current_divisor: i32 = 100000; + { + let mut i: i32 = 0; + while i < 5 { + { + if weight_numeric / current_divisor == 0 { + buf.append('0'); + } + current_divisor /= 10; + } + i += 1; + } + } + + buf.append(weight_numeric); + } + + pub fn add_weight_code(&self, buf: &StringBuilder, weight: i32) ; + + pub fn check_weight(&self, weight: i32) -> i32 ; +} + +// NEW FILE: abstract_expanded_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ +pub struct AbstractExpandedDecoder { + + let information: BitArray; + + let general_decoder: GeneralAppIdDecoder; +} + +impl AbstractExpandedDecoder { + + fn new( information: &BitArray) -> AbstractExpandedDecoder { + let .information = information; + let .generalDecoder = GeneralAppIdDecoder::new(information); + } + + pub fn get_information(&self) -> BitArray { + return self.information; + } + + pub fn get_general_decoder(&self) -> GeneralAppIdDecoder { + return self.general_decoder; + } + + pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> ; + + pub fn create_decoder( information: &BitArray) -> AbstractExpandedDecoder { + if information.get(1) { + return AI01AndOtherAIs::new(information); + } + if !information.get(2) { + return AnyAIDecoder::new(information); + } + let four_bit_encodation_method: i32 = GeneralAppIdDecoder::extract_numeric_value_from_bit_array(information, 1, 4); + match four_bit_encodation_method { + 4 => + { + return AI013103decoder::new(information); + } + 5 => + { + return AI01320xDecoder::new(information); + } + } + let five_bit_encodation_method: i32 = GeneralAppIdDecoder::extract_numeric_value_from_bit_array(information, 1, 5); + match five_bit_encodation_method { + 12 => + { + return AI01392xDecoder::new(information); + } + 13 => + { + return AI01393xDecoder::new(information); + } + } + let seven_bit_encodation_method: i32 = GeneralAppIdDecoder::extract_numeric_value_from_bit_array(information, 1, 7); + match seven_bit_encodation_method { + 56 => + { + return AI013x0x1xDecoder::new(information, "310", "11"); + } + 57 => + { + return AI013x0x1xDecoder::new(information, "320", "11"); + } + 58 => + { + return AI013x0x1xDecoder::new(information, "310", "13"); + } + 59 => + { + return AI013x0x1xDecoder::new(information, "320", "13"); + } + 60 => + { + return AI013x0x1xDecoder::new(information, "310", "15"); + } + 61 => + { + return AI013x0x1xDecoder::new(information, "320", "15"); + } + 62 => + { + return AI013x0x1xDecoder::new(information, "310", "17"); + } + 63 => + { + return AI013x0x1xDecoder::new(information, "320", "17"); + } + } + throw IllegalStateException::new(format!("unknown decoder: {}", information)); + } +} + +// NEW FILE: any_a_i_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + + const HEADER_SIZE: i32 = 2 + 1 + 2; +struct AnyAIDecoder { + super: AbstractExpandedDecoder; +} + +impl AnyAIDecoder { + + fn new( information: &BitArray) -> AnyAIDecoder { + super(information); + } + + pub fn parse_information(&self) -> /* throws NotFoundException, FormatException */Result> { + let buf: StringBuilder = StringBuilder::new(); + return Ok(self.get_general_decoder().decode_all_codes(&buf, HEADER_SIZE)); + } +} + +// NEW FILE: block_parsed_result.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ +struct BlockParsedResult { + + let decoded_information: DecodedInformation; + + let finished: bool; +} + +impl BlockParsedResult { + + fn new() -> BlockParsedResult { + this(null, false); + } + + fn new( information: &DecodedInformation, finished: bool) -> BlockParsedResult { + let .finished = finished; + let .decodedInformation = information; + } + + fn get_decoded_information(&self) -> DecodedInformation { + return self.decodedInformation; + } + + fn is_finished(&self) -> bool { + return self.finished; + } +} + +// NEW FILE: current_parsing_state.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ +struct CurrentParsingState { + + let mut position: i32; + + let mut encoding: State; +} + +impl CurrentParsingState { + + enum State { + + NUMERIC(), ALPHA(), ISO_IEC_646() + } + + fn new() -> CurrentParsingState { + let .position = 0; + let .encoding = State::NUMERIC; + } + + fn get_position(&self) -> i32 { + return self.position; + } + + fn set_position(&self, position: i32) { + self.position = position; + } + + fn increment_position(&self, delta: i32) { + self.position += delta; + } + + fn is_alpha(&self) -> bool { + return self.encoding == State::ALPHA; + } + + fn is_numeric(&self) -> bool { + return self.encoding == State::NUMERIC; + } + + fn is_iso_iec646(&self) -> bool { + return self.encoding == State::ISO_IEC_646; + } + + fn set_numeric(&self) { + self.encoding = State::NUMERIC; + } + + fn set_alpha(&self) { + self.encoding = State::ALPHA; + } + + fn set_iso_iec646(&self) { + self.encoding = State::ISO_IEC_646; + } +} + +// NEW FILE: decoded_char.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + +// It's not in Alphanumeric neither in ISO/IEC 646 charset + const FNC1: char = '$'; +struct DecodedChar { + super: DecodedObject; + + let value: char; +} + +impl DecodedChar { + + fn new( new_position: i32, value: char) -> DecodedChar { + super(new_position); + let .value = value; + } + + fn get_value(&self) -> char { + return self.value; + } + + fn is_f_n_c1(&self) -> bool { + return self.value == FNC1; + } +} + +// NEW FILE: decoded_information.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ +struct DecodedInformation { + super: DecodedObject; + + let new_string: String; + + let remaining_value: i32; + + let mut remaining: bool; +} + +impl DecodedInformation { + + fn new( new_position: i32, new_string: &String) -> DecodedInformation { + super(new_position); + let .newString = new_string; + let .remaining = false; + let .remainingValue = 0; + } + + fn new( new_position: i32, new_string: &String, remaining_value: i32) -> DecodedInformation { + super(new_position); + let .remaining = true; + let .remainingValue = remaining_value; + let .newString = new_string; + } + + fn get_new_string(&self) -> String { + return self.newString; + } + + fn is_remaining(&self) -> bool { + return self.remaining; + } + + fn get_remaining_value(&self) -> i32 { + return self.remainingValue; + } +} + +// NEW FILE: decoded_numeric.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + + const FNC1: i32 = 10; +struct DecodedNumeric { + super: DecodedObject; + + let first_digit: i32; + + let second_digit: i32; +} + +impl DecodedNumeric { + + fn new( new_position: i32, first_digit: i32, second_digit: i32) -> DecodedNumeric throws FormatException { + super(new_position); + if first_digit < 0 || first_digit > 10 || second_digit < 0 || second_digit > 10 { + throw FormatException::get_format_instance(); + } + let .firstDigit = first_digit; + let .secondDigit = second_digit; + } + + fn get_first_digit(&self) -> i32 { + return self.firstDigit; + } + + fn get_second_digit(&self) -> i32 { + return self.secondDigit; + } + + fn get_value(&self) -> i32 { + return self.firstDigit * 10 + self.secondDigit; + } + + fn is_first_digit_f_n_c1(&self) -> bool { + return self.firstDigit == FNC1; + } + + fn is_second_digit_f_n_c1(&self) -> bool { + return self.secondDigit == FNC1; + } +} + +// NEW FILE: decoded_object.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + */ +struct DecodedObject { + + let new_position: i32; +} + +impl DecodedObject { + + fn new( new_position: i32) -> DecodedObject { + let .newPosition = new_position; + } + + fn get_new_position(&self) -> i32 { + return self.newPosition; + } +} + +// NEW FILE: field_parser.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ + + const TWO_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); + + const THREE_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); + + const THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); + + const FOUR_DIGIT_DATA_LENGTH: Map = HashMap<>::new(); +struct FieldParser { +} + +impl FieldParser { + + static { + TWO_DIGIT_DATA_LENGTH::put("00", &DataLength::fixed(18)); + TWO_DIGIT_DATA_LENGTH::put("01", &DataLength::fixed(14)); + TWO_DIGIT_DATA_LENGTH::put("02", &DataLength::fixed(14)); + TWO_DIGIT_DATA_LENGTH::put("10", &DataLength::variable(20)); + TWO_DIGIT_DATA_LENGTH::put("11", &DataLength::fixed(6)); + TWO_DIGIT_DATA_LENGTH::put("12", &DataLength::fixed(6)); + TWO_DIGIT_DATA_LENGTH::put("13", &DataLength::fixed(6)); + TWO_DIGIT_DATA_LENGTH::put("15", &DataLength::fixed(6)); + TWO_DIGIT_DATA_LENGTH::put("17", &DataLength::fixed(6)); + TWO_DIGIT_DATA_LENGTH::put("20", &DataLength::fixed(2)); + TWO_DIGIT_DATA_LENGTH::put("21", &DataLength::variable(20)); + TWO_DIGIT_DATA_LENGTH::put("22", &DataLength::variable(29)); + TWO_DIGIT_DATA_LENGTH::put("30", &DataLength::variable(8)); + TWO_DIGIT_DATA_LENGTH::put("37", &DataLength::variable(8)); + //internal company codes + { + let mut i: i32 = 90; + while i <= 99 { + { + TWO_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::variable(30)); + } + i += 1; + } + } + + } + + static { + THREE_DIGIT_DATA_LENGTH::put("240", &DataLength::variable(30)); + THREE_DIGIT_DATA_LENGTH::put("241", &DataLength::variable(30)); + THREE_DIGIT_DATA_LENGTH::put("242", &DataLength::variable(6)); + THREE_DIGIT_DATA_LENGTH::put("250", &DataLength::variable(30)); + THREE_DIGIT_DATA_LENGTH::put("251", &DataLength::variable(30)); + THREE_DIGIT_DATA_LENGTH::put("253", &DataLength::variable(17)); + THREE_DIGIT_DATA_LENGTH::put("254", &DataLength::variable(20)); + THREE_DIGIT_DATA_LENGTH::put("400", &DataLength::variable(30)); + THREE_DIGIT_DATA_LENGTH::put("401", &DataLength::variable(30)); + THREE_DIGIT_DATA_LENGTH::put("402", &DataLength::fixed(17)); + THREE_DIGIT_DATA_LENGTH::put("403", &DataLength::variable(30)); + THREE_DIGIT_DATA_LENGTH::put("410", &DataLength::fixed(13)); + THREE_DIGIT_DATA_LENGTH::put("411", &DataLength::fixed(13)); + THREE_DIGIT_DATA_LENGTH::put("412", &DataLength::fixed(13)); + THREE_DIGIT_DATA_LENGTH::put("413", &DataLength::fixed(13)); + THREE_DIGIT_DATA_LENGTH::put("414", &DataLength::fixed(13)); + THREE_DIGIT_DATA_LENGTH::put("420", &DataLength::variable(20)); + THREE_DIGIT_DATA_LENGTH::put("421", &DataLength::variable(15)); + THREE_DIGIT_DATA_LENGTH::put("422", &DataLength::fixed(3)); + THREE_DIGIT_DATA_LENGTH::put("423", &DataLength::variable(15)); + THREE_DIGIT_DATA_LENGTH::put("424", &DataLength::fixed(3)); + THREE_DIGIT_DATA_LENGTH::put("425", &DataLength::fixed(3)); + THREE_DIGIT_DATA_LENGTH::put("426", &DataLength::fixed(3)); + } + + static { + { + let mut i: i32 = 310; + while i <= 316 { + { + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); + } + i += 1; + } + } + + { + let mut i: i32 = 320; + while i <= 336 { + { + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); + } + i += 1; + } + } + + { + let mut i: i32 = 340; + while i <= 357 { + { + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); + } + i += 1; + } + } + + { + let mut i: i32 = 360; + while i <= 369 { + { + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put(&String::value_of(i), &DataLength::fixed(6)); + } + i += 1; + } + } + + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("390", &DataLength::variable(15)); + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("391", &DataLength::variable(18)); + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("392", &DataLength::variable(15)); + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("393", &DataLength::variable(18)); + THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::put("703", &DataLength::variable(30)); + } + + static { + FOUR_DIGIT_DATA_LENGTH::put("7001", &DataLength::fixed(13)); + FOUR_DIGIT_DATA_LENGTH::put("7002", &DataLength::variable(30)); + FOUR_DIGIT_DATA_LENGTH::put("7003", &DataLength::fixed(10)); + FOUR_DIGIT_DATA_LENGTH::put("8001", &DataLength::fixed(14)); + FOUR_DIGIT_DATA_LENGTH::put("8002", &DataLength::variable(20)); + FOUR_DIGIT_DATA_LENGTH::put("8003", &DataLength::variable(30)); + FOUR_DIGIT_DATA_LENGTH::put("8004", &DataLength::variable(30)); + FOUR_DIGIT_DATA_LENGTH::put("8005", &DataLength::fixed(6)); + FOUR_DIGIT_DATA_LENGTH::put("8006", &DataLength::fixed(18)); + FOUR_DIGIT_DATA_LENGTH::put("8007", &DataLength::variable(30)); + FOUR_DIGIT_DATA_LENGTH::put("8008", &DataLength::variable(12)); + FOUR_DIGIT_DATA_LENGTH::put("8018", &DataLength::fixed(18)); + FOUR_DIGIT_DATA_LENGTH::put("8020", &DataLength::variable(25)); + FOUR_DIGIT_DATA_LENGTH::put("8100", &DataLength::fixed(6)); + FOUR_DIGIT_DATA_LENGTH::put("8101", &DataLength::fixed(10)); + FOUR_DIGIT_DATA_LENGTH::put("8102", &DataLength::fixed(2)); + FOUR_DIGIT_DATA_LENGTH::put("8110", &DataLength::variable(70)); + FOUR_DIGIT_DATA_LENGTH::put("8200", &DataLength::variable(70)); + } + + fn new() -> FieldParser { + } + + fn parse_fields_in_general_purpose( raw_information: &String) -> /* throws NotFoundException */Result> { + if raw_information.is_empty() { + return Ok(null); + } + if raw_information.length() < 2 { + throw NotFoundException::get_not_found_instance(); + } + let two_digit_data_length: DataLength = TWO_DIGIT_DATA_LENGTH::get(&raw_information.substring(0, 2)); + if two_digit_data_length != null { + if two_digit_data_length.variable { + return Ok(::process_variable_a_i(2, two_digit_data_length.len(), &raw_information)); + } + return Ok(::process_fixed_a_i(2, two_digit_data_length.len(), &raw_information)); + } + if raw_information.length() < 3 { + throw NotFoundException::get_not_found_instance(); + } + let first_three_digits: String = raw_information.substring(0, 3); + let three_digit_data_length: DataLength = THREE_DIGIT_DATA_LENGTH::get(&first_three_digits); + if three_digit_data_length != null { + if three_digit_data_length.variable { + return Ok(::process_variable_a_i(3, three_digit_data_length.len(), &raw_information)); + } + return Ok(::process_fixed_a_i(3, three_digit_data_length.len(), &raw_information)); + } + if raw_information.length() < 4 { + throw NotFoundException::get_not_found_instance(); + } + let three_digit_plus_digit_data_length: DataLength = THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH::get(&first_three_digits); + if three_digit_plus_digit_data_length != null { + if three_digit_plus_digit_data_length.variable { + return Ok(::process_variable_a_i(4, three_digit_plus_digit_data_length.len(), &raw_information)); + } + return Ok(::process_fixed_a_i(4, three_digit_plus_digit_data_length.len(), &raw_information)); + } + let first_four_digit_length: DataLength = FOUR_DIGIT_DATA_LENGTH::get(&raw_information.substring(0, 4)); + if first_four_digit_length != null { + if first_four_digit_length.variable { + return Ok(::process_variable_a_i(4, first_four_digit_length.len(), &raw_information)); + } + return Ok(::process_fixed_a_i(4, first_four_digit_length.len(), &raw_information)); + } + throw NotFoundException::get_not_found_instance(); + } + + fn process_fixed_a_i( ai_size: i32, field_size: i32, raw_information: &String) -> /* throws NotFoundException */Result> { + if raw_information.length() < ai_size { + throw NotFoundException::get_not_found_instance(); + } + let ai: String = raw_information.substring(0, ai_size); + if raw_information.length() < ai_size + field_size { + throw NotFoundException::get_not_found_instance(); + } + let field: String = raw_information.substring(ai_size, ai_size + field_size); + let remaining: String = raw_information.substring(ai_size + field_size); + let result: String = format!("({}){}", ai, field); + let parsed_a_i: String = ::parse_fields_in_general_purpose(&remaining); + return Ok( if parsed_a_i == null { result } else { format!("{}{}", result, parsed_a_i) }); + } + + fn process_variable_a_i( ai_size: i32, variable_field_size: i32, raw_information: &String) -> /* throws NotFoundException */Result> { + let ai: String = raw_information.substring(0, ai_size); + let max_size: i32 = Math::min(&raw_information.length(), ai_size + variable_field_size); + let field: String = raw_information.substring(ai_size, max_size); + let remaining: String = raw_information.substring(max_size); + let result: String = format!("({}){}", ai, field); + let parsed_a_i: String = ::parse_fields_in_general_purpose(&remaining); + return Ok( if parsed_a_i == null { result } else { format!("{}{}", result, parsed_a_i) }); + } + + struct DataLength { + + let variable: bool; + + let length: i32; + } + + impl DataLength { + + fn new( variable: bool, length: i32) -> DataLength { + let .variable = variable; + let .len() = length; + } + + fn fixed( length: i32) -> DataLength { + return DataLength::new(false, length); + } + + fn variable( length: i32) -> DataLength { + return DataLength::new(true, length); + } + } + +} + +// NEW FILE: general_app_id_decoder.rs +/* + * Copyright (C) 2010 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::oned::rss::expanded::decoders; + +/** + * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) + * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) + */ +struct GeneralAppIdDecoder { + + let information: BitArray; + + let current: CurrentParsingState = CurrentParsingState::new(); + + let buffer: StringBuilder = StringBuilder::new(); +} + +impl GeneralAppIdDecoder { + + fn new( information: &BitArray) -> GeneralAppIdDecoder { + let .information = information; + } + + fn decode_all_codes(&self, buff: &StringBuilder, initial_position: i32) -> /* throws NotFoundException, FormatException */Result> { + let current_position: i32 = initial_position; + let mut remaining: String = null; + loop { { + let info: DecodedInformation = self.decode_general_purpose_field(current_position, &remaining); + let parsed_fields: String = FieldParser::parse_fields_in_general_purpose(&info.get_new_string()); + if parsed_fields != null { + buff.append(&parsed_fields); + } + if info.is_remaining() { + remaining = String::value_of(&info.get_remaining_value()); + } else { + remaining = null; + } + if current_position == info.get_new_position() { + // No step forward! + break; + } + current_position = info.get_new_position(); + }if !(true) break;} + return Ok(buff.to_string()); + } + + fn is_still_numeric(&self, pos: i32) -> bool { + // and one of the first 4 bits is "1". + if pos + 7 > self.information.get_size() { + return pos + 4 <= self.information.get_size(); + } + { + let mut i: i32 = pos; + while i < pos + 3 { + { + if self.information.get(i) { + return true; + } + } + i += 1; + } + } + + return self.information.get(pos + 3); + } + + fn decode_numeric(&self, pos: i32) -> /* throws FormatException */Result> { + if pos + 7 > self.information.get_size() { + let numeric: i32 = ::extract_numeric_value_from_bit_array(pos, 4); + if numeric == 0 { + return Ok(DecodedNumeric::new(&self.information.get_size(), DecodedNumeric::FNC1, DecodedNumeric::FNC1)); + } + return Ok(DecodedNumeric::new(&self.information.get_size(), numeric - 1, DecodedNumeric::FNC1)); + } + let numeric: i32 = ::extract_numeric_value_from_bit_array(pos, 7); + let digit1: i32 = (numeric - 8) / 11; + let digit2: i32 = (numeric - 8) % 11; + return Ok(DecodedNumeric::new(pos + 7, digit1, digit2)); + } + + fn extract_numeric_value_from_bit_array(&self, pos: i32, bits: i32) -> i32 { + return ::extract_numeric_value_from_bit_array(self.information, pos, bits); + } + + fn extract_numeric_value_from_bit_array( information: &BitArray, pos: i32, bits: i32) -> i32 { + let mut value: i32 = 0; + { + let mut i: i32 = 0; + while i < bits { + { + if information.get(pos + i) { + value |= 1 << (bits - i - 1); + } + } + i += 1; + } + } + + return value; + } + + fn decode_general_purpose_field(&self, pos: i32, remaining: &String) -> /* throws FormatException */Result> { + self.buffer.set_length(0); + if remaining != null { + self.buffer.append(&remaining); + } + self.current.set_position(pos); + let last_decoded: DecodedInformation = self.parse_blocks(); + if last_decoded != null && last_decoded.is_remaining() { + return Ok(DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string(), &last_decoded.get_remaining_value())); + } + return Ok(DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string())); + } + + fn parse_blocks(&self) -> /* throws FormatException */Result> { + let is_finished: bool; + let mut result: BlockParsedResult; + loop { { + let initial_position: i32 = self.current.get_position(); + if self.current.is_alpha() { + result = self.parse_alpha_block(); + is_finished = result.is_finished(); + } else if self.current.is_iso_iec646() { + result = self.parse_iso_iec646_block(); + is_finished = result.is_finished(); + } else { + // it must be numeric + result = self.parse_numeric_block(); + is_finished = result.is_finished(); + } + let position_changed: bool = initial_position != self.current.get_position(); + if !position_changed && !is_finished { + break; + } + }if !(!is_finished) break;} + return Ok(result.get_decoded_information()); + } + + fn parse_numeric_block(&self) -> /* throws FormatException */Result> { + while self.is_still_numeric(&self.current.get_position()) { + let numeric: DecodedNumeric = self.decode_numeric(&self.current.get_position()); + self.current.set_position(&numeric.get_new_position()); + if numeric.is_first_digit_f_n_c1() { + let mut information: DecodedInformation; + if numeric.is_second_digit_f_n_c1() { + information = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); + } else { + information = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string(), &numeric.get_second_digit()); + } + return Ok(BlockParsedResult::new(information, true)); + } + self.buffer.append(&numeric.get_first_digit()); + if numeric.is_second_digit_f_n_c1() { + let information: DecodedInformation = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); + return Ok(BlockParsedResult::new(information, true)); + } + self.buffer.append(&numeric.get_second_digit()); + } + if self.is_numeric_to_alpha_numeric_latch(&self.current.get_position()) { + self.current.set_alpha(); + self.current.increment_position(4); + } + return Ok(BlockParsedResult::new()); + } + + fn parse_iso_iec646_block(&self) -> /* throws FormatException */Result> { + while self.is_still_iso_iec646(&self.current.get_position()) { + let iso: DecodedChar = self.decode_iso_iec646(&self.current.get_position()); + self.current.set_position(&iso.get_new_position()); + if iso.is_f_n_c1() { + let information: DecodedInformation = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); + return Ok(BlockParsedResult::new(information, true)); + } + self.buffer.append(&iso.get_value()); + } + if self.is_alpha_or646_to_numeric_latch(&self.current.get_position()) { + self.current.increment_position(3); + self.current.set_numeric(); + } else if self.is_alpha_to646_to_alpha_latch(&self.current.get_position()) { + if self.current.get_position() + 5 < self.information.get_size() { + self.current.increment_position(5); + } else { + self.current.set_position(&self.information.get_size()); + } + self.current.set_alpha(); + } + return Ok(BlockParsedResult::new()); + } + + fn parse_alpha_block(&self) -> BlockParsedResult { + while self.is_still_alpha(&self.current.get_position()) { + let alpha: DecodedChar = self.decode_alphanumeric(&self.current.get_position()); + self.current.set_position(&alpha.get_new_position()); + if alpha.is_f_n_c1() { + let information: DecodedInformation = DecodedInformation::new(&self.current.get_position(), &self.buffer.to_string()); + //end of the char block + return BlockParsedResult::new(information, true); + } + self.buffer.append(&alpha.get_value()); + } + if self.is_alpha_or646_to_numeric_latch(&self.current.get_position()) { + self.current.increment_position(3); + self.current.set_numeric(); + } else if self.is_alpha_to646_to_alpha_latch(&self.current.get_position()) { + if self.current.get_position() + 5 < self.information.get_size() { + self.current.increment_position(5); + } else { + self.current.set_position(&self.information.get_size()); + } + self.current.set_iso_iec646(); + } + return BlockParsedResult::new(); + } + + fn is_still_iso_iec646(&self, pos: i32) -> bool { + if pos + 5 > self.information.get_size() { + return false; + } + let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); + if five_bit_value >= 5 && five_bit_value < 16 { + return true; + } + if pos + 7 > self.information.get_size() { + return false; + } + let seven_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 7); + if seven_bit_value >= 64 && seven_bit_value < 116 { + return true; + } + if pos + 8 > self.information.get_size() { + return false; + } + let eight_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 8); + return eight_bit_value >= 232 && eight_bit_value < 253; + } + + fn decode_iso_iec646(&self, pos: i32) -> /* throws FormatException */Result> { + let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); + if five_bit_value == 15 { + return Ok(DecodedChar::new(pos + 5, DecodedChar::FNC1)); + } + if five_bit_value >= 5 && five_bit_value < 15 { + return Ok(DecodedChar::new(pos + 5, ('0' + five_bit_value - 5) as char)); + } + let seven_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 7); + if seven_bit_value >= 64 && seven_bit_value < 90 { + return Ok(DecodedChar::new(pos + 7, (seven_bit_value + 1) as char)); + } + if seven_bit_value >= 90 && seven_bit_value < 116 { + return Ok(DecodedChar::new(pos + 7, (seven_bit_value + 7) as char)); + } + let eight_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 8); + let mut c: char; + match eight_bit_value { + 232 => + { + c = '!'; + break; + } + 233 => + { + c = '"'; + break; + } + 234 => + { + c = '%'; + break; + } + 235 => + { + c = '&'; + break; + } + 236 => + { + c = '\''; + break; + } + 237 => + { + c = '('; + break; + } + 238 => + { + c = ')'; + break; + } + 239 => + { + c = '*'; + break; + } + 240 => + { + c = '+'; + break; + } + 241 => + { + c = ','; + break; + } + 242 => + { + c = '-'; + break; + } + 243 => + { + c = '.'; + break; + } + 244 => + { + c = '/'; + break; + } + 245 => + { + c = ':'; + break; + } + 246 => + { + c = ';'; + break; + } + 247 => + { + c = '<'; + break; + } + 248 => + { + c = '='; + break; + } + 249 => + { + c = '>'; + break; + } + 250 => + { + c = '?'; + break; + } + 251 => + { + c = '_'; + break; + } + 252 => + { + c = ' '; + break; + } + _ => + { + throw FormatException::get_format_instance(); + } + } + return Ok(DecodedChar::new(pos + 8, c)); + } + + fn is_still_alpha(&self, pos: i32) -> bool { + if pos + 5 > self.information.get_size() { + return false; + } + // We now check if it's a valid 5-bit value (0..9 and FNC1) + let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); + if five_bit_value >= 5 && five_bit_value < 16 { + return true; + } + if pos + 6 > self.information.get_size() { + return false; + } + let six_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 6); + // 63 not included + return six_bit_value >= 16 && six_bit_value < 63; + } + + fn decode_alphanumeric(&self, pos: i32) -> DecodedChar { + let five_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 5); + if five_bit_value == 15 { + return DecodedChar::new(pos + 5, DecodedChar::FNC1); + } + if five_bit_value >= 5 && five_bit_value < 15 { + return DecodedChar::new(pos + 5, ('0' + five_bit_value - 5) as char); + } + let six_bit_value: i32 = ::extract_numeric_value_from_bit_array(pos, 6); + if six_bit_value >= 32 && six_bit_value < 58 { + return DecodedChar::new(pos + 6, (six_bit_value + 33) as char); + } + let mut c: char; + match six_bit_value { + 58 => + { + c = '*'; + break; + } + 59 => + { + c = ','; + break; + } + 60 => + { + c = '-'; + break; + } + 61 => + { + c = '.'; + break; + } + 62 => + { + c = '/'; + break; + } + _ => + { + throw IllegalStateException::new(format!("Decoding invalid alphanumeric value: {}", six_bit_value)); + } + } + return DecodedChar::new(pos + 6, c); + } + + fn is_alpha_to646_to_alpha_latch(&self, pos: i32) -> bool { + if pos + 1 > self.information.get_size() { + return false; + } + { + let mut i: i32 = 0; + while i < 5 && i + pos < self.information.get_size() { + { + if i == 2 { + if !self.information.get(pos + 2) { + return false; + } + } else if self.information.get(pos + i) { + return false; + } + } + i += 1; + } + } + + return true; + } + + fn is_alpha_or646_to_numeric_latch(&self, pos: i32) -> bool { + // Next is alphanumeric if there are 3 positions and they are all zeros + if pos + 3 > self.information.get_size() { + return false; + } + { + let mut i: i32 = pos; + while i < pos + 3 { + { + if self.information.get(i) { + return false; + } + } + i += 1; + } + } + + return true; + } + + fn is_numeric_to_alpha_numeric_latch(&self, pos: i32) -> bool { + // if there is a subset of this just before the end of the symbol + if pos + 1 > self.information.get_size() { + return false; + } + { + let mut i: i32 = 0; + while i < 4 && i + pos < self.information.get_size() { + { + if self.information.get(pos + i) { + return false; + } + } + i += 1; + } + } + + return true; + } +} +