Initial generics

This commit is contained in:
Steve Cook
2023-03-01 22:08:12 -05:00
parent 26325928e7
commit a9bc58108c
65 changed files with 1013 additions and 883 deletions

View File

@@ -49,7 +49,7 @@ impl Default for CodaBarReader {
}
impl OneDReader for CodaBarReader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
@@ -309,7 +309,7 @@ impl CodaBarReader {
self.counterLength = 0;
// Start from the first white bit.
let mut i = row.getNextUnset(0);
let end = row.getSize();
let end = row.get_size();
if i >= end {
return Err(Exceptions::NOT_FOUND);
}

View File

@@ -32,7 +32,7 @@ use super::{one_d_reader, OneDReader};
pub struct Code128Reader;
impl OneDReader for Code128Reader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
@@ -294,7 +294,7 @@ impl OneDReader for Code128Reader {
nextStart = row.getNextUnset(nextStart);
if !row.isRange(
nextStart,
row.getSize().min(nextStart + (nextStart - lastStart) / 2),
row.get_size().min(nextStart + (nextStart - lastStart) / 2),
false,
)? {
return Err(Exceptions::NOT_FOUND);
@@ -354,7 +354,7 @@ impl OneDReader for Code128Reader {
}
impl Code128Reader {
fn findStartPattern(&self, row: &BitArray) -> Result<[usize; 3]> {
let width = row.getSize();
let width = row.get_size();
let rowOffset = row.getNextSet(0);
let mut counterPosition = 0;
@@ -371,7 +371,7 @@ impl Code128Reader {
let mut bestVariance = MAX_AVG_VARIANCE;
let mut bestMatch = -1_isize;
for startCode in CODE_START_A..=CODE_START_C {
let variance = one_d_reader::patternMatchVariance(
let variance = one_d_reader::pattern_match_variance(
&counters,
&CODE_PATTERNS[startCode as usize],
MAX_INDIVIDUAL_VARIANCE,
@@ -410,13 +410,13 @@ impl Code128Reader {
}
fn decodeCode(&self, row: &BitArray, counters: &mut [u32; 6], rowOffset: usize) -> Result<u8> {
one_d_reader::recordPattern(row, rowOffset, counters)?;
one_d_reader::record_pattern(row, rowOffset, counters)?;
let mut bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
let mut bestMatch = -1_isize;
for d in 0..CODE_PATTERNS.len() {
let pattern = &CODE_PATTERNS[d];
let variance =
one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
one_d_reader::pattern_match_variance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
if variance < bestVariance {
bestVariance = variance;
bestMatch = d as isize;

View File

@@ -483,18 +483,18 @@ fn encode(toEncode: &str, compact: bool, expectedLoopback: &str) -> Result<BitMa
WRITER.encode_with_hints(toEncode, &BarcodeFormat::CODE_128, 0, 0, &hints)?;
if !expectedLoopback.is_empty() {
let row = encRXingResult.getRow(0);
let rtRXingResult = reader.decodeRow(0, &row, &HashMap::new())?;
let rtRXingResult = reader.decode_row(0, &row, &HashMap::new())?;
let actual = rtRXingResult.getText();
assert_eq!(expectedLoopback, actual);
}
if compact {
//check that what is encoded compactly yields the same on loopback as what was encoded fast.
let row = encRXingResult.getRow(0);
let rtRXingResult = reader.decodeRow(0, &row, &HashMap::new())?;
let rtRXingResult = reader.decode_row(0, &row, &HashMap::new())?;
let actual = rtRXingResult.getText();
let encRXingResultFast = WRITER.encode(toEncode, &BarcodeFormat::CODE_128, 0, 0)?;
let row = encRXingResultFast.getRow(0);
let rtRXingResult = reader.decodeRow(0, &row, &HashMap::new())?;
let rtRXingResult = reader.decode_row(0, &row, &HashMap::new())?;
assert_eq!(rtRXingResult.getText(), actual);
}
Ok(encRXingResult)

View File

@@ -40,7 +40,7 @@ impl Default for Code39Reader {
}
}
impl OneDReader for Code39Reader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
@@ -52,12 +52,12 @@ impl OneDReader for Code39Reader {
let start = Self::findAsteriskPattern(row, &mut counters)?;
// Read off white space
let mut nextStart = row.getNextSet(start[1] as usize);
let end = row.getSize();
let end = row.get_size();
let mut decodedChar;
let mut lastStart;
loop {
one_d_reader::recordPattern(row, nextStart, &mut counters)?;
one_d_reader::record_pattern(row, nextStart, &mut counters)?;
let pattern = Self::toNarrowWidePattern(&counters);
if pattern < 0 {
return Err(Exceptions::NOT_FOUND);
@@ -205,7 +205,7 @@ impl Code39Reader {
}
fn findAsteriskPattern(row: &BitArray, counters: &mut [u32]) -> Result<Vec<u32>> {
let width = row.getSize();
let width = row.get_size();
let rowOffset = row.getNextSet(0);
let mut counterPosition = 0;
@@ -429,7 +429,9 @@ mod code_39_extended_mode_test_case {
BitMatrix::parse_strings(encodedRXingResult, "1", "0").expect("bitmatrix parse");
// let row = BitArray::with_size(matrix.getWidth() as usize);
let row = matrix.getRow(0);
let result = sut.decodeRow(0, &row, &HashMap::new()).expect("decode row");
let result = sut
.decode_row(0, &row, &HashMap::new())
.expect("decode row");
assert_eq!(expectedRXingResult, result.getText());
}
}

View File

@@ -45,7 +45,7 @@ impl Default for Code93Reader {
}
impl OneDReader for Code93Reader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
@@ -54,7 +54,7 @@ impl OneDReader for Code93Reader {
let start = self.findAsteriskPattern(row)?;
// Read off white space
let mut nextStart = row.getNextSet(start[1]);
let end = row.getSize();
let end = row.get_size();
let mut theCounters = self.counters;
theCounters.fill(0);
@@ -63,7 +63,7 @@ impl OneDReader for Code93Reader {
let mut decodedChar;
let mut lastStart;
loop {
one_d_reader::recordPattern(row, nextStart, &mut theCounters)?;
one_d_reader::record_pattern(row, nextStart, &mut theCounters)?;
let pattern = Self::toPattern(&theCounters);
if pattern < 0 {
return Err(Exceptions::NOT_FOUND);
@@ -163,7 +163,7 @@ impl Code93Reader {
}
fn findAsteriskPattern(&mut self, row: &BitArray) -> Result<[usize; 2]> {
let width = row.getSize();
let width = row.get_size();
let rowOffset = row.getNextSet(0);
self.counters.fill(0);
@@ -385,7 +385,7 @@ mod Code93ReaderTestCase {
// let mut row = BitArray::with_size(matrix.getWidth() as usize);
let row = matrix.getRow(0);
let result = sut
.decodeRow(0, &row, &HashMap::new())
.decode_row(0, &row, &HashMap::new())
.expect("must decode");
assert_eq!(expectedRXingResult, result.getText());
}

View File

@@ -50,7 +50,7 @@ impl UPCEANReader for EAN13Reader {
// counters[1] = 0;
// counters[2] = 0;
// counters[3] = 0;
let end = row.getSize();
let end = row.get_size();
let mut rowOffset = startRange[1];
let mut lgPatternFound = 0;

View File

@@ -46,7 +46,7 @@ impl UPCEANReader for EAN8Reader {
// counters[1] = 0;
// counters[2] = 0;
// counters[3] = 0;
let end = row.getSize();
let end = row.get_size();
let mut rowOffset = startRange[1];
let mut x = 0;

View File

@@ -104,7 +104,7 @@ impl Default for ITFReader {
}
impl OneDReader for ITFReader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
@@ -189,7 +189,7 @@ impl ITFReader {
while payloadStart < payloadEnd {
// Get 10 runs of black/white.
one_d_reader::recordPattern(row, payloadStart, &mut counterDigitPair)?;
one_d_reader::record_pattern(row, payloadStart, &mut counterDigitPair)?;
// Split them into each array
for k in 0..5 {
let twoK = 2 * k;
@@ -275,7 +275,7 @@ impl ITFReader {
* @throws NotFoundException Throws exception if no black lines are found in the row
*/
fn skipWhiteSpace(row: &BitArray) -> Result<usize> {
let width = row.getSize();
let width = row.get_size();
let endStart = row.getNextSet(0);
if endStart == width {
return Err(Exceptions::NOT_FOUND);
@@ -312,8 +312,8 @@ impl ITFReader {
// Now recalculate the indices of where the 'endblock' starts & stops to
// accommodate the reversed nature of the search
let temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
endPattern[0] = row.get_size() - endPattern[1];
endPattern[1] = row.get_size() - temp;
Ok(endPattern)
};
@@ -341,7 +341,7 @@ impl ITFReader {
) -> Result<[usize; 2]> {
let patternLength = pattern.len();
let mut counters = vec![0u32; patternLength]; //new int[patternLength];
let width = row.getSize();
let width = row.get_size();
let mut isWhite = false;
let mut counterPosition = 0;
@@ -352,7 +352,7 @@ impl ITFReader {
counters[counterPosition] += 1;
} else {
if counterPosition == patternLength - 1 {
if one_d_reader::patternMatchVariance(
if one_d_reader::pattern_match_variance(
&counters,
pattern,
MAX_INDIVIDUAL_VARIANCE,
@@ -390,7 +390,7 @@ impl ITFReader {
let max = PATTERNS.len();
for (i, pattern) in PATTERNS.iter().enumerate().take(max) {
let variance =
one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
one_d_reader::pattern_match_variance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
if variance < bestVariance {
bestVariance = variance;
bestMatch = i as isize;

View File

@@ -24,25 +24,110 @@ use super::ITFReader;
use super::MultiFormatUPCEANReader;
use super::OneDReader;
use crate::common::Result;
use crate::BarcodeFormat;
use crate::DecodeHintValue;
use crate::Exceptions;
use crate::{BarcodeFormat, Binarizer, RXingResult};
/**
* @author dswitkin@google.com (Daniel Switkin)
* @author Sean Owen
*/
#[derive(Default)]
pub struct MultiFormatOneDReader(Vec<Box<dyn OneDReader>>);
pub struct MultiFormatOneDReader {
internal_hints: DecodingHintDictionary,
possible_formats: HashSet<BarcodeFormat>,
use_code_39_check_digit: bool,
}
impl OneDReader for MultiFormatOneDReader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row_number: u32,
row: &crate::common::BitArray,
hints: &crate::DecodingHintDictionary,
) -> Result<crate::RXingResult> {
for reader in self.0.iter_mut() {
if let Ok(res) = reader.decodeRow(rowNumber, row, hints) {
hints: &DecodingHintDictionary,
) -> Result<RXingResult> {
// reader.decode_row(rowNumber, row, hints)
let Self {
possible_formats,
use_code_39_check_digit,
internal_hints,
} = self;
if !possible_formats.is_empty() {
if possible_formats.contains(&BarcodeFormat::EAN_13)
|| possible_formats.contains(&BarcodeFormat::UPC_A)
|| possible_formats.contains(&BarcodeFormat::EAN_8)
|| possible_formats.contains(&BarcodeFormat::UPC_E)
{
if let Ok(res) =
MultiFormatUPCEANReader::new(internal_hints).decode_row(row_number, row, hints)
{
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::CODE_39) {
if let Ok(res) = Code39Reader::with_use_check_digit(*use_code_39_check_digit)
.decode_row(row_number, row, hints)
{
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::CODE_93) {
if let Ok(res) = Code93Reader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::CODE_128) {
if let Ok(res) = Code128Reader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::ITF) {
if let Ok(res) = ITFReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::CODABAR) {
if let Ok(res) = CodaBarReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::RSS_14) {
if let Ok(res) = RSS14Reader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::RSS_EXPANDED) {
if let Ok(res) = RSSExpandedReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
} else {
if let Ok(res) =
MultiFormatUPCEANReader::new(internal_hints).decode_row(row_number, row, hints)
{
return Ok(res);
}
if let Ok(res) = Code39Reader::with_use_check_digit(*use_code_39_check_digit)
.decode_row(row_number, row, hints)
{
return Ok(res);
}
if let Ok(res) = CodaBarReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = Code93Reader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = Code128Reader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = ITFReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = RSS14Reader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = RSSExpandedReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
@@ -52,57 +137,23 @@ impl OneDReader for MultiFormatOneDReader {
}
impl MultiFormatOneDReader {
pub fn new(hints: &DecodingHintDictionary) -> Self {
let useCode39CheckDigit = matches!(
let use_code_39_check_digit = matches!(
hints.get(&DecodeHintType::ASSUME_CODE_39_CHECK_DIGIT),
Some(DecodeHintValue::AssumeCode39CheckDigit(true))
);
let mut readers: Vec<Box<dyn OneDReader>> = Vec::new();
if let Some(DecodeHintValue::PossibleFormats(possibleFormats)) =
let possible_formats = if let Some(DecodeHintValue::PossibleFormats(p)) =
hints.get(&DecodeHintType::POSSIBLE_FORMATS)
{
if possibleFormats.contains(&BarcodeFormat::EAN_13)
|| possibleFormats.contains(&BarcodeFormat::UPC_A)
|| possibleFormats.contains(&BarcodeFormat::EAN_8)
|| possibleFormats.contains(&BarcodeFormat::UPC_E)
{
readers.push(Box::new(MultiFormatUPCEANReader::new(hints)));
}
if possibleFormats.contains(&BarcodeFormat::CODE_39) {
readers.push(Box::new(Code39Reader::with_use_check_digit(
useCode39CheckDigit,
)));
}
if possibleFormats.contains(&BarcodeFormat::CODE_93) {
readers.push(Box::<Code93Reader>::default());
}
if possibleFormats.contains(&BarcodeFormat::CODE_128) {
readers.push(Box::<Code128Reader>::default());
}
if possibleFormats.contains(&BarcodeFormat::ITF) {
readers.push(Box::<ITFReader>::default());
}
if possibleFormats.contains(&BarcodeFormat::CODABAR) {
readers.push(Box::<CodaBarReader>::default());
}
if possibleFormats.contains(&BarcodeFormat::RSS_14) {
readers.push(Box::<RSS14Reader>::default());
}
if possibleFormats.contains(&BarcodeFormat::RSS_EXPANDED) {
readers.push(Box::<RSSExpandedReader>::default());
}
}
if readers.is_empty() {
readers.push(Box::new(MultiFormatUPCEANReader::new(hints)));
readers.push(Box::<Code39Reader>::default());
readers.push(Box::<CodaBarReader>::default());
readers.push(Box::<Code93Reader>::default());
readers.push(Box::<Code128Reader>::default());
readers.push(Box::<ITFReader>::default());
readers.push(Box::<RSS14Reader>::default());
readers.push(Box::<RSSExpandedReader>::default());
}
p.clone()
} else {
HashSet::new()
};
Self(readers)
Self {
possible_formats,
use_code_39_check_digit,
internal_hints: hints.clone(),
}
}
}
@@ -111,20 +162,20 @@ use crate::DecodingHintDictionary;
use crate::RXingResultMetadataType;
use crate::RXingResultMetadataValue;
use crate::Reader;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
impl Reader for MultiFormatOneDReader {
fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result<crate::RXingResult> {
fn decode<B: Binarizer>(&mut self, image: &mut crate::BinaryBitmap<B>) -> Result<RXingResult> {
self.decode_with_hints(image, &HashMap::new())
}
// Note that we don't try rotation without the try harder flag, even if rotation was supported.
fn decode_with_hints(
fn decode_with_hints<B: Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap,
image: &mut crate::BinaryBitmap<B>,
hints: &DecodingHintDictionary,
) -> Result<crate::RXingResult> {
let first_try = self.doDecode(image, hints);
) -> Result<RXingResult> {
let first_try = self._do_decode(image, hints);
if first_try.is_ok() {
return first_try;
}
@@ -133,9 +184,9 @@ impl Reader for MultiFormatOneDReader {
hints.get(&DecodeHintType::TRY_HARDER),
Some(DecodeHintValue::TryHarder(true))
);
if tryHarder && image.isRotateSupported() {
let mut rotatedImage = image.rotateCounterClockwise();
let mut result = self.doDecode(&mut rotatedImage, hints)?;
if tryHarder && image.is_rotate_supported() {
let mut rotatedImage = image.rotate_counter_clockwise();
let mut result = self._do_decode(&mut rotatedImage, hints)?;
// Record that we found it rotated 90 degrees CCW / 270 degrees CW
let metadata = result.getRXingResultMetadata();
let mut orientation = 270;
@@ -156,7 +207,7 @@ impl Reader for MultiFormatOneDReader {
RXingResultMetadataValue::Orientation(orientation),
);
// Update result points
let height = rotatedImage.getHeight();
let height = rotatedImage.get_height();
let total_points = result.getPoints().len();
let points = result.getPointsMut();
for point in points.iter_mut().take(total_points) {
@@ -169,10 +220,4 @@ impl Reader for MultiFormatOneDReader {
Err(Exceptions::NOT_FOUND)
}
}
fn reset(&mut self) {
for reader in self.0.iter_mut() {
reader.reset();
}
}
}

View File

@@ -15,11 +15,11 @@
*/
use crate::common::Result;
use crate::BarcodeFormat;
use crate::DecodeHintValue;
use crate::Exceptions;
use crate::RXingResult;
use crate::Reader;
use crate::{BarcodeFormat, Binarizer};
use super::EAN13Reader;
use super::EAN8Reader;
@@ -35,47 +35,122 @@ use super::{OneDReader, UPCEANReader};
*
* @author Sean Owen
*/
pub struct MultiFormatUPCEANReader(Vec<Box<dyn UPCEANReader>>);
pub struct MultiFormatUPCEANReader {
possible_formats: HashSet<BarcodeFormat>,
}
impl OneDReader for MultiFormatUPCEANReader {
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
hints: &DecodingHintDictionary,
) -> Result<RXingResult> {
let Self {
ref possible_formats,
} = self;
// Compute this location once and reuse it on multiple implementations
let start_guard_pattern = STAND_IN.find_start_guard_pattern(row)?;
if !possible_formats.is_empty() {
if possible_formats.contains(&BarcodeFormat::EAN_13) {
if let Ok(res) = self.try_decode_function(
&EAN13Reader::default(),
rowNumber,
row,
hints,
&start_guard_pattern,
) {
return Ok(res);
}
} else if possible_formats.contains(&BarcodeFormat::UPC_A) {
if let Ok(res) = self.try_decode_function(
&UPCAReader::default(),
rowNumber,
row,
hints,
&start_guard_pattern,
) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::EAN_8) {
if let Ok(res) = self.try_decode_function(
&EAN8Reader::default(),
rowNumber,
row,
hints,
&start_guard_pattern,
) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::UPC_E) {
if let Ok(res) = self.try_decode_function(
&UPCEReader::default(),
rowNumber,
row,
hints,
&start_guard_pattern,
) {
return Ok(res);
}
}
} else {
if let Ok(res) = self.try_decode_function(
&EAN13Reader::default(),
rowNumber,
row,
hints,
&start_guard_pattern,
) {
return Ok(res);
}
if let Ok(res) = self.try_decode_function(
&EAN8Reader::default(),
rowNumber,
row,
hints,
&start_guard_pattern,
) {
return Ok(res);
}
if let Ok(res) = self.try_decode_function(
&UPCEReader::default(),
rowNumber,
row,
hints,
&start_guard_pattern,
) {
return Ok(res);
}
}
Err(Exceptions::NOT_FOUND)
}
}
impl MultiFormatUPCEANReader {
pub fn new(hints: &DecodingHintDictionary) -> Self {
let mut readers: Vec<Box<dyn UPCEANReader>> = Vec::new();
if let Some(DecodeHintValue::PossibleFormats(possibleFormats)) =
let possible_formats = if let Some(DecodeHintValue::PossibleFormats(p)) =
hints.get(&DecodeHintType::POSSIBLE_FORMATS)
{
// Collection<BarcodeFormat> possibleFormats = hints == null ? null :
// (Collection<BarcodeFormat>) hints.get(DecodeHintType.POSSIBLE_FORMATS);
// Collection<UPCEANReader> readers = new ArrayList<>();
if possibleFormats.contains(&BarcodeFormat::EAN_13) {
readers.push(Box::<EAN13Reader>::default());
} else if possibleFormats.contains(&BarcodeFormat::UPC_A) {
readers.push(Box::<UPCAReader>::default());
}
if possibleFormats.contains(&BarcodeFormat::EAN_8) {
readers.push(Box::<EAN8Reader>::default());
}
if possibleFormats.contains(&BarcodeFormat::UPC_E) {
readers.push(Box::<UPCEReader>::default());
}
}
if readers.is_empty() {
readers.push(Box::<EAN13Reader>::default());
// UPC-A is covered by EAN-13
readers.push(Box::<EAN8Reader>::default());
readers.push(Box::<UPCEReader>::default());
}
p.clone()
} else {
HashSet::default()
};
Self(readers)
Self { possible_formats }
}
fn try_decode_function(
fn try_decode_function<R: UPCEANReader>(
&self,
reader: &Box<dyn UPCEANReader>,
reader: &R,
rowNumber: u32,
row: &crate::common::BitArray,
hints: &crate::DecodingHintDictionary,
hints: &DecodingHintDictionary,
startGuardPattern: &[usize; 2],
) -> Result<crate::RXingResult> {
) -> Result<RXingResult> {
let result = reader.decodeRowWithGuardRange(rowNumber, row, startGuardPattern, hints)?;
// Special case: a 12-digit code encoded in UPC-A is identical to a "0"
// followed by those 12 digits encoded as EAN-13. Each will recognize such a code,
@@ -117,46 +192,24 @@ impl MultiFormatUPCEANReader {
}
}
impl OneDReader for MultiFormatUPCEANReader {
fn decodeRow(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
hints: &crate::DecodingHintDictionary,
) -> Result<crate::RXingResult> {
// Compute this location once and reuse it on multiple implementations
let startGuardPattern = STAND_IN.findStartGuardPattern(row)?;
for reader in &self.0 {
// for (UPCEANReader reader : readers) {
let try_result =
self.try_decode_function(reader, rowNumber, row, hints, &startGuardPattern);
if try_result.is_ok() {
return try_result;
}
}
Err(Exceptions::NOT_FOUND)
}
}
use crate::DecodeHintType;
use crate::DecodingHintDictionary;
use crate::RXingResultMetadataType;
use crate::RXingResultMetadataValue;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
impl Reader for MultiFormatUPCEANReader {
fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result<crate::RXingResult> {
fn decode<B: Binarizer>(&mut self, image: &mut crate::BinaryBitmap<B>) -> Result<RXingResult> {
self.decode_with_hints(image, &HashMap::new())
}
// Note that we don't try rotation without the try harder flag, even if rotation was supported.
fn decode_with_hints(
fn decode_with_hints<B: Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap,
image: &mut crate::BinaryBitmap<B>,
hints: &DecodingHintDictionary,
) -> Result<crate::RXingResult> {
let first_try = self.doDecode(image, hints);
) -> Result<RXingResult> {
let first_try = self._do_decode(image, hints);
if first_try.is_ok() {
return first_try;
}
@@ -165,16 +218,16 @@ impl Reader for MultiFormatUPCEANReader {
hints.get(&DecodeHintType::TRY_HARDER),
Some(DecodeHintValue::TryHarder(true))
);
if tryHarder && image.isRotateSupported() {
let mut rotatedImage = image.rotateCounterClockwise();
let mut result = self.doDecode(&mut rotatedImage, hints)?;
if tryHarder && image.is_rotate_supported() {
let mut rotatedImage = image.rotate_counter_clockwise();
let mut result = self._do_decode(&mut rotatedImage, hints)?;
// Record that we found it rotated 90 degrees CCW / 270 degrees CW
let metadata = result.getRXingResultMetadata();
let mut orientation = 270;
if metadata.contains_key(&RXingResultMetadataType::ORIENTATION) {
// But if we found it reversed in doDecode(), add in that result here:
orientation = (orientation
+ if let Some(crate::RXingResultMetadataValue::Orientation(or)) =
+ if let Some(RXingResultMetadataValue::Orientation(or)) =
metadata.get(&RXingResultMetadataType::ORIENTATION)
{
*or
@@ -188,7 +241,7 @@ impl Reader for MultiFormatUPCEANReader {
RXingResultMetadataValue::Orientation(orientation),
);
// Update result points
let height = rotatedImage.getHeight();
let height = rotatedImage.get_height();
let total_points = result.getPoints().len();
let points = result.getPointsMut();
for point in points.iter_mut().take(total_points) {
@@ -201,10 +254,4 @@ impl Reader for MultiFormatUPCEANReader {
Err(Exceptions::NOT_FOUND)
}
}
fn reset(&mut self) {
for reader in self.0.iter_mut() {
reader.reset();
}
}
}

View File

@@ -16,8 +16,8 @@
use crate::{
common::{BitArray, Result},
point, BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions,
RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader,
point, Binarizer, BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary,
Exceptions, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader,
};
/**
@@ -42,45 +42,45 @@ pub trait OneDReader: Reader {
* @return The contents of the decoded barcode
* @throws NotFoundException Any spontaneous errors which occur
*/
fn doDecode(
fn _do_decode<B: Binarizer>(
&mut self,
image: &mut BinaryBitmap,
image: &mut BinaryBitmap<B>,
hints: &DecodingHintDictionary,
) -> Result<RXingResult> {
let mut hints = hints.clone();
let width = image.getWidth();
let height = image.getHeight();
let width = image.get_width();
let height = image.get_height();
let tryHarder = matches!(
let try_harder = matches!(
hints.get(&DecodeHintType::TRY_HARDER),
Some(DecodeHintValue::TryHarder(true))
);
let rowStep = 1.max(height >> (if tryHarder { 8 } else { 5 }));
let maxLines = if tryHarder {
let row_step = 1.max(height >> (if try_harder { 8 } else { 5 }));
let max_lines = if try_harder {
height // Look at the whole image, not just the center
} else {
15 // 15 rows spaced 1/32 apart is roughly the middle half of the image
};
let middle = height / 2;
for x in 0..maxLines {
for x in 0..max_lines {
// Scanning from the middle out. Determine which row we're looking at next:
let rowStepsAboveOrBelow = (x + 1) / 2;
let isAbove = (x & 0x01) == 0; // i.e. is x even?
let rowNumber: isize = middle as isize
+ rowStep as isize
* (if isAbove {
rowStepsAboveOrBelow as isize
let row_steps_above_or_below = (x + 1) / 2;
let is_above = (x & 0x01) == 0; // i.e. is x even?
let row_number: isize = middle as isize
+ row_step as isize
* (if is_above {
row_steps_above_or_below as isize
} else {
-(rowStepsAboveOrBelow as isize)
-(row_steps_above_or_below as isize)
});
if rowNumber < 0 || rowNumber >= height as isize {
if row_number < 0 || row_number >= height as isize {
// Oops, if we run off the top or bottom, stop
break;
}
// Estimate black point for this row and load it:
let mut row = if let Ok(res) = image.getBlackRow(rowNumber as usize) {
let mut row = if let Ok(res) = image.get_black_row(row_number as usize) {
res
} else {
continue;
@@ -104,7 +104,7 @@ pub trait OneDReader: Reader {
hints.remove(&DecodeHintType::NEED_RESULT_POINT_CALLBACK);
}
}
let Ok(mut result) = self.decodeRow(rowNumber as u32, &row, &hints) else {
let Ok(mut result) = self.decode_row(row_number as u32, &row, &hints) else {
continue
};
// We found our barcode
@@ -140,7 +140,7 @@ pub trait OneDReader: Reader {
* @throws ChecksumException if a potential barcode is found but does not pass its checksum
* @throws FormatException if a potential barcode is found but format is invalid
*/
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &BitArray,
@@ -158,39 +158,42 @@ pub trait OneDReader: Reader {
* @param maxIndividualVariance The most any counter can differ before we give up
* @return ratio of total variance between counters and pattern compared to total pattern size
*/
pub fn patternMatchVariance(counters: &[u32], pattern: &[u32], maxIndividualVariance: f32) -> f32 {
let mut maxIndividualVariance = maxIndividualVariance;
let numCounters = counters.len();
pub fn pattern_match_variance(
counters: &[u32],
pattern: &[u32],
mut max_individual_variance: f32,
) -> f32 {
let num_counters = counters.len();
let mut total = 0.0;
let mut patternLength = 0;
for i in 0..numCounters {
let mut pattern_length = 0;
for i in 0..num_counters {
total += counters[i] as f32;
patternLength += pattern[i];
pattern_length += pattern[i];
}
if total < patternLength as f32 {
if total < pattern_length as f32 {
// If we don't even have one pixel per unit of bar width, assume this is too small
// to reliably match, so fail:
return f32::INFINITY;
}
let unitBarWidth = total / patternLength as f32;
maxIndividualVariance *= unitBarWidth;
let unit_bar_width = total / pattern_length as f32;
max_individual_variance *= unit_bar_width;
let mut totalVariance = 0.0;
for x in 0..numCounters {
let mut total_variance = 0.0;
for x in 0..num_counters {
let counter = counters[x];
let scaledPattern = (pattern[x] as f32) * unitBarWidth;
let variance = if (counter as f32) > scaledPattern {
counter as f32 - scaledPattern
let scaled_pattern = (pattern[x] as f32) * unit_bar_width;
let variance = if (counter as f32) > scaled_pattern {
counter as f32 - scaled_pattern
} else {
scaledPattern - counter as f32
scaled_pattern - counter as f32
};
if variance > maxIndividualVariance {
if variance > max_individual_variance {
return f32::INFINITY;
}
totalVariance += variance;
total_variance += variance;
}
totalVariance / total
total_variance / total
}
/**
@@ -206,56 +209,56 @@ pub fn patternMatchVariance(counters: &[u32], pattern: &[u32], maxIndividualVari
* @throws NotFoundException if counters cannot be filled entirely from row before running out
* of pixels
*/
pub fn recordPattern(row: &BitArray, start: usize, counters: &mut [u32]) -> Result<()> {
let numCounters = counters.len();
pub fn record_pattern(row: &BitArray, start: usize, counters: &mut [u32]) -> Result<()> {
let num_counters = counters.len();
counters.fill(0);
let end = row.getSize();
let end = row.get_size();
if start >= end {
return Err(Exceptions::NOT_FOUND);
}
let mut isWhite = !row.get(start);
let mut counterPosition = 0;
let mut is_white = !row.get(start);
let mut counter_position = 0;
let mut i = start;
while i < end {
if row.get(i) != isWhite {
counters[counterPosition] += 1;
if row.get(i) != is_white {
counters[counter_position] += 1;
} else {
counterPosition += 1;
if counterPosition == numCounters {
counter_position += 1;
if counter_position == num_counters {
break;
} else {
counters[counterPosition] = 1;
isWhite = !isWhite;
counters[counter_position] = 1;
is_white = !is_white;
}
}
i += 1;
}
// If we read fully the last section of pixels and filled up our counters -- or filled
// the last counter but ran off the side of the image, OK. Otherwise, a problem.
if !(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end)) {
if !(counter_position == num_counters || (counter_position == num_counters - 1 && i == end)) {
return Err(Exceptions::NOT_FOUND);
}
Ok(())
}
pub fn recordPatternInReverse(row: &BitArray, start: usize, counters: &mut [u32]) -> Result<()> {
pub fn record_pattern_in_reverse(row: &BitArray, start: usize, counters: &mut [u32]) -> Result<()> {
let mut start = start;
// This could be more efficient I guess
let mut numTransitionsLeft = counters.len() as isize;
let mut num_transitions_left = counters.len() as isize;
let mut last = row.get(start);
while start > 0 && numTransitionsLeft >= 0 {
while start > 0 && num_transitions_left >= 0 {
start -= 1;
if row.get(start) != last {
numTransitionsLeft -= 1;
num_transitions_left -= 1;
last = !last;
}
}
if numTransitionsLeft >= 0 {
if num_transitions_left >= 0 {
return Err(Exceptions::NOT_FOUND);
}
recordPattern(row, start + 1, counters)?;
record_pattern(row, start + 1, counters)?;
Ok(())
}

View File

@@ -33,8 +33,11 @@ pub trait AbstractRSSReaderTrait: OneDReader {
fn parseFinderValue(counters: &[u32], finderPatterns: &[[u32; 4]]) -> Result<u32> {
for (value, pattern) in finderPatterns.iter().enumerate() {
if one_d_reader::patternMatchVariance(counters, pattern, Self::MAX_INDIVIDUAL_VARIANCE)
< Self::MAX_AVG_VARIANCE
if one_d_reader::pattern_match_variance(
counters,
pattern,
Self::MAX_INDIVIDUAL_VARIANCE,
) < Self::MAX_AVG_VARIANCE
{
return Ok(value as u32);
}

View File

@@ -38,7 +38,7 @@ pub struct AI01392xDecoder<'a> {
impl AI01decoder for AI01392xDecoder<'_> {}
impl AbstractExpandedDecoder for AI01392xDecoder<'_> {
fn parseInformation(&mut self) -> Result<String> {
if self.information.getSize() < Self::HEADER_SIZE + Self::GTIN_SIZE as usize {
if self.information.get_size() < Self::HEADER_SIZE + Self::GTIN_SIZE as usize {
return Err(crate::Exceptions::NOT_FOUND);
}

View File

@@ -38,7 +38,7 @@ pub struct AI01393xDecoder<'a> {
impl AI01decoder for AI01393xDecoder<'_> {}
impl AbstractExpandedDecoder for AI01393xDecoder<'_> {
fn parseInformation(&mut self) -> Result<String> {
if self.information.getSize() < Self::HEADER_SIZE + Self::GTIN_SIZE as usize {
if self.information.get_size() < Self::HEADER_SIZE + Self::GTIN_SIZE as usize {
return Err(crate::Exceptions::NOT_FOUND);
}

View File

@@ -54,7 +54,7 @@ impl AI01weightDecoder for AI013x0x1xDecoder<'_> {
impl AI01decoder for AI013x0x1xDecoder<'_> {}
impl AbstractExpandedDecoder for AI013x0x1xDecoder<'_> {
fn parseInformation(&mut self) -> Result<String> {
if self.information.getSize()
if self.information.get_size()
!= Self::HEADER_SIZE + Self::GTIN_SIZE as usize + Self::WEIGHT_SIZE + Self::DATE_SIZE
{
return Err(crate::Exceptions::NOT_FOUND);

View File

@@ -50,7 +50,7 @@ impl AI01weightDecoder for AI013x0xDecoder<'_> {
}
impl AbstractExpandedDecoder for AI013x0xDecoder<'_> {
fn parseInformation(&mut self) -> Result<String> {
if self.information.getSize()
if self.information.get_size()
!= Self::HEADER_SIZE + Self::GTIN_SIZE as usize + Self::WEIGHT_SIZE
{
return Err(crate::Exceptions::NOT_FOUND);

View File

@@ -82,8 +82,8 @@ impl<'a> GeneralAppIdDecoder<'_> {
fn isStillNumeric(&self, pos: usize) -> bool {
// It's numeric if it still has 7 positions
// and one of the first 4 bits is "1".
if pos + 7 > self.information.getSize() {
return pos + 4 <= self.information.getSize();
if pos + 7 > self.information.get_size() {
return pos + 4 <= self.information.get_size();
}
for i in pos..pos + 3 {
@@ -97,17 +97,17 @@ impl<'a> GeneralAppIdDecoder<'_> {
}
fn decodeNumeric(&self, pos: usize) -> Result<DecodedNumeric> {
if pos + 7 > self.information.getSize() {
if pos + 7 > self.information.get_size() {
let numeric = self.extractNumericValueFromBitArray(pos, 4);
if numeric == 0 {
return DecodedNumeric::new(
self.information.getSize(),
self.information.get_size(),
DecodedNumeric::FNC1,
DecodedNumeric::FNC1,
);
}
return DecodedNumeric::new(
self.information.getSize(),
self.information.get_size(),
numeric - 1,
DecodedNumeric::FNC1,
);
@@ -263,10 +263,10 @@ impl<'a> GeneralAppIdDecoder<'_> {
self.current.incrementPosition(3);
self.current.setNumeric();
} else if self.isAlphaTo646ToAlphaLatch(self.current.getPosition()) {
if self.current.getPosition() + 5 < self.information.getSize() {
if self.current.getPosition() + 5 < self.information.get_size() {
self.current.incrementPosition(5);
} else {
self.current.setPosition(self.information.getSize());
self.current.setPosition(self.information.get_size());
}
self.current.setAlpha();
@@ -295,10 +295,10 @@ impl<'a> GeneralAppIdDecoder<'_> {
self.current.incrementPosition(3);
self.current.setNumeric();
} else if self.isAlphaTo646ToAlphaLatch(self.current.getPosition()) {
if self.current.getPosition() + 5 < self.information.getSize() {
if self.current.getPosition() + 5 < self.information.get_size() {
self.current.incrementPosition(5);
} else {
self.current.setPosition(self.information.getSize());
self.current.setPosition(self.information.get_size());
}
self.current.setIsoIec646();
@@ -308,7 +308,7 @@ impl<'a> GeneralAppIdDecoder<'_> {
}
fn isStillIsoIec646(&self, pos: usize) -> bool {
if pos + 5 > self.information.getSize() {
if pos + 5 > self.information.get_size() {
return false;
}
@@ -317,7 +317,7 @@ impl<'a> GeneralAppIdDecoder<'_> {
return true;
}
if pos + 7 > self.information.getSize() {
if pos + 7 > self.information.get_size() {
return false;
}
@@ -326,7 +326,7 @@ impl<'a> GeneralAppIdDecoder<'_> {
return true;
}
if pos + 8 > self.information.getSize() {
if pos + 8 > self.information.get_size() {
return false;
}
@@ -394,7 +394,7 @@ impl<'a> GeneralAppIdDecoder<'_> {
}
fn isStillAlpha(&self, pos: usize) -> bool {
if pos + 5 > self.information.getSize() {
if pos + 5 > self.information.get_size() {
return false;
}
@@ -404,7 +404,7 @@ impl<'a> GeneralAppIdDecoder<'_> {
return true;
}
if pos + 6 > self.information.getSize() {
if pos + 6 > self.information.get_size() {
return false;
}
@@ -452,12 +452,12 @@ impl<'a> GeneralAppIdDecoder<'_> {
}
fn isAlphaTo646ToAlphaLatch(&self, pos: usize) -> bool {
if pos + 1 > self.information.getSize() {
if pos + 1 > self.information.get_size() {
return false;
}
let mut i = 0;
while i < 5 && i + pos < self.information.getSize() {
while i < 5 && i + pos < self.information.get_size() {
if i == 2 {
if !self.information.get(pos + 2) {
return false;
@@ -474,7 +474,7 @@ impl<'a> GeneralAppIdDecoder<'_> {
fn isAlphaOr646ToNumericLatch(&self, pos: usize) -> bool {
// Next is alphanumeric if there are 3 positions and they are all zeros
if pos + 3 > self.information.getSize() {
if pos + 3 > self.information.get_size() {
return false;
}
@@ -490,12 +490,12 @@ impl<'a> GeneralAppIdDecoder<'_> {
fn isNumericToAlphaNumericLatch(&self, pos: usize) -> bool {
// Next is alphanumeric if there are 4 positions and they are all zeros, or
// if there is a subset of this just before the end of the symbol
if pos + 1 > self.information.getSize() {
if pos + 1 > self.information.get_size() {
return false;
}
let mut i = 0;
while i < 4 && i + pos < self.information.getSize() {
while i < 4 && i + pos < self.information.get_size() {
if self.information.get(pos + i) {
return false;
}

View File

@@ -177,8 +177,8 @@ fn assertCorrectImage2binary(fileName: &str, expected: &str) {
let binaryMap = BinaryBitmap::new(Rc::new(GlobalHistogramBinarizer::new(Box::new(
BufferedImageLuminanceSource::new(image),
))));
let rowNumber = binaryMap.getHeight() / 2;
let row = binaryMap.getBlackRow(rowNumber).expect("row");
let rowNumber = binaryMap.get_height() / 2;
let row = binaryMap.get_black_row(rowNumber).expect("row");
// let pairs = Vec::new();
// try {

View File

@@ -74,12 +74,12 @@ fn assertCorrectImage2result(fileName: &str, expected: ExpandedProductParsedRXin
let binaryMap = BinaryBitmap::new(Rc::new(GlobalHistogramBinarizer::new(Box::new(
BufferedImageLuminanceSource::new(image),
))));
let rowNumber = binaryMap.getHeight() / 2;
let row = binaryMap.getBlackRow(rowNumber).expect("get row");
let rowNumber = binaryMap.get_height() / 2;
let row = binaryMap.get_black_row(rowNumber).expect("get row");
let mut rssExpandedReader = RSSExpandedReader::new();
let theRXingResult = rssExpandedReader
.decodeRow(rowNumber as u32, &row, &HashMap::new())
.decode_row(rowNumber as u32, &row, &HashMap::new())
.expect("must decode");
assert_eq!(

View File

@@ -187,12 +187,12 @@ fn assertCorrectImage2string(fileName: &str, expected: &str) {
let binaryMap = BinaryBitmap::new(Rc::new(GlobalHistogramBinarizer::new(Box::new(
BufferedImageLuminanceSource::new(image),
))));
let rowNumber = binaryMap.getHeight() / 2;
let row = binaryMap.getBlackRow(rowNumber).expect("get row");
let rowNumber = binaryMap.get_height() / 2;
let row = binaryMap.get_black_row(rowNumber).expect("get row");
let mut rssExpandedReader = RSSExpandedReader::new();
let result = rssExpandedReader
.decodeRow(rowNumber as u32, &row, &HashMap::new())
.decode_row(rowNumber as u32, &row, &HashMap::new())
.expect("should decode");
assert_eq!(&BarcodeFormat::RSS_EXPANDED, result.getBarcodeFormat());

View File

@@ -45,8 +45,8 @@ fn testFindFinderPatterns() {
let binaryMap = BinaryBitmap::new(Rc::new(GlobalHistogramBinarizer::new(Box::new(
BufferedImageLuminanceSource::new(image),
))));
let rowNumber = binaryMap.getHeight() as u32 / 2;
let row = binaryMap.getBlackRow(rowNumber as usize).expect("ok");
let rowNumber = binaryMap.get_height() as u32 / 2;
let row = binaryMap.get_black_row(rowNumber as usize).expect("ok");
let mut previousPairs = Vec::new(); //new ArrayList<>();
let mut rssExpandedReader = RSSExpandedReader::new();
@@ -91,8 +91,8 @@ fn testRetrieveNextPairPatterns() {
let binaryMap = BinaryBitmap::new(Rc::new(GlobalHistogramBinarizer::new(Box::new(
BufferedImageLuminanceSource::new(image),
))));
let rowNumber = binaryMap.getHeight() as u32 / 2;
let row = binaryMap.getBlackRow(rowNumber as usize).expect("create");
let rowNumber = binaryMap.get_height() as u32 / 2;
let row = binaryMap.get_black_row(rowNumber as usize).expect("create");
let mut previousPairs = Vec::new(); //new ArrayList<>();
let mut rssExpandedReader = RSSExpandedReader::new();
@@ -120,7 +120,7 @@ fn testDecodeCheckCharacter() {
BufferedImageLuminanceSource::new(image.clone()),
))));
let row = binaryMap
.getBlackRow(binaryMap.getHeight() / 2)
.get_black_row(binaryMap.get_height() / 2)
.expect("create");
let startEnd = [145, 243]; //image pixels where the A1 pattern starts (at 124) and ends (at 214)
@@ -148,7 +148,7 @@ fn testDecodeDataCharacter() {
BufferedImageLuminanceSource::new(image.clone()),
))));
let row = binaryMap
.getBlackRow(binaryMap.getHeight() / 2)
.get_black_row(binaryMap.get_height() / 2)
.expect("create");
let startEnd = [145, 243]; //image pixels where the A1 pattern starts (at 124) and ends (at 214)

View File

@@ -29,14 +29,14 @@ use std::collections::HashMap;
use crate::{
common::{BitArray, Result},
oned::{
recordPattern, recordPatternInReverse,
record_pattern, record_pattern_in_reverse,
rss::{
rss_utils, AbstractRSSReaderTrait, DataCharacter, DataCharacterTrait, FinderPattern,
Pair,
},
OneDReader,
},
BarcodeFormat, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions,
BarcodeFormat, Binarizer, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions,
RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader,
};
@@ -151,7 +151,7 @@ pub struct RSSExpandedReader {
}
impl AbstractRSSReaderTrait for RSSExpandedReader {}
impl OneDReader for RSSExpandedReader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
@@ -173,26 +173,26 @@ impl OneDReader for RSSExpandedReader {
}
}
impl Reader for RSSExpandedReader {
fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result<crate::RXingResult> {
fn decode<B: Binarizer>(&mut self, image: &mut crate::BinaryBitmap<B>) -> Result<RXingResult> {
self.decode_with_hints(image, &HashMap::new())
}
// Note that we don't try rotation without the try harder flag, even if rotation was supported.
fn decode_with_hints(
fn decode_with_hints<B: Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap,
image: &mut crate::BinaryBitmap<B>,
hints: &DecodingHintDictionary,
) -> Result<crate::RXingResult> {
if let Ok(res) = self.doDecode(image, hints) {
if let Ok(res) = self._do_decode(image, hints) {
Ok(res)
} else {
let tryHarder = matches!(
hints.get(&DecodeHintType::TRY_HARDER),
Some(DecodeHintValue::TryHarder(true))
);
if tryHarder && image.isRotateSupported() {
let mut rotatedImage = image.rotateCounterClockwise();
let mut result = self.doDecode(&mut rotatedImage, hints)?;
if tryHarder && image.is_rotate_supported() {
let mut rotatedImage = image.rotate_counter_clockwise();
let mut result = self._do_decode(&mut rotatedImage, hints)?;
// Record that we found it rotated 90 degrees CCW / 270 degrees CW
let metadata = result.getRXingResultMetadata();
let mut orientation = 270;
@@ -213,7 +213,7 @@ impl Reader for RSSExpandedReader {
RXingResultMetadataValue::Orientation(orientation),
);
// Update result points
let height = rotatedImage.getHeight();
let height = rotatedImage.get_height();
let total_points = result.getPoints().len();
let points = result.getPointsMut();
@@ -684,7 +684,7 @@ impl RSSExpandedReader {
// counters[2] = 0;
// counters[3] = 0;
let width = row.getSize();
let width = row.get_size();
let mut rowOffset;
if forcedOffset >= 0 {
@@ -823,9 +823,9 @@ impl RSSExpandedReader {
counters.fill(0);
if leftChar {
recordPatternInReverse(row, pattern.getStartEnd()[0], counters)?;
record_pattern_in_reverse(row, pattern.getStartEnd()[0], counters)?;
} else {
recordPattern(row, pattern.getStartEnd()[1], counters)?;
record_pattern(row, pattern.getStartEnd()[1], counters)?;
// reverse it
counters.reverse();
// let mut i = 0;

View File

@@ -39,8 +39,8 @@ fn testDecodingRowByRow() {
let binaryMap = test_case_util::getBinaryBitmap("1000.png");
let firstRowNumber = binaryMap.getHeight() / 3;
let firstRow = binaryMap.getBlackRow(firstRowNumber).expect("get row");
let firstRowNumber = binaryMap.get_height() / 3;
let firstRow = binaryMap.get_black_row(firstRowNumber).expect("get row");
// let tester = ;
@@ -72,9 +72,9 @@ fn testDecodingRowByRow() {
.unwrap()
.getStartEndMut()[1] = 0;
let secondRowNumber = 2 * binaryMap.getHeight() / 3;
let secondRowNumber = 2 * binaryMap.get_height() / 3;
let mut secondRow = binaryMap
.getBlackRow(secondRowNumber)
.get_black_row(secondRowNumber)
.expect("get row")
.into_owned();

View File

@@ -19,8 +19,8 @@ use std::collections::HashMap;
use crate::{
common::{BitArray, Result},
oned::{one_d_reader, OneDReader},
point, BarcodeFormat, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions,
RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader,
point, BarcodeFormat, Binarizer, DecodeHintType, DecodeHintValue, DecodingHintDictionary,
Exceptions, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader,
};
use super::{
@@ -45,12 +45,12 @@ pub struct RSS14Reader {
impl AbstractRSSReaderTrait for RSS14Reader {}
impl OneDReader for RSS14Reader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
hints: &crate::DecodingHintDictionary,
) -> Result<crate::RXingResult> {
row: &BitArray,
hints: &DecodingHintDictionary,
) -> Result<RXingResult> {
let mut row = row.clone();
let leftPair = self.decodePair(&row, false, rowNumber, hints);
Self::addOrTally(&mut self.possibleLeftPairs, leftPair);
@@ -73,26 +73,26 @@ impl OneDReader for RSS14Reader {
}
}
impl Reader for RSS14Reader {
fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result<crate::RXingResult> {
fn decode<B: Binarizer>(&mut self, image: &mut crate::BinaryBitmap<B>) -> Result<RXingResult> {
self.decode_with_hints(image, &HashMap::new())
}
// Note that we don't try rotation without the try harder flag, even if rotation was supported.
fn decode_with_hints(
fn decode_with_hints<B: Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap,
image: &mut crate::BinaryBitmap<B>,
hints: &DecodingHintDictionary,
) -> Result<crate::RXingResult> {
if let Ok(res) = self.doDecode(image, hints) {
if let Ok(res) = self._do_decode(image, hints) {
Ok(res)
} else {
let tryHarder = matches!(
hints.get(&DecodeHintType::TRY_HARDER),
Some(DecodeHintValue::TryHarder(true))
);
if tryHarder && image.isRotateSupported() {
let mut rotatedImage = image.rotateCounterClockwise();
let mut result = self.doDecode(&mut rotatedImage, hints)?;
if tryHarder && image.is_rotate_supported() {
let mut rotatedImage = image.rotate_counter_clockwise();
let mut result = self._do_decode(&mut rotatedImage, hints)?;
// Record that we found it rotated 90 degrees CCW / 270 degrees CW
let metadata = result.getRXingResultMetadata();
let mut orientation = 270;
@@ -113,7 +113,7 @@ impl Reader for RSS14Reader {
RXingResultMetadataValue::Orientation(orientation),
);
// Update result points
let height = rotatedImage.getHeight();
let height = rotatedImage.get_height();
let total_points = result.getPoints().len();
let points = result.getPointsMut();
for point in points.iter_mut().take(total_points) {
@@ -257,7 +257,7 @@ impl RSS14Reader {
let mut center: f32 = (startEnd[0] + startEnd[1] - 1) as f32 / 2.0;
if right {
// row is actually reversed
center = row.getSize() as f32 - 1.0 - center;
center = row.get_size() as f32 - 1.0 - center;
}
cb(point(center, rowNumber as f32));
}
@@ -287,9 +287,9 @@ impl RSS14Reader {
counters.fill(0);
if outsideChar {
one_d_reader::recordPatternInReverse(row, pattern.getStartEnd()[0], counters)?;
one_d_reader::record_pattern_in_reverse(row, pattern.getStartEnd()[0], counters)?;
} else {
one_d_reader::recordPattern(row, pattern.getStartEnd()[1], counters)?;
one_d_reader::record_pattern(row, pattern.getStartEnd()[1], counters)?;
// reverse it
counters.reverse();
// let mut i = 0;
@@ -379,7 +379,7 @@ impl RSS14Reader {
let counters = &mut self.decodeFinderCounters;
counters.fill(0);
let width = row.getSize();
let width = row.get_size();
let mut isWhite = false;
let mut rowOffset = 0;
while rowOffset < width {
@@ -445,8 +445,8 @@ impl RSS14Reader {
let mut end = startEnd[1];
if right {
// row is actually reversed
start = row.getSize() - 1 - start;
end = row.getSize() - 1 - end;
start = row.get_size() - 1 - start;
end = row.get_size() - 1 - end;
}
Ok(FinderPattern::new(

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
use crate::{common::Result, BarcodeFormat, Exceptions, RXingResult, Reader};
use crate::{common::Result, BarcodeFormat, Binarizer, Exceptions, RXingResult, Reader};
use super::{EAN13Reader, OneDReader, UPCEANReader};
@@ -28,32 +28,50 @@ use super::{EAN13Reader, OneDReader, UPCEANReader};
pub struct UPCAReader(EAN13Reader);
impl Reader for UPCAReader {
fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result<crate::RXingResult> {
fn decode<B: Binarizer>(&mut self, image: &mut crate::BinaryBitmap<B>) -> Result<RXingResult> {
Self::maybeReturnRXingResult(self.0.decode(image)?)
}
fn decode_with_hints(
fn decode_with_hints<B: Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap,
image: &mut crate::BinaryBitmap<B>,
hints: &crate::DecodingHintDictionary,
) -> Result<crate::RXingResult> {
) -> Result<RXingResult> {
Self::maybeReturnRXingResult(self.0.decode_with_hints(image, hints)?)
}
}
impl OneDReader for UPCAReader {
fn decodeRow(
fn decode_row(
&mut self,
rowNumber: u32,
row: &crate::common::BitArray,
hints: &crate::DecodingHintDictionary,
) -> Result<crate::RXingResult> {
Self::maybeReturnRXingResult(self.0.decodeRow(rowNumber, row, hints)?)
) -> Result<RXingResult> {
Self::maybeReturnRXingResult(self.0.decode_row(rowNumber, row, hints)?)
}
}
impl UPCEANReader for UPCAReader {
fn getBarcodeFormat(&self) -> crate::BarcodeFormat {
fn decodeRowWithGuardRange(
&self,
rowNumber: u32,
row: &crate::common::BitArray,
startGuardRange: &[usize; 2],
hints: &crate::DecodingHintDictionary,
) -> Result<RXingResult>
where
Self: Sized,
{
Self::maybeReturnRXingResult(self.0.decodeRowWithGuardRange(
rowNumber,
row,
startGuardRange,
hints,
)?)
}
fn getBarcodeFormat(&self) -> BarcodeFormat {
BarcodeFormat::UPC_A
}
@@ -65,24 +83,6 @@ impl UPCEANReader for UPCAReader {
) -> Result<usize> {
self.0.decodeMiddle(row, startRange, resultString)
}
fn decodeRowWithGuardRange(
&self,
rowNumber: u32,
row: &crate::common::BitArray,
startGuardRange: &[usize; 2],
hints: &crate::DecodingHintDictionary,
) -> Result<crate::RXingResult>
where
Self: Sized,
{
Self::maybeReturnRXingResult(self.0.decodeRowWithGuardRange(
rowNumber,
row,
startGuardRange,
hints,
)?)
}
}
impl UPCAReader {

View File

@@ -41,7 +41,7 @@ impl UPCEANReader for UPCEReader {
) -> Result<usize> {
let mut counters = [0_u32; 4];
let end = row.getSize();
let end = row.get_size();
let mut rowOffset = startRange[1];
let mut lgPatternFound = 0;

View File

@@ -73,7 +73,7 @@ impl UPCEANExtension2Support {
let mut counters = self.decodeMiddleCounters;
counters.fill(0);
let end = row.getSize();
let end = row.get_size();
let mut rowOffset = startRange[1] as usize;
let mut checkParity = 0;

View File

@@ -73,7 +73,7 @@ impl UPCEANExtension5Support {
resultString: &mut String,
) -> Result<u32> {
let mut counters = [0_u32; 4];
let end = row.getSize();
let end = row.get_size();
let mut rowOffset = startRange[1];
let mut lgPatternFound = 0;

View File

@@ -16,7 +16,7 @@
use crate::{
common::{BitArray, Result},
point, BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, RXingResult,
point, BarcodeFormat, Binarizer, DecodeHintType, DecodeHintValue, Exceptions, RXingResult,
RXingResultMetadataType, RXingResultMetadataValue, Reader,
};
@@ -101,7 +101,7 @@ pub const L_AND_G_PATTERNS: [[u32; 4]; 20] = {
* @author alasdair@google.com (Alasdair Mackintosh)
*/
pub trait UPCEANReader: OneDReader {
fn findStartGuardPattern(&self, row: &BitArray) -> Result<[usize; 2]> {
fn find_start_guard_pattern(&self, row: &BitArray) -> Result<[usize; 2]> {
let mut foundStart = false;
let mut startRange = [0; 2];
let mut nextStart = 0;
@@ -182,7 +182,7 @@ pub trait UPCEANReader: OneDReader {
// spec might want more whitespace, but in practice this is the maximum we can count on.
let end = endRange[1];
let quietEnd = end + (end - endRange[0]);
if quietEnd >= row.getSize() || !row.isRange(end, quietEnd, false)? {
if quietEnd >= row.get_size() || !row.isRange(end, quietEnd, false)? {
return Err(Exceptions::NOT_FOUND);
}
@@ -382,7 +382,7 @@ pub trait UPCEANReader: OneDReader {
pattern: &[u32],
counters: &mut [u32],
) -> Result<[usize; 2]> {
let width = row.getSize();
let width = row.get_size();
let rowOffset = if whiteFirst {
row.getNextUnset(rowOffset)
} else {
@@ -398,7 +398,7 @@ pub trait UPCEANReader: OneDReader {
counters[counterPosition] += 1;
} else {
if counterPosition == patternLength - 1 {
if one_d_reader::patternMatchVariance(
if one_d_reader::pattern_match_variance(
counters,
pattern,
MAX_INDIVIDUAL_VARIANCE,
@@ -443,13 +443,13 @@ pub trait UPCEANReader: OneDReader {
rowOffset: usize,
patterns: &[[u32; 4]],
) -> Result<usize> {
one_d_reader::recordPattern(row, rowOffset, counters)?;
one_d_reader::record_pattern(row, rowOffset, counters)?;
let mut bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
let mut bestMatch = -1_isize;
let max = patterns.len();
for (i, pattern) in patterns.iter().enumerate().take(max) {
let variance: f32 =
one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
one_d_reader::pattern_match_variance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
if variance < bestVariance {
bestVariance = variance;
bestMatch = i as isize;
@@ -503,7 +503,7 @@ impl UPCEANReader for StandInStruct {
}
}
impl OneDReader for StandInStruct {
fn decodeRow(
fn decode_row(
&mut self,
_rowNumber: u32,
_row: &BitArray,
@@ -514,13 +514,13 @@ impl OneDReader for StandInStruct {
}
impl Reader for StandInStruct {
fn decode(&mut self, _image: &mut crate::BinaryBitmap) -> Result<RXingResult> {
fn decode<B: Binarizer>(&mut self, _image: &mut crate::BinaryBitmap<B>) -> Result<RXingResult> {
todo!()
}
fn decode_with_hints(
fn decode_with_hints<B: Binarizer>(
&mut self,
_image: &mut crate::BinaryBitmap,
_image: &mut crate::BinaryBitmap<B>,
_hints: &crate::DecodingHintDictionary,
) -> Result<RXingResult> {
todo!()