use super::rss::expanded::RSSExpandedReader;
use super::rss::RSS14Reader;
use super::CodaBarReader;
use super::Code128Reader;
use super::Code39Reader;
use super::Code93Reader;
use super::ITFReader;
use super::MultiFormatUPCEANReader;
use super::OneDReader;
use super::TelepenReader;
use crate::common::Result;
use crate::DecodeHints;
use crate::Exceptions;
use crate::{BarcodeFormat, Binarizer, RXingResult};
#[derive(Default)]
pub struct MultiFormatOneDReader {
internal_hints: DecodeHints,
possible_formats: HashSet<BarcodeFormat>,
use_code_39_check_digit: bool,
rss_14_reader: RSS14Reader,
rss_expanded_reader: RSSExpandedReader,
}
impl OneDReader for MultiFormatOneDReader {
fn decode_row(
&mut self,
row_number: u32,
row: &crate::common::BitArray,
hints: &DecodeHints,
) -> Result<RXingResult> {
let Self {
possible_formats,
use_code_39_check_digit,
internal_hints,
rss_14_reader,
rss_expanded_reader,
} = 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.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) = rss_14_reader.decode_row(row_number, row, hints) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::RSS_EXPANDED) {
if let Ok(res) = rss_expanded_reader.decode_row(row_number, row, hints) {
return Ok(res);
}
}
if possible_formats.contains(&BarcodeFormat::TELEPEN) {
if let Ok(res) = TelepenReader::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.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) = rss_14_reader.decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = rss_expanded_reader.decode_row(row_number, row, hints) {
return Ok(res);
}
if let Ok(res) = TelepenReader::default().decode_row(row_number, row, hints) {
return Ok(res);
}
}
Err(Exceptions::NOT_FOUND)
}
}
impl MultiFormatOneDReader {
pub fn new(hints: &DecodeHints) -> Self {
let use_code_39_check_digit = matches!(hints.AssumeCode39CheckDigit, Some(true));
let possible_formats = if let Some(p) = &hints.PossibleFormats {
p.clone()
} else {
HashSet::new()
};
Self {
possible_formats,
use_code_39_check_digit,
rss_14_reader: RSS14Reader::default(),
internal_hints: hints.clone(),
rss_expanded_reader: RSSExpandedReader::default(),
}
}
}
use crate::RXingResultMetadataType;
use crate::RXingResultMetadataValue;
use crate::Reader;
use std::collections::HashSet;
impl Reader for MultiFormatOneDReader {
fn decode<B: Binarizer>(&mut self, image: &mut crate::BinaryBitmap<B>) -> Result<RXingResult> {
self.decode_with_hints(image, &DecodeHints::default())
}
fn decode_with_hints<B: Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap<B>,
hints: &DecodeHints,
) -> Result<RXingResult> {
let first_try = self._do_decode(image, hints);
if first_try.is_ok() {
return first_try;
}
let tryHarder = hints.TryHarder.unwrap_or(false);
if tryHarder && image.is_rotate_supported() {
let mut rotatedImage = image.rotate_counter_clockwise();
let mut result = self._do_decode(&mut rotatedImage, hints)?;
let metadata = result.getRXingResultMetadata();
let mut orientation = 270;
if metadata.contains_key(&RXingResultMetadataType::ORIENTATION) {
orientation = (orientation
+ if let Some(crate::RXingResultMetadataValue::Orientation(or)) =
metadata.get(&RXingResultMetadataType::ORIENTATION)
{
*or
} else {
0
})
% 360;
}
result.putMetadata(
RXingResultMetadataType::ORIENTATION,
RXingResultMetadataValue::Orientation(orientation),
);
let height = rotatedImage.get_height();
let total_points = result.getPoints().len();
let points = result.getPointsMut();
for point in points.iter_mut().take(total_points) {
std::mem::swap(&mut point.x, &mut point.y);
point.x = height as f32 - point.x - 1.0;
}
Ok(result)
} else {
Err(Exceptions::NOT_FOUND)
}
}
fn reset(&mut self) {
self.rss_14_reader.reset();
self.rss_expanded_reader.reset();
}
}