initial port complete, untested, builds

This commit is contained in:
Henry Schimke
2023-04-03 12:18:35 -05:00
parent 8fc6a240b3
commit 1ef262e967
5 changed files with 219 additions and 122 deletions

View File

@@ -65,6 +65,8 @@ pub enum BarcodeFormat {
/** QR Code 2D barcode format. */ /** QR Code 2D barcode format. */
QR_CODE, QR_CODE,
MICRO_QR_CODE,
/** RSS 14 */ /** RSS 14 */
RSS_14, RSS_14,
@@ -102,6 +104,7 @@ impl Display for BarcodeFormat {
BarcodeFormat::MAXICODE => "maxicode", BarcodeFormat::MAXICODE => "maxicode",
BarcodeFormat::PDF_417 => "pdf 417", BarcodeFormat::PDF_417 => "pdf 417",
BarcodeFormat::QR_CODE => "qrcode", BarcodeFormat::QR_CODE => "qrcode",
BarcodeFormat::MICRO_QR_CODE => "mqr",
BarcodeFormat::RSS_14 => "rss 14", BarcodeFormat::RSS_14 => "rss 14",
BarcodeFormat::RSS_EXPANDED => "rss expanded", BarcodeFormat::RSS_EXPANDED => "rss expanded",
BarcodeFormat::UPC_A => "upc a", BarcodeFormat::UPC_A => "upc a",
@@ -140,6 +143,9 @@ impl From<&str> for BarcodeFormat {
"maxicode" | "maxi_code" => BarcodeFormat::MAXICODE, "maxicode" | "maxi_code" => BarcodeFormat::MAXICODE,
"pdf 417" | "pdf_417" | "pdf417" | "iso 15438" | "iso_15438" => BarcodeFormat::PDF_417, "pdf 417" | "pdf_417" | "pdf417" | "iso 15438" | "iso_15438" => BarcodeFormat::PDF_417,
"qrcode" | "qr_code" | "qr code" => BarcodeFormat::QR_CODE, "qrcode" | "qr_code" | "qr code" => BarcodeFormat::QR_CODE,
"mqr" | "microqr" | "micro_qr" | "micro_qrcode" | "micro_qr_code" | "mqr_code" => {
BarcodeFormat::MICRO_QR_CODE
}
"rss 14" | "rss_14" | "rss14" | "gs1 databar" | "gs1 databar coupon" "rss 14" | "rss_14" | "rss14" | "gs1 databar" | "gs1 databar coupon"
| "gs1_databar_coupon" => BarcodeFormat::RSS_14, | "gs1_databar_coupon" => BarcodeFormat::RSS_14,
"rss expanded" | "expanded rss" | "rss_expanded" => BarcodeFormat::RSS_EXPANDED, "rss expanded" | "expanded rss" | "rss_expanded" => BarcodeFormat::RSS_EXPANDED,

View File

@@ -17,6 +17,7 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use crate::common::Result; use crate::common::Result;
use crate::qrcode::cpp_port::QrReader;
use crate::{ use crate::{
aztec::AztecReader, datamatrix::DataMatrixReader, maxicode::MaxiCodeReader, aztec::AztecReader, datamatrix::DataMatrixReader, maxicode::MaxiCodeReader,
oned::MultiFormatOneDReader, pdf417::PDF417Reader, qrcode::QRCodeReader, BarcodeFormat, oned::MultiFormatOneDReader, pdf417::PDF417Reader, qrcode::QRCodeReader, BarcodeFormat,
@@ -164,7 +165,16 @@ impl MultiFormatReader {
for possible_format in self.possible_formats.iter() { for possible_format in self.possible_formats.iter() {
let res = match possible_format { let res = match possible_format {
BarcodeFormat::QR_CODE => { BarcodeFormat::QR_CODE => {
QRCodeReader::default().decode_with_hints(image, &self.hints) let default_qr =
QRCodeReader::default().decode_with_hints(image, &self.hints);
if default_qr.is_ok() {
default_qr
} else {
QrReader::default().decode_with_hints(image, &self.hints)
}
}
BarcodeFormat::MICRO_QR_CODE => {
QrReader::default().decode_with_hints(image, &self.hints)
} }
BarcodeFormat::DATA_MATRIX => { BarcodeFormat::DATA_MATRIX => {
DataMatrixReader::default().decode_with_hints(image, &self.hints) DataMatrixReader::default().decode_with_hints(image, &self.hints)
@@ -199,6 +209,9 @@ impl MultiFormatReader {
if let Ok(res) = QRCodeReader::default().decode_with_hints(image, &self.hints) { if let Ok(res) = QRCodeReader::default().decode_with_hints(image, &self.hints) {
return Ok(res); return Ok(res);
} }
if let Ok(res) = QrReader::default().decode_with_hints(image, &self.hints) {
return Ok(res);
}
if let Ok(res) = DataMatrixReader::default().decode_with_hints(image, &self.hints) { if let Ok(res) = DataMatrixReader::default().decode_with_hints(image, &self.hints) {
return Ok(res); return Ok(res);
} }

View File

@@ -27,9 +27,9 @@ use crate::{
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
pub struct FinderPatternSet { pub struct FinderPatternSet {
bl: ConcentricPattern, pub bl: ConcentricPattern,
tl: ConcentricPattern, pub tl: ConcentricPattern,
tr: ConcentricPattern, pub tr: ConcentricPattern,
} }
pub type FinderPatterns = Vec<ConcentricPattern>; pub type FinderPatterns = Vec<ConcentricPattern>;

View File

@@ -5,22 +5,6 @@
*/ */
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// #include "QRReader.h"
// #include "BinaryBitmap.h"
// #include "ConcentricFinder.h"
// #include "DecodeHints.h"
// #include "DecoderResult.h"
// #include "DetectorResult.h"
// #include "LogMatrix.h"
// #include "QRDecoder.h"
// #include "QRDetector.h"
// #include "Result.h"
// #include <utility>
// namespace ZXing::QRCode {
// Result Reader::decode(const BinaryBitmap& image) const // Result Reader::decode(const BinaryBitmap& image) const
// { // {
// #if 1 // #if 1
@@ -133,13 +117,31 @@
// } // namespace ZXing::QRCode // } // namespace ZXing::QRCode
use crate::{
common::{cpp_essentials::ConcentricPattern, DetectorRXingResult, HybridBinarizer},
multi::MultipleBarcodeReader,
BarcodeFormat, BinaryBitmap, DecodeHintType, DecodeHintValue, DecodingHintDictionary,
Exceptions, RXingResult, Reader,
};
use crate::{Reader, DecodingHintDictionary, multi::MultipleBarcodeReader}; use super::{
decoder::Decode,
detector::{
DetectPureMQR, DetectPureQR, FindFinderPatterns, GenerateFinderPatternSets, SampleMQR,
SampleQR,
},
};
pub struct QrReader{} use crate::qrcode::detector::QRCodeDetectorResult as DetectorResult;
#[derive(Default)]
pub struct QrReader;
impl Reader for QrReader { impl Reader for QrReader {
fn decode<B: crate::Binarizer>(&mut self, image: &mut crate::BinaryBitmap<B>) -> crate::common::Result<crate::RXingResult> { fn decode<B: crate::Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap<B>,
) -> crate::common::Result<crate::RXingResult> {
self.decode_with_hints(image, &DecodingHintDictionary::new()) self.decode_with_hints(image, &DecodingHintDictionary::new())
} }
@@ -147,47 +149,67 @@ impl Reader for QrReader {
&mut self, &mut self,
image: &mut crate::BinaryBitmap<B>, image: &mut crate::BinaryBitmap<B>,
hints: &crate::DecodingHintDictionary, hints: &crate::DecodingHintDictionary,
) -> crate::common::Result<crate::RXingResult> { ) -> crate::common::Result<RXingResult> {
todo!()
// #if 1 // #if 1
if !matches!(
hints.get(&DecodeHintType::PURE_BARCODE),
Some(DecodeHintValue::PureBarcode(true))
)
// if !matches!(Some(hints.get(&DecodeHintType::PURE_BARCODE)))
// if (!_hints.isPure()) // if (!_hints.isPure())
{
return Ok(self
.decode_set_number_with_hints(image, hints, 1)?
.first()
.ok_or(Exceptions::NOT_FOUND)?
.clone());
// return FirstOrDefault(decode(image, 1)); // return FirstOrDefault(decode(image, 1));
}
// #endif // #endif
// auto binImg = image.getBitMatrix(); let binImg = image.get_black_matrix(); //image.getBitMatrix();
// if (binImg == nullptr) // if (binImg == nullptr)
// return {}; // {return {};}
// DetectorResult detectorResult; let mut detectorResult = Err(Exceptions::NOT_FOUND);
// if (_hints.hasFormat(BarcodeFormat::QRCode)) if let Some(DecodeHintValue::PossibleFormats(formats)) =
// detectorResult = DetectPureQR(*binImg); hints.get(&DecodeHintType::POSSIBLE_FORMATS)
// if (_hints.hasFormat(BarcodeFormat::MicroQRCode) && !detectorResult.isValid()) {
// detectorResult = DetectPureMQR(*binImg); if formats.contains(&BarcodeFormat::QR_CODE) {
detectorResult = DetectPureQR(binImg);
}
if formats.contains(&BarcodeFormat::MICRO_QR_CODE) && detectorResult.is_err() {
detectorResult = DetectPureMQR(binImg);
}
}
let detectorResult = detectorResult?;
// let detectorResult: DetectorResult;
// if (_hints.hasFormat(BarcodeFormat::QR_CODE))
// {detectorResult = DetectPureQR(binImg);}
// if (_hints.hasFormat(BarcodeFormat::MICRO_QR_CODE) && !detectorResult.isValid())
// {detectorResult = DetectPureMQR(binImg);}
// if (!detectorResult.isValid()) // if (!detectorResult.isValid())
// return {}; // {return {};}
// auto decoderResult = Decode(detectorResult.bits()); let decoderResult = Decode(detectorResult.getBits())?;
// auto position = detectorResult.position(); let position = detectorResult.getPoints();
Ok(RXingResult::new(
&decoderResult.content().to_string(),
decoderResult.content().bytes().to_vec(),
position.to_vec(),
if detectorResult.getBits().width() < 21 {
BarcodeFormat::MICRO_QR_CODE
} else {
BarcodeFormat::QR_CODE
},
))
// return Result(std::move(decoderResult), std::move(position), // return Result(std::move(decoderResult), std::move(position),
// detectorResult.bits().width() < 21 ? BarcodeFormat::MicroQRCode : BarcodeFormat::QRCode); // detectorResult.bits().width() < 21 ? BarcodeFormat::MICRO_QR_CODE : BarcodeFormat::QR_CODE);
// }
// void logFPSet(const FinderPatternSet& fps [[maybe_unused]])
// {
// #ifdef PRINT_DEBUG
// auto drawLine = [](PointF a, PointF b) {
// int steps = maxAbsComponent(b - a);
// PointF dir = bresenhamDirection(PointF(b - a));
// for (int i = 0; i < steps; ++i)
// log(centered(a + i * dir), 2);
// };
// drawLine(fps.bl, fps.tl);
// drawLine(fps.tl, fps.tr);
// drawLine(fps.tr, fps.bl);
// #endif
} }
} }
@@ -204,69 +226,125 @@ impl MultipleBarcodeReader for QrReader {
image: &mut crate::BinaryBitmap<B>, image: &mut crate::BinaryBitmap<B>,
hints: &DecodingHintDictionary, hints: &DecodingHintDictionary,
) -> crate::common::Result<Vec<crate::RXingResult>> { ) -> crate::common::Result<Vec<crate::RXingResult>> {
todo!() self.decode_set_number_with_hints(image, hints, u32::MAX)
// auto binImg = image.getBitMatrix(); }
}
impl QrReader {
fn decode_set_number_with_hints<B: crate::Binarizer>(
&mut self,
image: &mut crate::BinaryBitmap<B>,
hints: &DecodingHintDictionary,
count: u32,
) -> crate::common::Result<Vec<RXingResult>> {
let binImg = image.get_black_matrix(); //image.getBitMatrix();
let maxSymbols = count;
// if (binImg == nullptr) // if (binImg == nullptr)
// return {}; // {return {};}
// #ifdef PRINT_DEBUG // #ifdef PRINT_DEBUG
// LogMatrixWriter lmw(log, *binImg, 5, "qr-log.pnm"); // LogMatrixWriter lmw(log, *binImg, 5, "qr-log.pnm");
// #endif // #endif
let try_harder = matches!(
hints.get(&DecodeHintType::TRY_HARDER),
Some(DecodeHintValue::TryHarder(true))
);
// auto allFPs = FindFinderPatterns(*binImg, _hints.tryHarder()); let mut allFPs = FindFinderPatterns(binImg, try_harder);
// #ifdef PRINT_DEBUG // #ifdef PRINT_DEBUG
// printf("allFPs: %d\n", Size(allFPs)); // printf("allFPs: %d\n", Size(allFPs));
// #endif // #endif
// std::vector<ConcentricPattern> usedFPs; let mut usedFPs: Vec<ConcentricPattern> = Vec::new();
// Results results; let mut results: Vec<RXingResult> = Vec::new();
let (check_qr, check_mqr) = if let Some(DecodeHintValue::PossibleFormats(formats)) =
hints.get(&DecodeHintType::POSSIBLE_FORMATS)
{
(
formats.contains(&BarcodeFormat::QR_CODE),
formats.contains(&BarcodeFormat::MICRO_QR_CODE),
)
} else {
(true, true)
};
if check_qr {
// if (_hints.hasFormat(BarcodeFormat::QRCode)) { // if (_hints.hasFormat(BarcodeFormat::QRCode)) {
// auto allFPSets = GenerateFinderPatternSets(allFPs); let allFPSets = GenerateFinderPatternSets(&mut allFPs);
for fpSet in allFPSets {
// for (const auto& fpSet : allFPSets) { // for (const auto& fpSet : allFPSets) {
// if (Contains(usedFPs, fpSet.bl) || Contains(usedFPs, fpSet.tl) || Contains(usedFPs, fpSet.tr)) if (usedFPs.contains(&fpSet.bl)
// continue; || usedFPs.contains(&fpSet.tl)
|| usedFPs.contains(&fpSet.tr))
{
continue;
}
// logFPSet(fpSet); // logFPSet(fpSet);
// auto detectorResult = SampleQR(*binImg, fpSet); let detectorResult = SampleQR(binImg, &fpSet);
// if (detectorResult.isValid()) { if let Ok(detectorResult) = detectorResult {
// auto decoderResult = Decode(detectorResult.bits()); // if (detectorResult.is_ok()) {
// auto position = detectorResult.position(); let decoderResult = Decode(detectorResult.getBits());
// if (decoderResult.isValid()) { let position = detectorResult.getPoints();
// usedFPs.push_back(fpSet.bl); if let Ok(decoderResult) = decoderResult {
// usedFPs.push_back(fpSet.tl); if (decoderResult.isValid()) {
// usedFPs.push_back(fpSet.tr); usedFPs.push(fpSet.bl);
// } usedFPs.push(fpSet.tl);
// if (decoderResult.isValid(_hints.returnErrors())) { usedFPs.push(fpSet.tr);
// results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QRCode); }
// if (maxSymbols && Size(results) == maxSymbols)
// break;
// }
// }
// }
// }
if (decoderResult.isValid()) {
results.push(RXingResult::new(
&decoderResult.content().to_string(),
decoderResult.content().bytes().to_vec(),
position.to_vec(),
BarcodeFormat::QR_CODE,
));
// results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::QR_CODE);
if (maxSymbols != 0 && (results.len() as u32) == maxSymbols) {
break;
}
}
}
}
}
}
if (check_mqr && !(maxSymbols != 0 && (results.len() as u32) == maxSymbols)) {
// if (_hints.hasFormat(BarcodeFormat::MicroQRCode) && !(maxSymbols && Size(results) == maxSymbols)) { // if (_hints.hasFormat(BarcodeFormat::MicroQRCode) && !(maxSymbols && Size(results) == maxSymbols)) {
for fp in allFPs {
// for (const auto& fp : allFPs) { // for (const auto& fp : allFPs) {
// if (Contains(usedFPs, fp)) if (usedFPs.contains(&fp)) {
// continue; continue;
}
// auto detectorResult = SampleMQR(*binImg, fp); let detectorResult = SampleMQR(binImg, fp);
// if (detectorResult.isValid()) { if let Ok(detectorResult) = detectorResult {
// auto decoderResult = Decode(detectorResult.bits()); // if (detectorResult.is_ok()) {
// auto position = detectorResult.position(); let decoderResult = Decode(detectorResult.getBits());
// if (decoderResult.isValid(_hints.returnErrors())) { let position = detectorResult.getPoints();
// results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MicroQRCode); if let Ok(decoderResult) = decoderResult {
// if (maxSymbols && Size(results) == maxSymbols) if (decoderResult.isValid()) {
// break; results.push(RXingResult::new(
// } &decoderResult.content().to_string(),
decoderResult.content().bytes().to_vec(),
position.to_vec(),
BarcodeFormat::MICRO_QR_CODE,
));
// results.emplace_back(std::move(decoderResult), std::move(position), BarcodeFormat::MICRO_QR_CODE);
// } if (maxSymbols != 0 && (results.len() as u32) == maxSymbols) {
// } break;
// } }
}
// return results; }
}
}
}
return Ok(results);
} }
} }

View File

@@ -8,7 +8,7 @@ pub use qr_code_reader::*;
mod qr_code_writer; mod qr_code_writer;
pub use qr_code_writer::*; pub use qr_code_writer::*;
mod cpp_port; pub mod cpp_port;
#[cfg(test)] #[cfg(test)]
#[cfg(feature = "image")] #[cfg(feature = "image")]