oned moved

This commit is contained in:
Henry Schimke
2022-08-14 17:59:56 -05:00
parent 40b2142193
commit aff9e1088a
119 changed files with 10227 additions and 9790 deletions

View File

@@ -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;
/**
* <p>Decodes Codabar barcodes.</p>
*
* @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<char> = 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<i32>; 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<char>; 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<i32>;
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<DecodeHintType, ?>) -> /* throws NotFoundException */Result<Result, Rc<Exception>> {
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<Void, Rc<Exception>> {
// First, sum up the total size of our four categories of stripe sizes;
let mut sizes: vec![Vec<i32>; 4] = vec![0, 0, 0, 0, ]
;
let mut counts: vec![Vec<i32>; 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<Void, Rc<Exception>> {
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<i32, Rc<Exception>> {
{
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<char>, 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<i32> = 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;
}
}

View File

@@ -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<char>; 4] = vec!['A', 'B', 'C', 'D', ]
;
const ALT_START_END_CHARS: vec![Vec<char>; 4] = vec!['T', 'N', '*', 'E', ]
;
const CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED: vec![Vec<char>; 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<BarcodeFormat> {
return Collections::singleton(BarcodeFormat::CODABAR);
}
pub fn encode(&self, contents: &String) -> Vec<bool> {
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;
}
}

View File

@@ -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;
/**
* <p>Decodes Code 128 barcodes.</p>
*
* @author Sean Owen
*/
const CODE_PATTERNS: vec![vec![Vec<Vec<i32>>; 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<Vec<i32>, Rc<Exception>> {
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<i32>, row_offset: i32) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
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<i32> = 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<DecodeHintType, ?>) -> /* throws NotFoundException, FormatException, ChecksumException */Result<Result, Rc<Exception>> {
let convert_f_n_c1: bool = hints != null && hints.contains_key(DecodeHintType::ASSUME_GS1);
let symbology_modifier: i32 = 0;
let start_pattern_info: Vec<i32> = ::find_start_pattern(row);
let start_code: i32 = start_pattern_info[2];
let raw_codes: List<Byte> = 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);
}
}

View File

@@ -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<BarcodeFormat> {
return Collections::singleton(BarcodeFormat::CODE_128);
}
pub fn encode(&self, contents: &String) -> Vec<bool> {
return self.encode(&contents, null);
}
pub fn encode(&self, contents: &String, hints: &Map<EncodeHintType, ?>) -> Vec<bool> {
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<EncodeHintType, ?>) -> 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<bool> {
let length: i32 = contents.length();
// temporary storage for patterns
let patterns: Collection<Vec<i32>> = 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<Vec<i32>>, check_sum: i32) -> Vec<bool> {
// 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<i32> 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<i32> 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<Vec<i32>>;
let min_path: Vec<Vec<Latch>>;
}
impl MinimalEncoder {
enum Charset {
A(), B(), C(), NONE()
}
enum Latch {
A(), B(), C(), SHIFT(), NONE()
}
fn encode(&self, contents: &String) -> Vec<bool> {
self.memoized_cost = : [[i32; contents.length()]; 4] = [[0; contents.length()]; 4];
self.min_path = : [[Option<Latch>; contents.length()]; 4] = [[None; contents.length()]; 4];
self.encode(&contents, Charset::NONE, 0);
let patterns: Collection<Vec<i32>> = 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<Vec<i32>>, pattern_index: i32, check_sum: &Vec<i32>, check_weight: &Vec<i32>, 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;
}
}
}

View File

@@ -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;
/**
* <p>Decodes Code 39 barcodes. Supports "Full ASCII Code 39" if USE_CODE_39_EXTENDED_MODE is set.</p>
*
* @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<i32>; 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<i32>;
}
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<DecodeHintType, ?>) -> /* throws NotFoundException, ChecksumException, FormatException */Result<Result, Rc<Exception>> {
let the_counters: Vec<i32> = self.counters;
Arrays::fill(&the_counters, 0);
let result: StringBuilder = self.decode_row_result;
result.set_length(0);
let start: Vec<i32> = ::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<i32>) -> /* throws NotFoundException */Result<Vec<i32>, Rc<Exception>> {
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>) -> 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<char, Rc<Exception>> {
{
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<String, Rc<Exception>> {
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());
}
}

View File

@@ -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;
/**
* <p>Decodes Code 93 barcodes.</p>
*
* @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<char> = 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<i32>; 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<i32>;
}
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<DecodeHintType, ?>) -> /* throws NotFoundException, ChecksumException, FormatException */Result<Result, Rc<Exception>> {
let start: Vec<i32> = 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<i32> = 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<Vec<i32>, Rc<Exception>> {
let width: i32 = row.get_size();
let row_offset: i32 = row.get_next_set(0);
Arrays::fill(&self.counters, 0);
let the_counters: Vec<i32> = 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>) -> 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<char, Rc<Exception>> {
{
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<String, Rc<Exception>> {
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<Void, Rc<Exception>> {
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<Void, Rc<Exception>> {
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();
}
}
}

View File

@@ -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<BarcodeFormat> {
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<bool> {
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<bool>, pos: i32, pattern: &Vec<i32>, 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<bool>, 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();
}
}

View File

@@ -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;
/**
* <p>Implements decoding of the EAN-13 format.</p>
*
* @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<i32>; 10] = vec![0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A, ]
;
pub struct EAN13Reader {
super: UPCEANReader;
let decode_middle_counters: Vec<i32>;
}
impl EAN13Reader {
pub fn new() -> EAN13Reader {
decode_middle_counters = : [i32; 4] = [0; 4];
}
pub fn decode_middle(&self, row: &BitArray, start_range: &Vec<i32>, result_string: &StringBuilder) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
let mut counters: Vec<i32> = 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<i32> = 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<Void, Rc<Exception>> {
{
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();
}
}

View File

@@ -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<BarcodeFormat> {
return Collections::singleton(BarcodeFormat::EAN_13);
}
pub fn encode(&self, contents: &String) -> Vec<bool> {
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;
}
}

View File

@@ -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;
/**
* <p>Implements decoding of the EAN-8 format.</p>
*
* @author Sean Owen
*/
pub struct EAN8Reader {
super: UPCEANReader;
let decode_middle_counters: Vec<i32>;
}
impl EAN8Reader {
pub fn new() -> EAN8Reader {
decode_middle_counters = : [i32; 4] = [0; 4];
}
pub fn decode_middle(&self, row: &BitArray, start_range: &Vec<i32>, result: &StringBuilder) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
let mut counters: Vec<i32> = 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<i32> = 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;
}
}

View File

@@ -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<BarcodeFormat> {
return Collections::singleton(BarcodeFormat::EAN_8);
}
/**
* @return a byte array of horizontal pixels (false = white, true = black)
*/
pub fn encode(&self, contents: &String) -> Vec<bool> {
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;
}
}

View File

@@ -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
* <a href="http://en.wikipedia.org/wiki/List_of_GS1_country_codes">
* http://en.wikipedia.org/wiki/List_of_GS1_country_codes</a>.
*
* @author Sean Owen
*/
struct EANManufacturerOrgSupport {
let ranges: List<Vec<i32>> = ArrayList<>::new();
let country_identifiers: List<String> = 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<i32> = 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<i32>, 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");
}
}

View File

@@ -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;
/**
* <p>Implements decoding of the ITF format, or Interleaved Two of Five.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p><a href="http://en.wikipedia.org/wiki/Interleaved_2_of_5">http://en.wikipedia.org/wiki/Interleaved_2_of_5</a>
* is a great reference for Interleaved 2 of 5 information.</p>
*
* @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<i32>; 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<i32>; 4] = vec![N, N, N, N, ]
;
const END_PATTERN_REVERSED: vec![vec![Vec<Vec<i32>>; 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<Vec<i32>>; 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<DecodeHintType, ?>) -> /* throws FormatException, NotFoundException */Result<Result, Rc<Exception>> {
// Find out where the Middle section (payload) starts & ends
let start_range: Vec<i32> = self.decode_start(row);
let end_range: Vec<i32> = 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<i32> = null;
if hints != null {
allowed_lengths = hints.get(DecodeHintType::ALLOWED_LENGTHS) as Vec<i32>;
}
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<Void, Rc<Exception>> {
// 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<Vec<i32>, Rc<Exception>> {
let end_start: i32 = ::skip_white_space(row);
let start_pattern: Vec<i32> = ::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<Void, Rc<Exception>> {
// 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<i32, Rc<Exception>> {
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<Vec<i32>, Rc<Exception>> {
// 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<i32>;
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<i32>) -> /* throws NotFoundException */Result<Vec<i32>, Rc<Exception>> {
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<i32>) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
// 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<i32> = 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();
}
}
}

View File

@@ -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<i32>; 4] = vec![1, 1, 1, 1, ]
;
const END_PATTERN: vec![Vec<i32>; 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<Vec<i32>>; 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<BarcodeFormat> {
return Collections::singleton(BarcodeFormat::ITF);
}
pub fn encode(&self, contents: &String) -> Vec<bool> {
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;
}
}

View File

@@ -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<OneDReader>; 0] = [None; 0];
pub struct MultiFormatOneDReader {
super: OneDReader;
let readers: Vec<OneDReader>;
}
impl MultiFormatOneDReader {
pub fn new( hints: &Map<DecodeHintType, ?>) -> MultiFormatOneDReader {
let possible_formats: Collection<BarcodeFormat> = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection<BarcodeFormat> };
let use_code39_check_digit: bool = hints != null && hints.get(DecodeHintType::ASSUME_CODE_39_CHECK_DIGIT) != null;
let mut readers: Collection<OneDReader> = 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<DecodeHintType, ?>) -> /* throws NotFoundException */Result<Result, Rc<Exception>> {
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();
}
}
}

View File

@@ -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;
/**
* <p>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.</p>
*
* @author Sean Owen
*/
const EMPTY_READER_ARRAY: [Option<UPCEANReader>; 0] = [None; 0];
pub struct MultiFormatUPCEANReader {
super: OneDReader;
let readers: Vec<UPCEANReader>;
}
impl MultiFormatUPCEANReader {
pub fn new( hints: &Map<DecodeHintType, ?>) -> MultiFormatUPCEANReader {
let possible_formats: Collection<BarcodeFormat> = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection<BarcodeFormat> };
let mut readers: Collection<UPCEANReader> = 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<DecodeHintType, ?>) -> /* throws NotFoundException */Result<Result, Rc<Exception>> {
// Compute this location once and reuse it on multiple implementations
let start_guard_pattern: Vec<i32> = 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<BarcodeFormat> = if hints == null { null } else { hints.get(DecodeHintType::POSSIBLE_FORMATS) as Collection<BarcodeFormat> };
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();
}
}
}

View File

@@ -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<Result, Rc<Exception>> {
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<DecodeHintType, ?>) -> /* throws NotFoundException, FormatException */Result<Result, Rc<Exception>> {
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<ResultMetadataType, ?> = 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<ResultPoint> = 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<DecodeHintType, ?>) -> /* throws NotFoundException */Result<Result, Rc<Exception>> {
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<DecodeHintType, Object> = 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<ResultPoint> = 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<i32>) -> /* throws NotFoundException */Result<Void, Rc<Exception>> {
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<i32>) -> /* throws NotFoundException */Result<Void, Rc<Exception>> {
// 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<i32>, pattern: &Vec<i32>, 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;
}
/**
* <p>Attempts to decode a one-dimensional barcode format given a single row of
* an image.</p>
*
* @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<DecodeHintType, ?>) -> /* throws NotFoundException, ChecksumException, FormatException */Result<Result, Rc<Exception>> ;
}

View File

@@ -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;
/**
* <p>Encapsulates functionality and implementation that is common to one-dimensional barcodes.</p>
*
* @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<bool> ;
/**
* 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<EncodeHintType, ?>) -> Vec<bool> {
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<EncodeHintType, ?>) -> 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<BarcodeFormat> = 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<bool> = self.encode(&contents, &hints);
return ::render_result(&code, width, height, sides_margin);
}
pub fn get_supported_write_formats(&self) -> Collection<BarcodeFormat> {
return null;
}
/**
* @return a byte array of horizontal pixels (0 = white, 1 = black)
*/
fn render_result( code: &Vec<bool>, 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<bool>, pos: i32, pattern: &Vec<i32>, 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;
}
}

View File

@@ -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<i32>;
let data_character_counters: Vec<i32>;
let odd_rounding_errors: Vec<f32>;
let even_rounding_errors: Vec<f32>;
let odd_counts: Vec<i32>;
let even_counts: Vec<i32>;
}
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<i32> {
return self.decode_finder_counters;
}
pub fn get_data_character_counters(&self) -> Vec<i32> {
return self.data_character_counters;
}
pub fn get_odd_rounding_errors(&self) -> Vec<f32> {
return self.odd_rounding_errors;
}
pub fn get_even_rounding_errors(&self) -> Vec<f32> {
return self.even_rounding_errors;
}
pub fn get_odd_counts(&self) -> Vec<i32> {
return self.odd_counts;
}
pub fn get_even_counts(&self) -> Vec<i32> {
return self.even_counts;
}
pub fn parse_finder_value( counters: &Vec<i32>, finder_patterns: &Vec<Vec<i32>>) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
{
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>) -> i32 {
return MathUtils::sum(&array);
}
pub fn increment( array: &Vec<i32>, errors: &Vec<f32>) {
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<i32>, errors: &Vec<f32>) {
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<i32>) -> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<ExpandedPair>) -> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<String, Rc<Exception>> {
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());
}
}

View File

@@ -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<String, Rc<Exception>> {
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());
}
}

View File

@@ -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<String, Rc<Exception>> {
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;
}
}

View File

@@ -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<String, Rc<Exception>> {
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());
}
}

View File

@@ -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<String, Rc<Exception>> {
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));
}
}

View File

@@ -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);
}
}

View File

@@ -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 ;
}

View File

@@ -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<String, Rc<Exception>> ;
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));
}
}

View File

@@ -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<String, Rc<Exception>> {
let buf: StringBuilder = StringBuilder::new();
return Ok(self.get_general_decoder().decode_all_codes(&buf, HEADER_SIZE));
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<String, DataLength> = HashMap<>::new();
const THREE_DIGIT_DATA_LENGTH: Map<String, DataLength> = HashMap<>::new();
const THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH: Map<String, DataLength> = HashMap<>::new();
const FOUR_DIGIT_DATA_LENGTH: Map<String, DataLength> = 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<String, Rc<Exception>> {
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<String, Rc<Exception>> {
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<String, Rc<Exception>> {
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);
}
}
}

View File

@@ -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<String, Rc<Exception>> {
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<DecodedNumeric, Rc<Exception>> {
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<DecodedInformation, Rc<Exception>> {
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<DecodedInformation, Rc<Exception>> {
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<BlockParsedResult, Rc<Exception>> {
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<BlockParsedResult, Rc<Exception>> {
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<DecodedChar, Rc<Exception>> {
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;
}
}

View File

@@ -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);
}
}

View File

@@ -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<ExpandedPair>;
let row_number: i32;
}
impl ExpandedRow {
fn new( pairs: &List<ExpandedPair>, row_number: i32) -> ExpandedRow {
let .pairs = ArrayList<>::new(&pairs);
let .rowNumber = row_number;
}
fn get_pairs(&self) -> List<ExpandedPair> {
return self.pairs;
}
fn get_row_number(&self) -> i32 {
return self.rowNumber;
}
fn is_equivalent(&self, other_pairs: &List<ExpandedPair>) -> 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();
}
}

View File

@@ -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<i32>; 5] = vec![7, 5, 4, 3, 1, ]
;
const EVEN_TOTAL_SUBSET: vec![Vec<i32>; 5] = vec![4, 20, 52, 104, 204, ]
;
const GSUM: vec![Vec<i32>; 5] = vec![0, 348, 1388, 2948, 3988, ]
;
const FINDER_PATTERNS: vec![vec![Vec<Vec<i32>>; 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<Vec<i32>>; 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<Vec<i32>>; 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<ExpandedPair> = ArrayList<>::new(MAX_PAIRS);
let rows: List<ExpandedRow> = 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<DecodeHintType, ?>) -> /* throws NotFoundException, FormatException */Result<Result, Rc<Exception>> {
// 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<List<ExpandedPair>, Rc<Exception>> {
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<ExpandedPair> = 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<ExpandedPair> {
// 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<ExpandedPair> = 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<ExpandedRow>, current_row: i32) -> /* throws NotFoundException */Result<List<ExpandedPair>, Rc<Exception>> {
{
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<ExpandedRow> = 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<ExpandedPair>) -> bool {
for let sequence: Vec<i32> 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<ExpandedPair>, rows: &Collection<ExpandedRow>) {
{
let iterator: Iterator<ExpandedRow> = 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<ExpandedPair>, rows: &Iterable<ExpandedRow>) -> 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<ExpandedRow> {
return self.rows;
}
// Not private for unit testing
fn construct_result( pairs: &List<ExpandedPair>) -> /* throws NotFoundException, FormatException */Result<Result, Rc<Exception>> {
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<ResultPoint> = pairs.get(0).get_finder_pattern().get_result_points();
let last_points: Vec<ResultPoint> = 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<ExpandedPair>, row_number: i32) -> /* throws NotFoundException */Result<ExpandedPair, Rc<Exception>> {
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<ExpandedPair>, forced_offset: i32) -> /* throws NotFoundException */Result<Void, Rc<Exception>> {
let mut counters: Vec<i32> = 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<i32>) {
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<i32> = 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<DataCharacter, Rc<Exception>> {
let mut counters: Vec<i32> = 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<i32> = self.get_odd_counts();
let even_counts: Vec<i32> = self.get_even_counts();
let odd_rounding_errors: Vec<f32> = self.get_odd_rounding_errors();
let even_rounding_errors: Vec<f32> = 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<Void, Rc<Exception>> {
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());
}
}
}

View File

@@ -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<i32>;
let result_points: Vec<ResultPoint>;
}
impl FinderPattern {
pub fn new( value: i32, start_end: &Vec<i32>, 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<i32> {
return self.start_end;
}
pub fn get_result_points(&self) -> Vec<ResultPoint> {
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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<i32>; 5] = vec![1, 10, 34, 70, 126, ]
;
const INSIDE_ODD_TOTAL_SUBSET: vec![Vec<i32>; 4] = vec![4, 20, 48, 81, ]
;
const OUTSIDE_GSUM: vec![Vec<i32>; 5] = vec![0, 161, 961, 2015, 2715, ]
;
const INSIDE_GSUM: vec![Vec<i32>; 4] = vec![0, 336, 1036, 1516, ]
;
const OUTSIDE_ODD_WIDEST: vec![Vec<i32>; 5] = vec![8, 6, 4, 3, 1, ]
;
const INSIDE_ODD_WIDEST: vec![Vec<i32>; 4] = vec![2, 4, 6, 8, ]
;
const FINDER_PATTERNS: vec![vec![Vec<Vec<i32>>; 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<Pair>;
let possible_right_pairs: List<Pair>;
}
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<DecodeHintType, ?>) -> /* throws NotFoundException */Result<Result, Rc<Exception>> {
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: &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<ResultPoint> = left_pair.get_finder_pattern().get_result_points();
let right_points: Vec<ResultPoint> = 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<DecodeHintType, ?>) -> Pair {
let tryResult1 = 0;
'try1: loop {
{
let start_end: Vec<i32> = 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<DataCharacter, Rc<Exception>> {
let mut counters: Vec<i32> = 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<i32> = self.get_odd_counts();
let even_counts: Vec<i32> = self.get_even_counts();
let odd_rounding_errors: Vec<f32> = self.get_odd_rounding_errors();
let even_rounding_errors: Vec<f32> = 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<Vec<i32>, Rc<Exception>> {
let mut counters: Vec<i32> = 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<i32>) -> /* throws NotFoundException */Result<FinderPattern, Rc<Exception>> {
// 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<i32> = 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<Void, Rc<Exception>> {
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());
}
}
}

View File

@@ -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<i32>, 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;
}
}

View File

@@ -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;
/**
* <p>Implements decoding of the UPC-A format.</p>
*
* @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<i32>, hints: &Map<DecodeHintType, ?>) -> /* throws NotFoundException, FormatException, ChecksumException */Result<Result, Rc<Exception>> {
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<DecodeHintType, ?>) -> /* throws NotFoundException, FormatException, ChecksumException */Result<Result, Rc<Exception>> {
return Ok(::maybe_return_result(&self.ean13_reader.decode_row(row_number, row, &hints)));
}
pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, FormatException */Result<Result, Rc<Exception>> {
return Ok(::maybe_return_result(&self.ean13_reader.decode(image)));
}
pub fn decode(&self, image: &BinaryBitmap, hints: &Map<DecodeHintType, ?>) -> /* throws NotFoundException, FormatException */Result<Result, Rc<Exception>> {
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<i32>, result_string: &StringBuilder) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
return Ok(self.ean13_reader.decode_middle(row, &start_range, &result_string));
}
fn maybe_return_result( result: &Result) -> /* throws FormatException */Result<Result, Rc<Exception>> {
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();
}
}
}

View File

@@ -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<EncodeHintType, ?>) -> 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);
}
}

View File

@@ -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<i32>) -> /* throws NotFoundException */Result<Result, Rc<Exception>> {
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<ResultMetadataType, Object> = ::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<i32>, result_string: &StringBuilder) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
let mut counters: Vec<i32> = 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<ResultMetadataType, Object> {
if raw.length() != 2 {
return null;
}
let result: Map<ResultMetadataType, Object> = EnumMap<>::new(ResultMetadataType.class);
result.put(ResultMetadataType::ISSUE_NUMBER, &Integer::value_of(&raw));
return result;
}
}

View File

@@ -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<i32>; 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<i32>) -> /* throws NotFoundException */Result<Result, Rc<Exception>> {
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<ResultMetadataType, Object> = ::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<i32>, result_string: &StringBuilder) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
let mut counters: Vec<i32> = 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<i32, Rc<Exception>> {
{
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<ResultMetadataType, Object> {
if raw.length() != 5 {
return null;
}
let value: Object = ::parse_extension5_string(&raw);
if value == null {
return null;
}
let result: Map<ResultMetadataType, Object> = 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);
}
}

View File

@@ -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<i32>; 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<Result, Rc<Exception>> {
let extension_start_range: Vec<i32> = 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
}
}
}

View File

@@ -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;
/**
* <p>Encapsulates functionality and implementation that is common to UPC and EAN families
* of one-dimensional barcodes.</p>
*
* @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<i32>; 3] = vec![1, 1, 1, ]
;
/**
* Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
*/
const MIDDLE_PATTERN: vec![Vec<i32>; 5] = vec![1, 1, 1, 1, 1, ]
;
/**
* end guard pattern.
*/
const END_PATTERN: vec![Vec<i32>; 6] = vec![1, 1, 1, 1, 1, 1, ]
;
/**
* "Odd", or "L" patterns used to encode UPC/EAN digits.
*/
const L_PATTERNS: vec![vec![Vec<Vec<i32>>; 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<Vec<i32>>;
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<i32> = 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<Vec<i32>, Rc<Exception>> {
let found_start: bool = false;
let start_range: Vec<i32> = 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<DecodeHintType, ?>) -> /* throws NotFoundException, ChecksumException, FormatException */Result<Result, Rc<Exception>> {
return Ok(self.decode_row(row_number, row, &::find_start_guard_pattern(row), &hints));
}
/**
* <p>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.</p>
*
* @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<i32>, hints: &Map<DecodeHintType, ?>) -> /* throws NotFoundException, ChecksumException, FormatException */Result<Result, Rc<Exception>> {
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<i32> = 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<i32> = if hints == null { null } else { hints.get(DecodeHintType::ALLOWED_EAN_EXTENSIONS) as Vec<i32> };
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<bool, Rc<Exception>> {
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<bool, Rc<Exception>> {
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<i32, Rc<Exception>> {
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<Vec<i32>, Rc<Exception>> {
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<i32>) -> /* throws NotFoundException */Result<Vec<i32>, Rc<Exception>> {
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<i32>, counters: &Vec<i32>) -> /* throws NotFoundException */Result<Vec<i32>, Rc<Exception>> {
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<i32>, row_offset: i32, patterns: &Vec<Vec<i32>>) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
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<i32> = 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<i32>, result_string: &StringBuilder) -> /* throws NotFoundException */Result<i32, Rc<Exception>> ;
}

View File

@@ -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;
/**
* <p>Encapsulates functionality and implementation that is common to UPC and EAN families
* of one-dimensional barcodes.</p>
*
* @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;
}
}

View File

@@ -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;
/**
* <p>Implements decoding of the UPC-E format.</p>
* <p><a href="http://www.barcodeisland.com/upce.phtml">This</a> is a great reference for
* UPC-E information.</p>
*
* @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<i32>; 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<Vec<i32>>; 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<i32>;
}
impl UPCEReader {
pub fn new() -> UPCEReader {
decode_middle_counters = : [i32; 4] = [0; 4];
}
pub fn decode_middle(&self, row: &BitArray, start_range: &Vec<i32>, result: &StringBuilder) -> /* throws NotFoundException */Result<i32, Rc<Exception>> {
let mut counters: Vec<i32> = 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<Vec<i32>, Rc<Exception>> {
return Ok(find_guard_pattern(row, end_start, true, &MIDDLE_END_PATTERN));
}
pub fn check_checksum(&self, s: &String) -> /* throws FormatException */Result<bool, Rc<Exception>> {
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<Void, Rc<Exception>> {
{
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<char>; 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();
}
}

View File

@@ -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<BarcodeFormat> {
return Collections::singleton(BarcodeFormat::UPC_E);
}
pub fn encode(&self, contents: &String) -> Vec<bool> {
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;
}
}