From dc1a1505b1564092f17b21922627bf00b6dcce5b Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Fri, 26 Jan 2024 14:39:24 -0600 Subject: [PATCH] wip: inop! builds but does not work --- src/common/bit_array.rs | 14 ++-- src/common/quad.rs | 10 +-- src/oned/cpp/dxfilm_edge_reader.rs | 35 ++++---- src/oned/cpp/one_d_reader.rs | 123 +++++++++++++++++++++-------- 4 files changed, 118 insertions(+), 64 deletions(-) diff --git a/src/common/bit_array.rs b/src/common/bit_array.rs index a6b8cf7..5b96873 100644 --- a/src/common/bit_array.rs +++ b/src/common/bit_array.rs @@ -413,6 +413,12 @@ impl Default for BitArray { impl From for Vec { fn from(value: BitArray) -> Self { + (&value).into() + } +} + +impl From<&BitArray> for Vec { + fn from(value: &BitArray) -> Self { let mut array = vec![0; value.getSizeInBytes()]; value.toBytes(0, &mut array, 0, value.getSizeInBytes()); array @@ -443,11 +449,3 @@ impl From<&BitArray> for Vec { array } } - -impl Index for BitArray { - type Output = bool; - - fn index(&self, index: usize) -> &Self::Output { - &self.get(index) - } -} diff --git a/src/common/quad.rs b/src/common/quad.rs index 27b2a2e..a52fa97 100644 --- a/src/common/quad.rs +++ b/src/common/quad.rs @@ -278,13 +278,9 @@ impl TryFrom<&Vec> for Quadrilateral { fn try_from(value: &Vec) -> Result { if value.len() == 4 { - Ok( - Self( - [value[0], value[1], value[2], value[3]] - ) - ) - }else{ + Ok(Self([value[0], value[1], value[2], value[3]])) + } else { Err(Exceptions::INDEX_OUT_OF_BOUNDS) } } -} \ No newline at end of file +} diff --git a/src/oned/cpp/dxfilm_edge_reader.rs b/src/oned/cpp/dxfilm_edge_reader.rs index 632ac09..5734149 100644 --- a/src/oned/cpp/dxfilm_edge_reader.rs +++ b/src/oned/cpp/dxfilm_edge_reader.rs @@ -6,13 +6,10 @@ use crate::{ common::{ - cpp_essentials::{ - FindLeftGuardBy, FixedPattern, IsRightGuard, PatternView, ToInt, ToIntPos, - }, + cpp_essentials::{FindLeftGuardBy, FixedPattern, IsRightGuard, PatternView, ToIntPos}, BitArray, }, - point, point_i, BarcodeFormat, DecodeHintValue, DecodingHintDictionary, Exceptions, PointI, - RXingResult, + point, BarcodeFormat, DecodeHintValue, DecodingHintDictionary, Exceptions, PointI, RXingResult, }; use super::row_reader::{DecodingState, RowReader}; @@ -42,6 +39,12 @@ pub struct DXFilmEdgeReader<'a> { options: &'a DecodingHintDictionary, } +impl<'a> DXFilmEdgeReader<'_> { + pub fn new(hints: &'a DecodingHintDictionary) -> DXFilmEdgeReader<'a> { + DXFilmEdgeReader { options: hints } + } +} + fn IsPattern( view: &PatternView, pattern: &FixedPattern, @@ -259,7 +262,7 @@ impl<'a> RowReader for DXFilmEdgeReader<'_> { let modules = (next[0] as f32 / clock.moduleSize() + 0.5) as u32; // even index means we are at a bar, otherwise at a space // dataBits.appendBits(if next.index() % 2 == 0 {0xFFFFFFFF} else {0x0}, modules); - for i in 0..modules { + for _i in 0..modules { dataBits.appendBits( if next.index() % 2 == 0 { 0xFFFFFFFF @@ -267,7 +270,7 @@ impl<'a> RowReader for DXFilmEdgeReader<'_> { 0x0 }, modules as usize, - ); + )?; // should it be 0xFFFFFFFF } @@ -287,19 +290,19 @@ impl<'a> RowReader for DXFilmEdgeReader<'_> { } // The following bits are always white (=false), they are separators. - if (dataBits[0] != false //0 - || dataBits[8] != false //0 + if (dataBits.get(0) != false //0 + || dataBits.get(8) != false //0 || (if clock.hasFrameNr { - (dataBits[20] != false/*0*/ || dataBits[22] != false/*0*/) + (dataBits.get(20) != false/*0*/ || dataBits.get(22) != false/*0*/) } else { - dataBits[14] != false//0 + dataBits.get(14) != false//0 })) { return Err(Exceptions::NOT_FOUND); } // Check the parity bit - let db_hld = Into::>::into(dataBits); //.iter().rev().skip(2).fold(0, |acc, e| acc + u8::from(*e)); + let db_hld = Into::>::into(&dataBits); //.iter().rev().skip(2).fold(0, |acc, e| acc + u8::from(*e)); let signalSum = db_hld .iter() .rev() @@ -311,12 +314,12 @@ impl<'a> RowReader for DXFilmEdgeReader<'_> { } // Compute the DX 1 number (product number) - let Some(productNumber) = ToIntPos(&Into::>::into(dataBits), 1, 7) else { + let Some(productNumber) = ToIntPos(&Into::>::into(&dataBits), 1, 7) else { return Err(Exceptions::NOT_FOUND); }; // Compute the DX 2 number (generation number) - let Some(generationNumber) = ToIntPos(&Into::>::into(dataBits), 9, 4) else { + let Some(generationNumber) = ToIntPos(&Into::>::into(&dataBits), 9, 4) else { return Err(Exceptions::NOT_FOUND); }; @@ -326,9 +329,9 @@ impl<'a> RowReader for DXFilmEdgeReader<'_> { // txt.reserve(10); txt = (productNumber.to_string()) + "-" + (&generationNumber.to_string()); if (clock.hasFrameNr) { - let frameNr = ToIntPos(&Into::>::into(dataBits), 13, 6).unwrap_or(0); + let frameNr = ToIntPos(&Into::>::into(&dataBits), 13, 6).unwrap_or(0); txt += &("/".to_owned() + &(frameNr.to_string())); - if (dataBits[19] != false/*0*/) { + if (dataBits.get(19) != false/*0*/) { txt += "A"; } } diff --git a/src/oned/cpp/one_d_reader.rs b/src/oned/cpp/one_d_reader.rs index 6032056..5ffc20f 100644 --- a/src/oned/cpp/one_d_reader.rs +++ b/src/oned/cpp/one_d_reader.rs @@ -5,15 +5,14 @@ */ // SPDX-License-Identifier: Apache-2.0 -use std::any::Any; use std::collections::HashMap; use crate::common::cpp_essentials::{GetPatternRow, PatternRow, PatternView}; -use crate::Binarizer; use crate::{multi::MultipleBarcodeReader, RXingResult, Reader}; use crate::{ point, BarcodeFormat, BinaryBitmap, DecodingHintDictionary, Exceptions, PointT, ResultPoint, }; +use crate::{Binarizer, DecodeHintType, DecodeHintValue}; use crate::common::{LineOrientation, Quadrilateral, Result}; @@ -87,14 +86,14 @@ impl<'a> ODReader<'_> { let mut checkRows = Vec::new(); let mut bars: PatternRow = PatternRow::new(vec![0; 128]); // e.g. EAN-13 has 59 bars/spaces - // bars.reserve(128); // e.g. EAN-13 has 59 bars/spaces + // bars.reserve(128); // e.g. EAN-13 has 59 bars/spaces // #ifdef PRINT_DEBUG // BitMatrix dbg(width, height); // #endif let mut i = 0; - 'outer: while i < maxLines { + 'outer: while i < maxLines { // for (int i = 0; i < maxLines; i++) { // Scanning from the middle out. Determine which row we're looking at next: @@ -185,7 +184,9 @@ impl<'a> ODReader<'_> { let mut result_hld = readers[r] .decodePattern(rowNumber as u32, &mut next, decodingState[r]) .ok(); - if result_hld.is_some() /*|| (returnErrors && result.is_none())*/ { + if result_hld.is_some() + /*|| (returnErrors && result.is_none())*/ + { let mut result = result_hld.as_mut().unwrap(); IncrementLineCount(&mut result); if (upsideDown) { @@ -202,7 +203,7 @@ impl<'a> ODReader<'_> { let points = result.getPointsMut(); for p in points { // for (auto& p : points) { - *p = point(p.getY(), width as f32- p.getX() - 1.0); + *p = point(p.getY(), width as f32 - p.getX() - 1.0); } // result.addPoints(points); // result.setPosition(std::move(points)); @@ -210,9 +211,11 @@ impl<'a> ODReader<'_> { // check if we know this code already for other_hld in res.iter_mut() { - let Some(mut other) = other_hld else{ continue;}; + let Some(mut other) = other_hld.as_mut() else { + continue; + }; // for (auto& other : res) { - if (result == &other) { + if (result == other) { // merge the position information let dTop = PointT::maxAbsComponent( other.getPoints()[0] - result.getPoints()[0], @@ -238,7 +241,7 @@ impl<'a> ODReader<'_> { other.replace_points(points); IncrementLineCount(&mut other); // clear the result, so we don't insert it again below - result_hld = None; //Result(); + // result_hld = None; //Result(); break; } } @@ -263,7 +266,7 @@ impl<'a> ODReader<'_> { && res.iter().fold(0, |acc, e| { if let Some(itm) = &res[r] { acc + i32::from((itm.line_count() >= minLineCount as usize)) - }else { + } else { acc } }) == maxSymbols as i32) @@ -285,34 +288,72 @@ impl<'a> ODReader<'_> { // out: // remove all symbols with insufficient line count - res.retain(|e| if let Some(itm) = e {itm.line_count() < minLineCount as usize} else {false}); + res.retain(|e| { + if let Some(itm) = e { + itm.line_count() < minLineCount as usize + } else { + false + } + }); // let it = std::remove_if(res.begin(), res.end(), [&](auto&& r) { return r.lineCount() < minLineCount; }); // res.erase(it, res.end()); // if symbols overlap, remove the one with a lower line count - for (i, a_hld) in res.iter().enumerate() { - let a = a_hld.as_ref().unwrap(); - // for (auto a = res.begin(); a != res.end(); ++a){ - for b_hld in res.iter().skip(i) { - let b = b_hld.as_ref().unwrap(); - // for (auto b = std::next(a); b != res.end(); ++b){ - let Ok(q1) =Quadrilateral::try_from(a.getPoints()) else {continue;}; - let Ok(q2) = Quadrilateral::try_from(b.getPoints()) else {continue;}; - if (Quadrilateral::have_intersecting_bounding_boxes(&q1, &q2)) { - *(if a.line_count() < b.line_count() { - a_hld - } else { - b_hld - }) = None; + for i in 0..res.len() { + for j in i..res.len() { + if res[i].is_some() && res[j].is_some() { + let Ok(q1) = Quadrilateral::try_from(res[i].as_ref().unwrap().getPoints()) + else { + continue; + }; + let Ok(q2) = Quadrilateral::try_from(res[j].as_ref().unwrap().getPoints()) + else { + continue; + }; + if (Quadrilateral::have_intersecting_bounding_boxes(&q1, &q2)) { + let a_lc = res[i].as_ref().unwrap().line_count(); + let b_lc = res[j].as_ref().unwrap().line_count(); + if a_lc < b_lc { + res[i] = None; + } else { + res[j] = None; + } + } } } } + // // if symbols overlap, remove the one with a lower line count + // for (i, a_hld) in res.iter().enumerate() { + // let a = a_hld.as_ref().unwrap(); + // // let a_lc = a_hld.as_ref().unwrap().line_count(); + // // let a_pts = a_hld.as_ref().unwrap().getPoints().clone(); + // // for (auto a = res.begin(); a != res.end(); ++a){ + // for (j, b_hld) in res.iter().skip(i).enumerate() { + // let b = b_hld.as_ref().unwrap(); + // // for (auto b = std::next(a); b != res.end(); ++b){ + // let Ok(q1) =Quadrilateral::try_from(a.getPoints()) else {continue;}; + // let Ok(q2) = Quadrilateral::try_from(b.getPoints()) else {continue;}; + // if (Quadrilateral::have_intersecting_bounding_boxes(&q1, &q2)) { + // if a.line_count() < b.line_count() { + // // delete_list.insert(i); + // // *a_hld = None; + // res.remove(i); + // } else { + // // delete_list.insert(i+j); + // res.remove(i+j); + // } + // } + // } + // } //TODO: C++20 res.erase_if() - res - - .retain(|r| if let Some(itm) = r { - itm.getBarcodeFormat() == &BarcodeFormat::UNSUPORTED_FORMAT } else { false }); + res.retain(|r| { + if let Some(itm) = r { + itm.getBarcodeFormat() == &BarcodeFormat::UNSUPORTED_FORMAT + } else { + false + } + }); // it = std::remove_if(res.begin(), res.end(), [](auto&& r) { return r.format() == BarcodeFormat::None; }); // res.erase(it, res.end()); @@ -327,7 +368,7 @@ impl<'a> ODReader<'_> { impl<'a> ODReader<'_> { pub fn decode_single( &self, - hints: &DecodingHintDictionary, + _hints: &DecodingHintDictionary, image: &BinaryBitmap, ) -> Result { let mut result = Self::DoDecode( @@ -360,7 +401,7 @@ impl<'a> ODReader<'_> { pub fn decode_with_max_symbols( &self, - hints: &DecodingHintDictionary, + _hints: &DecodingHintDictionary, image: &BinaryBitmap, maxSymbols: u32, ) -> Result> { @@ -431,8 +472,24 @@ impl<'a> MultipleBarcodeReader for ODReader<'_> { } impl<'a> ODReader<'_> { - pub fn new(hints: &DecodingHintDictionary) -> Self { - unimplemented!() + pub fn new(hints: &DecodingHintDictionary) -> ODReader { + ODReader { + reader: DXFilmEdgeReader::new(hints), + try_harder: matches!( + hints.get(&DecodeHintType::TRY_HARDER), + Some(DecodeHintValue::TryHarder(true)) + ), + is_pure: matches!( + hints.get(&DecodeHintType::PURE_BARCODE), + Some(DecodeHintValue::PureBarcode(true)) + ), + min_line_count: 2, + return_errors: false, + try_rotate: matches!( + hints.get(&DecodeHintType::TRY_HARDER), + Some(DecodeHintValue::TryHarder(true)) + ), + } } }