mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
stage: moving performance enhancements into main
several incomplete features are gated behind the `experimental_features` flag.
This commit is contained in:
@@ -12,3 +12,6 @@ keywords = ["barcode", "2d_barcode", "1d_barcode", "barcode_reader", "barcode_wr
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.4.13", features = ["derive"] }
|
clap = { version = "4.4.13", features = ["derive"] }
|
||||||
rxing = {path = "../../", version = "~0.5.7", features = ["image", "svg_read", "svg_write"] }
|
rxing = {path = "../../", version = "~0.5.7", features = ["image", "svg_read", "svg_write"] }
|
||||||
|
|
||||||
|
#[profile.release]
|
||||||
|
#debug = true
|
||||||
@@ -66,6 +66,9 @@ impl BufferedImageLuminanceSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LuminanceSource for BufferedImageLuminanceSource {
|
impl LuminanceSource for BufferedImageLuminanceSource {
|
||||||
|
const SUPPORTS_CROP: bool = true;
|
||||||
|
const SUPPORTS_ROTATION: bool = true;
|
||||||
|
|
||||||
fn get_row(&self, y: usize) -> Vec<u8> {
|
fn get_row(&self, y: usize) -> Vec<u8> {
|
||||||
let width = self.get_width(); // - self.left as usize;
|
let width = self.get_width(); // - self.left as usize;
|
||||||
|
|
||||||
@@ -87,8 +90,6 @@ impl LuminanceSource for BufferedImageLuminanceSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_column(&self, x: usize) -> Vec<u8> {
|
fn get_column(&self, x: usize) -> Vec<u8> {
|
||||||
let width = self.get_height(); // - self.left as usize;
|
|
||||||
|
|
||||||
let pixels: Vec<u8> = || -> Option<Vec<u8>> {
|
let pixels: Vec<u8> = || -> Option<Vec<u8>> {
|
||||||
Some(
|
Some(
|
||||||
self.image
|
self.image
|
||||||
@@ -153,10 +154,6 @@ impl LuminanceSource for BufferedImageLuminanceSource {
|
|||||||
self.height
|
self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_crop_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
image: self.image.clone(),
|
image: self.image.clone(),
|
||||||
@@ -167,10 +164,6 @@ impl LuminanceSource for BufferedImageLuminanceSource {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_rotate_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn invert(&mut self) {
|
fn invert(&mut self) {
|
||||||
let mut img = (*self.image).clone();
|
let mut img = (*self.image).clone();
|
||||||
img.invert();
|
img.invert();
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ fn test_get_next_set5() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_set_bulk() {
|
fn test_set_bulk() {
|
||||||
let mut array = BitArray::with_size(64);
|
let mut array = BitArray::with_size(64);
|
||||||
array.setBulk(32, 0xFFFF0000);
|
array.setBulk(32, 0b11111111111111110000000000000000);
|
||||||
for i in 0..48 {
|
for i in 0..48 {
|
||||||
// for (int i = 0; i < 48; i++) {
|
// for (int i = 0; i < 48; i++) {
|
||||||
assert!(!array.get(i));
|
assert!(!array.get(i));
|
||||||
@@ -150,7 +150,7 @@ fn test_set_bulk() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_append_bit() {
|
fn test_append_bit() {
|
||||||
let mut array = BitArray::new();
|
let mut array = BitArray::new();
|
||||||
array.appendBits(0x000001E, 6).expect("must append)");
|
array.appendBits(0b11110, 6).expect("must append)");
|
||||||
let mut array_2 = BitArray::new();
|
let mut array_2 = BitArray::new();
|
||||||
array_2.appendBit(false);
|
array_2.appendBit(false);
|
||||||
array_2.appendBit(true);
|
array_2.appendBit(true);
|
||||||
@@ -159,7 +159,9 @@ fn test_append_bit() {
|
|||||||
array_2.appendBit(true);
|
array_2.appendBit(true);
|
||||||
array_2.appendBit(false);
|
array_2.appendBit(false);
|
||||||
|
|
||||||
assert_eq!(array, array_2)
|
assert_eq!(array.get_size(), array_2.get_size());
|
||||||
|
|
||||||
|
assert_eq!(array.getBitArray(), array_2.getBitArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -234,18 +236,37 @@ fn test_is_range() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reverse_algorithm_test() {
|
fn reverse_algorithm_test() {
|
||||||
let oldBits: Vec<u32> = vec![128, 256, 512, 6453324, 50934953];
|
let oldBits: Vec<super::BitFieldBaseType> = vec![128, 256, 512, 6453324, 50934953];
|
||||||
for size in 1..160 {
|
for size in 1..160 {
|
||||||
// for (int size = 1; size < 160; size++) {
|
// for (int size = 1; size < 160; size++) {
|
||||||
let newBitsOriginal = reverse_original(&oldBits.clone(), size);
|
let newBitsOriginal = reverse_original(&oldBits.clone(), size);
|
||||||
let mut newBitArray = BitArray::with_initial_values(oldBits.clone(), size);
|
let mut newBitArray = BitArray::with_initial_values(oldBits.clone(), size);
|
||||||
newBitArray.reverse();
|
newBitArray.reverse();
|
||||||
let newBitsNew = newBitArray.getBitArray();
|
let newBitsNew = newBitArray.getBitArray();
|
||||||
assert!(arrays_are_equal(
|
assert!(
|
||||||
&newBitsOriginal,
|
arrays_are_equal(&newBitsOriginal, newBitsNew, size / 32 + 1),
|
||||||
newBitsNew,
|
"size: ({}) : {:?}/{:?}",
|
||||||
size / 32 + 1
|
size,
|
||||||
));
|
newBitsOriginal,
|
||||||
|
newBitsNew
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reverse_test_2() {
|
||||||
|
let initial_data: super::BitFieldBaseType = 0b00_00_11_00_00_00_00_00_00_00_00_00_00_00_00_00;
|
||||||
|
// let expected_data = vec![0b00_00_00_00_00_00_00_00_00_00_00_00_00_11_00_00_u32];
|
||||||
|
// let mut array = BitArray::with_initial_values(initial_data.clone(), 4);
|
||||||
|
for x in 1..=32 {
|
||||||
|
let expected_data = reverse_original(&[initial_data], x);
|
||||||
|
let mut array = BitArray::with_size(x);
|
||||||
|
array.setBulk(0, initial_data);
|
||||||
|
// dbg!(&array);
|
||||||
|
assert_eq!(&[initial_data], array.getBitArray());
|
||||||
|
array.reverse();
|
||||||
|
// dbg!(&array);
|
||||||
|
assert_eq!(expected_data, array.getBitArray(), "for x = {x}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +292,48 @@ fn test_equals() {
|
|||||||
// assert_eq!(a.hash(), b.hash());
|
// assert_eq!(a.hash(), b.hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reverse_original(oldBits: &[u32], size: usize) -> Vec<u32> {
|
#[test]
|
||||||
|
fn test_xor() {
|
||||||
|
let val_1: super::BitFieldBaseType = 0b01_00_11;
|
||||||
|
let val_2: super::BitFieldBaseType = 0b10_11_10;
|
||||||
|
let mut array_1 = BitArray::with_initial_values(vec![val_1], 32);
|
||||||
|
let array_2 = BitArray::with_initial_values(vec![val_2], 32);
|
||||||
|
|
||||||
|
array_1.xor(&array_2).expect("xor complete");
|
||||||
|
|
||||||
|
assert_eq!(array_1.getBitArray(), &[0b11_11_01]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_xor_2() {
|
||||||
|
for i in 1..33 {
|
||||||
|
let val_1: super::BitFieldBaseType = 0b01_00_11;
|
||||||
|
let val_2: super::BitFieldBaseType = 0b10_01_10;
|
||||||
|
let mut array_1 = BitArray::new(); //BitArray::with_initial_values(vec![val_1], i);
|
||||||
|
let mut array_2 = BitArray::new(); //BitArray::with_initial_values(vec![val_2], i);
|
||||||
|
|
||||||
|
array_1.appendBits(val_1, i).expect("append");
|
||||||
|
array_2.appendBits(val_2, i).expect("append");
|
||||||
|
|
||||||
|
array_1.xor(&array_2).expect("xor complete");
|
||||||
|
|
||||||
|
match i {
|
||||||
|
1 => assert_eq!(array_1.getBitArray(), &[0b1]),
|
||||||
|
2 => assert_eq!(array_1.getBitArray(), &[0b10]),
|
||||||
|
3 => assert_eq!(array_1.getBitArray(), &[0b10_1]),
|
||||||
|
4 => assert_eq!(array_1.getBitArray(), &[0b10_10]),
|
||||||
|
5 => assert_eq!(array_1.getBitArray(), &[0b10_10_1]),
|
||||||
|
6 => assert_eq!(array_1.getBitArray(), &[0b10_10_11]),
|
||||||
|
7..=24 => assert_eq!(array_1.getBitArray(), &[0b10_10_11 << (i - 6)], "{i}"),
|
||||||
|
_ => assert_eq!(array_1.getBitArray(), &[0b10_10_11 << i - 6, 0], "{i}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reverse_original(
|
||||||
|
oldBits: &[super::BitFieldBaseType],
|
||||||
|
size: usize,
|
||||||
|
) -> Vec<super::BitFieldBaseType> {
|
||||||
let mut newBits = vec![0; oldBits.len()];
|
let mut newBits = vec![0; oldBits.len()];
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
// for (int i = 0; i < size; i++) {
|
// for (int i = 0; i < size; i++) {
|
||||||
@@ -282,13 +344,12 @@ fn reverse_original(oldBits: &[u32], size: usize) -> Vec<u32> {
|
|||||||
newBits
|
newBits
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bit_set(bits: &[u32], i: usize) -> bool {
|
fn bit_set(bits: &[super::BitFieldBaseType], i: usize) -> bool {
|
||||||
(bits[i / 32] & (1 << (i & 0x1F))) != 0
|
(bits[i / 32] & (1 << (i & 0x1F))) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arrays_are_equal(left: &[u32], right: &[u32], size: usize) -> bool {
|
fn arrays_are_equal<T: Eq + Default>(left: &[T], right: &[T], size: usize) -> bool {
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
// for (int i = 0; i < size; i++) {
|
|
||||||
if left[i] != right[i] {
|
if left[i] != right[i] {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
95
src/common/adaptive_threshold_binarizer.rs
Normal file
95
src/common/adaptive_threshold_binarizer.rs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use image::{DynamicImage, ImageBuffer, Luma};
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
|
use crate::{Binarizer, Exceptions, LuminanceSource};
|
||||||
|
|
||||||
|
use super::{BitArray, BitMatrix, Result};
|
||||||
|
|
||||||
|
/// The `AdaptiveThresholdBinarizer` works using the `imageproc::contrast::adaptive_threshold`
|
||||||
|
/// function. This is an alternative to the other Binarizers available. It is largely
|
||||||
|
/// untested.
|
||||||
|
pub struct AdaptiveThresholdBinarizer<LS: LuminanceSource> {
|
||||||
|
source: LS,
|
||||||
|
matrix: OnceCell<BitMatrix>,
|
||||||
|
radius: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<LS: LuminanceSource> AdaptiveThresholdBinarizer<LS> {
|
||||||
|
pub fn new(source: LS, radius: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
source,
|
||||||
|
radius,
|
||||||
|
matrix: OnceCell::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<LS: LuminanceSource> AdaptiveThresholdBinarizer<LS> {
|
||||||
|
fn buildMatrix(&self) -> Result<BitMatrix> {
|
||||||
|
let image_buffer = {
|
||||||
|
let Some(buff): Option<ImageBuffer<Luma<u8>, Vec<u8>>> = ImageBuffer::from_vec(
|
||||||
|
self.source.get_width() as u32,
|
||||||
|
self.source.get_height() as u32,
|
||||||
|
self.source.get_matrix(),
|
||||||
|
) else {
|
||||||
|
return Err(Exceptions::ILLEGAL_ARGUMENT);
|
||||||
|
};
|
||||||
|
buff
|
||||||
|
};
|
||||||
|
|
||||||
|
let filtered_iamge =
|
||||||
|
imageproc::contrast::adaptive_threshold(&image_buffer, self.radius.into());
|
||||||
|
|
||||||
|
let dynamic_filtered = DynamicImage::from(filtered_iamge);
|
||||||
|
|
||||||
|
dynamic_filtered.try_into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<LS: LuminanceSource> Binarizer for AdaptiveThresholdBinarizer<LS> {
|
||||||
|
type Source = LS;
|
||||||
|
|
||||||
|
fn get_luminance_source(&self) -> &Self::Source {
|
||||||
|
&self.source
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_black_row(&self, y: usize) -> Result<Cow<BitArray>> {
|
||||||
|
let matrix = self.matrix.get_or_try_init(|| self.buildMatrix())?;
|
||||||
|
Ok(Cow::Owned(matrix.getRow(y as u32)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_black_matrix(&self) -> super::Result<&BitMatrix> {
|
||||||
|
self.matrix.get_or_try_init(|| self.buildMatrix())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_black_line(&self, l: usize, lt: super::LineOrientation) -> Result<Cow<BitArray>> {
|
||||||
|
match lt {
|
||||||
|
super::LineOrientation::Row => self.get_black_row(l),
|
||||||
|
super::LineOrientation::Column => {
|
||||||
|
let matrix = self.matrix.get_or_try_init(|| self.buildMatrix())?;
|
||||||
|
Ok(Cow::Owned(matrix.getCol(l as u32)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_binarizer(&self, source: Self::Source) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
source: source,
|
||||||
|
matrix: OnceCell::new(),
|
||||||
|
radius: self.radius,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_width(&self) -> usize {
|
||||||
|
self.source.get_width()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_height(&self) -> usize {
|
||||||
|
self.source.get_height()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,13 +18,15 @@
|
|||||||
|
|
||||||
// import java.util.Arrays;
|
// import java.util.Arrays;
|
||||||
|
|
||||||
use std::ops::Index;
|
|
||||||
use std::{cmp, fmt};
|
use std::{cmp, fmt};
|
||||||
|
|
||||||
use crate::common::Result;
|
use crate::common::Result;
|
||||||
use crate::Exceptions;
|
use crate::Exceptions;
|
||||||
|
|
||||||
static LOAD_FACTOR: f32 = 0.75;
|
const LOAD_FACTOR: f32 = 0.75;
|
||||||
|
|
||||||
|
type BaseType = super::BitFieldBaseType;
|
||||||
|
const BASE_BITS: usize = super::BIT_FIELD_BASE_BITS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>
|
* <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>
|
||||||
@@ -33,7 +35,7 @@ static LOAD_FACTOR: f32 = 0.75;
|
|||||||
*/
|
*/
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||||
pub struct BitArray {
|
pub struct BitArray {
|
||||||
bits: Vec<u32>,
|
bits: Vec<BaseType>,
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,14 +49,14 @@ impl BitArray {
|
|||||||
|
|
||||||
pub fn with_size(size: usize) -> Self {
|
pub fn with_size(size: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bits: BitArray::makeArray(size),
|
bits: makeArray(size),
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For testing only
|
/// For testing only
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn with_initial_values(bits: Vec<u32>, size: usize) -> Self {
|
pub fn with_initial_values(bits: Vec<BaseType>, size: usize) -> Self {
|
||||||
Self { bits, size }
|
Self { bits, size }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,12 +68,14 @@ impl BitArray {
|
|||||||
(self.size + 7) / 8
|
(self.size + 7) / 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ensure_capacity(&mut self, newSize: usize) {
|
fn ensure_capacity(&mut self, newSize: usize) {
|
||||||
if newSize > self.bits.len() * 32 {
|
let target_size = (newSize as f32 / LOAD_FACTOR).ceil() as usize;
|
||||||
let mut newBits = BitArray::makeArray((newSize as f32 / LOAD_FACTOR).ceil() as usize);
|
let array_desired_length = (target_size + BASE_BITS - 1) / BASE_BITS;
|
||||||
//System.arraycopy(bits, 0, newBits, 0, bits.length);
|
|
||||||
newBits[0..self.bits.len()].clone_from_slice(&self.bits[0..self.bits.len()]);
|
if self.bits.len() < array_desired_length {
|
||||||
self.bits = newBits;
|
let additional_capacity = array_desired_length - self.bits.len();
|
||||||
|
self.bits.extend(vec![0; additional_capacity]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,11 +84,11 @@ impl BitArray {
|
|||||||
* @return true iff bit i is set
|
* @return true iff bit i is set
|
||||||
*/
|
*/
|
||||||
pub fn get(&self, i: usize) -> bool {
|
pub fn get(&self, i: usize) -> bool {
|
||||||
(self.bits[i / 32] & (1 << (i & 0x1F))) != 0
|
(self.bits[i / BASE_BITS] & (1 << (i & 0x1F))) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_get(&self, i: usize) -> Option<bool> {
|
pub fn try_get(&self, i: usize) -> Option<bool> {
|
||||||
if (i / 32) >= self.bits.len() {
|
if (i / BASE_BITS) >= self.bits.len() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(self.get(i))
|
Some(self.get(i))
|
||||||
@@ -97,7 +101,7 @@ impl BitArray {
|
|||||||
* @param i bit to set
|
* @param i bit to set
|
||||||
*/
|
*/
|
||||||
pub fn set(&mut self, i: usize) {
|
pub fn set(&mut self, i: usize) {
|
||||||
self.bits[i / 32] |= 1 << (i & 0x1F);
|
self.bits[i / BASE_BITS] |= 1 << (i & 0x1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +110,7 @@ impl BitArray {
|
|||||||
* @param i bit to set
|
* @param i bit to set
|
||||||
*/
|
*/
|
||||||
pub fn flip(&mut self, i: usize) {
|
pub fn flip(&mut self, i: usize) {
|
||||||
self.bits[i / 32] ^= 1 << (i & 0x1F);
|
self.bits[i / BASE_BITS] ^= 1 << (i & 0x1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,7 +123,7 @@ impl BitArray {
|
|||||||
if from >= self.size {
|
if from >= self.size {
|
||||||
return self.size;
|
return self.size;
|
||||||
}
|
}
|
||||||
let mut bitsOffset = from / 32;
|
let mut bitsOffset = from / BASE_BITS;
|
||||||
let mut currentBits = self.bits[bitsOffset] as i64;
|
let mut currentBits = self.bits[bitsOffset] as i64;
|
||||||
// mask off lesser bits first
|
// mask off lesser bits first
|
||||||
currentBits &= -(1 << (from & 0x1F));
|
currentBits &= -(1 << (from & 0x1F));
|
||||||
@@ -130,7 +134,7 @@ impl BitArray {
|
|||||||
}
|
}
|
||||||
currentBits = self.bits[bitsOffset] as i64;
|
currentBits = self.bits[bitsOffset] as i64;
|
||||||
}
|
}
|
||||||
let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize;
|
let result = (bitsOffset * BASE_BITS) + currentBits.trailing_zeros() as usize;
|
||||||
cmp::min(result, self.size)
|
cmp::min(result, self.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +147,7 @@ impl BitArray {
|
|||||||
if from >= self.size {
|
if from >= self.size {
|
||||||
return self.size;
|
return self.size;
|
||||||
}
|
}
|
||||||
let mut bitsOffset = from / 32;
|
let mut bitsOffset = from / BASE_BITS;
|
||||||
let mut currentBits = !self.bits[bitsOffset] as i64;
|
let mut currentBits = !self.bits[bitsOffset] as i64;
|
||||||
// mask off lesser bits first
|
// mask off lesser bits first
|
||||||
currentBits &= -(1 << (from & 0x1F));
|
currentBits &= -(1 << (from & 0x1F));
|
||||||
@@ -154,7 +158,7 @@ impl BitArray {
|
|||||||
}
|
}
|
||||||
currentBits = !self.bits[bitsOffset] as i64;
|
currentBits = !self.bits[bitsOffset] as i64;
|
||||||
}
|
}
|
||||||
let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize;
|
let result = (bitsOffset * BASE_BITS) + currentBits.trailing_zeros() as usize;
|
||||||
cmp::min(result, self.size)
|
cmp::min(result, self.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,8 +169,8 @@ impl BitArray {
|
|||||||
* @param newBits the new value of the next 32 bits. Note again that the least-significant bit
|
* @param newBits the new value of the next 32 bits. Note again that the least-significant bit
|
||||||
* corresponds to bit i, the next-least-significant to i+1, and so on.
|
* corresponds to bit i, the next-least-significant to i+1, and so on.
|
||||||
*/
|
*/
|
||||||
pub fn setBulk(&mut self, i: usize, newBits: u32) {
|
pub fn setBulk(&mut self, i: usize, newBits: BaseType) {
|
||||||
self.bits[i / 32] = newBits;
|
self.bits[i / BASE_BITS] = newBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -184,15 +188,15 @@ impl BitArray {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
end -= 1; // will be easier to treat this as the last actually set bit -- inclusive
|
end -= 1; // will be easier to treat this as the last actually set bit -- inclusive
|
||||||
let firstInt = start / 32;
|
let firstInt = start / BASE_BITS;
|
||||||
let lastInt = end / 32;
|
let lastInt = end / BASE_BITS;
|
||||||
for i in firstInt..=lastInt {
|
for i in firstInt..=lastInt {
|
||||||
//for (int i = firstInt; i <= lastInt; i++) {
|
//for (int i = firstInt; i <= lastInt; i++) {
|
||||||
let firstBit = if i > firstInt { 0 } else { start & 0x1F };
|
let firstBit = if i > firstInt { 0 } else { start & 0x1F };
|
||||||
let lastBit = if i < lastInt { 31 } else { end & 0x1F };
|
let lastBit = if i < lastInt { 31 } else { end & 0x1F };
|
||||||
// Ones from firstBit to lastBit, inclusive
|
// Ones from firstBit to lastBit, inclusive
|
||||||
let mask: u64 = (2 << lastBit) - (1 << firstBit);
|
let mask: u64 = (2 << lastBit) - (1 << firstBit);
|
||||||
self.bits[i] |= mask as u32;
|
self.bits[i] |= mask as BaseType;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -201,11 +205,6 @@ impl BitArray {
|
|||||||
* Clears all bits (sets to false).
|
* Clears all bits (sets to false).
|
||||||
*/
|
*/
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
// let max = self.bits.len();
|
|
||||||
// for i in 0..max {
|
|
||||||
// //for (int i = 0; i < max; i++) {
|
|
||||||
// self.bits[i] = 0;
|
|
||||||
// }
|
|
||||||
self.bits.fill(0);
|
self.bits.fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,8 +226,8 @@ impl BitArray {
|
|||||||
return Ok(true); // empty range matches
|
return Ok(true); // empty range matches
|
||||||
}
|
}
|
||||||
end -= 1; // will be easier to treat this as the last actually set bit -- inclusive
|
end -= 1; // will be easier to treat this as the last actually set bit -- inclusive
|
||||||
let firstInt = start / 32;
|
let firstInt = start / BASE_BITS;
|
||||||
let lastInt = end / 32;
|
let lastInt = end / BASE_BITS;
|
||||||
for i in firstInt..=lastInt {
|
for i in firstInt..=lastInt {
|
||||||
//for (int i = firstInt; i <= lastInt; i++) {
|
//for (int i = firstInt; i <= lastInt; i++) {
|
||||||
let firstBit = if i > firstInt { 0 } else { start & 0x1F };
|
let firstBit = if i > firstInt { 0 } else { start & 0x1F };
|
||||||
@@ -238,7 +237,7 @@ impl BitArray {
|
|||||||
|
|
||||||
// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
|
// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
|
||||||
// equals the mask, or we're looking for 0s and the masked portion is not all 0s
|
// equals the mask, or we're looking for 0s and the masked portion is not all 0s
|
||||||
if (self.bits[i] & mask as u32) != (if value { mask as u32 } else { 0 }) {
|
if (self.bits[i] & mask as BaseType) != (if value { mask as BaseType } else { 0 }) {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,7 +247,7 @@ impl BitArray {
|
|||||||
pub fn appendBit(&mut self, bit: bool) {
|
pub fn appendBit(&mut self, bit: bool) {
|
||||||
self.ensure_capacity(self.size + 1);
|
self.ensure_capacity(self.size + 1);
|
||||||
if bit {
|
if bit {
|
||||||
self.bits[self.size / 32] |= 1 << (self.size & 0x1F);
|
self.bits[self.size / BASE_BITS] |= 1 << (self.size & 0x1F);
|
||||||
}
|
}
|
||||||
self.size += 1;
|
self.size += 1;
|
||||||
}
|
}
|
||||||
@@ -261,11 +260,12 @@ impl BitArray {
|
|||||||
* @param value {@code int} containing bits to append
|
* @param value {@code int} containing bits to append
|
||||||
* @param numBits bits from value to append
|
* @param numBits bits from value to append
|
||||||
*/
|
*/
|
||||||
pub fn appendBits(&mut self, value: u32, num_bits: usize) -> Result<()> {
|
pub fn appendBits(&mut self, value: BaseType, num_bits: usize) -> Result<()> {
|
||||||
if num_bits > 32 {
|
if num_bits > BASE_BITS {
|
||||||
return Err(Exceptions::illegal_argument_with(
|
return Err(Exceptions::illegal_argument_with(format!(
|
||||||
"num bits must be between 0 and 32",
|
"num bits must be between 0 and {}",
|
||||||
));
|
BaseType::BITS
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if num_bits == 0 {
|
if num_bits == 0 {
|
||||||
@@ -277,7 +277,7 @@ impl BitArray {
|
|||||||
for numBitsLeft in (0..num_bits).rev() {
|
for numBitsLeft in (0..num_bits).rev() {
|
||||||
//for (int numBitsLeft = numBits - 1; numBitsLeft >= 0; numBitsLeft--) {
|
//for (int numBitsLeft = numBits - 1; numBitsLeft >= 0; numBitsLeft--) {
|
||||||
if (value & (1 << numBitsLeft)) != 0 {
|
if (value & (1 << numBitsLeft)) != 0 {
|
||||||
self.bits[next_size / 32] |= 1 << (next_size & 0x1F);
|
self.bits[next_size / BASE_BITS] |= 1 << (next_size & 0x1F);
|
||||||
}
|
}
|
||||||
next_size += 1;
|
next_size += 1;
|
||||||
}
|
}
|
||||||
@@ -298,11 +298,11 @@ impl BitArray {
|
|||||||
if self.size != other.size {
|
if self.size != other.size {
|
||||||
return Err(Exceptions::illegal_argument_with("Sizes don't match"));
|
return Err(Exceptions::illegal_argument_with("Sizes don't match"));
|
||||||
}
|
}
|
||||||
for i in 0..self.bits.len() {
|
for (lhs, rhs) in self.bits.iter_mut().zip(other.bits.iter()) {
|
||||||
//for (int i = 0; i < bits.length; i++) {
|
//for (int i = 0; i < bits.length; i++) {
|
||||||
// The last int could be incomplete (i.e. not have 32 bits in
|
// The last int could be incomplete (i.e. not have 32 bits in
|
||||||
// it) but there is no problem since 0 XOR 0 == 0.
|
// it) but there is no problem since 0 XOR 0 == 0.
|
||||||
self.bits[i] ^= other.bits[i];
|
*lhs ^= rhs;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -335,7 +335,7 @@ impl BitArray {
|
|||||||
* @return underlying array of ints. The first element holds the first 32 bits, and the least
|
* @return underlying array of ints. The first element holds the first 32 bits, and the least
|
||||||
* significant bit is bit 0.
|
* significant bit is bit 0.
|
||||||
*/
|
*/
|
||||||
pub fn getBitArray(&self) -> &[u32] {
|
pub fn getBitArray(&self) -> &[BaseType] {
|
||||||
&self.bits
|
&self.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,52 +343,35 @@ impl BitArray {
|
|||||||
* Reverses all bits in the array.
|
* Reverses all bits in the array.
|
||||||
*/
|
*/
|
||||||
pub fn reverse(&mut self) {
|
pub fn reverse(&mut self) {
|
||||||
let mut newBits = vec![0; self.bits.len()];
|
// let mut newBits = vec![0; self.bits.len()];
|
||||||
// reverse all int's first
|
// reverse all int's first
|
||||||
let len = (self.size - 1) / 32;
|
let len = (self.size - 1) / 32;
|
||||||
let oldBitsLen = len + 1;
|
let oldBitsLen = len + 1;
|
||||||
for i in 0..oldBitsLen {
|
// let array_size = self.size.div_ceil(BASE_TYPE::BITS as usize);
|
||||||
//for (int i = 0; i < oldBitsLen; i++) {
|
|
||||||
newBits[len - i] = self.bits[i].reverse_bits();
|
// for (new_bits, old_bits) in newBits.iter_mut().take(oldBitsLen).zip(self.bits.iter().take(oldBitsLen).rev()) {
|
||||||
}
|
// *new_bits = old_bits.reverse_bits();
|
||||||
|
// }
|
||||||
|
self.bits[..oldBitsLen].reverse();
|
||||||
|
self.bits[..oldBitsLen]
|
||||||
|
.iter_mut()
|
||||||
|
.for_each(|bit_store| *bit_store = bit_store.reverse_bits());
|
||||||
|
self.bits[oldBitsLen..].fill(0);
|
||||||
|
|
||||||
// now correct the int's if the bit size isn't a multiple of 32
|
// now correct the int's if the bit size isn't a multiple of 32
|
||||||
if self.size != oldBitsLen * 32 {
|
if self.size != oldBitsLen * BASE_BITS {
|
||||||
let leftOffset = oldBitsLen * 32 - self.size;
|
let leftOffset = oldBitsLen * BASE_BITS - self.size;
|
||||||
let mut currentInt = newBits[0] >> leftOffset;
|
let mut currentInt = self.bits[0] >> leftOffset;
|
||||||
for i in 1..oldBitsLen {
|
for i in 1..oldBitsLen {
|
||||||
//for (int i = 1; i < oldBitsLen; i++) {
|
//for (int i = 1; i < oldBitsLen; i++) {
|
||||||
let nextInt = newBits[i];
|
let nextInt = self.bits[i];
|
||||||
currentInt |= nextInt << (32 - leftOffset);
|
currentInt |= nextInt << (BASE_BITS - leftOffset);
|
||||||
newBits[i - 1] = currentInt;
|
self.bits[i - 1] = currentInt;
|
||||||
currentInt = nextInt >> leftOffset;
|
currentInt = nextInt >> leftOffset;
|
||||||
}
|
}
|
||||||
newBits[oldBitsLen - 1] = currentInt;
|
self.bits[oldBitsLen - 1] = currentInt;
|
||||||
}
|
}
|
||||||
self.bits = newBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn makeArray(size: usize) -> Vec<u32> {
|
|
||||||
vec![0; (size + 31) / 32]
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public boolean equals(Object o) {
|
|
||||||
// if (!(o instanceof BitArray)) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// BitArray other = (BitArray) o;
|
|
||||||
// return size == other.size && Arrays.equals(bits, other.bits);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public int hashCode() {
|
|
||||||
// return 31 * size + Arrays.hashCode(bits);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public BitArray clone() {
|
|
||||||
// return new BitArray(bits.clone(), size);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for BitArray {
|
impl fmt::Display for BitArray {
|
||||||
@@ -427,13 +410,6 @@ impl From<&BitArray> for Vec<u8> {
|
|||||||
|
|
||||||
impl From<BitArray> for Vec<bool> {
|
impl From<BitArray> for Vec<bool> {
|
||||||
fn from(value: BitArray) -> Self {
|
fn from(value: BitArray) -> Self {
|
||||||
// let mut array = vec![false; value.size];
|
|
||||||
|
|
||||||
// for (pixel, element) in array.iter_mut().enumerate().take(value.size) {
|
|
||||||
// *element = value.get(pixel);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// array
|
|
||||||
Self::from(&value)
|
Self::from(&value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,3 +425,7 @@ impl From<&BitArray> for Vec<bool> {
|
|||||||
array
|
array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn makeArray(size: usize) -> Vec<BaseType> {
|
||||||
|
vec![0; (size + BASE_BITS - 1) / BASE_BITS]
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ use crate::{point_f, point_i, Exceptions, Point};
|
|||||||
|
|
||||||
use super::BitArray;
|
use super::BitArray;
|
||||||
|
|
||||||
|
type BaseType = super::BitFieldBaseType;
|
||||||
|
const BASE_BITS: usize = super::BIT_FIELD_BASE_BITS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Represents a 2D matrix of bits. In function arguments below, and throughout the common
|
* <p>Represents a 2D matrix of bits. In function arguments below, and throughout the common
|
||||||
* module, x is the column position, and y is the row position. The ordering is always x, y.
|
* module, x is the column position, and y is the row position. The ordering is always x, y.
|
||||||
@@ -45,7 +48,7 @@ pub struct BitMatrix {
|
|||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
row_size: usize,
|
row_size: usize,
|
||||||
bits: Vec<u32>,
|
bits: Vec<BaseType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitMatrix {
|
impl BitMatrix {
|
||||||
@@ -73,8 +76,11 @@ impl BitMatrix {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
row_size: ((width + 31) / 32) as usize,
|
row_size: ((width as usize + BASE_BITS - 1) / BASE_BITS) as usize,
|
||||||
bits: vec![0; (((width + 31) / 32) * height) as usize],
|
bits: vec![
|
||||||
|
0;
|
||||||
|
(((width as usize + BASE_BITS - 1) / BASE_BITS) * height as usize) as usize
|
||||||
|
],
|
||||||
})
|
})
|
||||||
// this.width = width;
|
// this.width = width;
|
||||||
// this.height = height;
|
// this.height = height;
|
||||||
@@ -83,7 +89,7 @@ impl BitMatrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn with_all_data(&self, width: u32, height: u32, rowSize: usize, bits: Vec<u32>) -> Self {
|
fn with_all_data(&self, width: u32, height: u32, rowSize: usize, bits: Vec<BaseType>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
@@ -235,7 +241,7 @@ impl BitMatrix {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_offset(&self, y: u32, x: u32) -> usize {
|
fn get_offset(&self, y: u32, x: u32) -> usize {
|
||||||
y as usize * self.row_size + (x as usize / 32)
|
y as usize * self.row_size + (x as usize / BASE_BITS)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_get(&self, x: u32, y: u32) -> Option<bool> {
|
pub fn try_get(&self, x: u32, y: u32) -> Option<bool> {
|
||||||
@@ -387,7 +393,7 @@ impl BitMatrix {
|
|||||||
let offset = y as usize * self.row_size;
|
let offset = y as usize * self.row_size;
|
||||||
for x in left..right {
|
for x in left..right {
|
||||||
//for (int x = left; x < right; x++) {
|
//for (int x = left; x < right; x++) {
|
||||||
self.bits[offset + (x as usize / 32)] |= 1 << (x & 0x1f);
|
self.bits[offset + (x as usize / BASE_BITS)] |= 1 << (x & 0x1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -407,7 +413,7 @@ impl BitMatrix {
|
|||||||
let offset = y as usize * self.row_size;
|
let offset = y as usize * self.row_size;
|
||||||
for x in 0..self.row_size {
|
for x in 0..self.row_size {
|
||||||
//for (int x = 0; x < rowSize; x++) {
|
//for (int x = 0; x < rowSize; x++) {
|
||||||
rw.setBulk(x * 32, self.bits[offset + x]);
|
rw.setBulk(x * BASE_BITS, self.bits[offset + x]);
|
||||||
}
|
}
|
||||||
rw
|
rw
|
||||||
}
|
}
|
||||||
@@ -489,7 +495,7 @@ impl BitMatrix {
|
|||||||
pub fn rotate90(&mut self) {
|
pub fn rotate90(&mut self) {
|
||||||
let newWidth = self.height;
|
let newWidth = self.height;
|
||||||
let newHeight = self.width;
|
let newHeight = self.width;
|
||||||
let newRowSize = (newWidth + 31) / 32;
|
let newRowSize = (newWidth + BASE_BITS as u32 - 1) / BASE_BITS as u32;
|
||||||
let mut newBits = vec![0; (newRowSize * newHeight) as usize];
|
let mut newBits = vec![0; (newRowSize * newHeight) as usize];
|
||||||
|
|
||||||
for y in 0..self.height {
|
for y in 0..self.height {
|
||||||
@@ -498,7 +504,8 @@ impl BitMatrix {
|
|||||||
//for (int x = 0; x < width; x++) {
|
//for (int x = 0; x < width; x++) {
|
||||||
let offset = self.get_offset(y, x);
|
let offset = self.get_offset(y, x);
|
||||||
if ((self.bits[offset] >> (x & 0x1f)) & 1) != 0 {
|
if ((self.bits[offset] >> (x & 0x1f)) & 1) != 0 {
|
||||||
let newOffset: usize = ((newHeight - 1 - x) * newRowSize + (y / 32)) as usize;
|
let newOffset: usize =
|
||||||
|
((newHeight - 1 - x) * newRowSize + (y / BASE_BITS as u32)) as usize;
|
||||||
newBits[newOffset] |= 1 << (y & 0x1f);
|
newBits[newOffset] |= 1 << (y & 0x1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,22 +538,22 @@ impl BitMatrix {
|
|||||||
top = top.min(y);
|
top = top.min(y);
|
||||||
bottom = bottom.max(y);
|
bottom = bottom.max(y);
|
||||||
|
|
||||||
if x32 * 32 < left as usize {
|
if x32 * BASE_BITS < left as usize {
|
||||||
let mut bit = 0;
|
let mut bit = 0;
|
||||||
while (theBits << (31 - bit)) == 0 {
|
while (theBits << (BASE_BITS - 1 - bit)) == 0 {
|
||||||
bit += 1;
|
bit += 1;
|
||||||
}
|
}
|
||||||
if (x32 * 32 + bit) < left as usize {
|
if (x32 * BASE_BITS + bit) < left as usize {
|
||||||
left = (x32 * 32 + bit) as u32;
|
left = (x32 * BASE_BITS + bit) as u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if x32 * 32 + 31 > right as usize {
|
if x32 * BASE_BITS + BASE_BITS - 1 > right as usize {
|
||||||
let mut bit = 31;
|
let mut bit = BASE_BITS - 1;
|
||||||
while (theBits >> bit) == 0 {
|
while (theBits >> bit) == 0 {
|
||||||
bit -= 1;
|
bit -= 1;
|
||||||
}
|
}
|
||||||
if (x32 * 32 + bit) > right as usize {
|
if (x32 * BASE_BITS + bit) > right as usize {
|
||||||
right = (x32 * 32 + bit) as u32;
|
right = (x32 * BASE_BITS + bit) as u32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -574,7 +581,7 @@ impl BitMatrix {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let y = bitsOffset / self.row_size;
|
let y = bitsOffset / self.row_size;
|
||||||
let mut x = (bitsOffset % self.row_size) * 32;
|
let mut x = (bitsOffset % self.row_size) * BASE_BITS;
|
||||||
|
|
||||||
let theBits = self.bits[bitsOffset];
|
let theBits = self.bits[bitsOffset];
|
||||||
let mut bit = 0;
|
let mut bit = 0;
|
||||||
@@ -595,10 +602,10 @@ impl BitMatrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let y = bitsOffset as usize / self.row_size;
|
let y = bitsOffset as usize / self.row_size;
|
||||||
let mut x = (bitsOffset as usize % self.row_size) * 32;
|
let mut x = (bitsOffset as usize % self.row_size) * BASE_BITS;
|
||||||
|
|
||||||
let theBits = self.bits[bitsOffset as usize];
|
let theBits = self.bits[bitsOffset as usize];
|
||||||
let mut bit = 31;
|
let mut bit = BASE_BITS - 1;
|
||||||
while (theBits >> bit) == 0 {
|
while (theBits >> bit) == 0 {
|
||||||
bit -= 1;
|
bit -= 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ use crate::point_f;
|
|||||||
|
|
||||||
use super::BitMatrix;
|
use super::BitMatrix;
|
||||||
|
|
||||||
static BIT_MATRIX_POINTS: [u32; 6] = [1, 2, 2, 0, 3, 1];
|
const BIT_MATRIX_POINTS: [u32; 6] = [1, 2, 2, 0, 3, 1];
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_set() {
|
fn test_get_set() {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
//package com.google.zxing.common;
|
//package com.google.zxing.common;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
use std::io::{ErrorKind, Read};
|
||||||
|
|
||||||
use crate::common::Result;
|
use crate::common::Result;
|
||||||
use crate::Exceptions;
|
use crate::Exceptions;
|
||||||
@@ -173,3 +174,28 @@ impl BitSource {
|
|||||||
8 * (self.bytes.len() - self.byte_offset) - self.bit_offset
|
8 * (self.bytes.len() - self.byte_offset) - self.bit_offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Read for BitSource {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
|
let requested_bytes = buf.len();
|
||||||
|
let available = self.available();
|
||||||
|
|
||||||
|
let to_read = if requested_bytes <= available {
|
||||||
|
requested_bytes
|
||||||
|
} else {
|
||||||
|
available
|
||||||
|
};
|
||||||
|
|
||||||
|
for byte in buf.iter_mut().take(to_read) {
|
||||||
|
let Ok(bits) = self.readBits(8) else {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
ErrorKind::Unsupported,
|
||||||
|
"unable to read bits",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
*byte = bits as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(to_read)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
// import java.io.ByteArrayOutputStream;
|
// import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that lets one easily build an array of bytes by appending bits at a time.
|
* Class that lets one easily build an array of bytes by appending bits at a time.
|
||||||
*
|
*
|
||||||
@@ -71,3 +73,19 @@ impl Default for BitSourceBuilder {
|
|||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Write for BitSourceBuilder {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||||
|
let mut written = 0;
|
||||||
|
for byte in buf.iter() {
|
||||||
|
self.write(*byte as u32, 8);
|
||||||
|
written += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(written)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -349,3 +349,18 @@ impl Default for SymbologyIdentifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::io::Write for ECIStringBuilder {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||||
|
if buf.len() == 1 {
|
||||||
|
self.append_byte(buf[0]);
|
||||||
|
} else {
|
||||||
|
self.append_bytes(buf);
|
||||||
|
}
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -175,12 +175,12 @@ impl<LS: LuminanceSource> HybridBinarizer<LS> {
|
|||||||
// for (int y = 0; y < subHeight; y++) {
|
// for (int y = 0; y < subHeight; y++) {
|
||||||
let yoffset = u32::min(y << BLOCK_SIZE_POWER, maxYOffset);
|
let yoffset = u32::min(y << BLOCK_SIZE_POWER, maxYOffset);
|
||||||
|
|
||||||
let top = Self::cap(y, sub_height - 3);
|
let top = u32::clamp(y, 2, sub_height - 3); // Self::cap(y, sub_height - 3);
|
||||||
for x in 0..sub_width {
|
for x in 0..sub_width {
|
||||||
// for (int x = 0; x < subWidth; x++) {
|
// for (int x = 0; x < subWidth; x++) {
|
||||||
let xoffset = u32::min(x << BLOCK_SIZE_POWER, maxXOffset);
|
let xoffset = u32::min(x << BLOCK_SIZE_POWER, maxXOffset);
|
||||||
|
|
||||||
let left = Self::cap(x, sub_width - 3);
|
let left = u32::clamp(x, 2, sub_width - 3); //Self::cap(x, sub_width - 3);
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
for z in -2..=2 {
|
for z in -2..=2 {
|
||||||
// for (int z = -2; z <= 2; z++) {
|
// for (int z = -2; z <= 2; z++) {
|
||||||
@@ -197,11 +197,6 @@ impl<LS: LuminanceSource> HybridBinarizer<LS> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn cap(value: u32, max: u32) -> u32 {
|
|
||||||
u32::clamp(value, 2, max)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a single threshold to a block of pixels.
|
* Applies a single threshold to a block of pixels.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -121,3 +121,11 @@ pub use line_orientation::LineOrientation;
|
|||||||
mod otsu_level_binarizer;
|
mod otsu_level_binarizer;
|
||||||
#[cfg(feature = "otsu_level")]
|
#[cfg(feature = "otsu_level")]
|
||||||
pub use otsu_level_binarizer::*;
|
pub use otsu_level_binarizer::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "image")]
|
||||||
|
mod adaptive_threshold_binarizer;
|
||||||
|
#[cfg(feature = "image")]
|
||||||
|
pub use adaptive_threshold_binarizer::*;
|
||||||
|
|
||||||
|
pub type BitFieldBaseType = u32;
|
||||||
|
pub const BIT_FIELD_BASE_BITS: usize = BitFieldBaseType::BITS as usize;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use once_cell::sync::Lazy;
|
|||||||
use crate::common::Result;
|
use crate::common::Result;
|
||||||
use crate::Exceptions;
|
use crate::Exceptions;
|
||||||
|
|
||||||
static VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::buildVersions);
|
static VERSIONS: Lazy<Box<[Version]>> = Lazy::new(Version::buildVersions);
|
||||||
|
|
||||||
pub type VersionRef = &'static Version;
|
pub type VersionRef = &'static Version;
|
||||||
|
|
||||||
@@ -118,8 +118,8 @@ impl Version {
|
|||||||
/**
|
/**
|
||||||
* See ISO 16022:2006 5.5.1 Table 7
|
* See ISO 16022:2006 5.5.1 Table 7
|
||||||
*/
|
*/
|
||||||
fn buildVersions() -> Vec<Version> {
|
fn buildVersions() -> Box<[Version]> {
|
||||||
vec![
|
Box::new([
|
||||||
Version::new(1, 10, 10, 8, 8, ECBlocks::new(5, ECB::new(1, 3))),
|
Version::new(1, 10, 10, 8, 8, ECBlocks::new(5, ECB::new(1, 3))),
|
||||||
Version::new(2, 12, 12, 10, 10, ECBlocks::new(7, ECB::new(1, 5))),
|
Version::new(2, 12, 12, 10, 10, ECBlocks::new(7, ECB::new(1, 5))),
|
||||||
Version::new(3, 14, 14, 12, 12, ECBlocks::new(10, ECB::new(1, 8))),
|
Version::new(3, 14, 14, 12, 12, ECBlocks::new(10, ECB::new(1, 8))),
|
||||||
@@ -177,7 +177,7 @@ impl Version {
|
|||||||
Version::new(46, 26, 40, 24, 18, ECBlocks::new(38, ECB::new(1, 70))),
|
Version::new(46, 26, 40, 24, 18, ECBlocks::new(38, ECB::new(1, 70))),
|
||||||
Version::new(47, 26, 48, 24, 22, ECBlocks::new(42, ECB::new(1, 90))),
|
Version::new(47, 26, 48, 24, 22, ECBlocks::new(42, ECB::new(1, 90))),
|
||||||
Version::new(48, 26, 64, 24, 14, ECBlocks::new(50, ECB::new(1, 118))),
|
Version::new(48, 26, 64, 24, 14, ECBlocks::new(50, ECB::new(1, 118))),
|
||||||
]
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,20 +195,20 @@ impl fmt::Display for Version {
|
|||||||
*/
|
*/
|
||||||
pub struct ECBlocks {
|
pub struct ECBlocks {
|
||||||
ecCodewords: u32,
|
ecCodewords: u32,
|
||||||
ecBlocks: Vec<ECB>,
|
ecBlocks: Box<[ECB]>,
|
||||||
}
|
}
|
||||||
impl ECBlocks {
|
impl ECBlocks {
|
||||||
pub fn new(ecCodewords: u32, ecBlocks: ECB) -> Self {
|
pub fn new(ecCodewords: u32, ecBlocks: ECB) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ecCodewords,
|
ecCodewords,
|
||||||
ecBlocks: vec![ecBlocks],
|
ecBlocks: Box::new([ecBlocks]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new2(ecCodewords: u32, ecBlocks1: ECB, ecBlocks2: ECB) -> Self {
|
pub fn new2(ecCodewords: u32, ecBlocks1: ECB, ecBlocks2: ECB) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ecCodewords,
|
ecCodewords,
|
||||||
ecBlocks: vec![ecBlocks1, ecBlocks2],
|
ecBlocks: Box::new([ecBlocks1, ecBlocks2]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,18 +231,18 @@ pub struct ECB {
|
|||||||
dataCodewords: u32,
|
dataCodewords: u32,
|
||||||
}
|
}
|
||||||
impl ECB {
|
impl ECB {
|
||||||
pub fn new(count: u32, dataCodewords: u32) -> Self {
|
pub const fn new(count: u32, dataCodewords: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
count,
|
count,
|
||||||
dataCodewords,
|
dataCodewords,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getCount(&self) -> u32 {
|
pub const fn getCount(&self) -> u32 {
|
||||||
self.count
|
self.count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDataCodewords(&self) -> u32 {
|
pub const fn getDataCodewords(&self) -> u32 {
|
||||||
self.dataCodewords
|
self.dataCodewords
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,9 @@ pub mod helpers;
|
|||||||
mod luma_luma_source;
|
mod luma_luma_source;
|
||||||
pub use luma_luma_source::*;
|
pub use luma_luma_source::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "experimental_features")]
|
||||||
mod filtered_image_reader;
|
mod filtered_image_reader;
|
||||||
|
#[cfg(feature = "experimental_features")]
|
||||||
pub use filtered_image_reader::*;
|
pub use filtered_image_reader::*;
|
||||||
|
|
||||||
#[cfg(feature = "svg_read")]
|
#[cfg(feature = "svg_read")]
|
||||||
|
|||||||
@@ -9,13 +9,16 @@ pub struct Luma8LuminanceSource {
|
|||||||
/// image origin in the form (x,y)
|
/// image origin in the form (x,y)
|
||||||
origin: (u32, u32),
|
origin: (u32, u32),
|
||||||
/// raw data for luma 8
|
/// raw data for luma 8
|
||||||
data: Vec<u8>,
|
data: Box<[u8]>,
|
||||||
/// flag indicating if the underlying data needs to be inverted for use
|
/// flag indicating if the underlying data needs to be inverted for use
|
||||||
inverted: bool,
|
inverted: bool,
|
||||||
/// original dimensions of the data, used to manage crop
|
/// original dimensions of the data, used to manage crop
|
||||||
original_dimension: (u32, u32),
|
original_dimension: (u32, u32),
|
||||||
}
|
}
|
||||||
impl LuminanceSource for Luma8LuminanceSource {
|
impl LuminanceSource for Luma8LuminanceSource {
|
||||||
|
const SUPPORTS_CROP: bool = true;
|
||||||
|
const SUPPORTS_ROTATION: bool = true;
|
||||||
|
|
||||||
fn get_row(&self, y: usize) -> Vec<u8> {
|
fn get_row(&self, y: usize) -> Vec<u8> {
|
||||||
let chunk_size = self.original_dimension.0 as usize;
|
let chunk_size = self.original_dimension.0 as usize;
|
||||||
let row_skip = y + self.origin.1 as usize;
|
let row_skip = y + self.origin.1 as usize;
|
||||||
@@ -30,16 +33,6 @@ impl LuminanceSource for Luma8LuminanceSource {
|
|||||||
} else {
|
} else {
|
||||||
Vec::from(&self.data[data_start..data_end])
|
Vec::from(&self.data[data_start..data_end])
|
||||||
}
|
}
|
||||||
|
|
||||||
// self.data
|
|
||||||
// .chunks_exact(chunk_size)
|
|
||||||
// .skip(row_skip)
|
|
||||||
// .take(1)
|
|
||||||
// .flatten()
|
|
||||||
// .skip(column_skip)
|
|
||||||
// .take(column_take)
|
|
||||||
// .map(|byte| Self::invert_if_should(*byte, self.inverted))
|
|
||||||
// .collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_column(&self, x: usize) -> Vec<u8> {
|
fn get_column(&self, x: usize) -> Vec<u8> {
|
||||||
@@ -85,10 +78,6 @@ impl LuminanceSource for Luma8LuminanceSource {
|
|||||||
self.inverted = !self.inverted;
|
self.inverted = !self.inverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_crop_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
dimensions: (width as u32, height as u32),
|
dimensions: (width as u32, height as u32),
|
||||||
@@ -99,10 +88,6 @@ impl LuminanceSource for Luma8LuminanceSource {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_rotate_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rotate_counter_clockwise(&self) -> Result<Self> {
|
fn rotate_counter_clockwise(&self) -> Result<Self> {
|
||||||
let mut new_matrix = Self {
|
let mut new_matrix = Self {
|
||||||
dimensions: self.dimensions,
|
dimensions: self.dimensions,
|
||||||
@@ -123,7 +108,14 @@ impl LuminanceSource for Luma8LuminanceSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_luma8_point(&self, column: usize, row: usize) -> u8 {
|
fn get_luma8_point(&self, column: usize, row: usize) -> u8 {
|
||||||
self.get_row(row)[column]
|
let chunk_size = self.original_dimension.0 as usize;
|
||||||
|
let row_skip = row + self.origin.1 as usize;
|
||||||
|
let column_skip = self.origin.0 as usize;
|
||||||
|
|
||||||
|
let data_start = (chunk_size * row_skip) + column_skip;
|
||||||
|
let data_point = data_start + column;
|
||||||
|
|
||||||
|
Self::invert_if_should(self.data[data_point], self.inverted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +155,7 @@ impl Luma8LuminanceSource {
|
|||||||
new_data[offset_b] = self.data[offset_a];
|
new_data[offset_b] = self.data[offset_a];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.data = new_data;
|
self.data = new_data.into_boxed_slice();
|
||||||
self.dimensions = new_dim;
|
self.dimensions = new_dim;
|
||||||
self.original_dimension = (self.original_dimension.1, self.original_dimension.0);
|
self.original_dimension = (self.original_dimension.1, self.original_dimension.0);
|
||||||
self.origin = (self.origin.1, self.origin.0);
|
self.origin = (self.origin.1, self.origin.0);
|
||||||
@@ -184,7 +176,7 @@ impl Luma8LuminanceSource {
|
|||||||
Self {
|
Self {
|
||||||
dimensions: (width, height),
|
dimensions: (width, height),
|
||||||
origin: (0, 0),
|
origin: (0, 0),
|
||||||
data: source,
|
data: source.into_boxed_slice(),
|
||||||
inverted: false,
|
inverted: false,
|
||||||
original_dimension: (width, height),
|
original_dimension: (width, height),
|
||||||
}
|
}
|
||||||
@@ -194,13 +186,13 @@ impl Luma8LuminanceSource {
|
|||||||
Self {
|
Self {
|
||||||
dimensions: (width as u32, height as u32),
|
dimensions: (width as u32, height as u32),
|
||||||
origin: (0, 0),
|
origin: (0, 0),
|
||||||
data: vec![0u8; width * height],
|
data: vec![0u8; width * height].into_boxed_slice(),
|
||||||
inverted: false,
|
inverted: false,
|
||||||
original_dimension: (width as u32, height as u32),
|
original_dimension: (width as u32, height as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_matrix_mut(&mut self) -> &mut Vec<u8> {
|
pub fn get_matrix_mut(&mut self) -> &mut Box<[u8]> {
|
||||||
&mut self.data
|
&mut self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,16 +236,19 @@ mod tests {
|
|||||||
(rect_wide.dimensions.1, rect_wide.dimensions.0)
|
(rect_wide.dimensions.1, rect_wide.dimensions.0)
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(rotated_square.data, vec![3, 6, 9, 2, 5, 8, 1, 4, 7]);
|
assert_eq!(
|
||||||
|
rotated_square.data,
|
||||||
|
vec![3, 6, 9, 2, 5, 8, 1, 4, 7].into_boxed_slice()
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
rotated_wide_rect.data,
|
rotated_wide_rect.data,
|
||||||
vec![1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1]
|
vec![1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1].into_boxed_slice()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
rotated_tall_rect.data,
|
rotated_tall_rect.data,
|
||||||
vec![0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0]
|
vec![0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0].into_boxed_slice()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ use crate::Exceptions;
|
|||||||
* @author dswitkin@google.com (Daniel Switkin)
|
* @author dswitkin@google.com (Daniel Switkin)
|
||||||
*/
|
*/
|
||||||
pub trait LuminanceSource {
|
pub trait LuminanceSource {
|
||||||
//private final int width;
|
const SUPPORTS_ROTATION: bool = false;
|
||||||
//private final int height;
|
const SUPPORTS_CROP: bool = false;
|
||||||
|
|
||||||
//fn new( width:usize, height:usize) -> Self;
|
//fn new( width:usize, height:usize) -> Self;
|
||||||
|
|
||||||
@@ -75,7 +75,14 @@ pub trait LuminanceSource {
|
|||||||
* @return Whether this subclass supports cropping.
|
* @return Whether this subclass supports cropping.
|
||||||
*/
|
*/
|
||||||
fn is_crop_supported(&self) -> bool {
|
fn is_crop_supported(&self) -> bool {
|
||||||
false
|
Self::SUPPORTS_CROP
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether this subclass supports counter-clockwise rotation.
|
||||||
|
*/
|
||||||
|
fn is_rotate_supported(&self) -> bool {
|
||||||
|
Self::SUPPORTS_ROTATION
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,13 +104,6 @@ pub trait LuminanceSource {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Whether this subclass supports counter-clockwise rotation.
|
|
||||||
*/
|
|
||||||
fn is_rotate_supported(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a wrapper of this {@code LuminanceSource} which inverts the luminances it returns -- black becomes
|
* @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).
|
* white and vice versa, and each value becomes (255-value).
|
||||||
|
|||||||
@@ -1143,7 +1143,7 @@ mod detector_test {
|
|||||||
.read_to_string(&mut expected_result)
|
.read_to_string(&mut expected_result)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let detection = super::detect(bitmatrix, true).unwrap();
|
let detection = super::detect(&bitmatrix, true).unwrap();
|
||||||
|
|
||||||
// let i: image::DynamicImage = detection.getBits().into();
|
// let i: image::DynamicImage = detection.getBits().into();
|
||||||
// i.save("dbgfle-transformed.png")
|
// i.save("dbgfle-transformed.png")
|
||||||
|
|||||||
@@ -433,115 +433,115 @@ impl Code128Reader {
|
|||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
pub static CODE_PATTERNS: Lazy<[Vec<u32>; 107]> = Lazy::new(|| {
|
pub static CODE_PATTERNS: Lazy<[Box<[u32]>; 107]> = Lazy::new(|| {
|
||||||
[
|
[
|
||||||
vec![2, 1, 2, 2, 2, 2], // 0
|
Box::new([2, 1, 2, 2, 2, 2]), // 0
|
||||||
vec![2, 2, 2, 1, 2, 2],
|
Box::new([2, 2, 2, 1, 2, 2]),
|
||||||
vec![2, 2, 2, 2, 2, 1],
|
Box::new([2, 2, 2, 2, 2, 1]),
|
||||||
vec![1, 2, 1, 2, 2, 3],
|
Box::new([1, 2, 1, 2, 2, 3]),
|
||||||
vec![1, 2, 1, 3, 2, 2],
|
Box::new([1, 2, 1, 3, 2, 2]),
|
||||||
vec![1, 3, 1, 2, 2, 2], // 5
|
Box::new([1, 3, 1, 2, 2, 2]), // 5
|
||||||
vec![1, 2, 2, 2, 1, 3],
|
Box::new([1, 2, 2, 2, 1, 3]),
|
||||||
vec![1, 2, 2, 3, 1, 2],
|
Box::new([1, 2, 2, 3, 1, 2]),
|
||||||
vec![1, 3, 2, 2, 1, 2],
|
Box::new([1, 3, 2, 2, 1, 2]),
|
||||||
vec![2, 2, 1, 2, 1, 3],
|
Box::new([2, 2, 1, 2, 1, 3]),
|
||||||
vec![2, 2, 1, 3, 1, 2], // 10
|
Box::new([2, 2, 1, 3, 1, 2]), // 10
|
||||||
vec![2, 3, 1, 2, 1, 2],
|
Box::new([2, 3, 1, 2, 1, 2]),
|
||||||
vec![1, 1, 2, 2, 3, 2],
|
Box::new([1, 1, 2, 2, 3, 2]),
|
||||||
vec![1, 2, 2, 1, 3, 2],
|
Box::new([1, 2, 2, 1, 3, 2]),
|
||||||
vec![1, 2, 2, 2, 3, 1],
|
Box::new([1, 2, 2, 2, 3, 1]),
|
||||||
vec![1, 1, 3, 2, 2, 2], // 15
|
Box::new([1, 1, 3, 2, 2, 2]), // 15
|
||||||
vec![1, 2, 3, 1, 2, 2],
|
Box::new([1, 2, 3, 1, 2, 2]),
|
||||||
vec![1, 2, 3, 2, 2, 1],
|
Box::new([1, 2, 3, 2, 2, 1]),
|
||||||
vec![2, 2, 3, 2, 1, 1],
|
Box::new([2, 2, 3, 2, 1, 1]),
|
||||||
vec![2, 2, 1, 1, 3, 2],
|
Box::new([2, 2, 1, 1, 3, 2]),
|
||||||
vec![2, 2, 1, 2, 3, 1], // 20
|
Box::new([2, 2, 1, 2, 3, 1]), // 20
|
||||||
vec![2, 1, 3, 2, 1, 2],
|
Box::new([2, 1, 3, 2, 1, 2]),
|
||||||
vec![2, 2, 3, 1, 1, 2],
|
Box::new([2, 2, 3, 1, 1, 2]),
|
||||||
vec![3, 1, 2, 1, 3, 1],
|
Box::new([3, 1, 2, 1, 3, 1]),
|
||||||
vec![3, 1, 1, 2, 2, 2],
|
Box::new([3, 1, 1, 2, 2, 2]),
|
||||||
vec![3, 2, 1, 1, 2, 2], // 25
|
Box::new([3, 2, 1, 1, 2, 2]), // 25
|
||||||
vec![3, 2, 1, 2, 2, 1],
|
Box::new([3, 2, 1, 2, 2, 1]),
|
||||||
vec![3, 1, 2, 2, 1, 2],
|
Box::new([3, 1, 2, 2, 1, 2]),
|
||||||
vec![3, 2, 2, 1, 1, 2],
|
Box::new([3, 2, 2, 1, 1, 2]),
|
||||||
vec![3, 2, 2, 2, 1, 1],
|
Box::new([3, 2, 2, 2, 1, 1]),
|
||||||
vec![2, 1, 2, 1, 2, 3], // 30
|
Box::new([2, 1, 2, 1, 2, 3]), // 30
|
||||||
vec![2, 1, 2, 3, 2, 1],
|
Box::new([2, 1, 2, 3, 2, 1]),
|
||||||
vec![2, 3, 2, 1, 2, 1],
|
Box::new([2, 3, 2, 1, 2, 1]),
|
||||||
vec![1, 1, 1, 3, 2, 3],
|
Box::new([1, 1, 1, 3, 2, 3]),
|
||||||
vec![1, 3, 1, 1, 2, 3],
|
Box::new([1, 3, 1, 1, 2, 3]),
|
||||||
vec![1, 3, 1, 3, 2, 1], // 35
|
Box::new([1, 3, 1, 3, 2, 1]), // 35
|
||||||
vec![1, 1, 2, 3, 1, 3],
|
Box::new([1, 1, 2, 3, 1, 3]),
|
||||||
vec![1, 3, 2, 1, 1, 3],
|
Box::new([1, 3, 2, 1, 1, 3]),
|
||||||
vec![1, 3, 2, 3, 1, 1],
|
Box::new([1, 3, 2, 3, 1, 1]),
|
||||||
vec![2, 1, 1, 3, 1, 3],
|
Box::new([2, 1, 1, 3, 1, 3]),
|
||||||
vec![2, 3, 1, 1, 1, 3], // 40
|
Box::new([2, 3, 1, 1, 1, 3]), // 40
|
||||||
vec![2, 3, 1, 3, 1, 1],
|
Box::new([2, 3, 1, 3, 1, 1]),
|
||||||
vec![1, 1, 2, 1, 3, 3],
|
Box::new([1, 1, 2, 1, 3, 3]),
|
||||||
vec![1, 1, 2, 3, 3, 1],
|
Box::new([1, 1, 2, 3, 3, 1]),
|
||||||
vec![1, 3, 2, 1, 3, 1],
|
Box::new([1, 3, 2, 1, 3, 1]),
|
||||||
vec![1, 1, 3, 1, 2, 3], // 45
|
Box::new([1, 1, 3, 1, 2, 3]), // 45
|
||||||
vec![1, 1, 3, 3, 2, 1],
|
Box::new([1, 1, 3, 3, 2, 1]),
|
||||||
vec![1, 3, 3, 1, 2, 1],
|
Box::new([1, 3, 3, 1, 2, 1]),
|
||||||
vec![3, 1, 3, 1, 2, 1],
|
Box::new([3, 1, 3, 1, 2, 1]),
|
||||||
vec![2, 1, 1, 3, 3, 1],
|
Box::new([2, 1, 1, 3, 3, 1]),
|
||||||
vec![2, 3, 1, 1, 3, 1], // 50
|
Box::new([2, 3, 1, 1, 3, 1]), // 50
|
||||||
vec![2, 1, 3, 1, 1, 3],
|
Box::new([2, 1, 3, 1, 1, 3]),
|
||||||
vec![2, 1, 3, 3, 1, 1],
|
Box::new([2, 1, 3, 3, 1, 1]),
|
||||||
vec![2, 1, 3, 1, 3, 1],
|
Box::new([2, 1, 3, 1, 3, 1]),
|
||||||
vec![3, 1, 1, 1, 2, 3],
|
Box::new([3, 1, 1, 1, 2, 3]),
|
||||||
vec![3, 1, 1, 3, 2, 1], // 55
|
Box::new([3, 1, 1, 3, 2, 1]), // 55
|
||||||
vec![3, 3, 1, 1, 2, 1],
|
Box::new([3, 3, 1, 1, 2, 1]),
|
||||||
vec![3, 1, 2, 1, 1, 3],
|
Box::new([3, 1, 2, 1, 1, 3]),
|
||||||
vec![3, 1, 2, 3, 1, 1],
|
Box::new([3, 1, 2, 3, 1, 1]),
|
||||||
vec![3, 3, 2, 1, 1, 1],
|
Box::new([3, 3, 2, 1, 1, 1]),
|
||||||
vec![3, 1, 4, 1, 1, 1], // 60
|
Box::new([3, 1, 4, 1, 1, 1]), // 60
|
||||||
vec![2, 2, 1, 4, 1, 1],
|
Box::new([2, 2, 1, 4, 1, 1]),
|
||||||
vec![4, 3, 1, 1, 1, 1],
|
Box::new([4, 3, 1, 1, 1, 1]),
|
||||||
vec![1, 1, 1, 2, 2, 4],
|
Box::new([1, 1, 1, 2, 2, 4]),
|
||||||
vec![1, 1, 1, 4, 2, 2],
|
Box::new([1, 1, 1, 4, 2, 2]),
|
||||||
vec![1, 2, 1, 1, 2, 4], // 65
|
Box::new([1, 2, 1, 1, 2, 4]), // 65
|
||||||
vec![1, 2, 1, 4, 2, 1],
|
Box::new([1, 2, 1, 4, 2, 1]),
|
||||||
vec![1, 4, 1, 1, 2, 2],
|
Box::new([1, 4, 1, 1, 2, 2]),
|
||||||
vec![1, 4, 1, 2, 2, 1],
|
Box::new([1, 4, 1, 2, 2, 1]),
|
||||||
vec![1, 1, 2, 2, 1, 4],
|
Box::new([1, 1, 2, 2, 1, 4]),
|
||||||
vec![1, 1, 2, 4, 1, 2], // 70
|
Box::new([1, 1, 2, 4, 1, 2]), // 70
|
||||||
vec![1, 2, 2, 1, 1, 4],
|
Box::new([1, 2, 2, 1, 1, 4]),
|
||||||
vec![1, 2, 2, 4, 1, 1],
|
Box::new([1, 2, 2, 4, 1, 1]),
|
||||||
vec![1, 4, 2, 1, 1, 2],
|
Box::new([1, 4, 2, 1, 1, 2]),
|
||||||
vec![1, 4, 2, 2, 1, 1],
|
Box::new([1, 4, 2, 2, 1, 1]),
|
||||||
vec![2, 4, 1, 2, 1, 1], // 75
|
Box::new([2, 4, 1, 2, 1, 1]), // 75
|
||||||
vec![2, 2, 1, 1, 1, 4],
|
Box::new([2, 2, 1, 1, 1, 4]),
|
||||||
vec![4, 1, 3, 1, 1, 1],
|
Box::new([4, 1, 3, 1, 1, 1]),
|
||||||
vec![2, 4, 1, 1, 1, 2],
|
Box::new([2, 4, 1, 1, 1, 2]),
|
||||||
vec![1, 3, 4, 1, 1, 1],
|
Box::new([1, 3, 4, 1, 1, 1]),
|
||||||
vec![1, 1, 1, 2, 4, 2], // 80
|
Box::new([1, 1, 1, 2, 4, 2]), // 80
|
||||||
vec![1, 2, 1, 1, 4, 2],
|
Box::new([1, 2, 1, 1, 4, 2]),
|
||||||
vec![1, 2, 1, 2, 4, 1],
|
Box::new([1, 2, 1, 2, 4, 1]),
|
||||||
vec![1, 1, 4, 2, 1, 2],
|
Box::new([1, 1, 4, 2, 1, 2]),
|
||||||
vec![1, 2, 4, 1, 1, 2],
|
Box::new([1, 2, 4, 1, 1, 2]),
|
||||||
vec![1, 2, 4, 2, 1, 1], // 85
|
Box::new([1, 2, 4, 2, 1, 1]), // 85
|
||||||
vec![4, 1, 1, 2, 1, 2],
|
Box::new([4, 1, 1, 2, 1, 2]),
|
||||||
vec![4, 2, 1, 1, 1, 2],
|
Box::new([4, 2, 1, 1, 1, 2]),
|
||||||
vec![4, 2, 1, 2, 1, 1],
|
Box::new([4, 2, 1, 2, 1, 1]),
|
||||||
vec![2, 1, 2, 1, 4, 1],
|
Box::new([2, 1, 2, 1, 4, 1]),
|
||||||
vec![2, 1, 4, 1, 2, 1], // 90
|
Box::new([2, 1, 4, 1, 2, 1]), // 90
|
||||||
vec![4, 1, 2, 1, 2, 1],
|
Box::new([4, 1, 2, 1, 2, 1]),
|
||||||
vec![1, 1, 1, 1, 4, 3],
|
Box::new([1, 1, 1, 1, 4, 3]),
|
||||||
vec![1, 1, 1, 3, 4, 1],
|
Box::new([1, 1, 1, 3, 4, 1]),
|
||||||
vec![1, 3, 1, 1, 4, 1],
|
Box::new([1, 3, 1, 1, 4, 1]),
|
||||||
vec![1, 1, 4, 1, 1, 3], // 95
|
Box::new([1, 1, 4, 1, 1, 3]), // 95
|
||||||
vec![1, 1, 4, 3, 1, 1],
|
Box::new([1, 1, 4, 3, 1, 1]),
|
||||||
vec![4, 1, 1, 1, 1, 3],
|
Box::new([4, 1, 1, 1, 1, 3]),
|
||||||
vec![4, 1, 1, 3, 1, 1],
|
Box::new([4, 1, 1, 3, 1, 1]),
|
||||||
vec![1, 1, 3, 1, 4, 1],
|
Box::new([1, 1, 3, 1, 4, 1]),
|
||||||
vec![1, 1, 4, 1, 3, 1], // 100
|
Box::new([1, 1, 4, 1, 3, 1]), // 100
|
||||||
vec![3, 1, 1, 1, 4, 1],
|
Box::new([3, 1, 1, 1, 4, 1]),
|
||||||
vec![4, 1, 1, 1, 3, 1],
|
Box::new([4, 1, 1, 1, 3, 1]),
|
||||||
vec![2, 1, 1, 4, 1, 2],
|
Box::new([2, 1, 1, 4, 1, 2]),
|
||||||
vec![2, 1, 1, 2, 1, 4],
|
Box::new([2, 1, 1, 2, 1, 4]),
|
||||||
vec![2, 1, 1, 2, 3, 2], // 105
|
Box::new([2, 1, 1, 2, 3, 2]), // 105
|
||||||
vec![2, 3, 3, 1, 1, 1, 2],
|
Box::new([2, 3, 3, 1, 1, 1, 2]),
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ impl<'a> RowReader for DXFilmEdgeReader<'_> {
|
|||||||
for _i in 0..modules {
|
for _i in 0..modules {
|
||||||
dataBits.appendBits(
|
dataBits.appendBits(
|
||||||
if next.index() % 2 == 0 {
|
if next.index() % 2 == 0 {
|
||||||
0xFFFFFFFF
|
0xFFFFFFFF_u32
|
||||||
} else {
|
} else {
|
||||||
0x0
|
0x0
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,15 +25,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
pub struct EANManufacturerOrgSupport {
|
pub struct EANManufacturerOrgSupport {
|
||||||
ranges: Vec<Vec<u32>>, //= new ArrayList<>();
|
ranges: Vec<[u32; 2]>, //= new ArrayList<>();
|
||||||
countryIdentifiers: Vec<String>, // = new ArrayList<>();
|
countryIdentifiers: Vec<&'static str>, // = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EANManufacturerOrgSupport {
|
impl Default for EANManufacturerOrgSupport {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut slf = Self {
|
let mut slf = Self {
|
||||||
ranges: Default::default(),
|
ranges: Vec::with_capacity(150),
|
||||||
countryIdentifiers: Default::default(),
|
countryIdentifiers: Vec::with_capacity(150),
|
||||||
};
|
};
|
||||||
slf.initIfNeeded();
|
slf.initIfNeeded();
|
||||||
slf
|
slf
|
||||||
@@ -42,14 +42,14 @@ impl Default for EANManufacturerOrgSupport {
|
|||||||
|
|
||||||
impl EANManufacturerOrgSupport {
|
impl EANManufacturerOrgSupport {
|
||||||
pub fn lookupCountryIdentifier(&self, productCode: &str) -> Option<&str> {
|
pub fn lookupCountryIdentifier(&self, productCode: &str) -> Option<&str> {
|
||||||
let prefix = productCode[0..3].parse::<u32>().expect("must parse prefix");
|
let prefix = productCode[0..3].parse::<u32>().ok()?;
|
||||||
let max = self.ranges.len();
|
let max = self.ranges.len();
|
||||||
for (i, range) in self.ranges.iter().enumerate().take(max) {
|
for (i, range) in self.ranges.iter().enumerate().take(max) {
|
||||||
let start = range[0];
|
let start = range[0];
|
||||||
if prefix < start {
|
if prefix < start {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let end = if range.len() == 1 { start } else { range[1] };
|
let end = if range[1] == 0 { start } else { range[1] };
|
||||||
if prefix <= end {
|
if prefix <= end {
|
||||||
return Some(self.countryIdentifiers.get(i)?);
|
return Some(self.countryIdentifiers.get(i)?);
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ impl EANManufacturerOrgSupport {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&mut self, range: Vec<u32>, id: String) {
|
fn add(&mut self, range: [u32; 2], id: &'static str) {
|
||||||
self.ranges.push(range);
|
self.ranges.push(range);
|
||||||
self.countryIdentifiers.push(id);
|
self.countryIdentifiers.push(id);
|
||||||
}
|
}
|
||||||
@@ -67,112 +67,112 @@ impl EANManufacturerOrgSupport {
|
|||||||
if !self.ranges.is_empty() {
|
if !self.ranges.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.add(vec![0, 19], "US/CA".to_owned());
|
self.add([0, 19], "US/CA");
|
||||||
self.add(vec![30, 39], "US".to_owned());
|
self.add([30, 39], "US");
|
||||||
self.add(vec![60, 139], "US/CA".to_owned());
|
self.add([60, 139], "US/CA");
|
||||||
self.add(vec![300, 379], "FR".to_owned());
|
self.add([300, 379], "FR");
|
||||||
self.add(vec![380], "BG".to_owned());
|
self.add([380, 0], "BG");
|
||||||
self.add(vec![383], "SI".to_owned());
|
self.add([383, 0], "SI");
|
||||||
self.add(vec![385], "HR".to_owned());
|
self.add([385, 0], "HR");
|
||||||
self.add(vec![387], "BA".to_owned());
|
self.add([387, 0], "BA");
|
||||||
self.add(vec![400, 440], "DE".to_owned());
|
self.add([400, 440], "DE");
|
||||||
self.add(vec![450, 459], "JP".to_owned());
|
self.add([450, 459], "JP");
|
||||||
self.add(vec![460, 469], "RU".to_owned());
|
self.add([460, 469], "RU");
|
||||||
self.add(vec![471], "TW".to_owned());
|
self.add([471, 0], "TW");
|
||||||
self.add(vec![474], "EE".to_owned());
|
self.add([474, 0], "EE");
|
||||||
self.add(vec![475], "LV".to_owned());
|
self.add([475, 0], "LV");
|
||||||
self.add(vec![476], "AZ".to_owned());
|
self.add([476, 0], "AZ");
|
||||||
self.add(vec![477], "LT".to_owned());
|
self.add([477, 0], "LT");
|
||||||
self.add(vec![478], "UZ".to_owned());
|
self.add([478, 0], "UZ");
|
||||||
self.add(vec![479], "LK".to_owned());
|
self.add([479, 0], "LK");
|
||||||
self.add(vec![480], "PH".to_owned());
|
self.add([480, 0], "PH");
|
||||||
self.add(vec![481], "BY".to_owned());
|
self.add([481, 0], "BY");
|
||||||
self.add(vec![482], "UA".to_owned());
|
self.add([482, 0], "UA");
|
||||||
self.add(vec![484], "MD".to_owned());
|
self.add([484, 0], "MD");
|
||||||
self.add(vec![485], "AM".to_owned());
|
self.add([485, 0], "AM");
|
||||||
self.add(vec![486], "GE".to_owned());
|
self.add([486, 0], "GE");
|
||||||
self.add(vec![487], "KZ".to_owned());
|
self.add([487, 0], "KZ");
|
||||||
self.add(vec![489], "HK".to_owned());
|
self.add([489, 0], "HK");
|
||||||
self.add(vec![490, 499], "JP".to_owned());
|
self.add([490, 499], "JP");
|
||||||
self.add(vec![500, 509], "GB".to_owned());
|
self.add([500, 509], "GB");
|
||||||
self.add(vec![520], "GR".to_owned());
|
self.add([520, 0], "GR");
|
||||||
self.add(vec![528], "LB".to_owned());
|
self.add([528, 0], "LB");
|
||||||
self.add(vec![529], "CY".to_owned());
|
self.add([529, 0], "CY");
|
||||||
self.add(vec![531], "MK".to_owned());
|
self.add([531, 0], "MK");
|
||||||
self.add(vec![535], "MT".to_owned());
|
self.add([535, 0], "MT");
|
||||||
self.add(vec![539], "IE".to_owned());
|
self.add([539, 0], "IE");
|
||||||
self.add(vec![540, 549], "BE/LU".to_owned());
|
self.add([540, 549], "BE/LU");
|
||||||
self.add(vec![560], "PT".to_owned());
|
self.add([560, 0], "PT");
|
||||||
self.add(vec![569], "IS".to_owned());
|
self.add([569, 0], "IS");
|
||||||
self.add(vec![570, 579], "DK".to_owned());
|
self.add([570, 579], "DK");
|
||||||
self.add(vec![590], "PL".to_owned());
|
self.add([590, 0], "PL");
|
||||||
self.add(vec![594], "RO".to_owned());
|
self.add([594, 0], "RO");
|
||||||
self.add(vec![599], "HU".to_owned());
|
self.add([599, 0], "HU");
|
||||||
self.add(vec![600, 601], "ZA".to_owned());
|
self.add([600, 601], "ZA");
|
||||||
self.add(vec![603], "GH".to_owned());
|
self.add([603, 0], "GH");
|
||||||
self.add(vec![608], "BH".to_owned());
|
self.add([608, 0], "BH");
|
||||||
self.add(vec![609], "MU".to_owned());
|
self.add([609, 0], "MU");
|
||||||
self.add(vec![611], "MA".to_owned());
|
self.add([611, 0], "MA");
|
||||||
self.add(vec![613], "DZ".to_owned());
|
self.add([613, 0], "DZ");
|
||||||
self.add(vec![616], "KE".to_owned());
|
self.add([616, 0], "KE");
|
||||||
self.add(vec![618], "CI".to_owned());
|
self.add([618, 0], "CI");
|
||||||
self.add(vec![619], "TN".to_owned());
|
self.add([619, 0], "TN");
|
||||||
self.add(vec![621], "SY".to_owned());
|
self.add([621, 0], "SY");
|
||||||
self.add(vec![622], "EG".to_owned());
|
self.add([622, 0], "EG");
|
||||||
self.add(vec![624], "LY".to_owned());
|
self.add([624, 0], "LY");
|
||||||
self.add(vec![625], "JO".to_owned());
|
self.add([625, 0], "JO");
|
||||||
self.add(vec![626], "IR".to_owned());
|
self.add([626, 0], "IR");
|
||||||
self.add(vec![627], "KW".to_owned());
|
self.add([627, 0], "KW");
|
||||||
self.add(vec![628], "SA".to_owned());
|
self.add([628, 0], "SA");
|
||||||
self.add(vec![629], "AE".to_owned());
|
self.add([629, 0], "AE");
|
||||||
self.add(vec![640, 649], "FI".to_owned());
|
self.add([640, 649], "FI");
|
||||||
self.add(vec![690, 695], "CN".to_owned());
|
self.add([690, 695], "CN");
|
||||||
self.add(vec![700, 709], "NO".to_owned());
|
self.add([700, 709], "NO");
|
||||||
self.add(vec![729], "IL".to_owned());
|
self.add([729, 0], "IL");
|
||||||
self.add(vec![730, 739], "SE".to_owned());
|
self.add([730, 739], "SE");
|
||||||
self.add(vec![740], "GT".to_owned());
|
self.add([740, 0], "GT");
|
||||||
self.add(vec![741], "SV".to_owned());
|
self.add([741, 0], "SV");
|
||||||
self.add(vec![742], "HN".to_owned());
|
self.add([742, 0], "HN");
|
||||||
self.add(vec![743], "NI".to_owned());
|
self.add([743, 0], "NI");
|
||||||
self.add(vec![744], "CR".to_owned());
|
self.add([744, 0], "CR");
|
||||||
self.add(vec![745], "PA".to_owned());
|
self.add([745, 0], "PA");
|
||||||
self.add(vec![746], "DO".to_owned());
|
self.add([746, 0], "DO");
|
||||||
self.add(vec![750], "MX".to_owned());
|
self.add([750, 0], "MX");
|
||||||
self.add(vec![754, 755], "CA".to_owned());
|
self.add([754, 755], "CA");
|
||||||
self.add(vec![759], "VE".to_owned());
|
self.add([759, 0], "VE");
|
||||||
self.add(vec![760, 769], "CH".to_owned());
|
self.add([760, 769], "CH");
|
||||||
self.add(vec![770], "CO".to_owned());
|
self.add([770, 0], "CO");
|
||||||
self.add(vec![773], "UY".to_owned());
|
self.add([773, 0], "UY");
|
||||||
self.add(vec![775], "PE".to_owned());
|
self.add([775, 0], "PE");
|
||||||
self.add(vec![777], "BO".to_owned());
|
self.add([777, 0], "BO");
|
||||||
self.add(vec![779], "AR".to_owned());
|
self.add([779, 0], "AR");
|
||||||
self.add(vec![780], "CL".to_owned());
|
self.add([780, 0], "CL");
|
||||||
self.add(vec![784], "PY".to_owned());
|
self.add([784, 0], "PY");
|
||||||
self.add(vec![785], "PE".to_owned());
|
self.add([785, 0], "PE");
|
||||||
self.add(vec![786], "EC".to_owned());
|
self.add([786, 0], "EC");
|
||||||
self.add(vec![789, 790], "BR".to_owned());
|
self.add([789, 790], "BR");
|
||||||
self.add(vec![800, 839], "IT".to_owned());
|
self.add([800, 839], "IT");
|
||||||
self.add(vec![840, 849], "ES".to_owned());
|
self.add([840, 849], "ES");
|
||||||
self.add(vec![850], "CU".to_owned());
|
self.add([850, 0], "CU");
|
||||||
self.add(vec![858], "SK".to_owned());
|
self.add([858, 0], "SK");
|
||||||
self.add(vec![859], "CZ".to_owned());
|
self.add([859, 0], "CZ");
|
||||||
self.add(vec![860], "YU".to_owned());
|
self.add([860, 0], "YU");
|
||||||
self.add(vec![865], "MN".to_owned());
|
self.add([865, 0], "MN");
|
||||||
self.add(vec![867], "KP".to_owned());
|
self.add([867, 0], "KP");
|
||||||
self.add(vec![868, 869], "TR".to_owned());
|
self.add([868, 869], "TR");
|
||||||
self.add(vec![870, 879], "NL".to_owned());
|
self.add([870, 879], "NL");
|
||||||
self.add(vec![880], "KR".to_owned());
|
self.add([880, 0], "KR");
|
||||||
self.add(vec![885], "TH".to_owned());
|
self.add([885, 0], "TH");
|
||||||
self.add(vec![888], "SG".to_owned());
|
self.add([888, 0], "SG");
|
||||||
self.add(vec![890], "IN".to_owned());
|
self.add([890, 0], "IN");
|
||||||
self.add(vec![893], "VN".to_owned());
|
self.add([893, 0], "VN");
|
||||||
self.add(vec![896], "PK".to_owned());
|
self.add([896, 0], "PK");
|
||||||
self.add(vec![899], "ID".to_owned());
|
self.add([899, 0], "ID");
|
||||||
self.add(vec![900, 919], "AT".to_owned());
|
self.add([900, 919], "AT");
|
||||||
self.add(vec![930, 939], "AU".to_owned());
|
self.add([930, 939], "AU");
|
||||||
self.add(vec![940, 949], "AZ".to_owned());
|
self.add([940, 949], "AZ");
|
||||||
self.add(vec![955], "MY".to_owned());
|
self.add([955, 0], "MY");
|
||||||
self.add(vec![958], "MO".to_owned());
|
self.add([958, 0], "MO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,19 +85,12 @@ pub trait AbstractRSSReaderTrait: OneDReader {
|
|||||||
let ratio: f32 = (firstTwoSum as f32) / (sum as f32);
|
let ratio: f32 = (firstTwoSum as f32) / (sum as f32);
|
||||||
if ratio >= Self::MIN_FINDER_PATTERN_RATIO && ratio <= Self::MAX_FINDER_PATTERN_RATIO {
|
if ratio >= Self::MIN_FINDER_PATTERN_RATIO && ratio <= Self::MAX_FINDER_PATTERN_RATIO {
|
||||||
// passes ratio test in spec, but see if the counts are unreasonable
|
// passes ratio test in spec, but see if the counts are unreasonable
|
||||||
// let minCounter = counters.iter().min();
|
|
||||||
// let maxCounter = counters.iter().max();
|
|
||||||
let mut minCounter = u32::MAX;
|
let mut minCounter = u32::MAX;
|
||||||
let mut maxCounter = u32::MIN;
|
let mut maxCounter = u32::MIN;
|
||||||
|
|
||||||
for counter in counters {
|
for counter in counters {
|
||||||
maxCounter = std::cmp::max(*counter, maxCounter);
|
maxCounter = std::cmp::max(*counter, maxCounter);
|
||||||
minCounter = std::cmp::min(*counter, minCounter);
|
minCounter = std::cmp::min(*counter, minCounter);
|
||||||
// if *counter > maxCounter {
|
|
||||||
// maxCounter = *counter;
|
|
||||||
// }
|
|
||||||
// if *counter < minCounter {
|
|
||||||
// minCounter = *counter;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
return maxCounter < 10 * minCounter;
|
return maxCounter < 10 * minCounter;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,62 +93,14 @@ pub fn createDecoder<'a>(
|
|||||||
let sevenBitEncodationMethod =
|
let sevenBitEncodationMethod =
|
||||||
GeneralAppIdDecoder::extractNumericValueFromBitArrayWithInformation(information, 1, 7);
|
GeneralAppIdDecoder::extractNumericValueFromBitArrayWithInformation(information, 1, 7);
|
||||||
match sevenBitEncodationMethod {
|
match sevenBitEncodationMethod {
|
||||||
56 => {
|
56 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "310", "11"))),
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
57 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "320", "11"))),
|
||||||
information,
|
58 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "310", "13"))),
|
||||||
"310".to_owned(),
|
59 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "320", "13"))),
|
||||||
"11".to_owned(),
|
60 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "310", "15"))),
|
||||||
)))
|
61 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "320", "15"))),
|
||||||
}
|
62 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "310", "17"))),
|
||||||
57 => {
|
63 => return Ok(Box::new(AI013x0x1xDecoder::new(information, "320", "17"))),
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
|
||||||
information,
|
|
||||||
"320".to_owned(),
|
|
||||||
"11".to_owned(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
58 => {
|
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
|
||||||
information,
|
|
||||||
"310".to_owned(),
|
|
||||||
"13".to_owned(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
59 => {
|
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
|
||||||
information,
|
|
||||||
"320".to_owned(),
|
|
||||||
"13".to_owned(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
60 => {
|
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
|
||||||
information,
|
|
||||||
"310".to_owned(),
|
|
||||||
"15".to_owned(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
61 => {
|
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
|
||||||
information,
|
|
||||||
"320".to_owned(),
|
|
||||||
"15".to_owned(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
62 => {
|
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
|
||||||
information,
|
|
||||||
"310".to_owned(),
|
|
||||||
"17".to_owned(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
63 => {
|
|
||||||
return Ok(Box::new(AI013x0x1xDecoder::new(
|
|
||||||
information,
|
|
||||||
"320".to_owned(),
|
|
||||||
"17".to_owned(),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ use super::{AI01decoder, AI01weightDecoder, AbstractExpandedDecoder, GeneralAppI
|
|||||||
pub struct AI013x0x1xDecoder<'a> {
|
pub struct AI013x0x1xDecoder<'a> {
|
||||||
information: &'a BitArray,
|
information: &'a BitArray,
|
||||||
decoder: GeneralAppIdDecoder<'a>,
|
decoder: GeneralAppIdDecoder<'a>,
|
||||||
dateCode: String,
|
dateCode: &'static str,
|
||||||
firstAIdigits: String,
|
firstAIdigits: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AI01weightDecoder for AI013x0x1xDecoder<'_> {
|
impl AI01weightDecoder for AI013x0x1xDecoder<'_> {
|
||||||
@@ -88,8 +88,8 @@ impl<'a> AI013x0x1xDecoder<'_> {
|
|||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
information: &'a BitArray,
|
information: &'a BitArray,
|
||||||
firstAIdigits: String,
|
firstAIdigits: &'static str,
|
||||||
dateCode: String,
|
dateCode: &'static str,
|
||||||
) -> AI013x0x1xDecoder<'a> {
|
) -> AI013x0x1xDecoder<'a> {
|
||||||
AI013x0x1xDecoder {
|
AI013x0x1xDecoder {
|
||||||
information,
|
information,
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ impl OneDReader for RSS14Reader {
|
|||||||
row.reverse();
|
row.reverse();
|
||||||
let rightPair = self.decodePair(&row, true, rowNumber, hints);
|
let rightPair = self.decodePair(&row, true, rowNumber, hints);
|
||||||
Self::addOrTally(&mut self.possibleRightPairs, rightPair);
|
Self::addOrTally(&mut self.possibleRightPairs, rightPair);
|
||||||
row.reverse();
|
|
||||||
for left in &self.possibleLeftPairs {
|
for left in &self.possibleLeftPairs {
|
||||||
if left.getCount() > 1 {
|
if left.getCount() > 1 {
|
||||||
for right in &self.possibleRightPairs {
|
for right in &self.possibleRightPairs {
|
||||||
@@ -246,35 +245,33 @@ impl RSS14Reader {
|
|||||||
rowNumber: u32,
|
rowNumber: u32,
|
||||||
hints: &DecodingHintDictionary,
|
hints: &DecodingHintDictionary,
|
||||||
) -> Option<Pair> {
|
) -> Option<Pair> {
|
||||||
let pos_pair = || -> Result<Pair> {
|
let startEnd = self.findFinderPattern(row, right).ok()?;
|
||||||
let startEnd = self.findFinderPattern(row, right)?;
|
let pattern = self
|
||||||
let pattern = self.parseFoundFinderPattern(row, rowNumber, right, &startEnd)?;
|
.parseFoundFinderPattern(row, rowNumber, right, &startEnd)
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
if let Some(DecodeHintValue::NeedResultPointCallback(cb)) =
|
if let Some(DecodeHintValue::NeedResultPointCallback(cb)) =
|
||||||
hints.get(&DecodeHintType::NEED_RESULT_POINT_CALLBACK)
|
hints.get(&DecodeHintType::NEED_RESULT_POINT_CALLBACK)
|
||||||
{
|
{
|
||||||
let startEnd = pattern.getStartEnd();
|
let startEnd = pattern.getStartEnd();
|
||||||
let mut center: f32 = (startEnd[0] + startEnd[1] - 1) as f32 / 2.0;
|
let mut center: f32 = (startEnd[0] + startEnd[1] - 1) as f32 / 2.0;
|
||||||
if right {
|
if right {
|
||||||
// row is actually reversed
|
// row is actually reversed
|
||||||
center = row.get_size() as f32 - 1.0 - center;
|
center = row.get_size() as f32 - 1.0 - center;
|
||||||
}
|
|
||||||
cb(point_f(center, rowNumber as f32));
|
|
||||||
}
|
}
|
||||||
|
cb(point_f(center, rowNumber as f32));
|
||||||
|
}
|
||||||
|
|
||||||
let outside = self.decodeDataCharacter(row, &pattern, true)?;
|
let outside = self.decodeDataCharacter(row, &pattern, true).ok()?;
|
||||||
let inside = self.decodeDataCharacter(row, &pattern, false)?;
|
let inside = self.decodeDataCharacter(row, &pattern, false).ok()?;
|
||||||
|
|
||||||
// todo!("must add callback");
|
// todo!("must add callback");
|
||||||
|
|
||||||
Ok(Pair::new(
|
Some(Pair::new(
|
||||||
1597 * outside.getValue() + inside.getValue(),
|
1597 * outside.getValue() + inside.getValue(),
|
||||||
outside.getChecksumPortion() + 4 * inside.getChecksumPortion(),
|
outside.getChecksumPortion() + 4 * inside.getChecksumPortion(),
|
||||||
pattern,
|
pattern,
|
||||||
))
|
))
|
||||||
}();
|
|
||||||
|
|
||||||
pos_pair.ok()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decodeDataCharacter(
|
fn decodeDataCharacter(
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ impl OneDimensionalCodeWriter for TelepenWriter {
|
|||||||
for c in decodedContents.chars() {
|
for c in decodedContents.chars() {
|
||||||
if c as u32 > 127 {
|
if c as u32 > 127 {
|
||||||
return Err(Exceptions::illegal_argument_with(
|
return Err(Exceptions::illegal_argument_with(
|
||||||
"Telepen only supports ASCII characters.".to_string(),
|
"Telepen only supports ASCII characters.",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ impl OneDimensionalCodeWriter for TelepenWriter {
|
|||||||
}
|
}
|
||||||
"0" => {
|
"0" => {
|
||||||
return Err(Exceptions::illegal_argument_with(
|
return Err(Exceptions::illegal_argument_with(
|
||||||
"Invalid bit combination!".to_string(),
|
"Invalid bit combination!",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ impl UPCEANExtension5Support {
|
|||||||
"99991" =>
|
"99991" =>
|
||||||
// Complementary
|
// Complementary
|
||||||
{
|
{
|
||||||
return Some("0.00".to_string())
|
return Some("0.00".to_owned())
|
||||||
}
|
}
|
||||||
"99990" => return Some("Used".to_owned()),
|
"99990" => return Some("Used".to_owned()),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -237,6 +237,9 @@ impl PlanarYUVLuminanceSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LuminanceSource for PlanarYUVLuminanceSource {
|
impl LuminanceSource for PlanarYUVLuminanceSource {
|
||||||
|
const SUPPORTS_CROP: bool = true;
|
||||||
|
const SUPPORTS_ROTATION: bool = false;
|
||||||
|
|
||||||
fn get_row(&self, y: usize) -> Vec<u8> {
|
fn get_row(&self, y: usize) -> Vec<u8> {
|
||||||
if y >= self.get_height() {
|
if y >= self.get_height() {
|
||||||
// //throw new IllegalArgumentException("Requested row is outside the image: " + y);
|
// //throw new IllegalArgumentException("Requested row is outside the image: " + y);
|
||||||
@@ -310,10 +313,6 @@ impl LuminanceSource for PlanarYUVLuminanceSource {
|
|||||||
self.height
|
self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_crop_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
||||||
PlanarYUVLuminanceSource::new_with_all(
|
PlanarYUVLuminanceSource::new_with_all(
|
||||||
self.yuv_data.clone(),
|
self.yuv_data.clone(),
|
||||||
@@ -329,10 +328,6 @@ impl LuminanceSource for PlanarYUVLuminanceSource {
|
|||||||
.map_err(|_| Exceptions::UNSUPPORTED_OPERATION)
|
.map_err(|_| Exceptions::UNSUPPORTED_OPERATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_rotate_supported(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn invert(&mut self) {
|
fn invert(&mut self) {
|
||||||
self.invert = !self.invert;
|
self.invert = !self.invert;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ impl ErrorCorrectionLevel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_value(&self) -> u8 {
|
pub const fn get_value(&self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
ErrorCorrectionLevel::L => 0x01,
|
ErrorCorrectionLevel::L => 0x01,
|
||||||
ErrorCorrectionLevel::M => 0x00,
|
ErrorCorrectionLevel::M => 0x00,
|
||||||
@@ -66,7 +66,7 @@ impl ErrorCorrectionLevel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ordinal(&self) -> u8 {
|
pub const fn get_ordinal(&self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
ErrorCorrectionLevel::L => 0,
|
ErrorCorrectionLevel::L => 0,
|
||||||
ErrorCorrectionLevel::M => 1,
|
ErrorCorrectionLevel::M => 1,
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ use once_cell::sync::Lazy;
|
|||||||
|
|
||||||
pub type VersionRef = &'static Version;
|
pub type VersionRef = &'static Version;
|
||||||
|
|
||||||
pub static VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::buildVersions);
|
pub static VERSIONS: Lazy<Box<[Version]>> = Lazy::new(Version::buildVersions);
|
||||||
pub static MICRO_VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::build_micro_versions);
|
pub static MICRO_VERSIONS: Lazy<Box<[Version]>> = Lazy::new(Version::build_micro_versions);
|
||||||
pub static MODEL1_VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::build_model1_versions);
|
pub static MODEL1_VERSIONS: Lazy<Box<[Version]>> = Lazy::new(Version::build_model1_versions);
|
||||||
pub static RMQR_VERSIONS: Lazy<Vec<Version>> = Lazy::new(Version::build_rmqr_versions);
|
pub static RMQR_VERSIONS: Lazy<Box<[Version]>> = Lazy::new(Version::build_rmqr_versions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See ISO 18004:2006 Annex D.
|
* See ISO 18004:2006 Annex D.
|
||||||
@@ -54,15 +54,15 @@ pub const VERSION_DECODE_INFO: [u32; 34] = [
|
|||||||
pub struct Version {
|
pub struct Version {
|
||||||
// private static final Version[] VERSIONS = buildVersions();
|
// private static final Version[] VERSIONS = buildVersions();
|
||||||
versionNumber: u32,
|
versionNumber: u32,
|
||||||
alignmentPatternCenters: Vec<u32>,
|
alignmentPatternCenters: Box<[u32]>,
|
||||||
ecBlocks: Vec<ECBlocks>,
|
ecBlocks: Box<[ECBlocks]>,
|
||||||
totalCodewords: u32,
|
totalCodewords: u32,
|
||||||
pub(crate) qr_type: Type,
|
pub(crate) qr_type: Type,
|
||||||
}
|
}
|
||||||
impl Version {
|
impl Version {
|
||||||
pub(super) fn new(
|
pub(super) fn new(
|
||||||
versionNumber: u32,
|
versionNumber: u32,
|
||||||
alignmentPatternCenters: Vec<u32>,
|
alignmentPatternCenters: Box<[u32]>,
|
||||||
ecBlocks: [ECBlocks; 4],
|
ecBlocks: [ECBlocks; 4],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
@@ -78,17 +78,20 @@ impl Version {
|
|||||||
Self {
|
Self {
|
||||||
versionNumber,
|
versionNumber,
|
||||||
alignmentPatternCenters,
|
alignmentPatternCenters,
|
||||||
ecBlocks: ecBlocks.to_vec(),
|
|
||||||
totalCodewords: total,
|
|
||||||
qr_type: if ecBlocks[0].getECCodewordsPerBlock() != 0 {
|
qr_type: if ecBlocks[0].getECCodewordsPerBlock() != 0 {
|
||||||
Type::Model2
|
Type::Model2
|
||||||
} else {
|
} else {
|
||||||
Type::RectMicro
|
Type::RectMicro
|
||||||
},
|
},
|
||||||
|
ecBlocks: Box::new(ecBlocks),
|
||||||
|
totalCodewords: total,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn without_alignment_patterns(versionNumber: u32, ecBlocks: Vec<ECBlocks>) -> Self {
|
pub(super) fn without_alignment_patterns(
|
||||||
|
versionNumber: u32,
|
||||||
|
ecBlocks: Box<[ECBlocks]>,
|
||||||
|
) -> Self {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
let ecCodewords = ecBlocks[0].getECCodewordsPerBlock();
|
let ecCodewords = ecBlocks[0].getECCodewordsPerBlock();
|
||||||
let ecbArray = ecBlocks[0].getECBlocks();
|
let ecbArray = ecBlocks[0].getECBlocks();
|
||||||
@@ -107,7 +110,7 @@ impl Version {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
versionNumber,
|
versionNumber,
|
||||||
alignmentPatternCenters: Vec::default(),
|
alignmentPatternCenters: Box::default(),
|
||||||
ecBlocks,
|
ecBlocks,
|
||||||
totalCodewords: total,
|
totalCodewords: total,
|
||||||
qr_type: symbol_type,
|
qr_type: symbol_type,
|
||||||
@@ -118,11 +121,11 @@ impl Version {
|
|||||||
self.versionNumber
|
self.versionNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAlignmentPatternCenters(&self) -> &[u32] {
|
pub const fn getAlignmentPatternCenters(&self) -> &[u32] {
|
||||||
&self.alignmentPatternCenters
|
&self.alignmentPatternCenters
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getTotalCodewords(&self) -> u32 {
|
pub const fn getTotalCodewords(&self) -> u32 {
|
||||||
self.totalCodewords
|
self.totalCodewords
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +134,7 @@ impl Version {
|
|||||||
// 17 + 4 * self.versionNumber
|
// 17 + 4 * self.versionNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getECBlocksForLevel(&self, ecLevel: ErrorCorrectionLevel) -> &ECBlocks {
|
pub const fn getECBlocksForLevel(&self, ecLevel: ErrorCorrectionLevel) -> &ECBlocks {
|
||||||
if ecLevel.get_ordinal() as usize >= self.ecBlocks.len() {
|
if ecLevel.get_ordinal() as usize >= self.ecBlocks.len() {
|
||||||
return &self.ecBlocks[ecLevel.get_ordinal() as usize % self.ecBlocks.len()];
|
return &self.ecBlocks[ecLevel.get_ordinal() as usize % self.ecBlocks.len()];
|
||||||
}
|
}
|
||||||
@@ -293,11 +296,11 @@ impl fmt::Display for Version {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ECBlocks {
|
pub struct ECBlocks {
|
||||||
ecCodewordsPerBlock: u32,
|
ecCodewordsPerBlock: u32,
|
||||||
ecBlocks: Vec<ECB>,
|
ecBlocks: Box<[ECB]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ECBlocks {
|
impl ECBlocks {
|
||||||
pub const fn new(ecCodewordsPerBlock: u32, ecBlocks: Vec<ECB>) -> Self {
|
pub const fn new(ecCodewordsPerBlock: u32, ecBlocks: Box<[ECB]>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ecCodewordsPerBlock,
|
ecCodewordsPerBlock,
|
||||||
ecBlocks,
|
ecBlocks,
|
||||||
@@ -310,7 +313,7 @@ impl ECBlocks {
|
|||||||
|
|
||||||
pub fn getNumBlocks(&self) -> u32 {
|
pub fn getNumBlocks(&self) -> u32 {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
for ecBlock in &self.ecBlocks {
|
for ecBlock in self.ecBlocks.iter() {
|
||||||
total += ecBlock.getCount();
|
total += ecBlock.getCount();
|
||||||
}
|
}
|
||||||
total
|
total
|
||||||
|
|||||||
@@ -13,18 +13,18 @@ macro_rules! qr_version {
|
|||||||
),+
|
),+
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
vec![
|
Box::new([
|
||||||
$(
|
$(
|
||||||
Version::without_alignment_patterns(
|
Version::without_alignment_patterns(
|
||||||
$version,
|
$version,
|
||||||
vec![
|
Box::new([
|
||||||
$(
|
$(
|
||||||
ECBlocks::new($ec_codewords_per_block, vec![ECB::new($count_1,$data_codewords_1),ECB::new($count_2,$data_codewords_2)])
|
ECBlocks::new($ec_codewords_per_block, Box::new([ECB::new($count_1,$data_codewords_1),ECB::new($count_2,$data_codewords_2)]))
|
||||||
),*
|
),*
|
||||||
]
|
])
|
||||||
)
|
)
|
||||||
),*
|
),*
|
||||||
]
|
])
|
||||||
};
|
};
|
||||||
// Model 2 & rMQR
|
// Model 2 & rMQR
|
||||||
(
|
(
|
||||||
@@ -38,27 +38,27 @@ macro_rules! qr_version {
|
|||||||
),+
|
),+
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
vec![
|
Box::new([
|
||||||
$(
|
$(
|
||||||
Version::new($version,
|
Version::new($version,
|
||||||
vec![
|
Box::new([
|
||||||
$(
|
$(
|
||||||
$alignment_pattern
|
$alignment_pattern
|
||||||
),*
|
),*
|
||||||
],
|
]),
|
||||||
[
|
[
|
||||||
$(
|
$(
|
||||||
ECBlocks::new($ec_codewords_per_block, vec![ECB::new($count_1,$data_codewords_1),ECB::new($count_2,$data_codewords_2)])
|
ECBlocks::new($ec_codewords_per_block, Box::new([ECB::new($count_1,$data_codewords_1),ECB::new($count_2,$data_codewords_2)]))
|
||||||
),*
|
),*
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
),*
|
),*
|
||||||
]
|
])
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Version {
|
impl Version {
|
||||||
pub fn build_micro_versions() -> Vec<Version> {
|
pub fn build_micro_versions() -> Box<[Version]> {
|
||||||
qr_version!(
|
qr_version!(
|
||||||
{
|
{
|
||||||
{1, {2, 1, 3, 0, 0}},
|
{1, {2, 1, 3, 0, 0}},
|
||||||
@@ -71,7 +71,7 @@ impl Version {
|
|||||||
/**
|
/**
|
||||||
* See ISO 18004:2006 6.5.1 Table 9
|
* See ISO 18004:2006 6.5.1 Table 9
|
||||||
*/
|
*/
|
||||||
pub fn buildVersions() -> Vec<Version> {
|
pub fn buildVersions() -> Box<[Version]> {
|
||||||
qr_version!({
|
qr_version!({
|
||||||
{1, {}, {
|
{1, {}, {
|
||||||
7, 1, 19, 0, 0,
|
7, 1, 19, 0, 0,
|
||||||
@@ -316,7 +316,7 @@ impl Version {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_model1_versions() -> Vec<Version> {
|
pub fn build_model1_versions() -> Box<[Version]> {
|
||||||
qr_version!(
|
qr_version!(
|
||||||
{
|
{
|
||||||
{1, {
|
{1, {
|
||||||
@@ -407,7 +407,7 @@ impl Version {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_rmqr_versions() -> Vec<Version> {
|
pub fn build_rmqr_versions() -> Box<[Version]> {
|
||||||
qr_version!(
|
qr_version!(
|
||||||
{
|
{
|
||||||
// Version number, alignment pattern centres, `ECBlocks`
|
// Version number, alignment pattern centres, `ECBlocks`
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ fn testXOR() {
|
|||||||
let mut v1 = BitArray::new();
|
let mut v1 = BitArray::new();
|
||||||
v1.appendBits(0x5555aaaa, 32).expect("append");
|
v1.appendBits(0x5555aaaa, 32).expect("append");
|
||||||
let mut v2 = BitArray::new();
|
let mut v2 = BitArray::new();
|
||||||
v2.appendBits(0xaaaa5555, 32).expect("append");
|
v2.appendBits(0xaaaa5555_u32, 32).expect("append");
|
||||||
v1.xor(&v2).expect("xor");
|
v1.xor(&v2).expect("xor");
|
||||||
assert_eq!(0xffffffff, getUnsignedInt(&v1));
|
assert_eq!(0xffffffff, getUnsignedInt(&v1));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ pub struct RGBLuminanceSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LuminanceSource for RGBLuminanceSource {
|
impl LuminanceSource for RGBLuminanceSource {
|
||||||
|
const SUPPORTS_CROP: bool = true;
|
||||||
|
|
||||||
/// gets a row, returns an empty row if we are out of bounds.
|
/// gets a row, returns an empty row if we are out of bounds.
|
||||||
fn get_row(&self, y: usize) -> Vec<u8> {
|
fn get_row(&self, y: usize) -> Vec<u8> {
|
||||||
if y >= self.get_height() {
|
if y >= self.get_height() {
|
||||||
@@ -111,10 +113,6 @@ impl LuminanceSource for RGBLuminanceSource {
|
|||||||
self.height
|
self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_crop_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
fn crop(&self, left: usize, top: usize, width: usize, height: usize) -> Result<Self> {
|
||||||
RGBLuminanceSource::new_complex(
|
RGBLuminanceSource::new_complex(
|
||||||
&self.luminances,
|
&self.luminances,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// dxfilmedge-1
|
// dxfilmedge-1
|
||||||
|
|
||||||
#![cfg(feature = "image")]
|
#![cfg(feature = "image, experimental_features")]
|
||||||
|
|
||||||
use rxing::{BarcodeFormat, FilteredImageReader, MultiFormatReader};
|
use rxing::{BarcodeFormat, FilteredImageReader, MultiFormatReader};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user