Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/common/cpp_essentials/concentric_finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ use crate::{
Point,
common::{
BitMatrix, Quadrilateral,
cpp_essentials::{
Direction, FixedPattern, IsPattern, PatternRow, PatternType, PatternView,
},
cpp_essentials::{Direction, FixedPattern, IsPattern, PatternType, PatternView},
},
point,
};
Expand Down Expand Up @@ -110,7 +108,7 @@ pub fn CheckSymmetricPattern<
}

assert!(range > 0);
let mut res: PatternRow = PatternRow::new(vec![0; LEN]);
let mut res: [PatternType; LEN] = [0; LEN];
let s_2 = (res.len()) / 2;
res[s_2] = (centerFwd + centerBwd - 1) as u16; // -1 because the starting pixel is counted twice
range -= res[s_2] as i32;
Expand All @@ -131,7 +129,7 @@ pub fn CheckSymmetricPattern<
}

if IsPattern::<E2E, LEN, SUM, false>(
&PatternView::new(&res),
&PatternView::from_slice(&res),
&FixedPattern::<LEN, SUM, false>::with_reference(pattern),
None,
0.0,
Expand Down
100 changes: 65 additions & 35 deletions src/common/cpp_essentials/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use crate::{
Exceptions,
common::{BitMatrix, Result},
common::{BitArray, BitMatrix, Result},
};

pub type PatternType = u16;
Expand Down Expand Up @@ -103,7 +103,7 @@ impl Iterator for PatternViewIterator<'_> {
self.current_position += 1;

Some(
*self.pattern_view.data.0.get(
*self.pattern_view.data.get(
self.current_position - 1 + self.pattern_view.start + self.pattern_view.current,
)?,
)
Expand All @@ -112,7 +112,7 @@ impl Iterator for PatternViewIterator<'_> {

#[derive(Debug, Clone, Copy)]
pub struct PatternView<'a> {
data: &'a PatternRow,
data: &'a [PatternType],
start: usize,
count: usize,
current: usize,
Expand All @@ -122,10 +122,15 @@ impl<'a> PatternView<'a> {
// A PatternRow always starts with the width of whitespace in front of the first black bar.
// The first element of the PatternView is the first bar.
pub fn new(bars: &'a PatternRow) -> PatternView<'a> {
Self::from_slice(&bars.0)
}

/// Build a view directly over a slice of bars, avoiding an owning `PatternRow` allocation.
pub fn from_slice(bars: &'a [PatternType]) -> PatternView<'a> {
PatternView {
data: bars,
start: 1,
count: bars.0.len(),
count: bars.len(),
current: 0,
}
}
Expand All @@ -138,38 +143,37 @@ impl<'a> PatternView<'a> {
_end: usize,
) -> PatternView<'a> {
PatternView {
data: bars,
data: &bars.0,
start,
count: size,
current: base,
}
}

pub fn data(&self) -> &PatternRow {
pub fn data(&self) -> &[PatternType] {
self.data
}
pub fn begin(&self) -> Option<PatternType> {
Some(*self.data.0.get(self.start)?)
Some(*self.data.get(self.start)?)
}
pub fn end(&self) -> Option<PatternType> {
// if self.start + self.count < self.data.0.len() {
// Some(self.data.0[self.start + self.count])
// if self.start + self.count < self.data.len() {
// Some(self.data[self.start + self.count])
// } else {
// None
// }
Some(self.data.0.len() as PatternType)
Some(self.data.len() as PatternType)
}

// int sum(int n = 0) const { return std::accumulate(_data, _data + (n == 0 ? _size : n), 0); }
pub fn sum(&self, n: Option<usize>) -> PatternType {
if self.count == self.data.len() {
return self.data.0.iter().sum::<PatternType>();
return self.data.iter().sum::<PatternType>();
}

let n = n.unwrap_or(self.count);

self.data
.0
.iter()
.skip(self.start + self.current)
.take(n)
Expand All @@ -194,15 +198,13 @@ impl<'a> PatternView<'a> {
}
pub fn pixelsInFront(&self) -> PatternType {
self.data
.0
.iter()
.take(self.start + self.current)
.copied()
.sum::<PatternType>() /*return std::accumulate(_base, _data, 0);*/
}
pub fn pixelsTillEnd(&self) -> PatternType {
self.data
.0
.iter()
.take(self.start + self.current + self.count)
.copied()
Expand All @@ -216,9 +218,9 @@ impl<'a> PatternView<'a> {
self.current == self.start + self.count - 1 /*return _data + _size == _end - 1;*/
}
pub fn isValidWithN(&self, n: usize) -> bool {
!self.data.0.is_empty()
!self.data.is_empty()
&& self.start <= self.current + self.start
&& self.current + n < (self.data.0.len())
&& self.current + n < (self.data.len())
/*return _data && _data >= _base && _data + n <= _end;*/
}
pub fn isValid(&self) -> bool {
Expand All @@ -227,14 +229,12 @@ impl<'a> PatternView<'a> {

pub fn has_quiet_zone_before(&self, scale: f32, acceptIfAtFirstBar: Option<bool>) -> bool {
(acceptIfAtFirstBar.unwrap_or(false) && self.isAtLastBar())
|| Into::<f32>::into(self.data.0[self.count])
>= Into::<f32>::into(self.sum(None)) * scale
|| Into::<f32>::into(self.data[self.count]) >= Into::<f32>::into(self.sum(None)) * scale
}

pub fn hasQuietZoneAfter(&self, scale: f32, acceptIfAtLastBar: Option<bool>) -> bool {
(acceptIfAtLastBar.unwrap_or(true) && self.isAtLastBar())
|| Into::<f32>::into(self.data.0[self.count])
>= Into::<f32>::into(self.sum(None)) * scale
|| Into::<f32>::into(self.data[self.count]) >= Into::<f32>::into(self.sum(None)) * scale
}

pub fn subView(&self, offset: usize, size: Option<usize>) -> PatternView<'a> {
Expand All @@ -256,7 +256,7 @@ impl<'a> PatternView<'a> {

pub fn shift(&mut self, n: usize) -> bool {
self.current += n;
!self.data.0.is_empty() //&& self.start + self.count <= (self.start + self.count)
!self.data.is_empty() //&& self.start + self.count <= (self.start + self.count)
}

pub fn skipPair(&mut self) -> bool {
Expand All @@ -279,18 +279,18 @@ impl<'a> PatternView<'a> {
}

fn try_get_index(&self, index: isize) -> Option<PatternType> {
if index.abs() > self.data.0.len() as isize {
if index.abs() > self.data.len() as isize {
return None;
}
if index >= 0 {
let fetch_spot = ((self.start + self.current) as isize + index) as usize;
return Some(self.data.0[fetch_spot]);
return Some(self.data[fetch_spot]);
}
if index.abs() > (self.start + self.current) as isize {
return None;
}
let fetch_spot = ((self.start + self.current) as isize + index) as usize;
Some(self.data.0[fetch_spot])
Some(self.data[fetch_spot])
}
}

Expand All @@ -302,18 +302,18 @@ impl std::ops::Index<isize> for PatternView<'_> {
return &self.data[index.unsigned_abs()];
}

if index > self.data.0.len() as isize {
if index > self.data.len() as isize {
panic!("array index out of bounds")
}
if index >= 0 {
let fetch_spot = ((self.start + self.current) as isize + index) as usize;
return &self.data.0[fetch_spot];
return &self.data[fetch_spot];
}
if index.abs() > self.start as isize {
panic!("array index out of bounds")
}
let fetch_spot = ((self.start + self.current) as isize + index) as usize;
&self.data.0[fetch_spot]
&self.data[fetch_spot]
}
}

Expand All @@ -325,10 +325,10 @@ impl std::ops::Index<usize> for PatternView<'_> {
return &self.data[index];
}

if index > self.data.0.len() {
if index > self.data.len() {
panic!("array index out of bounds")
}
self.data.0.get(self.start + self.current + index).unwrap()
self.data.get(self.start + self.current + index).unwrap()
}
}

Expand Down Expand Up @@ -362,10 +362,10 @@ impl<'a, const LEN: usize> From<&PatternView<'a>> for [PatternType; LEN] {

impl<'a> From<&PatternView<'a>> for &'a [PatternType] {
fn from(value: &PatternView<'a>) -> Self {
if value.data.0.len() == value.count {
&value.data.0
if value.data.len() == value.count {
value.data
} else {
&value.data.0[value.current + value.start..=value.current + value.start + value.count]
&value.data[value.current + value.start..=value.current + value.start + value.count]
}
}
}
Expand Down Expand Up @@ -725,9 +725,39 @@ pub fn GetPatternRowTP(matrix: &BitMatrix, r: u32, pr: &mut PatternRow, transpos
matrix.getRow(r)
};

let pixel_states: Vec<bool> = row.into();
// Compute the run-length pattern directly from the bit array, avoiding an
// intermediate Vec<bool> allocation (this runs for every scanned image row).
GetPatternRowFromBits(&row, pr)
}

/// Run-length-encode a BitArray row into `p_row` (white run first, per `PatternRow` convention).
fn GetPatternRowFromBits(b_row: &BitArray, p_row: &mut PatternRow) {
p_row.0.clear();

let mut current_color = Color::White;
let mut count: PatternType = 0;

for i in 0..b_row.get_size() {
let this_color = if b_row.get(i) {
Color::Black
} else {
Color::White
};
if current_color != this_color {
p_row.0.push(count);
count = 0;
current_color = this_color;
}
count += 1;
}

if count != 0 {
p_row.0.push(count);
}

GetPatternRow(&pixel_states, pr)
if current_color == Color::Black {
p_row.0.push(0);
}
}

pub fn GetPatternRow<T: Into<PatternType> + Copy + Default + From<T>>(
Expand Down Expand Up @@ -849,7 +879,7 @@ mod tests {

let mut pv = PatternView::new(&p_row);

assert_eq!(pv.data().0, p_row.0);
assert_eq!(pv.data(), p_row.0.as_slice());

assert_eq!(pv[0], 1_u16);
assert_eq!(pv[1], 1_u16);
Expand Down
50 changes: 23 additions & 27 deletions src/common/reedsolomon/generic_gf_poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,40 +48,36 @@ impl GenericGFPoly {
* or if leading coefficient is 0 and this is not a
* constant polynomial (that is, it is not the monomial "0")
*/
pub fn new(field: GenericGFRef, coefficients: &[i32]) -> Result<Self> {
pub fn new<T: Copy>(field: GenericGFRef, coefficients: &[T]) -> Result<Self>
where
i32: From<T>,
{
if coefficients.is_empty() {
return Err(Exceptions::illegal_argument_with(
"coefficients cannot be empty",
));
}
// The only generic work is widening to `i32`; trimming is done once in `from_coefficients`.
Self::from_coefficients(field, coefficients.iter().map(|&c| i32::from(c)).collect())
}

/// Build a polynomial from owned `i32` coefficients (most-significant first), stripping any
/// leading zeros. Non-generic so it is compiled once regardless of the input codeword type.
fn from_coefficients(field: GenericGFRef, mut coefficients: Vec<i32>) -> Result<Self> {
debug_assert!(!coefficients.is_empty());
if coefficients.len() > 1 && coefficients[0] == 0 {
// Leading term must be non-zero for anything except the constant polynomial "0"
match coefficients.iter().position(|&c| c != 0) {
// All zero: collapse to the monomial "0".
None => coefficients.truncate(1),
Some(first_non_zero) => {
coefficients.drain(..first_non_zero);
}
}
}
Ok(Self {
field,
coefficients: {
let coefficients_length = coefficients.len();
if coefficients_length > 1 && coefficients[0] == 0 {
// Leading term must be non-zero for anything except the constant polynomial "0"
let mut first_non_zero = 1;
while first_non_zero < coefficients_length && coefficients[first_non_zero] == 0
{
first_non_zero += 1;
}
if first_non_zero == coefficients_length {
vec![0]
} else {
let mut new_coefficients = vec![0; coefficients_length - first_non_zero];
let l = new_coefficients.len() - 1;
new_coefficients[0..=l].clone_from_slice(&coefficients[first_non_zero..]);
// System.arraycopy(coefficients,
// firstNonZero,
// this.coefficients,
// 0,
// this.coefficients.length);
new_coefficients
}
} else {
coefficients.to_vec()
}
},
coefficients,
})
}

Expand Down
Loading
Loading