checkin for entire port source tree

This commit is contained in:
Henry Schimke
2022-08-12 16:58:30 -05:00
parent 363de696ea
commit 3a4400e78c
2999 changed files with 100197 additions and 10 deletions

View File

@@ -0,0 +1,165 @@
/*
* 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

@@ -0,0 +1,59 @@
/*
* 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

@@ -0,0 +1,96 @@
/*
* 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

@@ -0,0 +1,39 @@
/*
* 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

@@ -0,0 +1,46 @@
/*
* 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

@@ -0,0 +1,50 @@
/*
* 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

@@ -0,0 +1,69 @@
/*
* 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

@@ -0,0 +1,93 @@
/*
* 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

@@ -0,0 +1,45 @@
/*
* 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

@@ -0,0 +1,46 @@
/*
* 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

@@ -0,0 +1,82 @@
/*
* 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

@@ -0,0 +1,56 @@
/*
* 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

@@ -0,0 +1,113 @@
/*
* 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

@@ -0,0 +1,39 @@
/*
* 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

@@ -0,0 +1,48 @@
/*
* 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

@@ -0,0 +1,76 @@
/*
* 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

@@ -0,0 +1,46 @@
/*
* 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

@@ -0,0 +1,60 @@
/*
* 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

@@ -0,0 +1,63 @@
/*
* 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

@@ -0,0 +1,36 @@
/*
* 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

@@ -0,0 +1,255 @@
/*
* 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

@@ -0,0 +1,508 @@
/*
* 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

@@ -0,0 +1,70 @@
/*
* 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

@@ -0,0 +1,66 @@
/*
* 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

@@ -0,0 +1,802 @@
/*
* 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

@@ -0,0 +1,63 @@
/*
* 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

@@ -0,0 +1,45 @@
/*
* 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

@@ -0,0 +1,500 @@
/*
* 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

@@ -0,0 +1,114 @@
/*
* 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;
}
}