working invert

This commit is contained in:
Henry
2022-08-21 22:39:42 -05:00
parent d1f4b9a77e
commit a5e10457c7

View File

@@ -1,29 +1,31 @@
mod common;
use std::fmt;
use std::any::{Any,TypeId};
use std::time::SystemTime;
use crate::common::{BitArray, BitMatrix};
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::fmt;
use std::hash::Hash;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug)]
pub struct IllegalArgumentException {
message: String,
}
impl IllegalArgumentException {
pub fn new(message: &str) -> Self {
Self {
message: message.to_owned()
message: message.to_owned(),
}
}
}
#[derive(Debug)]
pub struct UnsupportedOperationException {
message: String,
}
impl UnsupportedOperationException {
pub fn new(message: &str) -> Self {
Self {
message: message.to_owned()
message: message.to_owned(),
}
}
}
@@ -194,7 +196,6 @@ impl WriterException {
* @author Sean Owen
*/
pub enum BarcodeFormat {
/** Aztec 2D barcode format. */
AZTEC,
@@ -244,11 +245,9 @@ pub enum BarcodeFormat {
UPC_E,
/** UPC/EAN extension format. Not a stand-alone format. */
UPC_EAN_EXTENSION
UPC_EAN_EXTENSION,
}
/*
* Copyright 2008 ZXing authors
*
@@ -273,7 +272,6 @@ pub enum BarcodeFormat {
* @author dswitkin@google.com (Daniel Switkin)
*/
pub enum EncodeHintType {
/**
* Specifies what degree of error correction to use, for example in QR Codes.
* Type depends on the encoder. For example for QR codes it's type
@@ -387,7 +385,6 @@ pub enum EncodeHintType {
*/
QR_MASK_PATTERN,
/**
* Specifies whether to use compact mode for QR code (type {@link Boolean}, or "true" or "false"
* {@link String } value).
@@ -424,7 +421,6 @@ pub enum EncodeHintType {
* exclusive.
*/
CODE128_COMPACT,
}
/*
@@ -455,7 +451,6 @@ pub enum EncodeHintType {
* @see Reader#decode(BinaryBitmap,java.util.Map)
*/
pub enum DecodeHintType {
/**
* Unspecified, application-specific hint. Maps to an unspecified {@link Object}.
*/
@@ -515,7 +510,6 @@ pub enum DecodeHintType {
*/
NEED_RESULT_POINT_CALLBACK,
/**
* Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this.
* Maps to an {@code int[]} of the allowed extension lengths, for example [2], [5], or [2, 5].
@@ -530,7 +524,6 @@ pub enum DecodeHintType {
* second time with an inverted image. Doesn't matter what it maps to; use {@link Boolean#TRUE}.
*/
ALSO_INVERTED,
// End of enumeration values.
/*
@@ -551,12 +544,8 @@ pub enum DecodeHintType {
public Class<?> getValueType() {
return valueType;
}*/
}
/*
* Copyright 2008 ZXing authors
*
@@ -581,7 +570,6 @@ pub enum DecodeHintType {
* @author dswitkin@google.com (Daniel Switkin)
*/
pub trait Writer {
/**
* Encode a barcode using the default settings.
*
@@ -592,7 +580,12 @@ pub trait Writer {
* @return {@link BitMatrix} representing encoded barcode image
* @throws WriterException if contents cannot be encoded legally in a format
*/
fn encode( contents : &str, format : &BarcodeFormat, width : i32, height:i32) -> Result<BitMatrix,WriterException>;
fn encode(
contents: &str,
format: &BarcodeFormat,
width: i32,
height: i32,
) -> Result<BitMatrix, WriterException>;
/**
* @param contents The contents to encode in the barcode
@@ -603,15 +596,15 @@ pub trait Writer {
* @return {@link BitMatrix} representing encoded barcode image
* @throws WriterException if contents cannot be encoded legally in a format
*/
fn encode_with_hints<T>( contents :&str,
fn encode_with_hints<T>(
contents: &str,
format: &BarcodeFormat,
width: i32,
height: i32,
hints:HashMap<EncodeHintType,T>) -> Result<BitMatrix,WriterException>;
hints: HashMap<EncodeHintType, T>,
) -> Result<BitMatrix, WriterException>;
}
/*
* Copyright 2007 ZXing authors
*
@@ -633,7 +626,7 @@ pub trait Writer {
pub enum ReaderDecodeException {
NotFoundException(NotFoundException),
ChecksumException(ChecksumException),
FormatException(FormatException)
FormatException(FormatException),
}
/**
@@ -649,7 +642,6 @@ pub enum ReaderDecodeException {
* @author dswitkin@google.com (Daniel Switkin)
*/
pub trait Reader {
/**
* Locates and decodes a barcode in some format within an image.
*
@@ -675,14 +667,16 @@ pub trait Reader {
* @throws ChecksumException if a potential barcode is found but does not pass its checksum
* @throws FormatException if a potential barcode is found but format is invalid
*/
fn decode_with_hints<T>( image:BinaryBitmap, hints:HashMap<DecodeHintType,T>) -> Result<RXingResult<'static>,ReaderDecodeException>;
fn decode_with_hints<T>(
image: BinaryBitmap,
hints: HashMap<DecodeHintType, T>,
) -> Result<RXingResult<'static>, ReaderDecodeException>;
/**
* Resets any internal state the implementation has after a decode, to prepare it
* for reuse.
*/
fn reset();
}
/*
@@ -709,8 +703,8 @@ pub trait Reader {
*
* @author Sean Owen
*/
#[derive(Eq, PartialEq, Hash)]
pub enum RXingResultMetadataType {
/**
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
*/
@@ -789,7 +783,6 @@ pub enum RXingResultMetadataType {
SYMBOLOGY_IDENTIFIER,
}
/*
* Copyright 2007 ZXing authors
*
@@ -817,39 +810,58 @@ pub enum RXingResultMetadataType {
* @author Sean Owen
*/
pub struct RXingResult<'a> {
text: String,
rawBytes: Vec<u8>,
numBits: usize,
resultPoints: Vec<RXingResultPoint>,
format: BarcodeFormat,
resultMetadata: Option<HashMap<RXingResultMetadataType, &'a dyn Any>>,
timestamp:i64,
timestamp: u128,
}
impl RXingResult<'_> {
pub fn new( text: &str,
rawBytes: &Vec<u8>,
resultPoints:&Vec<RXingResultPoint>,
format:BarcodeFormat) -> Self{
Self::new_timestamp(text, rawBytes, resultPoints, &format, SystemTime::now())
}
pub fn new_timestamp( text : &str,
pub fn new(
text: &str,
rawBytes: Vec<u8>,
resultPoints: Vec<RXingResultPoint>,
format: BarcodeFormat,
timestamp : i64) -> Self{
Self::new_complex(text, rawBytes, 8 * rawBytes.len(),
resultPoints, format, timestamp)
) -> Self {
Self::new_timestamp(
text,
rawBytes,
resultPoints,
format,
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis(),
)
}
pub fn new_complex( text:&str,
pub fn new_timestamp(
text: &str,
rawBytes: Vec<u8>,
resultPoints: Vec<RXingResultPoint>,
format: BarcodeFormat,
timestamp: u128,
) -> Self {
Self::new_complex(
text,
rawBytes,
8 * rawBytes.len(),
resultPoints,
format,
timestamp,
)
}
pub fn new_complex(
text: &str,
rawBytes: Vec<u8>,
numBits: usize,
resultPoints: Vec<RXingResultPoint>,
format: BarcodeFormat,
timestamp:i64) -> Self{
timestamp: u128,
) -> Self {
Self {
text: text.to_owned(),
rawBytes: rawBytes,
@@ -936,10 +948,9 @@ impl RXingResult<'_> {
}
}
pub fn getTimestamp(&self) -> i64 {
pub fn getTimestamp(&self) -> u128 {
return self.timestamp;
}
}
impl fmt::Display for RXingResult<'_> {
@@ -948,7 +959,6 @@ impl fmt::Display for RXingResult<'_>{
}
}
/*
* Copyright 2007 ZXing authors
*
@@ -992,10 +1002,7 @@ impl PartialEq for RXingResultPoint {
impl Eq for RXingResultPoint {}
impl RXingResultPoint {
pub fn new(x: f32, y: f32) -> Self {
Self{
x,
y,
}
Self { x, y }
}
pub fn getX(&self) -> f32 {
@@ -1013,11 +1020,25 @@ impl RXingResultPoint {
* @param patterns array of three {@code RXingResultPoint} to order
*/
pub fn orderBestPatterns(patterns: &Vec<RXingResultPoint>) {
// Find distances between pattern centers
let zeroOneDistance = MathUtils::distance_float(patterns[0], patterns[1]);
let oneTwoDistance = MathUtils::distance_float(patterns[1], patterns[2]);
let zeroTwoDistance = MathUtils::distance_float(patterns[0], patterns[2]);
let zeroOneDistance = MathUtils::distance_float(
patterns[0].getX(),
patterns[0].getY(),
patterns[1].getX(),
patterns[1].getY(),
);
let oneTwoDistance = MathUtils::distance_float(
patterns[1].getX(),
patterns[1].getY(),
patterns[2].getX(),
patterns[2].getY(),
);
let zeroTwoDistance = MathUtils::distance_float(
patterns[0].getX(),
patterns[0].getY(),
patterns[2].getX(),
patterns[2].getY(),
);
let pointA: RXingResultPoint;
let pointB: RXingResultPoint;
@@ -1064,14 +1085,15 @@ impl RXingResultPoint {
/**
* Returns the z component of the cross product between vectors BC and BA.
*/
pub fn crossProductZ( pointA :&RXingResultPoint,
pub fn crossProductZ(
pointA: &RXingResultPoint,
pointB: &RXingResultPoint,
pointC: &RXingResultPoint) -> f32 {
pointC: &RXingResultPoint,
) -> f32 {
let bX = pointB.x;
let bY = pointB.y;
return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
}
}
impl fmt::Display for RXingResultPoint {
@@ -1080,7 +1102,6 @@ impl fmt::Display for RXingResultPoint {
}
}
/*
* Copyright 2012 ZXing authors
*
@@ -1104,7 +1125,6 @@ impl fmt::Display for RXingResultPoint {
*/
#[derive(Eq, PartialEq, Hash)]
pub struct Dimension {
width: usize,
height: usize,
}
@@ -1114,10 +1134,7 @@ impl Dimension {
if (width < 0 || height < 0) {
return Err(IllegalArgumentException::new(""));
}
Ok(Self{
width,
height,
})
Ok(Self { width, height })
}
pub fn getWidth(&self) -> usize {
@@ -1127,17 +1144,14 @@ impl Dimension {
pub fn getHeight(&self) -> usize {
return self.height;
}
}
impl fmt::Display for Dimension {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}x{}", self.width, self.height)
}
}
/*
* Copyright 2009 ZXing authors
*
@@ -1165,7 +1179,6 @@ impl fmt::Display for Dimension {
* @author dswitkin@google.com (Daniel Switkin)
*/
pub trait Binarizer {
//private final LuminanceSource source;
//fn new(source:dyn LuminanceSource) -> Self;
@@ -1206,15 +1219,13 @@ pub trait Binarizer {
* @param source The LuminanceSource this Binarizer will operate on.
* @return A new concrete Binarizer implementation object.
*/
fn createBinarizer(&self, source:dyn LuminanceSource) -> dyn Binarizer;
fn createBinarizer(&self, source: Box<dyn LuminanceSource>) -> Box<dyn Binarizer>;
fn getWidth(&self) -> usize;
fn getHeight(&self) -> usize;
}
/*
* Copyright 2009 ZXing authors
*
@@ -1240,17 +1251,15 @@ pub trait Binarizer {
* @author dswitkin@google.com (Daniel Switkin)
*/
pub struct BinaryBitmap {
binarizer: Box<dyn Binarizer>,
matrix: BitMatrix,
}
impl BinaryBitmap {
pub fn new(binarizer: Box<dyn Binarizer>) -> Self {
Self {
binarizer: binarizer,
matrix: binarizer.getBlackMatrix()
matrix: binarizer.getBlackMatrix(),
}
}
@@ -1319,8 +1328,14 @@ impl BinaryBitmap{
* @return A cropped version of this object.
*/
pub fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> BinaryBitmap {
let newSource = self.binarizer.getLuminanceSource().crop(left, top, width, height);
return BinaryBitmap::new(self.binarizer.createBinarizer(newSource));
let newSource = self
.binarizer
.getLuminanceSource()
.crop(left, top, width, height);
return BinaryBitmap::new(
self.binarizer
.createBinarizer(newSource.expect("new lum source expected")),
);
}
/**
@@ -1338,7 +1353,10 @@ impl BinaryBitmap{
*/
pub fn rotateCounterClockwise(&self) -> BinaryBitmap {
let newSource = self.binarizer.getLuminanceSource().rotateCounterClockwise();
return BinaryBitmap::new(self.binarizer.createBinarizer(newSource));
return BinaryBitmap::new(
self.binarizer
.createBinarizer(newSource.expect("new lum source expected")),
);
}
/**
@@ -1348,10 +1366,15 @@ impl BinaryBitmap{
* @return A rotated version of this object.
*/
pub fn rotateCounterClockwise45(&self) -> BinaryBitmap {
let newSource = self.binarizer.getLuminanceSource().rotateCounterClockwise45();
return BinaryBitmap::new(self.binarizer.createBinarizer(newSource));
let newSource = self
.binarizer
.getLuminanceSource()
.rotateCounterClockwise45();
return BinaryBitmap::new(
self.binarizer
.createBinarizer(newSource.expect("new lum source expected")),
);
}
}
impl fmt::Display for BinaryBitmap {
@@ -1360,7 +1383,6 @@ impl fmt::Display for BinaryBitmap {
}
}
/*
* Copyright 2009 ZXing authors
*
@@ -1386,13 +1408,9 @@ impl fmt::Display for BinaryBitmap {
* @see DecodeHintType#NEED_RESULT_POINT_CALLBACK
*/
pub trait RXingResultPointCallback {
fn foundPossibleRXingResultPoint(point: RXingResultPoint);
}
/*
* Copyright 2009 ZXing authors
*
@@ -1421,7 +1439,6 @@ pub trait RXingResultPointCallback {
* @author dswitkin@google.com (Daniel Switkin)
*/
pub trait LuminanceSource {
//private final int width;
//private final int height;
@@ -1478,8 +1495,16 @@ pub trait LuminanceSource {
* @param height The height of the rectangle to crop.
* @return A cropped version of this object.
*/
fn crop(&self, left:usize, top:usize, width:usize, height:usize) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
return Err( UnsupportedOperationException::new("This luminance source does not support cropping."));
fn crop(
&self,
left: usize,
top: usize,
width: usize,
height: usize,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
return Err(UnsupportedOperationException::new(
"This luminance source does not support cropping.",
));
}
/**
@@ -1493,9 +1518,9 @@ pub trait LuminanceSource {
* @return a wrapper of this {@code LuminanceSource} which inverts the luminances it returns -- black becomes
* white and vice versa, and each value becomes (255-value).
*/
fn invert(&self) -> InvertedLuminanceSource{
fn invert(&self) -> Box<dyn LuminanceSource>; /* {
return InvertedLuminanceSource::new_with_delegate(self);
}
}*/
/**
* Returns a new object with rotated image data by 90 degrees counterclockwise.
@@ -1503,8 +1528,12 @@ pub trait LuminanceSource {
*
* @return A rotated version of this object.
*/
fn rotateCounterClockwise(&self) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
return Err(UnsupportedOperationException::new("This luminance source does not support rotation by 90 degrees."));
fn rotateCounterClockwise(
&self,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
return Err(UnsupportedOperationException::new(
"This luminance source does not support rotation by 90 degrees.",
));
}
/**
@@ -1513,8 +1542,12 @@ pub trait LuminanceSource {
*
* @return A rotated version of this object.
*/
fn rotateCounterClockwise45(&self) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
return Err( UnsupportedOperationException::new("This luminance source does not support rotation by 45 degrees."));
fn rotateCounterClockwise45(
&self,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
return Err(UnsupportedOperationException::new(
"This luminance source does not support rotation by 45 degrees.",
));
}
/*
@@ -1542,10 +1575,8 @@ pub trait LuminanceSource {
}
return result.toString();
}*/
}
/*
* Copyright 2013 ZXing authors
*
@@ -1584,6 +1615,7 @@ impl InvertedLuminanceSource {
delegate,
}
}
fn new(width: usize, height: usize) -> Self {
let new_ils: Self;
new_ils.width = width;
@@ -1627,8 +1659,15 @@ for i in 0..length {
return self.delegate.isCropSupported();
}
fn crop(&self, left:usize, top:usize, width:usize, height:usize) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
return InvertedLuminanceSource::new_with_delegate(self.delegate.crop(left, top, width, height));
fn crop(
&self,
left: usize,
top: usize,
width: usize,
height: usize,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
let crop = self.delegate.crop(left, top, width, height)?;
return Ok(Box::new(InvertedLuminanceSource::new_with_delegate(crop)));
}
fn isRotateSupported(&self) -> bool {
@@ -1638,18 +1677,23 @@ for i in 0..length {
/**
* @return original delegate {@link LuminanceSource} since invert undoes itself
*/
fn invert(&self) -> InvertedLuminanceSource{
fn invert(&self) -> Box<(dyn LuminanceSource)> {
return self.delegate;
}
fn rotateCounterClockwise(&self) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
return InvertedLuminanceSource::new_with_delegate(self.delegate.rotateCounterClockwise());
fn rotateCounterClockwise(
&self,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
let rot = self.delegate.rotateCounterClockwise()?;
return Ok(Box::new(InvertedLuminanceSource::new_with_delegate(rot)));
}
fn rotateCounterClockwise45(&self) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
return InvertedLuminanceSource::new_with_delegate(self.delegate.rotateCounterClockwise45());
fn rotateCounterClockwise45(
&self,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
let rot_45 = self.delegate.rotateCounterClockwise45()?;
return Ok(Box::new(InvertedLuminanceSource::new_with_delegate(rot_45)));
}
}
/*
@@ -1683,7 +1727,6 @@ const THUMBNAIL_SCALE_FACTOR: usize = 2;
* @author dswitkin@google.com (Daniel Switkin)
*/
pub struct PlanarYUVLuminanceSource {
yuvData: Vec<u8>,
dataWidth: usize,
dataHeight: usize,
@@ -1702,11 +1745,12 @@ impl PlanarYUVLuminanceSource {
top: usize,
width: usize,
height: usize,
reverseHorizontal:bool) -> Result<Self,IllegalArgumentException> {
reverseHorizontal: bool,
) -> Result<Self, IllegalArgumentException> {
if (left + width > dataWidth || top + height > dataHeight) {
return Err( IllegalArgumentException::new("Crop rectangle does not fit within image data."));
return Err(IllegalArgumentException::new(
"Crop rectangle does not fit within image data.",
));
}
let new_s: Self = Self {
@@ -1793,11 +1837,9 @@ impl PlanarYUVLuminanceSource {
new_ils
}
}
impl LuminanceSource for PlanarYUVLuminanceSource {
fn getRow(&self, y: usize, row: &Vec<u8>) -> Vec<u8> {
let mut row = row.to_vec();
if (y < 0 || y >= self.getHeight()) {
@@ -1857,15 +1899,23 @@ impl LuminanceSource for PlanarYUVLuminanceSource{
return true;
}
fn crop(&self, left:usize, top:usize, width:usize, height:usize) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
match PlanarYUVLuminanceSource::new_with_all(self.yuvData,
fn crop(
&self,
left: usize,
top: usize,
width: usize,
height: usize,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
match PlanarYUVLuminanceSource::new_with_all(
self.yuvData,
self.dataWidth,
self.dataHeight,
self.left + left,
self.top + top,
width,
height,
false){
false,
) {
Ok(new) => Ok(Box::new(new)),
Err(err) => Err(UnsupportedOperationException::new("")),
}
@@ -1875,6 +1925,11 @@ impl LuminanceSource for PlanarYUVLuminanceSource{
return false;
}
fn invert(&self) -> Box<dyn LuminanceSource> {
let new_i = InvertedLuminanceSource::new_with_delegate(Box::new(*self));
Box::new(new_i)
}
}
/*
@@ -1903,7 +1958,6 @@ impl LuminanceSource for PlanarYUVLuminanceSource{
* @author Betaminos
*/
pub struct RGBLuminanceSource {
luminances: Vec<u8>,
dataWidth: usize,
dataHeight: usize,
@@ -1914,7 +1968,6 @@ pub struct RGBLuminanceSource {
}
impl LuminanceSource for RGBLuminanceSource {
fn getRow(&self, y: usize, row: &Vec<u8>) -> Vec<u8> {
let row = row.to_vec();
if y < 0 || y >= self.getHeight() {
@@ -1972,21 +2025,32 @@ impl LuminanceSource for RGBLuminanceSource {
return true;
}
fn crop(&self, left:usize, top:usize, width:usize, height:usize) -> Result<Box<dyn LuminanceSource>,UnsupportedOperationException> {
match RGBLuminanceSource::new_complex(&self.luminances,
fn crop(
&self,
left: usize,
top: usize,
width: usize,
height: usize,
) -> Result<Box<dyn LuminanceSource>, UnsupportedOperationException> {
match RGBLuminanceSource::new_complex(
&self.luminances,
self.dataWidth,
self.dataHeight,
self.left + left,
self.top + top,
width,
height) {
height,
) {
Ok(crop) => Ok(Box::new(crop)),
Err(error) => Err(UnsupportedOperationException::new("")),
}
}
fn invert(&self) -> Box<dyn LuminanceSource> {
let new_i = InvertedLuminanceSource::new_with_delegate(Box::new(*self));
Box::new(new_i)
}
}
impl RGBLuminanceSource {
@@ -2021,19 +2085,30 @@ impl RGBLuminanceSource {
// Calculate green-favouring average cheaply
luminances[offset] = (r + g2 + b) / 4;
}
Self { luminances, dataWidth, dataHeight, left: left, top: top, width, height }
Self {
luminances,
dataWidth,
dataHeight,
left: left,
top: top,
width,
height,
}
}
fn new_complex( pixels:&Vec<u8>,
fn new_complex(
pixels: &Vec<u8>,
dataWidth: usize,
dataHeight: usize,
left: usize,
top: usize,
width: usize,
height:usize) -> Result<Self,IllegalArgumentException>{
height: usize,
) -> Result<Self, IllegalArgumentException> {
if (left + width > dataWidth || top + height > dataHeight) {
return Err(IllegalArgumentException::new("Crop rectangle does not fit within image data."));
return Err(IllegalArgumentException::new(
"Crop rectangle does not fit within image data.",
));
}
Ok(Self {
luminances: todo!(),
@@ -2046,4 +2121,3 @@ impl RGBLuminanceSource {
})
}
}