mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-28 05:12:34 +00:00
pdf_417_reader port
This commit is contained in:
@@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009 ZXing authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.google.zxing.pdf417;
|
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
|
||||||
import com.google.zxing.BinaryBitmap;
|
|
||||||
import com.google.zxing.ChecksumException;
|
|
||||||
import com.google.zxing.DecodeHintType;
|
|
||||||
import com.google.zxing.FormatException;
|
|
||||||
import com.google.zxing.NotFoundException;
|
|
||||||
import com.google.zxing.Reader;
|
|
||||||
import com.google.zxing.RXingResult;
|
|
||||||
import com.google.zxing.RXingResultMetadataType;
|
|
||||||
import com.google.zxing.RXingResultPoint;
|
|
||||||
import com.google.zxing.common.DecoderRXingResult;
|
|
||||||
import com.google.zxing.multi.MultipleBarcodeReader;
|
|
||||||
import com.google.zxing.pdf417.decoder.PDF417ScanningDecoder;
|
|
||||||
import com.google.zxing.pdf417.detector.Detector;
|
|
||||||
import com.google.zxing.pdf417.detector.PDF417DetectorRXingResult;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This implementation can detect and decode PDF417 codes in an image.
|
|
||||||
*
|
|
||||||
* @author Guenther Grau
|
|
||||||
*/
|
|
||||||
public final class PDF417Reader implements Reader, MultipleBarcodeReader {
|
|
||||||
|
|
||||||
private static final RXingResult[] EMPTY_RESULT_ARRAY = new RXingResult[0];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Locates and decodes a PDF417 code in an image.
|
|
||||||
*
|
|
||||||
* @return a String representing the content encoded by the PDF417 code
|
|
||||||
* @throws NotFoundException if a PDF417 code cannot be found,
|
|
||||||
* @throws FormatException if a PDF417 cannot be decoded
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public RXingResult decode(BinaryBitmap image) throws NotFoundException, FormatException, ChecksumException {
|
|
||||||
return decode(image, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RXingResult decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, FormatException,
|
|
||||||
ChecksumException {
|
|
||||||
RXingResult[] result = decode(image, hints, false);
|
|
||||||
if (result.length == 0 || result[0] == null) {
|
|
||||||
throw NotFoundException.getNotFoundInstance();
|
|
||||||
}
|
|
||||||
return result[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RXingResult[] decodeMultiple(BinaryBitmap image) throws NotFoundException {
|
|
||||||
return decodeMultiple(image, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RXingResult[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException {
|
|
||||||
try {
|
|
||||||
return decode(image, hints, true);
|
|
||||||
} catch (FormatException | ChecksumException ignored) {
|
|
||||||
throw NotFoundException.getNotFoundInstance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static RXingResult[] decode(BinaryBitmap image, Map<DecodeHintType, ?> hints, boolean multiple)
|
|
||||||
throws NotFoundException, FormatException, ChecksumException {
|
|
||||||
List<RXingResult> results = new ArrayList<>();
|
|
||||||
PDF417DetectorRXingResult detectorRXingResult = Detector.detect(image, hints, multiple);
|
|
||||||
for (RXingResultPoint[] points : detectorRXingResult.getPoints()) {
|
|
||||||
DecoderRXingResult decoderRXingResult = PDF417ScanningDecoder.decode(detectorRXingResult.getBits(), points[4], points[5],
|
|
||||||
points[6], points[7], getMinCodewordWidth(points), getMaxCodewordWidth(points));
|
|
||||||
RXingResult result = new RXingResult(decoderRXingResult.getText(), decoderRXingResult.getRawBytes(), points, BarcodeFormat.PDF_417);
|
|
||||||
result.putMetadata(RXingResultMetadataType.ERROR_CORRECTION_LEVEL, decoderRXingResult.getECLevel());
|
|
||||||
PDF417RXingResultMetadata pdf417RXingResultMetadata = (PDF417RXingResultMetadata) decoderRXingResult.getOther();
|
|
||||||
if (pdf417RXingResultMetadata != null) {
|
|
||||||
result.putMetadata(RXingResultMetadataType.PDF417_EXTRA_METADATA, pdf417RXingResultMetadata);
|
|
||||||
}
|
|
||||||
result.putMetadata(RXingResultMetadataType.ORIENTATION, detectorRXingResult.getRotation());
|
|
||||||
result.putMetadata(RXingResultMetadataType.SYMBOLOGY_IDENTIFIER, "]L" + decoderRXingResult.getSymbologyModifier());
|
|
||||||
results.add(result);
|
|
||||||
}
|
|
||||||
return results.toArray(EMPTY_RESULT_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getMaxWidth(RXingResultPoint p1, RXingResultPoint p2) {
|
|
||||||
if (p1 == null || p2 == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) Math.abs(p1.getX() - p2.getX());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getMinWidth(RXingResultPoint p1, RXingResultPoint p2) {
|
|
||||||
if (p1 == null || p2 == null) {
|
|
||||||
return Integer.MAX_VALUE;
|
|
||||||
}
|
|
||||||
return (int) Math.abs(p1.getX() - p2.getX());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getMaxCodewordWidth(RXingResultPoint[] p) {
|
|
||||||
return Math.max(
|
|
||||||
Math.max(getMaxWidth(p[0], p[4]), getMaxWidth(p[6], p[2]) * PDF417Common.MODULES_IN_CODEWORD /
|
|
||||||
PDF417Common.MODULES_IN_STOP_PATTERN),
|
|
||||||
Math.max(getMaxWidth(p[1], p[5]), getMaxWidth(p[7], p[3]) * PDF417Common.MODULES_IN_CODEWORD /
|
|
||||||
PDF417Common.MODULES_IN_STOP_PATTERN));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getMinCodewordWidth(RXingResultPoint[] p) {
|
|
||||||
return Math.min(
|
|
||||||
Math.min(getMinWidth(p[0], p[4]), getMinWidth(p[6], p[2]) * PDF417Common.MODULES_IN_CODEWORD /
|
|
||||||
PDF417Common.MODULES_IN_STOP_PATTERN),
|
|
||||||
Math.min(getMinWidth(p[1], p[5]), getMinWidth(p[7], p[3]) * PDF417Common.MODULES_IN_CODEWORD /
|
|
||||||
PDF417Common.MODULES_IN_STOP_PATTERN));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
// nothing needs to be reset
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -114,7 +114,7 @@ fn applyRotation(matrix: &BitMatrix, rotation: u32) -> BitMatrix {
|
|||||||
* @param bitMatrix bit matrix to detect barcodes in
|
* @param bitMatrix bit matrix to detect barcodes in
|
||||||
* @return List of RXingResultPoint arrays containing the coordinates of found barcodes
|
* @return List of RXingResultPoint arrays containing the coordinates of found barcodes
|
||||||
*/
|
*/
|
||||||
fn detect(multiple: bool, bitMatrix: &BitMatrix) -> Vec<[Option<RXingResultPoint>; 8]> {
|
pub fn detect(multiple: bool, bitMatrix: &BitMatrix) -> Vec<[Option<RXingResultPoint>; 8]> {
|
||||||
let mut barcodeCoordinates: Vec<[Option<RXingResultPoint>; 8]> = Vec::new();
|
let mut barcodeCoordinates: Vec<[Option<RXingResultPoint>; 8]> = Vec::new();
|
||||||
let mut row = 0;
|
let mut row = 0;
|
||||||
let mut column = 0;
|
let mut column = 0;
|
||||||
|
|||||||
@@ -6,3 +6,6 @@ pub mod pdf_417_common;
|
|||||||
|
|
||||||
mod pdf_417_result_metadata;
|
mod pdf_417_result_metadata;
|
||||||
pub use pdf_417_result_metadata::*;
|
pub use pdf_417_result_metadata::*;
|
||||||
|
|
||||||
|
mod pdf_417_reader;
|
||||||
|
pub use pdf_417_reader::*;
|
||||||
|
|||||||
200
src/pdf417/pdf_417_reader.rs
Normal file
200
src/pdf417/pdf_417_reader.rs
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 ZXing authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
multi::MultipleBarcodeReader, BarcodeFormat, BinaryBitmap, DecodingHintDictionary, Exceptions,
|
||||||
|
RXingResult, RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint, Reader,
|
||||||
|
ResultPoint,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
decoder::pdf_417_scanning_decoder, detector::detector, pdf_417_common,
|
||||||
|
PDF417RXingResultMetadata,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation can detect and decode PDF417 codes in an image.
|
||||||
|
*
|
||||||
|
* @author Guenther Grau
|
||||||
|
*/
|
||||||
|
pub struct PDF417Reader;
|
||||||
|
|
||||||
|
impl Reader for PDF417Reader {
|
||||||
|
/**
|
||||||
|
* Locates and decodes a PDF417 code in an image.
|
||||||
|
*
|
||||||
|
* @return a String representing the content encoded by the PDF417 code
|
||||||
|
* @throws NotFoundException if a PDF417 code cannot be found,
|
||||||
|
* @throws FormatException if a PDF417 cannot be decoded
|
||||||
|
*/
|
||||||
|
fn decode(
|
||||||
|
&mut self,
|
||||||
|
image: &crate::BinaryBitmap,
|
||||||
|
) -> Result<crate::RXingResult, crate::Exceptions> {
|
||||||
|
self.decode_with_hints(image, &HashMap::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode_with_hints(
|
||||||
|
&mut self,
|
||||||
|
image: &crate::BinaryBitmap,
|
||||||
|
hints: &crate::DecodingHintDictionary,
|
||||||
|
) -> Result<crate::RXingResult, crate::Exceptions> {
|
||||||
|
let result = Self::decode(image, hints, false)?;
|
||||||
|
if result.is_empty() {
|
||||||
|
// if (result.length == 0 || result[0] == null) {
|
||||||
|
return Err(Exceptions::NotFoundException("".to_owned()));
|
||||||
|
}
|
||||||
|
Ok(result[0].clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl MultipleBarcodeReader for PDF417Reader {
|
||||||
|
fn decodeMultiple(
|
||||||
|
&mut self,
|
||||||
|
image: &crate::BinaryBitmap,
|
||||||
|
) -> Result<Vec<crate::RXingResult>, crate::Exceptions> {
|
||||||
|
self.decodeMultipleWithHints(image, &HashMap::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decodeMultipleWithHints(
|
||||||
|
&mut self,
|
||||||
|
image: &crate::BinaryBitmap,
|
||||||
|
hints: &crate::DecodingHintDictionary,
|
||||||
|
) -> Result<Vec<crate::RXingResult>, crate::Exceptions> {
|
||||||
|
//try {
|
||||||
|
Self::decode(image, hints, true)
|
||||||
|
//} catch (FormatException | ChecksumException ignored) {
|
||||||
|
// throw NotFoundException.getNotFoundInstance();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PDF417Reader {
|
||||||
|
fn decode(
|
||||||
|
image: &BinaryBitmap,
|
||||||
|
hints: &DecodingHintDictionary,
|
||||||
|
multiple: bool,
|
||||||
|
) -> Result<Vec<RXingResult>, Exceptions> {
|
||||||
|
let mut results = Vec::new(); //new ArrayList<>();
|
||||||
|
let detectorRXingResult = detector::detect_with_hints(image, hints, multiple)?;
|
||||||
|
for points in detectorRXingResult.getPoints() {
|
||||||
|
let points_filtered = points.iter().filter_map(|e| e.clone()).collect();
|
||||||
|
// for (RXingResultPoint[] points : detectorRXingResult.getPoints()) {
|
||||||
|
let decoderRXingResult = pdf_417_scanning_decoder::decode(
|
||||||
|
detectorRXingResult.getBits(),
|
||||||
|
points[4],
|
||||||
|
points[5],
|
||||||
|
points[6],
|
||||||
|
points[7],
|
||||||
|
Self::getMinCodewordWidth(points),
|
||||||
|
Self::getMaxCodewordWidth(points),
|
||||||
|
)?;
|
||||||
|
let mut result = RXingResult::new(
|
||||||
|
decoderRXingResult.getText().clone(),
|
||||||
|
decoderRXingResult.getRawBytes().clone(),
|
||||||
|
points_filtered,
|
||||||
|
BarcodeFormat::PDF_417,
|
||||||
|
);
|
||||||
|
|
||||||
|
result.putMetadata(
|
||||||
|
RXingResultMetadataType::ERROR_CORRECTION_LEVEL,
|
||||||
|
RXingResultMetadataValue::ErrorCorrectionLevel(
|
||||||
|
decoderRXingResult.getECLevel().to_owned(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(pdf417RXingResultMetadata) = decoderRXingResult.getOther() {
|
||||||
|
if pdf417RXingResultMetadata.is::<PDF417RXingResultMetadata>() {
|
||||||
|
let data = RXingResultMetadataValue::Pdf417ExtraMetadata(
|
||||||
|
pdf417RXingResultMetadata
|
||||||
|
.clone()
|
||||||
|
.downcast::<PDF417RXingResultMetadata>()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
result.putMetadata(RXingResultMetadataType::PDF417_EXTRA_METADATA, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// PDF417RXingResultMetadata pdf417RXingResultMetadata = (PDF417RXingResultMetadata) decoderRXingResult.getOther();
|
||||||
|
|
||||||
|
// if (pdf417RXingResultMetadata != null) {
|
||||||
|
// result.putMetadata(RXingResultMetadataType.PDF417_EXTRA_METADATA, pdf417RXingResultMetadata);
|
||||||
|
// }
|
||||||
|
|
||||||
|
result.putMetadata(
|
||||||
|
RXingResultMetadataType::ORIENTATION,
|
||||||
|
RXingResultMetadataValue::Orientation(detectorRXingResult.getRotation() as i32),
|
||||||
|
);
|
||||||
|
result.putMetadata(
|
||||||
|
RXingResultMetadataType::SYMBOLOGY_IDENTIFIER,
|
||||||
|
RXingResultMetadataValue::SymbologyIdentifier(format!(
|
||||||
|
"]L{}",
|
||||||
|
decoderRXingResult.getSymbologyModifier()
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
results.push(result);
|
||||||
|
}
|
||||||
|
Ok(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getMaxWidth(p1: &Option<RXingResultPoint>, p2: &Option<RXingResultPoint>) -> u32 {
|
||||||
|
if let (Some(p1), Some(p2)) = (p1, p2) {
|
||||||
|
(p1.getX() - p2.getX()).abs() as u32
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
// if p1 == null || p2 == null {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// return (int) Math.abs(p1.getX() - p2.getX());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getMinWidth(p1: &Option<RXingResultPoint>, p2: &Option<RXingResultPoint>) -> u32 {
|
||||||
|
if let (Some(p1), Some(p2)) = (p1, p2) {
|
||||||
|
(p1.getX() - p2.getX()).abs() as u32
|
||||||
|
} else {
|
||||||
|
u32::MAX
|
||||||
|
}
|
||||||
|
// if (p1 == null || p2 == null) {
|
||||||
|
// return Integer.MAX_VALUE;
|
||||||
|
// }
|
||||||
|
// return (int) Math.abs(p1.getX() - p2.getX());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getMaxCodewordWidth(p: &[Option<RXingResultPoint>]) -> u32 {
|
||||||
|
Self::getMaxWidth(&p[0], &p[4])
|
||||||
|
.max(
|
||||||
|
Self::getMaxWidth(&p[6], &p[2]) * pdf_417_common::MODULES_IN_CODEWORD
|
||||||
|
/ pdf_417_common::MODULES_IN_STOP_PATTERN,
|
||||||
|
)
|
||||||
|
.max(Self::getMaxWidth(&p[1], &p[5]).max(
|
||||||
|
Self::getMaxWidth(&p[7], &p[3]) * pdf_417_common::MODULES_IN_CODEWORD
|
||||||
|
/ pdf_417_common::MODULES_IN_STOP_PATTERN,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getMinCodewordWidth(p: &[Option<RXingResultPoint>]) -> u32 {
|
||||||
|
Self::getMinWidth(&p[0], &p[4])
|
||||||
|
.min(
|
||||||
|
Self::getMinWidth(&p[6], &p[2]) * pdf_417_common::MODULES_IN_CODEWORD
|
||||||
|
/ pdf_417_common::MODULES_IN_STOP_PATTERN,
|
||||||
|
)
|
||||||
|
.min(Self::getMinWidth(&p[1], &p[5]).min(
|
||||||
|
Self::getMinWidth(&p[7], &p[3]) * pdf_417_common::MODULES_IN_CODEWORD
|
||||||
|
/ pdf_417_common::MODULES_IN_STOP_PATTERN,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
/**
|
/**
|
||||||
* @author Guenther Grau
|
* @author Guenther Grau
|
||||||
*/
|
*/
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct PDF417RXingResultMetadata {
|
pub struct PDF417RXingResultMetadata {
|
||||||
segmentIndex: usize,
|
segmentIndex: usize,
|
||||||
fileId: String,
|
fileId: String,
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
//package com.google.zxing;
|
//package com.google.zxing;
|
||||||
|
|
||||||
|
use std::{any::Any, rc::Rc};
|
||||||
|
|
||||||
|
use crate::pdf417::PDF417RXingResultMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents some type of metadata about the result of the decoding that the decoder
|
* Represents some type of metadata about the result of the decoding that the decoder
|
||||||
* wishes to communicate back to the caller.
|
* wishes to communicate back to the caller.
|
||||||
@@ -180,7 +184,7 @@ pub enum RXingResultMetadataValue {
|
|||||||
/**
|
/**
|
||||||
* PDF417-specific metadata
|
* PDF417-specific metadata
|
||||||
*/
|
*/
|
||||||
Pdf417ExtraMetadata(String),
|
Pdf417ExtraMetadata(Rc<PDF417RXingResultMetadata>),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the code format supports structured append and the current scanned code is part of one then the
|
* If the code format supports structured append and the current scanned code is part of one then the
|
||||||
|
|||||||
Reference in New Issue
Block a user