diff --git a/crates/one-d-proc-derive/src/lib.rs b/crates/one-d-proc-derive/src/lib.rs index 4d59b12..92d2ccb 100644 --- a/crates/one-d-proc-derive/src/lib.rs +++ b/crates/one-d-proc-derive/src/lib.rs @@ -23,27 +23,28 @@ fn impl_one_d_reader_macro(ast: &syn::DeriveInput) -> TokenStream { use crate::RXingResultMetadataValue; use crate::RXingResultPoint; use crate::Reader; + use crate::Binarizer; impl Reader for #name { - fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { 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( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &DecodingHintDictionary, ) -> Result { - if let Ok(res) = self.doDecode(image, hints) { + if let Ok(res) = self._do_decode(image, hints) { Ok(res) }else { let tryHarder = hints.contains_key(&DecodeHintType::TRY_HARDER); - 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 rotated_image = image.rotate_counter_clockwise(); + let mut result = self._do_decode(&mut rotated_image, hints)?; // Record that we found it rotated 90 degrees CCW / 270 degrees CW - let metadata = result.getRXingResultMetadata(); + 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: @@ -58,7 +59,7 @@ fn impl_one_d_reader_macro(ast: &syn::DeriveInput) -> TokenStream { // Update result points // let points = result.getRXingResultPoints(); // if points != null { - let height = rotatedImage.getHeight(); + let height = rotated_image.get_height(); // for point in result.getRXingResultPointsMut().iter_mut() { let total_points = result.getRXingResultPoints().len(); let points = result.getRXingResultPointsMut(); @@ -93,13 +94,13 @@ fn impl_ean_reader_macro(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; let gen = quote! { impl super::OneDReader for #name { - fn decodeRow( + fn decode_row( &mut self, rowNumber: u32, row: &crate::common::BitArray, hints: &crate::DecodingHintDictionary, ) -> Result { - self.decodeRowWithGuardRange(rowNumber, row, &self.findStartGuardPattern(row)?, hints) + self.decodeRowWithGuardRange(rowNumber, row, &self.find_start_guard_pattern(row)?, hints) } } }; diff --git a/src/PlanarYUVLuminanceSourceTestCase.rs b/src/PlanarYUVLuminanceSourceTestCase.rs index e21b5a5..b24ecc9 100644 --- a/src/PlanarYUVLuminanceSourceTestCase.rs +++ b/src/PlanarYUVLuminanceSourceTestCase.rs @@ -52,10 +52,10 @@ fn test_no_crop() { false, ) .unwrap(); - assert_equals(&Y, 0, &source.getMatrix(), 0, Y.len()); + assert_equals(&Y, 0, &source.get_matrix(), 0, Y.len()); for r in 0..ROWS { // for (int r = 0; r < ROWS; r++) { - assert_equals(&Y, r * COLS, &source.getRow(r), 0, COLS); + assert_equals(&Y, r * COLS, &source.get_row(r), 0, COLS); } } @@ -73,8 +73,8 @@ fn test_crop() { false, ) .unwrap(); - assert!(source.isCropSupported()); - let cropMatrix = source.getMatrix(); + assert!(source.is_crop_supported()); + let cropMatrix = source.get_matrix(); for r in 0..ROWS - 2 { // for (int r = 0; r < ROWS - 2; r++) { assert_equals( @@ -87,7 +87,7 @@ fn test_crop() { } for r in 0..ROWS - 2 { // for (int r = 0; r < ROWS - 2; r++) { - assert_equals(&Y, (r + 1) * COLS + 1, &source.getRow(r), 0, COLS - 2); + assert_equals(&Y, (r + 1) * COLS + 1, &source.get_row(r), 0, COLS - 2); } } diff --git a/src/aztec/aztec_reader.rs b/src/aztec/aztec_reader.rs index e33c1b3..286fae2 100644 --- a/src/aztec/aztec_reader.rs +++ b/src/aztec/aztec_reader.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; use crate::{ common::{DecoderRXingResult, DetectorRXingResult, Result}, exceptions::Exceptions, - BarcodeFormat, BinaryBitmap, DecodeHintType, DecodeHintValue, RXingResult, + BarcodeFormat, Binarizer, BinaryBitmap, DecodeHintType, DecodeHintValue, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader, }; @@ -41,18 +41,18 @@ impl Reader for AztecReader { * @throws NotFoundException if a Data Matrix code cannot be found * @throws FormatException if a Data Matrix code cannot be decoded */ - fn decode(&mut self, image: &mut BinaryBitmap) -> Result { + fn decode(&mut self, image: &mut BinaryBitmap) -> Result { self.decode_with_hints(image, &HashMap::new()) } - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut BinaryBitmap, + image: &mut BinaryBitmap, hints: &HashMap, ) -> Result { // let notFoundException = None; // let formatException = None; - let mut detector = Detector::new(image.getBlackMatrix()); + let mut detector = Detector::new(image.get_black_matrix()); // try { diff --git a/src/aztec/encoder/aztec_encoder.rs b/src/aztec/encoder/aztec_encoder.rs index d5b784c..cbb7d56 100644 --- a/src/aztec/encoder/aztec_encoder.rs +++ b/src/aztec/encoder/aztec_encoder.rs @@ -157,8 +157,8 @@ pub fn encode_bytes_with_charset( let bits = HighLevelEncoder::with_charset(data.into(), charset).encode()?; // stuff bits and choose symbol size - let ecc_bits = bits.getSize() as u32 * min_eccpercent / 100 + 11; - let total_size_bits = bits.getSize() as u32 + ecc_bits; + let ecc_bits = bits.get_size() as u32 * min_eccpercent / 100 + 11; + let total_size_bits = bits.get_size() as u32 + ecc_bits; let mut compact; let mut layers: u32; let mut total_bits_in_layer_var; @@ -182,12 +182,12 @@ pub fn encode_bytes_with_charset( word_size = WORD_SIZE[layers as usize]; let usable_bits_in_layers = total_bits_in_layer_var - (total_bits_in_layer_var % word_size); stuffed_bits = stuffBits(&bits, word_size as usize)?; - if stuffed_bits.getSize() as u32 + ecc_bits > usable_bits_in_layers { + if stuffed_bits.get_size() as u32 + ecc_bits > usable_bits_in_layers { return Err(Exceptions::illegal_argument_with( "Data to large for user specified layer", )); } - if compact && stuffed_bits.getSize() as u32 > word_size * 64 { + if compact && stuffed_bits.get_size() as u32 > word_size * 64 { // Compact format only allows 64 data words, though C4 can hold more words than that return Err(Exceptions::illegal_argument_with( "Data to large for user specified layer", @@ -216,18 +216,18 @@ pub fn encode_bytes_with_charset( } // [Re]stuff the bits if this is the first opportunity, or if the // wordSize has changed - if stuffed_bits.getSize() == 0 || word_size != WORD_SIZE[layers as usize] { + if stuffed_bits.get_size() == 0 || word_size != WORD_SIZE[layers as usize] { word_size = WORD_SIZE[layers as usize]; stuffed_bits = stuffBits(&bits, word_size as usize)?; } let usable_bits_in_layers = total_bits_in_layer_var - (total_bits_in_layer_var % word_size); - if compact && stuffed_bits.getSize() as u32 > word_size * 64 { + if compact && stuffed_bits.get_size() as u32 > word_size * 64 { // Compact format only allows 64 data words, though C4 can hold more words than that i += 1; continue; } - if stuffed_bits.getSize() as u32 + ecc_bits <= usable_bits_in_layers { + if stuffed_bits.get_size() as u32 + ecc_bits <= usable_bits_in_layers { break; } i += 1; @@ -240,7 +240,7 @@ pub fn encode_bytes_with_charset( )?; // generate mode message - let messageSizeInWords = stuffed_bits.getSize() as u32 / word_size; + let messageSizeInWords = stuffed_bits.get_size() as u32 / word_size; let modeMessage = generateModeMessage(compact, layers, messageSizeInWords)?; // allocate symbol @@ -429,7 +429,7 @@ fn drawModeMessage(matrix: &mut BitMatrix, compact: bool, matrixSize: u32, modeM fn generateCheckWords(bitArray: &BitArray, totalBits: usize, wordSize: usize) -> Result { // bitArray is guaranteed to be a multiple of the wordSize, so no padding needed - let message_size_in_words = bitArray.getSize() / wordSize; + let message_size_in_words = bitArray.get_size() / wordSize; let mut rs = ReedSolomonEncoder::new(getGF(wordSize)?)?; let total_words = totalBits / wordSize; let mut message_words = bitsToWords(bitArray, wordSize, total_words); @@ -448,7 +448,7 @@ fn generateCheckWords(bitArray: &BitArray, totalBits: usize, wordSize: usize) -> fn bitsToWords(stuffedBits: &BitArray, wordSize: usize, totalWords: usize) -> Vec { let mut message = vec![0; totalWords]; let mut i = 0; - let n = stuffedBits.getSize() / wordSize; + let n = stuffedBits.get_size() / wordSize; while i < n { // for (i = 0, n = stuffedBits.getSize() / wordSize; i < n; i++) { let mut value = 0; @@ -483,7 +483,7 @@ fn getGF(wordSize: usize) -> Result { pub fn stuffBits(bits: &BitArray, word_size: usize) -> Result { let mut out = BitArray::new(); - let n = bits.getSize() as isize; + let n = bits.get_size() as isize; let mask = (1 << word_size) - 2; let mut i: isize = 0; while i < n { diff --git a/src/aztec/shared_test_methods.rs b/src/aztec/shared_test_methods.rs index 51e9779..11204b1 100644 --- a/src/aztec/shared_test_methods.rs +++ b/src/aztec/shared_test_methods.rs @@ -21,7 +21,7 @@ pub fn toBitArray(bits: &str) -> BitArray { #[allow(dead_code)] pub fn toBooleanArray(bitArray: &BitArray) -> Vec { - let mut result = vec![false; bitArray.getSize()]; + let mut result = vec![false; bitArray.get_size()]; // for i in 0..result.len() { for (i, res) in result.iter_mut().enumerate() { // for (int i = 0; i < result.length; i++) { diff --git a/src/binarizer.rs b/src/binarizer.rs index 7d73c46..8b424b3 100644 --- a/src/binarizer.rs +++ b/src/binarizer.rs @@ -16,7 +16,7 @@ //package com.google.zxing; -use std::{borrow::Cow, rc::Rc}; +use std::borrow::Cow; use crate::{ common::{BitArray, BitMatrix, Result}, @@ -35,7 +35,9 @@ pub trait Binarizer { //private final LuminanceSource source; //fn new(source:dyn LuminanceSource) -> Self; - fn getLuminanceSource(&self) -> &Box; + type Source: LuminanceSource; + + fn get_luminance_source(&self) -> &Self::Source; /** * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return @@ -51,7 +53,7 @@ pub trait Binarizer { * @return The array of bits for this row (true means black). * @throws NotFoundException if row can't be binarized */ - fn getBlackRow(&self, y: usize) -> Result>; + fn get_black_row(&self, y: usize) -> Result>; /** * Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive @@ -62,7 +64,7 @@ pub trait Binarizer { * @return The 2D array of bits for the image (true means black). * @throws NotFoundException if image can't be binarized to make a matrix */ - fn getBlackMatrix(&self) -> Result<&BitMatrix>; + fn get_black_matrix(&self) -> Result<&BitMatrix>; /** * Creates a new object with the same type as this Binarizer implementation, but with pristine @@ -72,9 +74,11 @@ pub trait Binarizer { * @param source The LuminanceSource this Binarizer will operate on. * @return A new concrete Binarizer implementation object. */ - fn createBinarizer(&self, source: Box) -> Rc; + fn create_binarizer(&self, source: Self::Source) -> Self + where + Self: Sized; - fn getWidth(&self) -> usize; + fn get_width(&self) -> usize; - fn getHeight(&self) -> usize; + fn get_height(&self) -> usize; } diff --git a/src/binary_bitmap.rs b/src/binary_bitmap.rs index 4a9f7d4..a17f900 100644 --- a/src/binary_bitmap.rs +++ b/src/binary_bitmap.rs @@ -16,11 +16,11 @@ //package com.google.zxing; -use std::{borrow::Cow, fmt, rc::Rc}; +use std::{borrow::Cow, fmt}; use crate::{ common::{BitArray, BitMatrix, Result}, - Binarizer, + Binarizer, LuminanceSource, }; /** @@ -30,13 +30,13 @@ use crate::{ * @author dswitkin@google.com (Daniel Switkin) */ -pub struct BinaryBitmap { - binarizer: Rc, +pub struct BinaryBitmap { + binarizer: B, matrix: Option, } -impl BinaryBitmap { - pub fn new(binarizer: Rc) -> Self { +impl BinaryBitmap { + pub fn new(binarizer: B) -> Self { Self { matrix: None, binarizer, @@ -46,15 +46,15 @@ impl BinaryBitmap { /** * @return The width of the bitmap. */ - pub fn getWidth(&self) -> usize { - self.binarizer.getWidth() + pub fn get_width(&self) -> usize { + self.binarizer.get_width() } /** * @return The height of the bitmap. */ - pub fn getHeight(&self) -> usize { - self.binarizer.getHeight() + pub fn get_height(&self) -> usize { + self.binarizer.get_height() } /** @@ -68,8 +68,8 @@ impl BinaryBitmap { * @return The array of bits for this row (true means black). * @throws NotFoundException if row can't be binarized */ - pub fn getBlackRow(&self, y: usize) -> Result> { - self.binarizer.getBlackRow(y) + pub fn get_black_row(&self, y: usize) -> Result> { + self.binarizer.get_black_row(y) } /** @@ -83,14 +83,14 @@ impl BinaryBitmap { * @return The 2D array of bits for the image (true means black). * @throws NotFoundException if image can't be binarized to make a matrix */ - pub fn getBlackMatrixMut(&mut self) -> &mut BitMatrix { + pub fn get_black_matrix_mut(&mut self) -> &mut BitMatrix { // The matrix is created on demand the first time it is requested, then cached. There are two // reasons for this: // 1. This work will never be done if the caller only installs 1D Reader objects, or if a // 1D Reader finds a barcode before the 2D Readers run. // 2. This work will only be done once even if the caller installs multiple 2D Readers. if self.matrix.is_none() { - self.matrix = Some(self.binarizer.getBlackMatrix().unwrap().clone()); + self.matrix = Some(self.binarizer.get_black_matrix().unwrap().clone()); } self.matrix.as_mut().unwrap() } @@ -106,14 +106,14 @@ impl BinaryBitmap { * @return The 2D array of bits for the image (true means black). * @throws NotFoundException if image can't be binarized to make a matrix */ - pub fn getBlackMatrix(&mut self) -> &BitMatrix { + pub fn get_black_matrix(&mut self) -> &BitMatrix { // The matrix is created on demand the first time it is requested, then cached. There are two // reasons for this: // 1. This work will never be done if the caller only installs 1D Reader objects, or if a // 1D Reader finds a barcode before the 2D Readers run. // 2. This work will only be done once even if the caller installs multiple 2D Readers. if self.matrix.is_none() { - self.matrix = Some(self.binarizer.getBlackMatrix().unwrap().clone()) + self.matrix = Some(self.binarizer.get_black_matrix().unwrap().clone()) } self.matrix.as_ref().unwrap() } @@ -121,8 +121,8 @@ impl BinaryBitmap { /** * @return Whether this bitmap can be cropped. */ - pub fn isCropSupported(&self) -> bool { - self.binarizer.getLuminanceSource().isCropSupported() + pub fn is_crop_supported(&self) -> bool { + self.binarizer.get_luminance_source().is_crop_supported() } /** @@ -137,22 +137,22 @@ impl BinaryBitmap { * @param height The height of the rectangle to crop. * @return A cropped version of this object. */ - pub fn crop(&mut self, left: usize, top: usize, width: usize, height: usize) -> BinaryBitmap { + pub fn crop(&mut self, left: usize, top: usize, width: usize, height: usize) -> Self { let newSource = self .binarizer - .getLuminanceSource() + .get_luminance_source() .crop(left, top, width, height); return BinaryBitmap::new( self.binarizer - .createBinarizer(newSource.expect("new lum source expected")), + .create_binarizer(newSource.expect("new lum source expected")), ); } /** * @return Whether this bitmap supports counter-clockwise rotation. */ - pub fn isRotateSupported(&self) -> bool { - return self.binarizer.getLuminanceSource().isRotateSupported(); + pub fn is_rotate_supported(&self) -> bool { + return self.binarizer.get_luminance_source().is_rotate_supported(); } /** @@ -163,11 +163,14 @@ impl BinaryBitmap { * * @return A rotated version of this object. */ - pub fn rotateCounterClockwise(&mut self) -> BinaryBitmap { - let newSource = self.binarizer.getLuminanceSource().rotateCounterClockwise(); + pub fn rotate_counter_clockwise(&mut self) -> Self { + let newSource = self + .binarizer + .get_luminance_source() + .rotate_counter_clockwise(); return BinaryBitmap::new( self.binarizer - .createBinarizer(newSource.expect("new lum source expected")), + .create_binarizer(newSource.expect("new lum source expected")), ); } @@ -179,19 +182,19 @@ impl BinaryBitmap { * * @return A rotated version of this object. */ - pub fn rotateCounterClockwise45(&self) -> BinaryBitmap { + pub fn rotate_counter_clockwise_45(&self) -> Self { let newSource = self .binarizer - .getLuminanceSource() - .rotateCounterClockwise45(); + .get_luminance_source() + .rotate_counter_clockwise_45(); return BinaryBitmap::new( self.binarizer - .createBinarizer(newSource.expect("new lum source expected")), + .create_binarizer(newSource.expect("new lum source expected")), ); } } -impl fmt::Display for BinaryBitmap { +impl fmt::Display for BinaryBitmap { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.matrix) } diff --git a/src/buffered_image_luminance_source.rs b/src/buffered_image_luminance_source.rs index 585ebfc..1811f50 100644 --- a/src/buffered_image_luminance_source.rs +++ b/src/buffered_image_luminance_source.rs @@ -88,8 +88,8 @@ impl BufferedImageLuminanceSource { } impl LuminanceSource for BufferedImageLuminanceSource { - fn getRow(&self, y: usize) -> Vec { - let width = self.getWidth(); // - self.left as usize; + fn get_row(&self, y: usize) -> Vec { + let width = self.get_width(); // - self.left as usize; let pixels: Vec = || -> Option> { Some( @@ -108,7 +108,7 @@ impl LuminanceSource for BufferedImageLuminanceSource { pixels } - fn getMatrix(&self) -> Vec { + fn get_matrix(&self) -> Vec { if self.height == self.image.height() as usize && self.width == self.image.width() as usize { return self.image.as_bytes().to_vec(); @@ -141,56 +141,50 @@ impl LuminanceSource for BufferedImageLuminanceSource { data } - fn getWidth(&self) -> usize { + fn get_width(&self) -> usize { self.width } - fn getHeight(&self) -> usize { + fn get_height(&self) -> usize { self.height } + fn is_crop_supported(&self) -> bool { + true + } + + fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result { + Ok(Self { + image: self.image.clone(), + width, + height, + left: self.left + left as u32, + top: self.top + top as u32, + }) + } + + fn is_rotate_supported(&self) -> bool { + true + } + fn invert(&mut self) { let mut img = (*self.image).clone(); img.invert(); self.image = Rc::new(img); } - fn isCropSupported(&self) -> bool { - true - } - - fn crop( - &self, - left: usize, - top: usize, - width: usize, - height: usize, - ) -> Result> { - Ok(Box::new(Self { - image: self.image.clone(), - width, - height, - left: self.left + left as u32, - top: self.top + top as u32, - })) - } - - fn isRotateSupported(&self) -> bool { - true - } - - fn rotateCounterClockwise(&self) -> Result> { + fn rotate_counter_clockwise(&self) -> Result { let img = self.image.rotate270(); - Ok(Box::new(Self { + Ok(Self { width: img.width() as usize, height: img.height() as usize, image: Rc::new(img), left: 0, top: 0, - })) + }) } - fn rotateCounterClockwise45(&self) -> Result> { + fn rotate_counter_clockwise_45(&self) -> Result { let img = rotate_about_center( &self.image.to_luma8(), MINUS_45_IN_RADIANS, @@ -200,12 +194,12 @@ impl LuminanceSource for BufferedImageLuminanceSource { let new_img = DynamicImage::from(img); - Ok(Box::new(Self { + Ok(Self { width: new_img.width() as usize, height: new_img.height() as usize, image: Rc::new(new_img), left: 0, top: 0, - })) + }) } } diff --git a/src/common/BitArrayTestCase.rs b/src/common/BitArrayTestCase.rs index 7225fd1..6dad57e 100644 --- a/src/common/BitArrayTestCase.rs +++ b/src/common/BitArrayTestCase.rs @@ -43,12 +43,12 @@ fn test_get_set() { #[test] fn test_get_next_set1() { let array = BitArray::with_size(32); - for i in 0..array.getSize() { + for i in 0..array.get_size() { // for (int i = 0; i < array.getSize(); i++) { assert_eq!(32, array.getNextSet(i), "{i}"); } let array = BitArray::with_size(33); - for i in 0..array.getSize() { + for i in 0..array.get_size() { // for (int i = 0; i < array.getSize(); i++) { assert_eq!(33, array.getNextSet(i), "{i}"); } @@ -58,13 +58,13 @@ fn test_get_next_set1() { fn test_get_next_set2() { let mut array = BitArray::with_size(33); array.set(31); - for i in 0..array.getSize() { + for i in 0..array.get_size() { // for (int i = 0; i < array.getSize(); i++) { assert_eq!(if i <= 31 { 31 } else { 33 }, array.getNextSet(i), "{i}"); } array = BitArray::with_size(33); array.set(32); - for i in 0..array.getSize() { + for i in 0..array.get_size() { // for (int i = 0; i < array.getSize(); i++) { assert_eq!(32, array.getNextSet(i), "{i}"); } @@ -75,7 +75,7 @@ fn test_get_next_set3() { let mut array = BitArray::with_size(63); array.set(31); array.set(32); - for i in 0..array.getSize() { + for i in 0..array.get_size() { // for (int i = 0; i < array.getSize(); i++) { let expected; if i <= 31 { @@ -94,7 +94,7 @@ fn test_get_next_set4() { let mut array = BitArray::with_size(63); array.set(33); array.set(40); - for i in 0..array.getSize() { + for i in 0..array.get_size() { // for (int i = 0; i < array.getSize(); i++) { let expected; if i <= 33 { @@ -117,14 +117,14 @@ fn test_get_next_set5() { let numSet = r.gen_range(0..20); for _j in 0..numSet { // for (int j = 0; j < numSet; j++) { - array.set(r.gen_range(0..array.getSize())); + array.set(r.gen_range(0..array.get_size())); } let numQueries = r.gen_range(0..20); for _j in 0..numQueries { // for (int j = 0; j < numQueries; j++) { - let query = r.gen_range(0..array.getSize()); + let query = r.gen_range(0..array.get_size()); let mut expected = query; - while expected < array.getSize() && !array.get(expected) { + while expected < array.get_size() && !array.get(expected) { expected += 1; } let actual = array.getNextSet(query); diff --git a/src/common/bit_array.rs b/src/common/bit_array.rs index 3c64235..225c74c 100644 --- a/src/common/bit_array.rs +++ b/src/common/bit_array.rs @@ -57,7 +57,7 @@ impl BitArray { Self { bits, size } } - pub fn getSize(&self) -> usize { + pub fn get_size(&self) -> usize { self.size } diff --git a/src/common/bit_matrix_test_case.rs b/src/common/bit_matrix_test_case.rs index 4a85ca5..826bb63 100644 --- a/src/common/bit_matrix_test_case.rs +++ b/src/common/bit_matrix_test_case.rs @@ -156,12 +156,12 @@ fn test_get_row() { // Should allocate let array = matrix.getRow(2); - assert_eq!(102, array.getSize()); + assert_eq!(102, array.get_size()); // Should reallocate // let mut array2 = BitArray::with_size(60); let array2 = matrix.getRow(2); - assert_eq!(102, array2.getSize()); + assert_eq!(102, array2.get_size()); // Should use provided object, with original BitArray size // let mut array3 = BitArray::with_size(200); diff --git a/src/common/global_histogram_binarizer.rs b/src/common/global_histogram_binarizer.rs index 44aa580..fee8ad1 100644 --- a/src/common/global_histogram_binarizer.rs +++ b/src/common/global_histogram_binarizer.rs @@ -20,7 +20,7 @@ // import com.google.zxing.LuminanceSource; // import com.google.zxing.NotFoundException; -use std::{borrow::Cow, rc::Rc}; +use std::borrow::Cow; use once_cell::unsync::OnceCell; @@ -29,6 +29,10 @@ use crate::{Binarizer, Exceptions, LuminanceSource}; use super::{BitArray, BitMatrix}; +const LUMINANCE_BITS: usize = 5; +const LUMINANCE_SHIFT: usize = 8 - LUMINANCE_BITS; +const LUMINANCE_BUCKETS: usize = 1 << LUMINANCE_BITS; + /** * This Binarizer implementation uses the old ZXing global histogram approach. It is suitable * for low-end mobile devices which don't have enough CPU or memory to use a local thresholding @@ -40,34 +44,35 @@ use super::{BitArray, BitMatrix}; * @author dswitkin@google.com (Daniel Switkin) * @author Sean Owen */ -pub struct GlobalHistogramBinarizer { +pub struct GlobalHistogramBinarizer { //_luminances: Vec, width: usize, height: usize, - source: Box, + source: LS, black_matrix: OnceCell, black_row_cache: Vec>, } -impl Binarizer for GlobalHistogramBinarizer { - fn getLuminanceSource(&self) -> &Box { +impl Binarizer for GlobalHistogramBinarizer { + type Source = LS; + + fn get_luminance_source(&self) -> &Self::Source { &self.source } // Applies simple sharpening to the row data to improve performance of the 1D Readers. - fn getBlackRow(&self, y: usize) -> Result> { + fn get_black_row(&self, y: usize) -> Result> { let row = self.black_row_cache[y].get_or_try_init(|| { - let source = self.getLuminanceSource(); - let width = source.getWidth(); + let source = self.get_luminance_source(); + let width = source.get_width(); let mut row = BitArray::with_size(width); // self.initArrays(width); - let localLuminances = source.getRow(y); - let mut localBuckets = [0; GlobalHistogramBinarizer::LUMINANCE_BUCKETS]; //self.buckets.clone(); + let localLuminances = source.get_row(y); + let mut localBuckets = [0; LUMINANCE_BUCKETS]; //self.buckets.clone(); for x in 0..width { // for (int x = 0; x < width; x++) { - localBuckets[((localLuminances[x]) >> GlobalHistogramBinarizer::LUMINANCE_SHIFT) - as usize] += 1; + localBuckets[((localLuminances[x]) >> LUMINANCE_SHIFT) as usize] += 1; } let blackPoint = Self::estimateBlackPoint(&localBuckets)?; @@ -102,63 +107,60 @@ impl Binarizer for GlobalHistogramBinarizer { } // Does not sharpen the data, as this call is intended to only be used by 2D Readers. - fn getBlackMatrix(&self) -> Result<&BitMatrix> { + fn get_black_matrix(&self) -> Result<&BitMatrix> { let matrix = self .black_matrix .get_or_try_init(|| Self::build_black_matrix(&self.source))?; Ok(matrix) } - fn createBinarizer(&self, source: Box) -> Rc { - Rc::new(GlobalHistogramBinarizer::new(source)) + fn create_binarizer(&self, source: LS) -> Self { + Self::new(source) } - fn getWidth(&self) -> usize { + fn get_width(&self) -> usize { self.width } - fn getHeight(&self) -> usize { + fn get_height(&self) -> usize { self.height } } -impl GlobalHistogramBinarizer { - const LUMINANCE_BITS: usize = 5; - const LUMINANCE_SHIFT: usize = 8 - GlobalHistogramBinarizer::LUMINANCE_BITS; - const LUMINANCE_BUCKETS: usize = 1 << GlobalHistogramBinarizer::LUMINANCE_BITS; +impl GlobalHistogramBinarizer { // const EMPTY: [u8; 0] = [0; 0]; - pub fn new(source: Box) -> Self { + pub fn new(source: LS) -> Self { Self { //_luminances: vec![0; source.getWidth()], - width: source.getWidth(), - height: source.getHeight(), + width: source.get_width(), + height: source.get_height(), black_matrix: OnceCell::new(), - black_row_cache: vec![OnceCell::default(); source.getHeight()], + black_row_cache: vec![OnceCell::default(); source.get_height()], source, } } - fn build_black_matrix(source: &Box) -> Result { + fn build_black_matrix(source: &LS) -> Result { // let source = source.getLuminanceSource(); - let width = source.getWidth(); - let height = source.getHeight(); + let width = source.get_width(); + let height = source.get_height(); let mut matrix = BitMatrix::new(width as u32, height as u32)?; // Quickly calculates the histogram by sampling four rows from the image. This proved to be // more robust on the blackbox tests than sampling a diagonal as we used to do. // self.initArrays(width); - let mut localBuckets = [0; GlobalHistogramBinarizer::LUMINANCE_BUCKETS]; //self.buckets.clone(); + let mut localBuckets = [0; LUMINANCE_BUCKETS]; //self.buckets.clone(); for y in 1..5 { // for (int y = 1; y < 5; y++) { let row = height * y / 5; - let localLuminances = source.getRow(row); + let localLuminances = source.get_row(row); let right = (width * 4) / 5; let mut x = width / 5; while x < right { // for (int x = width / 5; x < right; x++) { let pixel = localLuminances[x]; - localBuckets[(pixel >> GlobalHistogramBinarizer::LUMINANCE_SHIFT) as usize] += 1; + localBuckets[(pixel >> LUMINANCE_SHIFT) as usize] += 1; x += 1; } } @@ -167,7 +169,7 @@ impl GlobalHistogramBinarizer { // We delay reading the entire image luminance until the black point estimation succeeds. // Although we end up reading four rows twice, it is consistent with our motto of // "fail quickly" which is necessary for continuous scanning. - let localLuminances = source.getMatrix(); + let localLuminances = source.get_matrix(); for y in 0..height { // for (int y = 0; y < height; y++) { let offset = y * width; @@ -255,6 +257,6 @@ impl GlobalHistogramBinarizer { x -= 1; } - Ok((bestValley as u32) << GlobalHistogramBinarizer::LUMINANCE_SHIFT) + Ok((bestValley as u32) << LUMINANCE_SHIFT) } } diff --git a/src/common/hybrid_binarizer.rs b/src/common/hybrid_binarizer.rs index 3bf3004..663e38d 100644 --- a/src/common/hybrid_binarizer.rs +++ b/src/common/hybrid_binarizer.rs @@ -20,7 +20,7 @@ // import com.google.zxing.LuminanceSource; // import com.google.zxing.NotFoundException; -use std::{borrow::Cow, rc::Rc}; +use std::borrow::Cow; use once_cell::unsync::OnceCell; @@ -46,20 +46,22 @@ use super::{BitArray, BitMatrix, GlobalHistogramBinarizer}; * * @author dswitkin@google.com (Daniel Switkin) */ -pub struct HybridBinarizer { +pub struct HybridBinarizer { //width: usize, //height: usize, //source: Box, - ghb: GlobalHistogramBinarizer, + ghb: GlobalHistogramBinarizer, black_matrix: OnceCell, } -impl Binarizer for HybridBinarizer { - fn getLuminanceSource(&self) -> &Box { - self.ghb.getLuminanceSource() +impl Binarizer for HybridBinarizer { + type Source = LS; + + fn get_luminance_source(&self) -> &LS { + self.ghb.get_luminance_source() } - fn getBlackRow(&self, y: usize) -> Result> { - self.ghb.getBlackRow(y) + fn get_black_row(&self, y: usize) -> Result> { + self.ghb.get_black_row(y) } /** @@ -67,35 +69,36 @@ impl Binarizer for HybridBinarizer { * constructor instead, but there are some advantages to doing it lazily, such as making * profiling easier, and not doing heavy lifting when callers don't expect it. */ - fn getBlackMatrix(&self) -> Result<&BitMatrix> { + fn get_black_matrix(&self) -> Result<&BitMatrix> { let matrix = self .black_matrix .get_or_try_init(|| Self::calculateBlackMatrix(&self.ghb))?; Ok(matrix) } - fn createBinarizer(&self, source: Box) -> Rc { - Rc::new(HybridBinarizer::new(source)) + fn create_binarizer(&self, source: LS) -> Self { + Self::new(source) } - fn getWidth(&self) -> usize { - self.ghb.getWidth() + fn get_width(&self) -> usize { + self.ghb.get_width() } - fn getHeight(&self) -> usize { - self.ghb.getHeight() + fn get_height(&self) -> usize { + self.ghb.get_height() } } -impl HybridBinarizer { - // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels. - // So this is the smallest dimension in each axis we can accept. - const BLOCK_SIZE_POWER: usize = 3; - const BLOCK_SIZE: usize = 1 << HybridBinarizer::BLOCK_SIZE_POWER; // ...0100...00 - const BLOCK_SIZE_MASK: usize = HybridBinarizer::BLOCK_SIZE - 1; // ...0011...11 - const MINIMUM_DIMENSION: usize = HybridBinarizer::BLOCK_SIZE * 5; - const MIN_DYNAMIC_RANGE: usize = 24; - pub fn new(source: Box) -> Self { +// This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels. +// So this is the smallest dimension in each axis we can accept. +const BLOCK_SIZE_POWER: usize = 3; +const BLOCK_SIZE: usize = 1 << BLOCK_SIZE_POWER; // ...0100...00 +const BLOCK_SIZE_MASK: usize = BLOCK_SIZE - 1; // ...0011...11 +const MINIMUM_DIMENSION: usize = BLOCK_SIZE * 5; +const MIN_DYNAMIC_RANGE: usize = 24; + +impl HybridBinarizer { + pub fn new(source: LS) -> Self { let ghb = GlobalHistogramBinarizer::new(source); Self { black_matrix: OnceCell::new(), @@ -103,21 +106,21 @@ impl HybridBinarizer { } } - fn calculateBlackMatrix(ghb: &GlobalHistogramBinarizer) -> Result { + fn calculateBlackMatrix( + ghb: &GlobalHistogramBinarizer, + ) -> Result { // let matrix; - let source = ghb.getLuminanceSource(); - let width = source.getWidth(); - let height = source.getHeight(); - let matrix = if width >= HybridBinarizer::MINIMUM_DIMENSION - && height >= HybridBinarizer::MINIMUM_DIMENSION - { - let luminances = source.getMatrix(); - let mut sub_width = width >> HybridBinarizer::BLOCK_SIZE_POWER; - if (width & HybridBinarizer::BLOCK_SIZE_MASK) != 0 { + let source = ghb.get_luminance_source(); + let width = source.get_width(); + let height = source.get_height(); + let matrix = if width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION { + let luminances = source.get_matrix(); + let mut sub_width = width >> BLOCK_SIZE_POWER; + if (width & BLOCK_SIZE_MASK) != 0 { sub_width += 1; } - let mut sub_height = height >> HybridBinarizer::BLOCK_SIZE_POWER; - if (height & HybridBinarizer::BLOCK_SIZE_MASK) != 0 { + let mut sub_height = height >> BLOCK_SIZE_POWER; + if (height & BLOCK_SIZE_MASK) != 0 { sub_height += 1; } let black_points = Self::calculateBlackPoints( @@ -141,7 +144,7 @@ impl HybridBinarizer { Ok(new_matrix) } else { // If the image is too small, fall back to the global histogram approach. - let m = ghb.getBlackMatrix()?; + let m = ghb.get_black_matrix()?; Ok(m.clone()) }; // dbg!(matrix.to_string()); @@ -162,18 +165,18 @@ impl HybridBinarizer { black_points: &[Vec], matrix: &mut BitMatrix, ) { - let maxYOffset = height - HybridBinarizer::BLOCK_SIZE as u32; - let maxXOffset = width - HybridBinarizer::BLOCK_SIZE as u32; + let maxYOffset = height - BLOCK_SIZE as u32; + let maxXOffset = width - BLOCK_SIZE as u32; for y in 0..sub_height { // for (int y = 0; y < subHeight; y++) { - let mut yoffset = y << HybridBinarizer::BLOCK_SIZE_POWER; + let mut yoffset = y << BLOCK_SIZE_POWER; if yoffset > maxYOffset { yoffset = maxYOffset; } let top = Self::cap(y, sub_height - 3); for x in 0..sub_width { // for (int x = 0; x < subWidth; x++) { - let mut xoffset = x << HybridBinarizer::BLOCK_SIZE_POWER; + let mut xoffset = x << BLOCK_SIZE_POWER; if xoffset > maxXOffset { xoffset = maxXOffset; } @@ -215,9 +218,9 @@ impl HybridBinarizer { matrix: &mut BitMatrix, ) { let mut offset = yoffset * stride + xoffset; - for y in 0..HybridBinarizer::BLOCK_SIZE { + for y in 0..BLOCK_SIZE { // for (int y = 0, offset = yoffset * stride + xoffset; y < HybridBinarizer::BLOCK_SIZE; y++, offset += stride) { - for x in 0..HybridBinarizer::BLOCK_SIZE { + for x in 0..BLOCK_SIZE { // for (int x = 0; x < HybridBinarizer::BLOCK_SIZE; x++) { // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0. if luminances[offset as usize + x] as u32 <= threshold { @@ -240,18 +243,18 @@ impl HybridBinarizer { width: u32, height: u32, ) -> Vec> { - let maxYOffset = height as usize - HybridBinarizer::BLOCK_SIZE; - let maxXOffset = width as usize - HybridBinarizer::BLOCK_SIZE; + let maxYOffset = height as usize - BLOCK_SIZE; + let maxXOffset = width as usize - BLOCK_SIZE; let mut blackPoints = vec![vec![0; subWidth as usize]; subHeight as usize]; for y in 0..subHeight { // for (int y = 0; y < subHeight; y++) { - let mut yoffset = y << HybridBinarizer::BLOCK_SIZE_POWER; + let mut yoffset = y << BLOCK_SIZE_POWER; if yoffset > maxYOffset as u32 { yoffset = maxYOffset as u32; } for x in 0..subWidth { // for (int x = 0; x < subWidth; x++) { - let mut xoffset = x << HybridBinarizer::BLOCK_SIZE_POWER; + let mut xoffset = x << BLOCK_SIZE_POWER; if xoffset > maxXOffset as u32 { xoffset = maxXOffset as u32; } @@ -261,9 +264,9 @@ impl HybridBinarizer { let mut offset = yoffset * width + xoffset; let mut yy = 0; - while yy < HybridBinarizer::BLOCK_SIZE { + while yy < BLOCK_SIZE { // for (int yy = 0, offset = yoffset * width + xoffset; yy < HybridBinarizer::BLOCK_SIZE; yy++, offset += width) { - for xx in 0..HybridBinarizer::BLOCK_SIZE { + for xx in 0..BLOCK_SIZE { // for (int xx = 0; xx < HybridBinarizer::BLOCK_SIZE; xx++) { let pixel = luminances[offset as usize + xx]; sum += pixel as u32; @@ -276,13 +279,13 @@ impl HybridBinarizer { } } // short-circuit min/max tests once dynamic range is met - if (max - min) as usize > HybridBinarizer::MIN_DYNAMIC_RANGE { + if (max - min) as usize > MIN_DYNAMIC_RANGE { // finish the rest of the rows quickly offset += width; yy += 1; - while yy < HybridBinarizer::BLOCK_SIZE { + while yy < BLOCK_SIZE { // for (yy++, offset += width; yy < HybridBinarizer::BLOCK_SIZE; yy++, offset += width) { - for xx in 0..HybridBinarizer::BLOCK_SIZE { + for xx in 0..BLOCK_SIZE { // for (int xx = 0; xx < BLOCK_SIZE; xx++) { sum += luminances[offset as usize + xx] as u32; } @@ -296,8 +299,8 @@ impl HybridBinarizer { } // The default estimate is the average of the values in the block. - let mut average = sum >> (HybridBinarizer::BLOCK_SIZE_POWER * 2); - if (max - min) as usize <= HybridBinarizer::MIN_DYNAMIC_RANGE { + let mut average = sum >> (BLOCK_SIZE_POWER * 2); + if (max - min) as usize <= MIN_DYNAMIC_RANGE { // If variation within the block is low, assume this is a block with only light or only // dark pixels. In that case we do not want to use the average, as it would divide this // low contrast area into black and white pixels, essentially creating data out of noise. diff --git a/src/common/otsu_level_binarizer.rs b/src/common/otsu_level_binarizer.rs index bcd5921..cd2de5f 100644 --- a/src/common/otsu_level_binarizer.rs +++ b/src/common/otsu_level_binarizer.rs @@ -19,7 +19,7 @@ pub struct OtsuLevelBinarizer { impl OtsuLevelBinarizer { fn generate_threshold_matrix(source: &dyn LuminanceSource) -> Result { let image_buffer = { - let Some(buff) : Option,Vec>> = ImageBuffer::from_vec(source.getWidth() as u32, source.getHeight() as u32, source.getMatrix()) else { + let Some(buff) : Option,Vec>> = ImageBuffer::from_vec(source.get_width() as u32, source.get_height() as u32, source.get_matrix()) else { return Err(Exceptions::ILLEGAL_ARGUMENT) }; buff @@ -36,9 +36,9 @@ impl OtsuLevelBinarizer { pub fn new(source: Box) -> Self { Self { - width: source.getWidth(), - height: source.getHeight(), - black_row_cache: vec![OnceCell::default(); source.getHeight()], + width: source.get_width(), + height: source.get_height(), + black_row_cache: vec![OnceCell::default(); source.get_height()], source, black_matrix: OnceCell::new(), } @@ -46,38 +46,38 @@ impl OtsuLevelBinarizer { } impl Binarizer for OtsuLevelBinarizer { - fn getLuminanceSource(&self) -> &Box { + fn get_luminance_source(&self) -> &Box { &self.source } - fn getBlackRow(&self, y: usize) -> Result> { + fn get_black_row(&self, y: usize) -> Result> { let row = self.black_row_cache[y].get_or_try_init(|| { - let matrix = self.getBlackMatrix()?; + let matrix = self.get_black_matrix()?; Ok(matrix.getRow(y as u32)) })?; Ok(Cow::Borrowed(row)) } - fn getBlackMatrix(&self) -> Result<&super::BitMatrix> { + fn get_black_matrix(&self) -> Result<&super::BitMatrix> { let matrix = self .black_matrix .get_or_try_init(|| Self::generate_threshold_matrix(self.source.as_ref()))?; Ok(matrix) } - fn createBinarizer( + fn create_binarizer( &self, source: Box, ) -> std::rc::Rc { Rc::new(Self::new(source)) } - fn getWidth(&self) -> usize { + fn get_width(&self) -> usize { self.width } - fn getHeight(&self) -> usize { + fn get_height(&self) -> usize { self.height } } diff --git a/src/datamatrix/data_matrix_reader.rs b/src/datamatrix/data_matrix_reader.rs index 4c1f845..32dff89 100644 --- a/src/datamatrix/data_matrix_reader.rs +++ b/src/datamatrix/data_matrix_reader.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use crate::{ common::{BitMatrix, DecoderRXingResult, DetectorRXingResult, Result}, - BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, RXingResult, + BarcodeFormat, Binarizer, DecodeHintType, DecodeHintValue, Exceptions, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader, }; @@ -52,7 +52,10 @@ impl Reader for DataMatrixReader { * @throws FormatException if a Data Matrix code cannot be decoded * @throws ChecksumException if error correction fails */ - fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { + fn decode( + &mut self, + image: &mut crate::BinaryBitmap, + ) -> Result { self.decode_with_hints(image, &HashMap::new()) } @@ -64,9 +67,9 @@ impl Reader for DataMatrixReader { * @throws FormatException if a Data Matrix code cannot be decoded * @throws ChecksumException if error correction fails */ - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &crate::DecodingHintDictionary, ) -> Result { let try_harder = matches!( @@ -76,14 +79,14 @@ impl Reader for DataMatrixReader { let decoderRXingResult; let mut points = Vec::new(); if hints.contains_key(&DecodeHintType::PURE_BARCODE) { - let bits = self.extractPureBits(image.getBlackMatrix())?; + let bits = self.extractPureBits(image.get_black_matrix())?; decoderRXingResult = DECODER.decode(&bits)?; points.clear(); } else { //Result decoderRXingResult = if let Ok(fnd) = || -> Result { let detectorRXingResult = - zxing_cpp_detector::detect(image.getBlackMatrix(), try_harder, true)?; + zxing_cpp_detector::detect(image.get_black_matrix(), try_harder, true)?; let decoded = DECODER.decode(detectorRXingResult.getBits())?; points = detectorRXingResult.getPoints().to_vec(); Ok(decoded) @@ -91,14 +94,14 @@ impl Reader for DataMatrixReader { fnd } else if try_harder { if let Ok(fnd) = || -> Result { - let detectorRXingResult = Detector::new(image.getBlackMatrix())?.detect()?; + let detectorRXingResult = Detector::new(image.get_black_matrix())?.detect()?; let decoded = DECODER.decode(detectorRXingResult.getBits())?; points = detectorRXingResult.getPoints().to_vec(); Ok(decoded) }() { fnd } else { - let bits = self.extractPureBits(image.getBlackMatrix())?; + let bits = self.extractPureBits(image.get_black_matrix())?; DECODER.decode(&bits)? } } else { diff --git a/src/helpers.rs b/src/helpers.rs index 3843b02..5559bbf 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -2,7 +2,6 @@ use std::{ collections::{HashMap, HashSet}, io::Write, path::PathBuf, - rc::Rc, }; use crate::{ @@ -136,9 +135,7 @@ pub fn detect_in_file_with_hints( .or_insert(DecodeHintValue::TryHarder(true)); multi_format_reader.decode_with_hints( - &mut BinaryBitmap::new(Rc::new(HybridBinarizer::new(Box::new( - BufferedImageLuminanceSource::new(img), - )))), + &mut BinaryBitmap::new(HybridBinarizer::new(BufferedImageLuminanceSource::new(img))), hints, ) } @@ -163,9 +160,7 @@ pub fn detect_multiple_in_file_with_hints( .or_insert(DecodeHintValue::TryHarder(true)); scanner.decode_multiple_with_hints( - &mut BinaryBitmap::new(Rc::new(HybridBinarizer::new(Box::new( - BufferedImageLuminanceSource::new(img), - )))), + &mut BinaryBitmap::new(HybridBinarizer::new(BufferedImageLuminanceSource::new(img))), hints, ) } @@ -200,9 +195,9 @@ pub fn detect_in_luma_with_hints( .or_insert(DecodeHintValue::TryHarder(true)); multi_format_reader.decode_with_hints( - &mut BinaryBitmap::new(Rc::new(HybridBinarizer::new(Box::new( - Luma8LuminanceSource::new(luma, width, height), - )))), + &mut BinaryBitmap::new(HybridBinarizer::new(Luma8LuminanceSource::new( + luma, width, height, + ))), hints, ) } @@ -225,9 +220,9 @@ pub fn detect_multiple_in_luma_with_hints( .or_insert(DecodeHintValue::TryHarder(true)); scanner.decode_multiple_with_hints( - &mut BinaryBitmap::new(Rc::new(HybridBinarizer::new(Box::new( - Luma8LuminanceSource::new(luma, width, height), - )))), + &mut BinaryBitmap::new(HybridBinarizer::new(Luma8LuminanceSource::new( + luma, width, height, + ))), hints, ) } diff --git a/src/luma_luma_source.rs b/src/luma_luma_source.rs index 1d25521..0526a92 100644 --- a/src/luma_luma_source.rs +++ b/src/luma_luma_source.rs @@ -15,7 +15,7 @@ pub struct Luma8LuminanceSource { original_dimension: (u32, u32), } impl LuminanceSource for Luma8LuminanceSource { - fn getRow(&self, y: usize) -> Vec { + fn get_row(&self, y: usize) -> Vec { self.data .chunks_exact(self.original_dimension.0 as usize) .skip(y + self.origin.1 as usize) @@ -27,7 +27,7 @@ impl LuminanceSource for Luma8LuminanceSource { .collect() } - fn getMatrix(&self) -> Vec { + fn get_matrix(&self) -> Vec { self.data .iter() .skip((self.original_dimension.0 * self.origin.1) as usize) @@ -38,7 +38,7 @@ impl LuminanceSource for Luma8LuminanceSource { .flat_map(|f| { f.iter() .skip((self.origin.0) as usize) - .take(self.getWidth()) + .take(self.get_width()) .copied() }) // flatten this all out .copied() // copy it over so that it's u8 @@ -46,11 +46,11 @@ impl LuminanceSource for Luma8LuminanceSource { .collect() // collect into a vec } - fn getWidth(&self) -> usize { + fn get_width(&self) -> usize { self.dimensions.0 as usize } - fn getHeight(&self) -> usize { + fn get_height(&self) -> usize { self.dimensions.1 as usize } @@ -58,31 +58,25 @@ impl LuminanceSource for Luma8LuminanceSource { self.inverted = !self.inverted; } - fn isCropSupported(&self) -> bool { + fn is_crop_supported(&self) -> bool { true } - fn crop( - &self, - left: usize, - top: usize, - width: usize, - height: usize, - ) -> Result> { - Ok(Box::new(Self { + fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result { + Ok(Self { dimensions: (width as u32, height as u32), origin: (left as u32, top as u32), data: self.data.clone(), inverted: self.inverted, original_dimension: self.original_dimension, - })) + }) } - fn isRotateSupported(&self) -> bool { + fn is_rotate_supported(&self) -> bool { true } - fn rotateCounterClockwise(&self) -> Result> { + fn rotate_counter_clockwise(&self) -> Result { let mut new_matrix = Self { dimensions: self.dimensions, origin: self.origin, @@ -92,10 +86,10 @@ impl LuminanceSource for Luma8LuminanceSource { }; new_matrix.transpose(); new_matrix.reverseColumns(); - Ok(Box::new(new_matrix)) + Ok(new_matrix) } - fn rotateCounterClockwise45(&self) -> Result> { + fn rotate_counter_clockwise_45(&self) -> Result { Err(crate::Exceptions::unsupported_operation_with( "This luminance source does not support rotation by 45 degrees.", )) @@ -104,12 +98,12 @@ impl LuminanceSource for Luma8LuminanceSource { impl Luma8LuminanceSource { fn reverseColumns(&mut self) { - for i in 0..self.getWidth() { + for i in 0..self.get_width() { let mut j = 0; - let mut k = self.getWidth() - 1; + let mut k = self.get_width() - 1; while j < k { - let offset_a = (self.getWidth() * i) + j; - let offset_b = (self.getWidth() * i) + k; + let offset_a = (self.get_width() * i) + j; + let offset_b = (self.get_width() * i) + k; self.data.swap(offset_a, offset_b); j += 1; k -= 1; @@ -118,10 +112,10 @@ impl Luma8LuminanceSource { } fn transpose(&mut self) { - for i in 0..self.getHeight() { - for j in i..self.getWidth() { - let offset_a = (self.getWidth() * i) + j; - let offset_b = (self.getWidth() * j) + i; + for i in 0..self.get_height() { + for j in i..self.get_width() { + let offset_a = (self.get_width() * i) + j; + let offset_b = (self.get_width() * j) + i; self.data.swap(offset_a, offset_b); } } diff --git a/src/luminance_source.rs b/src/luminance_source.rs index 022c4ed..9c62d2e 100644 --- a/src/luminance_source.rs +++ b/src/luminance_source.rs @@ -46,7 +46,7 @@ pub trait LuminanceSource { * Always use the returned object, and ignore the .length of the array. * @return An array containing the luminance data. */ - fn getRow(&self, y: usize) -> Vec; + fn get_row(&self, y: usize) -> Vec; /** * Fetches luminance data for the underlying bitmap. Values should be fetched using: @@ -56,22 +56,22 @@ pub trait LuminanceSource { * larger than width * height bytes on some platforms. Do not modify the contents * of the result. */ - fn getMatrix(&self) -> Vec; + fn get_matrix(&self) -> Vec; /** * @return The width of the bitmap. */ - fn getWidth(&self) -> usize; + fn get_width(&self) -> usize; /** * @return The height of the bitmap. */ - fn getHeight(&self) -> usize; + fn get_height(&self) -> usize; /** * @return Whether this subclass supports cropping. */ - fn isCropSupported(&self) -> bool { + fn is_crop_supported(&self) -> bool { false } @@ -85,13 +85,10 @@ pub trait LuminanceSource { * @param height The height of the rectangle to crop. * @return A cropped version of this object. */ - fn crop( - &self, - _left: usize, - _top: usize, - _width: usize, - _height: usize, - ) -> Result> { + fn crop(&self, _left: usize, _top: usize, _width: usize, _height: usize) -> Result + where + Self: Sized, + { Err(Exceptions::unsupported_operation_with( "This luminance source does not support cropping.", )) @@ -100,7 +97,7 @@ pub trait LuminanceSource { /** * @return Whether this subclass supports counter-clockwise rotation. */ - fn isRotateSupported(&self) -> bool { + fn is_rotate_supported(&self) -> bool { false } @@ -118,7 +115,10 @@ pub trait LuminanceSource { * * @return A rotated version of this object. */ - fn rotateCounterClockwise(&self) -> Result> { + fn rotate_counter_clockwise(&self) -> Result + where + Self: Sized, + { Err(Exceptions::unsupported_operation_with( "This luminance source does not support rotation by 90 degrees.", )) @@ -130,7 +130,10 @@ pub trait LuminanceSource { * * @return A rotated version of this object. */ - fn rotateCounterClockwise45(&self) -> Result> { + fn rotate_counter_clockwise_45(&self) -> Result + where + Self: Sized, + { Err(Exceptions::unsupported_operation_with( "This luminance source does not support rotation by 45 degrees.", )) diff --git a/src/maxicode/detector.rs b/src/maxicode/detector.rs index f2015ff..11a475e 100644 --- a/src/maxicode/detector.rs +++ b/src/maxicode/detector.rs @@ -1144,7 +1144,7 @@ mod detector_test { let img = image::open(filename).unwrap(); let lum_src = BufferedImageLuminanceSource::new(img); let binarizer = HybridBinarizer::new(Box::new(lum_src)); - let bitmatrix = binarizer.getBlackMatrix().unwrap(); + let bitmatrix = binarizer.get_black_matrix().unwrap(); // let i: image::DynamicImage = bitmatrix.into(); // i.save("dbgfle.png").expect("should write image"); diff --git a/src/maxicode/maxi_code_reader.rs b/src/maxicode/maxi_code_reader.rs index 7b331ba..8b3cc18 100644 --- a/src/maxicode/maxi_code_reader.rs +++ b/src/maxicode/maxi_code_reader.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use crate::{ common::{BitMatrix, DetectorRXingResult, Result}, - BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, RXingResult, + BarcodeFormat, Binarizer, DecodeHintType, DecodeHintValue, Exceptions, RXingResult, RXingResultMetadataType, Reader, }; @@ -41,7 +41,10 @@ impl Reader for MaxiCodeReader { * @throws FormatException if a MaxiCode cannot be decoded * @throws ChecksumException if error correction fails */ - fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { + fn decode( + &mut self, + image: &mut crate::BinaryBitmap, + ) -> Result { self.decode_with_hints(image, &HashMap::new()) } @@ -53,9 +56,9 @@ impl Reader for MaxiCodeReader { * @throws FormatException if a MaxiCode cannot be decoded * @throws ChecksumException if error correction fails */ - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &crate::DecodingHintDictionary, ) -> Result { // Note that MaxiCode reader effectively always assumes PURE_BARCODE mode @@ -68,12 +71,12 @@ impl Reader for MaxiCodeReader { let mut rotation = None; let decoderRXingResult = if try_harder { - let result = detector::detect(image.getBlackMatrixMut(), try_harder)?; + let result = detector::detect(image.get_black_matrix_mut(), try_harder)?; rotation = Some(result.rotation()); let parsed_result = detector::read_bits(result.getBits())?; maxicode_decoder::decode_with_hints(&parsed_result, hints)? } else { - let bits = Self::extractPureBits(image.getBlackMatrix())?; + let bits = Self::extractPureBits(image.get_black_matrix())?; maxicode_decoder::decode_with_hints(&bits, hints)? }; diff --git a/src/multi/by_quadrant_reader.rs b/src/multi/by_quadrant_reader.rs index 348124c..e8aa165 100644 --- a/src/multi/by_quadrant_reader.rs +++ b/src/multi/by_quadrant_reader.rs @@ -17,7 +17,7 @@ use std::collections::HashMap; use crate::common::Result; -use crate::{point, Exceptions, Point, RXingResult, Reader}; +use crate::{point, Binarizer, Exceptions, Point, RXingResult, Reader}; /** * This class attempts to decode a barcode from an image, not by scanning the whole image, @@ -30,17 +30,17 @@ use crate::{point, Exceptions, Point, RXingResult, Reader}; */ pub struct ByQuadrantReader(T); impl Reader for ByQuadrantReader { - fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { self.decode_with_hints(image, &HashMap::new()) } - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &crate::DecodingHintDictionary, ) -> Result { - let width = image.getWidth(); - let height = image.getHeight(); + let width = image.get_width(); + let height = image.get_height(); let halfWidth = width / 2; let halfHeight = height / 2; diff --git a/src/multi/generic_multiple_barcode_reader.rs b/src/multi/generic_multiple_barcode_reader.rs index ddd6b81..cac49b5 100644 --- a/src/multi/generic_multiple_barcode_reader.rs +++ b/src/multi/generic_multiple_barcode_reader.rs @@ -17,8 +17,8 @@ use std::collections::HashMap; use crate::{ - common::Result, point, BinaryBitmap, DecodingHintDictionary, Exceptions, Point, RXingResult, - Reader, + common::Result, point, Binarizer, BinaryBitmap, DecodingHintDictionary, Exceptions, Point, + RXingResult, Reader, }; use super::MultipleBarcodeReader; @@ -41,20 +41,20 @@ use super::MultipleBarcodeReader; pub struct GenericMultipleBarcodeReader(T); impl MultipleBarcodeReader for GenericMultipleBarcodeReader { - fn decode_multiple( + fn decode_multiple( &mut self, - image: &mut crate::BinaryBitmap, - ) -> Result> { + image: &mut BinaryBitmap, + ) -> Result> { self.decode_multiple_with_hints(image, &HashMap::new()) } - fn decode_multiple_with_hints( + fn decode_multiple_with_hints( &mut self, - image: &mut crate::BinaryBitmap, - hints: &crate::DecodingHintDictionary, - ) -> Result> { + image: &mut BinaryBitmap, + hints: &DecodingHintDictionary, + ) -> Result> { let mut results = Vec::new(); - self.doDecodeMultiple(image, hints, &mut results, 0, 0, 0); + self.do_decode_multiple(image, hints, &mut results, 0, 0, 0); if results.is_empty() { return Err(Exceptions::NOT_FOUND); } @@ -69,9 +69,9 @@ impl GenericMultipleBarcodeReader { Self(delegate) } - fn doDecodeMultiple( + fn do_decode_multiple( &mut self, - image: &mut BinaryBitmap, + image: &mut BinaryBitmap, hints: &DecodingHintDictionary, results: &mut Vec, xOffset: u32, @@ -105,8 +105,8 @@ impl GenericMultipleBarcodeReader { return; } - let width = image.getWidth(); - let height = image.getHeight(); + let width = image.get_width(); + let height = image.get_height(); let mut minX: f32 = width as f32; let mut minY: f32 = height as f32; let mut maxX: f32 = 0.0; @@ -133,7 +133,7 @@ impl GenericMultipleBarcodeReader { // Decode left of barcode if minX > Self::MIN_DIMENSION_TO_RECUR { - self.doDecodeMultiple( + self.do_decode_multiple( &mut image.crop(0, 0, minX as usize, height), hints, results, @@ -144,7 +144,7 @@ impl GenericMultipleBarcodeReader { } // Decode above barcode if minY > Self::MIN_DIMENSION_TO_RECUR { - self.doDecodeMultiple( + self.do_decode_multiple( &mut image.crop(0, 0, width, minY as usize), hints, results, @@ -155,7 +155,7 @@ impl GenericMultipleBarcodeReader { } // Decode right of barcode if maxX < (width as f32) - Self::MIN_DIMENSION_TO_RECUR { - self.doDecodeMultiple( + self.do_decode_multiple( &mut image.crop(maxX as usize, 0, width - maxX as usize, height), hints, results, @@ -166,7 +166,7 @@ impl GenericMultipleBarcodeReader { } // Decode below barcode if maxY < (height as f32) - Self::MIN_DIMENSION_TO_RECUR { - self.doDecodeMultiple( + self.do_decode_multiple( &mut image.crop(0, maxY as usize, width, height - maxY as usize), hints, results, diff --git a/src/multi/multiple_barcode_reader.rs b/src/multi/multiple_barcode_reader.rs index 191d23b..3037b0b 100644 --- a/src/multi/multiple_barcode_reader.rs +++ b/src/multi/multiple_barcode_reader.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use crate::{common::Result, BinaryBitmap, DecodingHintDictionary, RXingResult}; +use crate::{common::Result, Binarizer, BinaryBitmap, DecodingHintDictionary, RXingResult}; /** * Implementation of this interface attempt to read several barcodes from one image. @@ -23,11 +23,14 @@ use crate::{common::Result, BinaryBitmap, DecodingHintDictionary, RXingResult}; * @author Sean Owen */ pub trait MultipleBarcodeReader { - fn decode_multiple(&mut self, image: &mut BinaryBitmap) -> Result>; - - fn decode_multiple_with_hints( + fn decode_multiple( &mut self, - image: &mut BinaryBitmap, + image: &mut BinaryBitmap, + ) -> Result>; + + fn decode_multiple_with_hints( + &mut self, + image: &mut BinaryBitmap, hints: &DecodingHintDictionary, ) -> Result>; } diff --git a/src/multi/qrcode/qr_code_multi_reader.rs b/src/multi/qrcode/qr_code_multi_reader.rs index 3500138..4c36afc 100644 --- a/src/multi/qrcode/qr_code_multi_reader.rs +++ b/src/multi/qrcode/qr_code_multi_reader.rs @@ -23,7 +23,8 @@ use crate::{ decoder::{self, QRCodeDecoderMetaData}, QRCodeReader, }, - BarcodeFormat, Exceptions, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, + BarcodeFormat, Binarizer, Exceptions, RXingResult, RXingResultMetadataType, + RXingResultMetadataValue, }; use super::detector::MultiDetector; @@ -37,20 +38,21 @@ use super::detector::MultiDetector; #[derive(Default)] pub struct QRCodeMultiReader(QRCodeReader); impl MultipleBarcodeReader for QRCodeMultiReader { - fn decode_multiple( + fn decode_multiple( &mut self, - image: &mut crate::BinaryBitmap, - ) -> Result> { + image: &mut crate::BinaryBitmap, + ) -> Result> { self.decode_multiple_with_hints(image, &HashMap::new()) } - fn decode_multiple_with_hints( + fn decode_multiple_with_hints( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &crate::DecodingHintDictionary, - ) -> Result> { + ) -> Result> { let mut results = Vec::new(); - let detectorRXingResults = MultiDetector::new(image.getBlackMatrix()).detectMulti(hints)?; + let detectorRXingResults = + MultiDetector::new(image.get_black_matrix()).detectMulti(hints)?; for detectorRXingResult in detectorRXingResults { let mut proc = || -> Result<()> { let decoderRXingResult = decoder::qrcode_decoder::decode_bitmatrix_with_hints( diff --git a/src/multi_format_reader.rs b/src/multi_format_reader.rs index 14b7951..a534354 100644 --- a/src/multi_format_reader.rs +++ b/src/multi_format_reader.rs @@ -14,14 +14,14 @@ * limitations under the License. */ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use crate::common::Result; use crate::{ aztec::AztecReader, datamatrix::DataMatrixReader, maxicode::MaxiCodeReader, oned::MultiFormatOneDReader, pdf417::PDF417Reader, qrcode::QRCodeReader, BarcodeFormat, - BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, RXingResult, - Reader, + Binarizer, BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary, Exceptions, + RXingResult, Reader, }; /** @@ -35,7 +35,8 @@ use crate::{ #[derive(Default)] pub struct MultiFormatReader { hints: DecodingHintDictionary, - readers: Vec>, + possible_formats: HashSet, + try_harder: bool, } impl Reader for MultiFormatReader { @@ -48,8 +49,8 @@ impl Reader for MultiFormatReader { * @return The contents of the image * @throws NotFoundException Any errors which occurred */ - fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { - self.set_ints(&HashMap::new()); + fn decode(&mut self, image: &mut BinaryBitmap) -> Result { + self.set_hints(&HashMap::new()); self.decode_internal(image) } @@ -61,20 +62,14 @@ impl Reader for MultiFormatReader { * @return The contents of the image * @throws NotFoundException Any errors which occurred */ - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut crate::BinaryBitmap, - hints: &crate::DecodingHintDictionary, - ) -> Result { - self.set_ints(hints); + image: &mut BinaryBitmap, + hints: &DecodingHintDictionary, + ) -> Result { + self.set_hints(hints); self.decode_internal(image) } - - fn reset(&mut self) { - for reader in self.readers.iter_mut() { - reader.reset(); - } - } } impl MultiFormatReader { @@ -86,10 +81,13 @@ impl MultiFormatReader { * @return The contents of the image * @throws NotFoundException Any errors which occurred */ - pub fn decode_with_state(&mut self, image: &mut BinaryBitmap) -> Result { + pub fn decode_with_state( + &mut self, + image: &mut BinaryBitmap, + ) -> Result { // Make sure to set up the default state so we don't crash - if self.readers.is_empty() { - self.set_ints(&HashMap::new()); + if self.possible_formats.is_empty() { + self.set_hints(&HashMap::new()); } self.decode_internal(image) } @@ -101,92 +99,130 @@ impl MultiFormatReader { * * @param hints The set of hints to use for subsequent calls to decode(image) */ - pub fn set_ints(&mut self, hints: &DecodingHintDictionary) { + pub fn set_hints(&mut self, hints: &DecodingHintDictionary) { self.hints = hints.clone(); - let tryHarder = matches!( + self.try_harder = matches!( self.hints.get(&DecodeHintType::TRY_HARDER), Some(DecodeHintValue::TryHarder(true)) ); - - let formats = hints.get(&DecodeHintType::POSSIBLE_FORMATS); - let mut readers: Vec> = Vec::new(); - if let Some(DecodeHintValue::PossibleFormats(formats)) = formats { - let addOneDReader = formats.contains(&BarcodeFormat::UPC_A) - || formats.contains(&BarcodeFormat::UPC_E) - || formats.contains(&BarcodeFormat::EAN_13) - || formats.contains(&BarcodeFormat::EAN_8) - || formats.contains(&BarcodeFormat::CODABAR) - || formats.contains(&BarcodeFormat::CODE_39) - || formats.contains(&BarcodeFormat::CODE_93) - || formats.contains(&BarcodeFormat::CODE_128) - || formats.contains(&BarcodeFormat::ITF) - || formats.contains(&BarcodeFormat::RSS_14) - || formats.contains(&BarcodeFormat::RSS_EXPANDED); - // Put 1D readers upfront in "normal" mode - if addOneDReader && !tryHarder { - readers.push(Box::new(MultiFormatOneDReader::new(hints))); - } - if formats.contains(&BarcodeFormat::QR_CODE) { - readers.push(Box::::default()); - } - if formats.contains(&BarcodeFormat::DATA_MATRIX) { - readers.push(Box::::default()); - } - if formats.contains(&BarcodeFormat::AZTEC) { - readers.push(Box::::default()); - } - if formats.contains(&BarcodeFormat::PDF_417) { - readers.push(Box::::default()); - } - if formats.contains(&BarcodeFormat::MAXICODE) { - readers.push(Box::::default()); - } - // At end in "try harder" mode - if addOneDReader && tryHarder { - readers.push(Box::new(MultiFormatOneDReader::new(hints))); - } - } - if readers.is_empty() { - if !tryHarder { - readers.push(Box::new(MultiFormatOneDReader::new(hints))); - } - - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::default()); - - if tryHarder { - readers.push(Box::new(MultiFormatOneDReader::new(hints))); - } - } - self.readers = readers; + self.possible_formats = if let Some(DecodeHintValue::PossibleFormats(formats)) = + hints.get(&DecodeHintType::POSSIBLE_FORMATS) + { + formats.clone() + } else { + HashSet::new() + }; } - pub fn decode_internal(&mut self, image: &mut BinaryBitmap) -> Result { - if !self.readers.is_empty() { - for reader in self.readers.iter_mut() { - let res = reader.decode_with_hints(image, &self.hints); - if res.is_ok() { - return res; - } + pub fn decode_internal( + &mut self, + image: &mut BinaryBitmap, + ) -> Result { + if !self.possible_formats.is_empty() { + let res = self.decode_formats(image); + if res.is_ok() { + return res; } if matches!( self.hints.get(&DecodeHintType::ALSO_INVERTED), Some(DecodeHintValue::AlsoInverted(true)) ) { // Calling all readers again with inverted image - image.getBlackMatrixMut().flip_self(); - for reader in self.readers.iter_mut() { - let res = reader.decode_with_hints(image, &self.hints); - if res.is_ok() { - return res; - } + image.get_black_matrix_mut().flip_self(); + let res = self.decode_formats(image); + if res.is_ok() { + return res; } } } Err(Exceptions::NOT_FOUND) } + + fn decode_formats(&self, image: &mut BinaryBitmap) -> Result { + if !self.possible_formats.is_empty() { + let one_d = self.possible_formats.contains(&BarcodeFormat::UPC_A) + || self.possible_formats.contains(&BarcodeFormat::UPC_E) + || self.possible_formats.contains(&BarcodeFormat::EAN_13) + || self.possible_formats.contains(&BarcodeFormat::EAN_8) + || self.possible_formats.contains(&BarcodeFormat::CODABAR) + || self.possible_formats.contains(&BarcodeFormat::CODE_39) + || self.possible_formats.contains(&BarcodeFormat::CODE_93) + || self.possible_formats.contains(&BarcodeFormat::CODE_128) + || self.possible_formats.contains(&BarcodeFormat::ITF) + || self.possible_formats.contains(&BarcodeFormat::RSS_14) + || self.possible_formats.contains(&BarcodeFormat::RSS_EXPANDED); + if one_d && !self.try_harder { + if let Ok(res) = + MultiFormatOneDReader::new(&self.hints).decode_with_hints(image, &self.hints) + { + return Ok(res); + } + } + for possible_format in self.possible_formats.iter() { + let res = match possible_format { + BarcodeFormat::QR_CODE => { + QRCodeReader::default().decode_with_hints(image, &self.hints) + } + BarcodeFormat::DATA_MATRIX => { + DataMatrixReader::default().decode_with_hints(image, &self.hints) + } + BarcodeFormat::AZTEC => { + AztecReader::default().decode_with_hints(image, &self.hints) + } + BarcodeFormat::PDF_417 => { + PDF417Reader::default().decode_with_hints(image, &self.hints) + } + BarcodeFormat::MAXICODE => { + MaxiCodeReader::default().decode_with_hints(image, &self.hints) + } + _ => Err(Exceptions::UNSUPPORTED_OPERATION), + }; + if res.is_ok() { + return res; + } + } + if one_d && self.try_harder { + if let Ok(res) = + MultiFormatOneDReader::new(&self.hints).decode_with_hints(image, &self.hints) + { + return Ok(res); + } + } + } else { + if !self.try_harder { + if let Ok(res) = + MultiFormatOneDReader::new(&self.hints).decode_with_hints(image, &self.hints) + { + return Ok(res); + } + } + + if let Ok(res) = QRCodeReader::default().decode_with_hints(image, &self.hints) { + return Ok(res); + } + if let Ok(res) = DataMatrixReader::default().decode_with_hints(image, &self.hints) { + return Ok(res); + } + if let Ok(res) = AztecReader::default().decode_with_hints(image, &self.hints) { + return Ok(res); + } + if let Ok(res) = PDF417Reader::default().decode_with_hints(image, &self.hints) { + return Ok(res); + } + if let Ok(res) = MaxiCodeReader::default().decode_with_hints(image, &self.hints) { + return Ok(res); + } + + if self.try_harder { + if let Ok(res) = + MultiFormatOneDReader::new(&self.hints).decode_with_hints(image, &self.hints) + { + return Ok(res); + } + } + } + + Err(Exceptions::UNSUPPORTED_OPERATION) + } } diff --git a/src/oned/coda_bar_reader.rs b/src/oned/coda_bar_reader.rs index e8d88e5..affcdff 100644 --- a/src/oned/coda_bar_reader.rs +++ b/src/oned/coda_bar_reader.rs @@ -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); } diff --git a/src/oned/code_128_reader.rs b/src/oned/code_128_reader.rs index bbf46e2..ae5a0ce 100644 --- a/src/oned/code_128_reader.rs +++ b/src/oned/code_128_reader.rs @@ -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 { - 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; diff --git a/src/oned/code_128_writer_test_tase.rs b/src/oned/code_128_writer_test_tase.rs index e82a838..fddb687 100644 --- a/src/oned/code_128_writer_test_tase.rs +++ b/src/oned/code_128_writer_test_tase.rs @@ -483,18 +483,18 @@ fn encode(toEncode: &str, compact: bool, expectedLoopback: &str) -> Result Result> { - 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()); } } diff --git a/src/oned/code_93_reader.rs b/src/oned/code_93_reader.rs index 75b18b3..168b8b8 100644 --- a/src/oned/code_93_reader.rs +++ b/src/oned/code_93_reader.rs @@ -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()); } diff --git a/src/oned/ean_13_reader.rs b/src/oned/ean_13_reader.rs index 8c589bf..4984d54 100644 --- a/src/oned/ean_13_reader.rs +++ b/src/oned/ean_13_reader.rs @@ -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; diff --git a/src/oned/ean_8_reader.rs b/src/oned/ean_8_reader.rs index 99a76be..fc708b2 100644 --- a/src/oned/ean_8_reader.rs +++ b/src/oned/ean_8_reader.rs @@ -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; diff --git a/src/oned/itf_reader.rs b/src/oned/itf_reader.rs index efe6625..f4e890e 100644 --- a/src/oned/itf_reader.rs +++ b/src/oned/itf_reader.rs @@ -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 { - 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; diff --git a/src/oned/multi_format_one_d_reader.rs b/src/oned/multi_format_one_d_reader.rs index 9647b1a..0977ec5 100644 --- a/src/oned/multi_format_one_d_reader.rs +++ b/src/oned/multi_format_one_d_reader.rs @@ -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>); +pub struct MultiFormatOneDReader { + internal_hints: DecodingHintDictionary, + possible_formats: HashSet, + 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 { - for reader in self.0.iter_mut() { - if let Ok(res) = reader.decodeRow(rowNumber, row, hints) { + hints: &DecodingHintDictionary, + ) -> Result { + // 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> = 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::::default()); - } - if possibleFormats.contains(&BarcodeFormat::CODE_128) { - readers.push(Box::::default()); - } - if possibleFormats.contains(&BarcodeFormat::ITF) { - readers.push(Box::::default()); - } - if possibleFormats.contains(&BarcodeFormat::CODABAR) { - readers.push(Box::::default()); - } - if possibleFormats.contains(&BarcodeFormat::RSS_14) { - readers.push(Box::::default()); - } - if possibleFormats.contains(&BarcodeFormat::RSS_EXPANDED) { - readers.push(Box::::default()); - } - } - if readers.is_empty() { - readers.push(Box::new(MultiFormatUPCEANReader::new(hints))); - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::default()); - readers.push(Box::::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 { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { 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( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &DecodingHintDictionary, - ) -> Result { - let first_try = self.doDecode(image, hints); + ) -> Result { + 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(); - } - } } diff --git a/src/oned/multi_format_upc_ean_reader.rs b/src/oned/multi_format_upc_ean_reader.rs index 2743157..956dbc7 100644 --- a/src/oned/multi_format_upc_ean_reader.rs +++ b/src/oned/multi_format_upc_ean_reader.rs @@ -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>); +pub struct MultiFormatUPCEANReader { + possible_formats: HashSet, +} + +impl OneDReader for MultiFormatUPCEANReader { + fn decode_row( + &mut self, + rowNumber: u32, + row: &crate::common::BitArray, + hints: &DecodingHintDictionary, + ) -> Result { + 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> = Vec::new(); - if let Some(DecodeHintValue::PossibleFormats(possibleFormats)) = + let possible_formats = if let Some(DecodeHintValue::PossibleFormats(p)) = hints.get(&DecodeHintType::POSSIBLE_FORMATS) { - // Collection possibleFormats = hints == null ? null : - // (Collection) hints.get(DecodeHintType.POSSIBLE_FORMATS); - // Collection readers = new ArrayList<>(); - if possibleFormats.contains(&BarcodeFormat::EAN_13) { - readers.push(Box::::default()); - } else if possibleFormats.contains(&BarcodeFormat::UPC_A) { - readers.push(Box::::default()); - } - if possibleFormats.contains(&BarcodeFormat::EAN_8) { - readers.push(Box::::default()); - } - if possibleFormats.contains(&BarcodeFormat::UPC_E) { - readers.push(Box::::default()); - } - } - if readers.is_empty() { - readers.push(Box::::default()); - // UPC-A is covered by EAN-13 - readers.push(Box::::default()); - readers.push(Box::::default()); - } + p.clone() + } else { + HashSet::default() + }; - Self(readers) + Self { possible_formats } } - fn try_decode_function( + fn try_decode_function( &self, - reader: &Box, + reader: &R, rowNumber: u32, row: &crate::common::BitArray, - hints: &crate::DecodingHintDictionary, + hints: &DecodingHintDictionary, startGuardPattern: &[usize; 2], - ) -> Result { + ) -> Result { 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 { - // 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 { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { 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( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &DecodingHintDictionary, - ) -> Result { - let first_try = self.doDecode(image, hints); + ) -> Result { + 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(); - } - } } diff --git a/src/oned/one_d_reader.rs b/src/oned/one_d_reader.rs index 7fc96dd..6e3e541 100644 --- a/src/oned/one_d_reader.rs +++ b/src/oned/one_d_reader.rs @@ -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( &mut self, - image: &mut BinaryBitmap, + image: &mut BinaryBitmap, hints: &DecodingHintDictionary, ) -> Result { 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(()) } diff --git a/src/oned/rss/abstract_rss_reader.rs b/src/oned/rss/abstract_rss_reader.rs index fe3fd1c..be51cc8 100644 --- a/src/oned/rss/abstract_rss_reader.rs +++ b/src/oned/rss/abstract_rss_reader.rs @@ -33,8 +33,11 @@ pub trait AbstractRSSReaderTrait: OneDReader { fn parseFinderValue(counters: &[u32], finderPatterns: &[[u32; 4]]) -> Result { 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); } diff --git a/src/oned/rss/expanded/decoders/ai_01392x_decoder.rs b/src/oned/rss/expanded/decoders/ai_01392x_decoder.rs index 6673bbf..1c507e2 100644 --- a/src/oned/rss/expanded/decoders/ai_01392x_decoder.rs +++ b/src/oned/rss/expanded/decoders/ai_01392x_decoder.rs @@ -38,7 +38,7 @@ pub struct AI01392xDecoder<'a> { impl AI01decoder for AI01392xDecoder<'_> {} impl AbstractExpandedDecoder for AI01392xDecoder<'_> { fn parseInformation(&mut self) -> Result { - 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); } diff --git a/src/oned/rss/expanded/decoders/ai_01393x_decoder.rs b/src/oned/rss/expanded/decoders/ai_01393x_decoder.rs index ea47e60..57ce704 100644 --- a/src/oned/rss/expanded/decoders/ai_01393x_decoder.rs +++ b/src/oned/rss/expanded/decoders/ai_01393x_decoder.rs @@ -38,7 +38,7 @@ pub struct AI01393xDecoder<'a> { impl AI01decoder for AI01393xDecoder<'_> {} impl AbstractExpandedDecoder for AI01393xDecoder<'_> { fn parseInformation(&mut self) -> Result { - 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); } diff --git a/src/oned/rss/expanded/decoders/ai_013x0x1x_decoder.rs b/src/oned/rss/expanded/decoders/ai_013x0x1x_decoder.rs index f18ccd3..097f3e3 100644 --- a/src/oned/rss/expanded/decoders/ai_013x0x1x_decoder.rs +++ b/src/oned/rss/expanded/decoders/ai_013x0x1x_decoder.rs @@ -54,7 +54,7 @@ impl AI01weightDecoder for AI013x0x1xDecoder<'_> { impl AI01decoder for AI013x0x1xDecoder<'_> {} impl AbstractExpandedDecoder for AI013x0x1xDecoder<'_> { fn parseInformation(&mut self) -> Result { - 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); diff --git a/src/oned/rss/expanded/decoders/ai_013x0x_decoder.rs b/src/oned/rss/expanded/decoders/ai_013x0x_decoder.rs index 9161e12..6e6f473 100644 --- a/src/oned/rss/expanded/decoders/ai_013x0x_decoder.rs +++ b/src/oned/rss/expanded/decoders/ai_013x0x_decoder.rs @@ -50,7 +50,7 @@ impl AI01weightDecoder for AI013x0xDecoder<'_> { } impl AbstractExpandedDecoder for AI013x0xDecoder<'_> { fn parseInformation(&mut self) -> Result { - 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); diff --git a/src/oned/rss/expanded/decoders/general_app_id_decoder.rs b/src/oned/rss/expanded/decoders/general_app_id_decoder.rs index 9226796..8d14fbc 100644 --- a/src/oned/rss/expanded/decoders/general_app_id_decoder.rs +++ b/src/oned/rss/expanded/decoders/general_app_id_decoder.rs @@ -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 { - 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; } diff --git a/src/oned/rss/expanded/rss_expanded_image_2_binary_test_tase.rs b/src/oned/rss/expanded/rss_expanded_image_2_binary_test_tase.rs index 4da6bed..3e64023 100644 --- a/src/oned/rss/expanded/rss_expanded_image_2_binary_test_tase.rs +++ b/src/oned/rss/expanded/rss_expanded_image_2_binary_test_tase.rs @@ -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 { diff --git a/src/oned/rss/expanded/rss_expanded_image_2_result_test_case.rs b/src/oned/rss/expanded/rss_expanded_image_2_result_test_case.rs index f8290ff..cc3c3d5 100644 --- a/src/oned/rss/expanded/rss_expanded_image_2_result_test_case.rs +++ b/src/oned/rss/expanded/rss_expanded_image_2_result_test_case.rs @@ -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!( diff --git a/src/oned/rss/expanded/rss_expanded_image_2_string_test_case.rs b/src/oned/rss/expanded/rss_expanded_image_2_string_test_case.rs index 27becda..2b1729b 100644 --- a/src/oned/rss/expanded/rss_expanded_image_2_string_test_case.rs +++ b/src/oned/rss/expanded/rss_expanded_image_2_string_test_case.rs @@ -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()); diff --git a/src/oned/rss/expanded/rss_expanded_internal_test_case.rs b/src/oned/rss/expanded/rss_expanded_internal_test_case.rs index c05b31f..0712c44 100644 --- a/src/oned/rss/expanded/rss_expanded_internal_test_case.rs +++ b/src/oned/rss/expanded/rss_expanded_internal_test_case.rs @@ -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) diff --git a/src/oned/rss/expanded/rss_expanded_reader.rs b/src/oned/rss/expanded/rss_expanded_reader.rs index 97ce504..1f49325 100644 --- a/src/oned/rss/expanded/rss_expanded_reader.rs +++ b/src/oned/rss/expanded/rss_expanded_reader.rs @@ -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 { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { 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( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &DecodingHintDictionary, ) -> Result { - 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; diff --git a/src/oned/rss/expanded/rss_expanded_stacked_internal_test_case.rs b/src/oned/rss/expanded/rss_expanded_stacked_internal_test_case.rs index 3affb4f..0a737dd 100644 --- a/src/oned/rss/expanded/rss_expanded_stacked_internal_test_case.rs +++ b/src/oned/rss/expanded/rss_expanded_stacked_internal_test_case.rs @@ -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(); diff --git a/src/oned/rss/rss_14_reader.rs b/src/oned/rss/rss_14_reader.rs index 056e69e..865fcf6 100644 --- a/src/oned/rss/rss_14_reader.rs +++ b/src/oned/rss/rss_14_reader.rs @@ -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 { + row: &BitArray, + hints: &DecodingHintDictionary, + ) -> Result { 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 { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { 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( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &DecodingHintDictionary, ) -> Result { - 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( diff --git a/src/oned/upc_a_reader.rs b/src/oned/upc_a_reader.rs index db225e1..16cb2b0 100644 --- a/src/oned/upc_a_reader.rs +++ b/src/oned/upc_a_reader.rs @@ -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 { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { Self::maybeReturnRXingResult(self.0.decode(image)?) } - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &crate::DecodingHintDictionary, - ) -> Result { + ) -> Result { 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 { - Self::maybeReturnRXingResult(self.0.decodeRow(rowNumber, row, hints)?) + ) -> Result { + 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 + 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 { self.0.decodeMiddle(row, startRange, resultString) } - - fn decodeRowWithGuardRange( - &self, - rowNumber: u32, - row: &crate::common::BitArray, - startGuardRange: &[usize; 2], - hints: &crate::DecodingHintDictionary, - ) -> Result - where - Self: Sized, - { - Self::maybeReturnRXingResult(self.0.decodeRowWithGuardRange( - rowNumber, - row, - startGuardRange, - hints, - )?) - } } impl UPCAReader { diff --git a/src/oned/upc_e_reader.rs b/src/oned/upc_e_reader.rs index 19fe337..d71f826 100644 --- a/src/oned/upc_e_reader.rs +++ b/src/oned/upc_e_reader.rs @@ -41,7 +41,7 @@ impl UPCEANReader for UPCEReader { ) -> Result { let mut counters = [0_u32; 4]; - let end = row.getSize(); + let end = row.get_size(); let mut rowOffset = startRange[1]; let mut lgPatternFound = 0; diff --git a/src/oned/upc_ean_extension_2_support.rs b/src/oned/upc_ean_extension_2_support.rs index 4bf5e8a..7e3cd4c 100644 --- a/src/oned/upc_ean_extension_2_support.rs +++ b/src/oned/upc_ean_extension_2_support.rs @@ -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; diff --git a/src/oned/upc_ean_extension_5_support.rs b/src/oned/upc_ean_extension_5_support.rs index ca8d51b..3b32b0f 100644 --- a/src/oned/upc_ean_extension_5_support.rs +++ b/src/oned/upc_ean_extension_5_support.rs @@ -73,7 +73,7 @@ impl UPCEANExtension5Support { resultString: &mut String, ) -> Result { let mut counters = [0_u32; 4]; - let end = row.getSize(); + let end = row.get_size(); let mut rowOffset = startRange[1]; let mut lgPatternFound = 0; diff --git a/src/oned/upc_ean_reader.rs b/src/oned/upc_ean_reader.rs index 9f5a762..caa984a 100644 --- a/src/oned/upc_ean_reader.rs +++ b/src/oned/upc_ean_reader.rs @@ -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 { - 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 { + fn decode(&mut self, _image: &mut crate::BinaryBitmap) -> Result { todo!() } - fn decode_with_hints( + fn decode_with_hints( &mut self, - _image: &mut crate::BinaryBitmap, + _image: &mut crate::BinaryBitmap, _hints: &crate::DecodingHintDictionary, ) -> Result { todo!() diff --git a/src/pdf417/detector/pdf_417_detector.rs b/src/pdf417/detector/pdf_417_detector.rs index 5ae0289..9f8f4c5 100644 --- a/src/pdf417/detector/pdf_417_detector.rs +++ b/src/pdf417/detector/pdf_417_detector.rs @@ -16,7 +16,7 @@ use crate::{ common::{BitMatrix, Result}, - point, BinaryBitmap, DecodingHintDictionary, Exceptions, Point, + point, Binarizer, BinaryBitmap, DecodingHintDictionary, Exceptions, Point, }; use std::borrow::Cow; @@ -64,8 +64,8 @@ const ROTATIONS: [u32; 4] = [0, 180, 270, 90]; * @return {@link PDF417DetectorRXingResult} encapsulating results of detecting a PDF417 code * @throws NotFoundException if no PDF417 Code can be found */ -pub fn detect_with_hints( - image: &mut BinaryBitmap, +pub fn detect_with_hints( + image: &mut BinaryBitmap, _hints: &DecodingHintDictionary, multiple: bool, ) -> Result { @@ -74,7 +74,7 @@ pub fn detect_with_hints( //boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER); //let try_harder = matches!(hints.get(&DecodeHintType::TRY_HARDER), Some(DecodeHintValue::TryHarder(true))); - let originalMatrix = image.getBlackMatrix(); + let originalMatrix = image.get_black_matrix(); for rotation in ROTATIONS { // for (int rotation : ROTATIONS) { let bitMatrix = applyRotation(originalMatrix, rotation)?; diff --git a/src/pdf417/pdf_417_reader.rs b/src/pdf417/pdf_417_reader.rs index bb954cc..27cabf7 100644 --- a/src/pdf417/pdf_417_reader.rs +++ b/src/pdf417/pdf_417_reader.rs @@ -17,7 +17,7 @@ use std::collections::HashMap; use crate::{ - common::Result, multi::MultipleBarcodeReader, BarcodeFormat, BinaryBitmap, + common::Result, multi::MultipleBarcodeReader, BarcodeFormat, Binarizer, BinaryBitmap, DecodingHintDictionary, Exceptions, Point, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader, }; @@ -43,13 +43,13 @@ impl Reader for PDF417Reader { * @throws NotFoundException if a PDF417 code cannot be found, * @throws FormatException if a PDF417 cannot be decoded */ - fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { + fn decode(&mut self, image: &mut BinaryBitmap) -> Result { self.decode_with_hints(image, &HashMap::new()) } - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut BinaryBitmap, hints: &crate::DecodingHintDictionary, ) -> Result { let result = Self::decode(image, hints, false)?; @@ -61,18 +61,18 @@ impl Reader for PDF417Reader { } impl MultipleBarcodeReader for PDF417Reader { - fn decode_multiple( + fn decode_multiple( &mut self, - image: &mut crate::BinaryBitmap, - ) -> Result> { + image: &mut BinaryBitmap, + ) -> Result> { self.decode_multiple_with_hints(image, &HashMap::new()) } - fn decode_multiple_with_hints( + fn decode_multiple_with_hints( &mut self, - image: &mut crate::BinaryBitmap, - hints: &crate::DecodingHintDictionary, - ) -> Result> { + image: &mut BinaryBitmap, + hints: &DecodingHintDictionary, + ) -> Result> { Self::decode(image, hints, true) } } @@ -82,8 +82,8 @@ impl PDF417Reader { Self::default() } - fn decode( - image: &mut BinaryBitmap, + fn decode( + image: &mut BinaryBitmap, hints: &DecodingHintDictionary, multiple: bool, ) -> Result> { diff --git a/src/planar_yuv_luminance_source.rs b/src/planar_yuv_luminance_source.rs index adeb526..aff992b 100644 --- a/src/planar_yuv_luminance_source.rs +++ b/src/planar_yuv_luminance_source.rs @@ -191,8 +191,8 @@ impl PlanarYUVLuminanceSource { } pub fn renderThumbnail(&self) -> Vec { - let width = self.getWidth() / THUMBNAIL_SCALE_FACTOR; - let height = self.getHeight() / THUMBNAIL_SCALE_FACTOR; + let width = self.get_width() / THUMBNAIL_SCALE_FACTOR; + let height = self.get_height() / THUMBNAIL_SCALE_FACTOR; let mut pixels = vec![0; width * height]; let yuv = &self.yuv_data; let mut input_offset = self.top * self.data_width + self.left; @@ -212,14 +212,14 @@ impl PlanarYUVLuminanceSource { * @return width of image from {@link #renderThumbnail()} */ pub fn getThumbnailWidth(&self) -> usize { - self.getWidth() / THUMBNAIL_SCALE_FACTOR + self.get_width() / THUMBNAIL_SCALE_FACTOR } /** * @return height of image from {@link #renderThumbnail()} */ pub fn getThumbnailHeight(&self) -> usize { - self.getHeight() / THUMBNAIL_SCALE_FACTOR + self.get_height() / THUMBNAIL_SCALE_FACTOR } fn reverseHorizontal(&mut self, width: usize, height: usize) { @@ -237,13 +237,13 @@ impl PlanarYUVLuminanceSource { } impl LuminanceSource for PlanarYUVLuminanceSource { - fn getRow(&self, y: usize) -> Vec { - if y >= self.getHeight() { + fn get_row(&self, y: usize) -> Vec { + if y >= self.get_height() { // //throw new IllegalArgumentException("Requested row is outside the image: " + y); // panic!("Requested row is outside the image: {y}"); return Vec::new(); } - let width = self.getWidth(); + let width = self.get_width(); let offset = (y + self.top) * self.data_width + self.left; @@ -256,9 +256,9 @@ impl LuminanceSource for PlanarYUVLuminanceSource { row } - fn getMatrix(&self) -> Vec { - let width = self.getWidth(); - let height = self.getHeight(); + fn get_matrix(&self) -> Vec { + let width = self.get_width(); + let height = self.get_height(); // If the caller asks for the entire underlying image, save the copy and give them the // original data. The docs specifically warn that result.length must be ignored. @@ -298,26 +298,20 @@ impl LuminanceSource for PlanarYUVLuminanceSource { matrix } - fn getWidth(&self) -> usize { + fn get_width(&self) -> usize { self.width } - fn getHeight(&self) -> usize { + fn get_height(&self) -> usize { self.height } - fn isCropSupported(&self) -> bool { + fn is_crop_supported(&self) -> bool { true } - fn crop( - &self, - left: usize, - top: usize, - width: usize, - height: usize, - ) -> Result> { - match PlanarYUVLuminanceSource::new_with_all( + fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result { + PlanarYUVLuminanceSource::new_with_all( self.yuv_data.clone(), self.data_width, self.data_height, @@ -327,13 +321,11 @@ impl LuminanceSource for PlanarYUVLuminanceSource { height, false, self.invert, - ) { - Ok(new) => Ok(Box::new(new)), - Err(_err) => Err(Exceptions::UNSUPPORTED_OPERATION), - } + ) + .map_err(|_| Exceptions::UNSUPPORTED_OPERATION) } - fn isRotateSupported(&self) -> bool { + fn is_rotate_supported(&self) -> bool { false } diff --git a/src/qrcode/encoder/bit_vector_testcase.rs b/src/qrcode/encoder/bit_vector_testcase.rs index 5517f9e..4270399 100644 --- a/src/qrcode/encoder/bit_vector_testcase.rs +++ b/src/qrcode/encoder/bit_vector_testcase.rs @@ -39,43 +39,43 @@ fn testAppendBit() { assert_eq!(0, v.getSizeInBytes()); // 1 v.appendBit(true); - assert_eq!(1, v.getSize()); + assert_eq!(1, v.get_size()); assert_eq!(0x80000000, getUnsignedInt(&v)); // 10 v.appendBit(false); - assert_eq!(2, v.getSize()); + assert_eq!(2, v.get_size()); assert_eq!(0x80000000, getUnsignedInt(&v)); // 101 v.appendBit(true); - assert_eq!(3, v.getSize()); + assert_eq!(3, v.get_size()); assert_eq!(0xa0000000, getUnsignedInt(&v)); // 1010 v.appendBit(false); - assert_eq!(4, v.getSize()); + assert_eq!(4, v.get_size()); assert_eq!(0xa0000000, getUnsignedInt(&v)); // 10101 v.appendBit(true); - assert_eq!(5, v.getSize()); + assert_eq!(5, v.get_size()); assert_eq!(0xa8000000, getUnsignedInt(&v)); // 101010 v.appendBit(false); - assert_eq!(6, v.getSize()); + assert_eq!(6, v.get_size()); assert_eq!(0xa8000000, getUnsignedInt(&v)); // 1010101 v.appendBit(true); - assert_eq!(7, v.getSize()); + assert_eq!(7, v.get_size()); assert_eq!(0xaa000000, getUnsignedInt(&v)); // 10101010 v.appendBit(false); - assert_eq!(8, v.getSize()); + assert_eq!(8, v.get_size()); assert_eq!(0xaa000000, getUnsignedInt(&v)); // 10101010 1 v.appendBit(true); - assert_eq!(9, v.getSize()); + assert_eq!(9, v.get_size()); assert_eq!(0xaa800000, getUnsignedInt(&v)); // 10101010 10 v.appendBit(false); - assert_eq!(10, v.getSize()); + assert_eq!(10, v.get_size()); assert_eq!(0xaa800000, getUnsignedInt(&v)); } @@ -83,15 +83,15 @@ fn testAppendBit() { fn testAppendBits() { let mut v = BitArray::new(); v.appendBits(0x1, 1).expect("append"); - assert_eq!(1, v.getSize()); + assert_eq!(1, v.get_size()); assert_eq!(0x80000000, getUnsignedInt(&v)); let mut v = BitArray::new(); v.appendBits(0xff, 8).expect("append"); - assert_eq!(8, v.getSize()); + assert_eq!(8, v.get_size()); assert_eq!(0xff000000, getUnsignedInt(&v)); let mut v = BitArray::new(); v.appendBits(0xff7, 12).expect("append"); - assert_eq!(12, v.getSize()); + assert_eq!(12, v.get_size()); assert_eq!(0xff700000, getUnsignedInt(&v)); } diff --git a/src/qrcode/encoder/matrix_util.rs b/src/qrcode/encoder/matrix_util.rs index ab68171..bb7ca27 100644 --- a/src/qrcode/encoder/matrix_util.rs +++ b/src/qrcode/encoder/matrix_util.rs @@ -174,11 +174,11 @@ pub fn embedTypeInfo( for (i, coordinates) in TYPE_INFO_COORDINATES .iter() .enumerate() - .take(typeInfoBits.getSize()) + .take(typeInfoBits.get_size()) { // Place bits in LSB to MSB order. LSB (least significant bit) is the last value in // "typeInfoBits". - let bit = typeInfoBits.get(typeInfoBits.getSize() - 1 - i); + let bit = typeInfoBits.get(typeInfoBits.get_size() - 1 - i); // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46). // let coordinates = TYPE_INFO_COORDINATES[i]; @@ -249,7 +249,7 @@ pub fn embedDataBits(dataBits: &BitArray, maskPattern: i32, matrix: &mut ByteMat continue; } let mut bit; - if bitIndex < dataBits.getSize() { + if bitIndex < dataBits.get_size() { bit = dataBits.get(bitIndex); bitIndex += 1; } else { @@ -273,11 +273,11 @@ pub fn embedDataBits(dataBits: &BitArray, maskPattern: i32, matrix: &mut ByteMat x -= 2; // Move to the left. } // All bits should be consumed. - if bitIndex != dataBits.getSize() { + if bitIndex != dataBits.get_size() { return Err(Exceptions::writer_with(format!( "Not all bits consumed: {}/{}", bitIndex, - dataBits.getSize() + dataBits.get_size() ))); } Ok(()) @@ -355,11 +355,11 @@ pub fn makeTypeInfoBits( maskBits.appendBits(TYPE_INFO_MASK_PATTERN, 15)?; bits.xor(&maskBits)?; - if bits.getSize() != 15 { + if bits.get_size() != 15 { // Just in case. return Err(Exceptions::writer_with(format!( "should not happen but we got: {}", - bits.getSize() + bits.get_size() ))); } Ok(()) @@ -372,11 +372,11 @@ pub fn makeVersionInfoBits(version: &Version, bits: &mut BitArray) -> Result<()> let bchCode = calculateBCHCode(version.getVersionNumber(), VERSION_INFO_POLY)?; bits.appendBits(bchCode, 12)?; - if bits.getSize() != 18 { + if bits.get_size() != 18 { // Just in case. return Err(Exceptions::writer_with(format!( "should not happen but we got: {}", - bits.getSize() + bits.get_size() ))); } Ok(()) diff --git a/src/qrcode/encoder/qrcode_encoder.rs b/src/qrcode/encoder/qrcode_encoder.rs index 9d99b64..cbe5257 100644 --- a/src/qrcode/encoder/qrcode_encoder.rs +++ b/src/qrcode/encoder/qrcode_encoder.rs @@ -286,7 +286,7 @@ fn calculateBitsNeeded( data_bits: &BitArray, version: VersionRef, ) -> u32 { - (header_bits.getSize() + mode.getCharacterCountBits(version) as usize + data_bits.getSize()) + (header_bits.get_size() + mode.getCharacterCountBits(version) as usize + data_bits.get_size()) as u32 } @@ -413,21 +413,21 @@ pub fn willFit(numInputBits: u32, version: VersionRef, ecLevel: &ErrorCorrection */ pub fn terminateBits(num_data_bytes: u32, bits: &mut BitArray) -> Result<()> { let capacity = num_data_bytes * 8; - if bits.getSize() > capacity as usize { + if bits.get_size() > capacity as usize { return Err(Exceptions::writer_with(format!( "data bits cannot fit in the QR Code{capacity} > " ))); } // Append Mode.TERMINATE if there is enough space (value is 0000) for _i in 0..4 { - if bits.getSize() >= capacity as usize { + if bits.get_size() >= capacity as usize { break; } bits.appendBit(false); } // Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details. // If the last byte isn't 8-bit aligned, we'll add padding bits. - let num_bits_in_last_byte = bits.getSize() & 0x07; + let num_bits_in_last_byte = bits.get_size() & 0x07; if num_bits_in_last_byte > 0 { for _i in num_bits_in_last_byte..8 { bits.appendBit(false); @@ -441,7 +441,7 @@ pub fn terminateBits(num_data_bytes: u32, bits: &mut BitArray) -> Result<()> { } bits.appendBits(if (i & 0x01) == 0 { 0xEC } else { 0x11 }, 8)?; } - if bits.getSize() != capacity as usize { + if bits.get_size() != capacity as usize { return Err(Exceptions::writer_with("Bits size does not equal capacity")); } Ok(()) diff --git a/src/qrcode/qr_code_reader.rs b/src/qrcode/qr_code_reader.rs index c123b97..4e9a294 100644 --- a/src/qrcode/qr_code_reader.rs +++ b/src/qrcode/qr_code_reader.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use crate::{ common::{BitMatrix, DecoderRXingResult, DetectorRXingResult, Result}, - BarcodeFormat, DecodeHintType, DecodeHintValue, Exceptions, Point, RXingResult, + BarcodeFormat, Binarizer, DecodeHintType, DecodeHintValue, Exceptions, Point, RXingResult, RXingResultMetadataType, RXingResultMetadataValue, Reader, }; @@ -48,27 +48,27 @@ impl Reader for QRCodeReader { * @throws FormatException if a QR code cannot be decoded * @throws ChecksumException if error correction fails */ - fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { + fn decode(&mut self, image: &mut crate::BinaryBitmap) -> Result { self.decode_with_hints(image, &HashMap::new()) } - fn decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut crate::BinaryBitmap, + image: &mut crate::BinaryBitmap, hints: &crate::DecodingHintDictionary, - ) -> Result { + ) -> Result { let decoderRXingResult: DecoderRXingResult; let mut points: Vec; if matches!( hints.get(&DecodeHintType::PURE_BARCODE), Some(DecodeHintValue::PureBarcode(true)) ) { - let bits = Self::extractPureBits(image.getBlackMatrix())?; + let bits = Self::extractPureBits(image.get_black_matrix())?; decoderRXingResult = qrcode_decoder::decode_bitmatrix_with_hints(&bits, hints)?; points = Vec::new(); } else { let detectorRXingResult = - Detector::new(image.getBlackMatrix()).detect_with_hints(hints)?; + Detector::new(image.get_black_matrix()).detect_with_hints(hints)?; decoderRXingResult = qrcode_decoder::decode_bitmatrix_with_hints(detectorRXingResult.getBits(), hints)?; points = detectorRXingResult.getPoints().to_vec(); diff --git a/src/reader.rs b/src/reader.rs index ca54467..ea5b1be 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -16,7 +16,7 @@ //package com.google.zxing; -use crate::{common::Result, BinaryBitmap, DecodingHintDictionary, RXingResult}; +use crate::{common::Result, Binarizer, BinaryBitmap, DecodingHintDictionary, RXingResult}; /** * Implementations of this interface can decode an image of a barcode in some format into @@ -40,7 +40,7 @@ pub trait 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 decode(&mut self, image: &mut BinaryBitmap) -> Result; + fn decode(&mut self, image: &mut BinaryBitmap) -> Result; /** * Locates and decodes a barcode in some format within an image. This method also accepts @@ -56,9 +56,9 @@ pub trait 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 decode_with_hints( + fn decode_with_hints( &mut self, - image: &mut BinaryBitmap, + image: &mut BinaryBitmap, hints: &DecodingHintDictionary, ) -> Result; diff --git a/src/rgb_luminance_source.rs b/src/rgb_luminance_source.rs index 96747fe..144350a 100644 --- a/src/rgb_luminance_source.rs +++ b/src/rgb_luminance_source.rs @@ -40,11 +40,11 @@ pub struct RGBLuminanceSource { impl LuminanceSource for RGBLuminanceSource { /// gets a row, returns an empty row if we are out of bounds. - fn getRow(&self, y: usize) -> Vec { - if y >= self.getHeight() { + fn get_row(&self, y: usize) -> Vec { + if y >= self.get_height() { return Vec::new(); } - let width = self.getWidth(); + let width = self.get_width(); let offset = (y + self.top) * self.dataWidth + self.left; @@ -58,9 +58,9 @@ impl LuminanceSource for RGBLuminanceSource { row } - fn getMatrix(&self) -> Vec { - let width = self.getWidth(); - let height = self.getHeight(); + fn get_matrix(&self) -> Vec { + let width = self.get_width(); + let height = self.get_height(); // If the caller asks for the entire underlying image, save the copy and give them the // original data. The docs specifically warn that result.length must be ignored. @@ -99,26 +99,20 @@ impl LuminanceSource for RGBLuminanceSource { matrix } - fn getWidth(&self) -> usize { + fn get_width(&self) -> usize { self.width } - fn getHeight(&self) -> usize { + fn get_height(&self) -> usize { self.height } - fn isCropSupported(&self) -> bool { + fn is_crop_supported(&self) -> bool { true } - fn crop( - &self, - left: usize, - top: usize, - width: usize, - height: usize, - ) -> Result> { - match RGBLuminanceSource::new_complex( + fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result { + RGBLuminanceSource::new_complex( &self.luminances, self.dataWidth, self.dataHeight, @@ -126,10 +120,8 @@ impl LuminanceSource for RGBLuminanceSource { self.top + top, width, height, - ) { - Ok(crop) => Ok(Box::new(crop)), - Err(_error) => Err(Exceptions::UNSUPPORTED_OPERATION), - } + ) + .map_err(|_| Exceptions::UNSUPPORTED_OPERATION) } fn invert(&mut self) { diff --git a/src/rgb_luminance_source_test_case.rs b/src/rgb_luminance_source_test_case.rs index 1c0a5f5..9677775 100644 --- a/src/rgb_luminance_source_test_case.rs +++ b/src/rgb_luminance_source_test_case.rs @@ -34,11 +34,11 @@ const SRC_DATA: [u32; 9] = [ fn testCrop() { let SOURCE = RGBLuminanceSource::new_with_width_height_pixels(3, 3, SRC_DATA.as_ref()); - assert!(SOURCE.isCropSupported()); + assert!(SOURCE.is_crop_supported()); let cropped = SOURCE.crop(1, 1, 1, 1).unwrap(); - assert_eq!(1, cropped.getHeight()); - assert_eq!(1, cropped.getWidth()); - assert_eq!(vec![0x7F], cropped.getRow(0)); + assert_eq!(1, cropped.get_height()); + assert_eq!(1, cropped.get_width()); + assert_eq!(vec![0x7F], cropped.get_row(0)); } #[test] @@ -47,22 +47,22 @@ fn testMatrix() { assert_eq!( vec![0x00, 0x7F, 0xFF, 0x3F, 0x7F, 0x3F, 0x3F, 0x7F, 0x3F], - SOURCE.getMatrix() + SOURCE.get_matrix() ); let croppedFullWidth = SOURCE.crop(0, 1, 3, 2).unwrap(); assert_eq!( vec![0x3F, 0x7F, 0x3F, 0x3F, 0x7F, 0x3F], - croppedFullWidth.getMatrix() + croppedFullWidth.get_matrix() ); let croppedCorner = SOURCE.crop(1, 1, 2, 2).unwrap(); - assert_eq!(vec![0x7F, 0x3F, 0x7F, 0x3F], croppedCorner.getMatrix()); + assert_eq!(vec![0x7F, 0x3F, 0x7F, 0x3F], croppedCorner.get_matrix()); } #[test] fn testGetRow() { let SOURCE = RGBLuminanceSource::new_with_width_height_pixels(3, 3, SRC_DATA.as_ref()); - assert_eq!(vec![0x3F, 0x7F, 0x3F], SOURCE.getRow(2)); + assert_eq!(vec![0x3F, 0x7F, 0x3F], SOURCE.get_row(2)); } // #[test] diff --git a/src/svg_luminance_source.rs b/src/svg_luminance_source.rs index ee62471..2a367a1 100644 --- a/src/svg_luminance_source.rs +++ b/src/svg_luminance_source.rs @@ -6,28 +6,28 @@ use resvg::{self, usvg::Options}; pub struct SVGLuminanceSource(BufferedImageLuminanceSource); impl LuminanceSource for SVGLuminanceSource { - fn getRow(&self, y: usize) -> Vec { - self.0.getRow(y) + fn get_row(&self, y: usize) -> Vec { + self.0.get_row(y) } - fn getMatrix(&self) -> Vec { - self.0.getMatrix() + fn get_matrix(&self) -> Vec { + self.0.get_matrix() } - fn getWidth(&self) -> usize { - self.0.getWidth() + fn get_width(&self) -> usize { + self.0.get_width() } - fn getHeight(&self) -> usize { - self.0.getHeight() + fn get_height(&self) -> usize { + self.0.get_height() } fn invert(&mut self) { self.0.invert() } - fn isCropSupported(&self) -> bool { - self.0.isCropSupported() + fn is_crop_supported(&self) -> bool { + self.0.is_crop_supported() } fn crop( @@ -40,16 +40,16 @@ impl LuminanceSource for SVGLuminanceSource { self.0.crop(left, top, width, height) } - fn isRotateSupported(&self) -> bool { - self.0.isRotateSupported() + fn is_rotate_supported(&self) -> bool { + self.0.is_rotate_supported() } - fn rotateCounterClockwise(&self) -> Result> { - self.0.rotateCounterClockwise() + fn rotate_counter_clockwise(&self) -> Result> { + self.0.rotate_counter_clockwise() } - fn rotateCounterClockwise45(&self) -> Result> { - self.0.rotateCounterClockwise45() + fn rotate_counter_clockwise_45(&self) -> Result> { + self.0.rotate_counter_clockwise_45() } }