From 6e81b2205421543435e3cebbe4cebfe8c80da428 Mon Sep 17 00:00:00 2001 From: Henry Date: Wed, 4 Jan 2023 17:50:27 -0600 Subject: [PATCH] basic luma8 source --- src/helpers.rs | 59 ++++++++++++++++++++++++++++++++------ src/lib.rs | 5 +++- src/luma_luma_source.rs | 63 +++++++++++++++++++++++++++++++++++++++++ src/luminance_source.rs | 1 + 4 files changed, 118 insertions(+), 10 deletions(-) create mode 100644 src/luma_luma_source.rs diff --git a/src/helpers.rs b/src/helpers.rs index 81e72ae..0c198c9 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -8,7 +8,8 @@ use crate::{ common::HybridBinarizer, multi::{GenericMultipleBarcodeReader, MultipleBarcodeReader}, BarcodeFormat, BinaryBitmap, BufferedImageLuminanceSource, DecodeHintType, DecodeHintValue, - DecodingHintDictionary, Exceptions, MultiFormatReader, RXingResult, Reader, + DecodingHintDictionary, Exceptions, Luma8LuminanceSource, MultiFormatReader, RXingResult, + Reader, }; #[cfg(feature = "image")] @@ -74,27 +75,67 @@ pub fn detect_multiple_in_file_with_hints( } pub fn detect_in_luma( - luma: &[u8], + luma: Vec, + width: u32, + height: u32, barcode_type: Option, ) -> Result { - detect_in_luma_with_hints(luma, barcode_type, &mut HashMap::new()) + detect_in_luma_with_hints(luma, height, width, barcode_type, &mut HashMap::new()) } pub fn detect_in_luma_with_hints( - luma: &[u8], + luma: Vec, + width: u32, + height: u32, barcode_type: Option, hints: &mut DecodingHintDictionary, ) -> Result { - Err(Exceptions::NotFoundException(None)) + let mut multi_format_reader = MultiFormatReader::default(); + + if let Some(bc_type) = barcode_type { + hints.insert( + DecodeHintType::POSSIBLE_FORMATS, + DecodeHintValue::PossibleFormats(HashSet::from([bc_type])), + ); + } + + if !hints.contains_key(&DecodeHintType::TRY_HARDER) { + hints.insert(DecodeHintType::TRY_HARDER, DecodeHintValue::TryHarder(true)); + } + + multi_format_reader.decode_with_hints( + &mut BinaryBitmap::new(Rc::new(RefCell::new(HybridBinarizer::new(Box::new( + Luma8LuminanceSource::new(luma, width, height), + ))))), + &hints, + ) } -pub fn detect_multiple_in_luma(luma: &[u8]) -> Result, Exceptions> { - detect_multiple_in_luma_with_hints(luma, &mut HashMap::new()) +pub fn detect_multiple_in_luma( + luma: Vec, + width: u32, + height: u32, +) -> Result, Exceptions> { + detect_multiple_in_luma_with_hints(luma, width, height, &mut HashMap::new()) } pub fn detect_multiple_in_luma_with_hints( - file_name: &[u8], + luma: Vec, + width: u32, + height: u32, hints: &mut DecodingHintDictionary, ) -> Result, Exceptions> { - Err(Exceptions::NotFoundException(None)) + let multi_format_reader = MultiFormatReader::default(); + let mut scanner = GenericMultipleBarcodeReader::new(multi_format_reader); + + if !hints.contains_key(&DecodeHintType::TRY_HARDER) { + hints.insert(DecodeHintType::TRY_HARDER, DecodeHintValue::TryHarder(true)); + } + + scanner.decode_multiple_with_hints( + &mut BinaryBitmap::new(Rc::new(RefCell::new(HybridBinarizer::new(Box::new( + Luma8LuminanceSource::new(luma, width, height), + ))))), + &hints, + ) } diff --git a/src/lib.rs b/src/lib.rs index 6e63618..7db688f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,4 +95,7 @@ mod multi_format_reader; pub use multi_format_reader::*; // Simple methods to help detect barcodes in common situations -pub mod helpers; \ No newline at end of file +pub mod helpers; + +mod luma_luma_source; +pub use luma_luma_source::*; \ No newline at end of file diff --git a/src/luma_luma_source.rs b/src/luma_luma_source.rs new file mode 100644 index 0000000..25d78db --- /dev/null +++ b/src/luma_luma_source.rs @@ -0,0 +1,63 @@ +use crate::LuminanceSource; + +pub struct Luma8LuminanceSource(u32, u32, Vec, bool); +impl LuminanceSource for Luma8LuminanceSource { + fn getRow(&self, y: usize) -> Vec { + self.2 + .chunks_exact(y * self.0 as usize) + .skip(y) + .take(1) + .flatten() + .map(|byte| Self::invert_if_should(*byte, self.3)) + .collect() + } + + fn getMatrix(&self) -> Vec { + self.2 + .iter() + .map(|byte| Self::invert_if_should(*byte, self.3)) + .collect() + } + + fn getWidth(&self) -> usize { + self.0 as usize + } + + fn getHeight(&self) -> usize { + self.1 as usize + } + + fn invert(&mut self) { + self.3 = !self.3; + } + + fn isCropSupported(&self) -> bool { + false + } + + fn crop( + &self, + _left: usize, + _top: usize, + _width: usize, + _height: usize, + ) -> Result, crate::Exceptions> { + Err(crate::Exceptions::UnsupportedOperationException(Some( + "This luminance source does not support cropping.".to_owned(), + ))) + } +} +impl Luma8LuminanceSource { + pub fn new(source: Vec, width: u32, height: u32) -> Self { + Self(width, height, source, false) + } + + #[inline(always)] + fn invert_if_should(byte: u8, invert: bool) -> u8 { + if invert { + 255 - byte + } else { + byte + } + } +} diff --git a/src/luminance_source.rs b/src/luminance_source.rs index a416312..acf1896 100644 --- a/src/luminance_source.rs +++ b/src/luminance_source.rs @@ -135,6 +135,7 @@ pub trait LuminanceSource { ))) } + #[inline(always)] fn invert_block_of_bytes(&self, vec_to_invert: Vec) -> Vec { let mut iv = vec_to_invert; for itm in iv.iter_mut() {