mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
Initial generics
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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!(
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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!()
|
||||
|
||||
Reference in New Issue
Block a user