auto-format common module

This commit is contained in:
Henry Schimke
2022-08-17 14:52:31 -05:00
parent 87f98db943
commit ba39b03bb5
3 changed files with 3296 additions and 2800 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,13 @@
use crate::{NotFoundException,ResultPoint};
use crate::common::{BitMatrix, BitMatrix}; use crate::common::{BitMatrix, BitMatrix};
use crate::{NotFoundException, ResultPoint};
// MathUtils.java // MathUtils.java
/** /**
* General math-related and numeric utility functions. * General math-related and numeric utility functions.
*/ */
pub struct MathUtils { pub struct MathUtils {}
}
impl MathUtils { impl MathUtils {
fn new() -> Self { fn new() -> Self {
Self {} Self {}
} }
@@ -79,12 +77,10 @@ impl MathUtils {
const MAX_MODULES: i32 = 32; const MAX_MODULES: i32 = 32;
#[deprecated] #[deprecated]
pub struct MonochromeRectangleDetector { pub struct MonochromeRectangleDetector {
image: BitMatrix,
image: BitMatrix
} }
impl MonochromeRectangleDetector { impl MonochromeRectangleDetector {
pub fn new(image: &BitMatrix) -> Self { pub fn new(image: &BitMatrix) -> Self {
Self { image } Self { image }
} }
@@ -99,7 +95,7 @@ impl MonochromeRectangleDetector {
* third, the rightmost * third, the rightmost
* @throws NotFoundException if no Data Matrix Code can be found * @throws NotFoundException if no Data Matrix Code can be found
*/ */
pub fn detect(&self) -> /* throws NotFoundException */Result<Vec<ResultPoint>, Rc<Exception>> { pub fn detect(&self) -> Result<Vec<ResultPoint>, Rc<Exception>> {
let height: i32 = self.image.get_height(); let height: i32 = self.image.get_height();
let width: i32 = self.image.get_width(); let width: i32 = self.image.get_width();
let half_height: i32 = height / 2; let half_height: i32 = height / 2;
@@ -110,17 +106,67 @@ impl MonochromeRectangleDetector {
let mut bottom: i32 = height; let mut bottom: i32 = height;
let mut left: i32 = 0; let mut left: i32 = 0;
let mut right: i32 = width; let mut right: i32 = width;
let point_a: ResultPoint = self.find_corner_from_center(half_width, 0, left, right, half_height, -delta_y, top, bottom, half_width / 2); let point_a: ResultPoint = self.find_corner_from_center(
half_width,
0,
left,
right,
half_height,
-delta_y,
top,
bottom,
half_width / 2,
);
top = point_a.get_y() as i32 - 1; top = point_a.get_y() as i32 - 1;
let point_b: ResultPoint = self.find_corner_from_center(half_width, -delta_x, left, right, half_height, 0, top, bottom, half_height / 2); let point_b: ResultPoint = self.find_corner_from_center(
half_width,
-delta_x,
left,
right,
half_height,
0,
top,
bottom,
half_height / 2,
);
left = point_b.get_x() as i32 - 1; left = point_b.get_x() as i32 - 1;
let point_c: ResultPoint = self.find_corner_from_center(half_width, delta_x, left, right, half_height, 0, top, bottom, half_height / 2); let point_c: ResultPoint = self.find_corner_from_center(
half_width,
delta_x,
left,
right,
half_height,
0,
top,
bottom,
half_height / 2,
);
right = point_c.get_x() as i32 + 1; right = point_c.get_x() as i32 + 1;
let point_d: ResultPoint = self.find_corner_from_center(half_width, 0, left, right, half_height, delta_y, top, bottom, half_width / 2); let point_d: ResultPoint = self.find_corner_from_center(
half_width,
0,
left,
right,
half_height,
delta_y,
top,
bottom,
half_width / 2,
);
bottom = point_d.get_y() as i32 + 1; bottom = point_d.get_y() as i32 + 1;
// Go try to find point A again with better information -- might have been off at first. // Go try to find point A again with better information -- might have been off at first.
point_a = self.find_corner_from_center(half_width, 0, left, right, half_height, -delta_y, top, bottom, half_width / 4); point_a = self.find_corner_from_center(
return Ok( vec![point_a, point_b, point_c, point_d, ]); half_width,
0,
left,
right,
half_height,
-delta_y,
top,
bottom,
half_width / 4,
);
return Ok(vec![point_a, point_b, point_c, point_d]);
} }
/** /**
@@ -141,7 +187,18 @@ impl MonochromeRectangleDetector {
* @return a {@link ResultPoint} encapsulating the corner that was found * @return a {@link ResultPoint} encapsulating the corner that was found
* @throws NotFoundException if such a point cannot be found * @throws NotFoundException if such a point cannot be found
*/ */
fn find_corner_from_center(&self, center_x: i32, delta_x: i32, left: i32, right: i32, center_y: i32, delta_y: i32, top: i32, bottom: i32, max_white_run: i32) -> Result<ResultPoint, NotFoundException> { fn find_corner_from_center(
&self,
center_x: i32,
delta_x: i32,
left: i32,
right: i32,
center_y: i32,
delta_y: i32,
top: i32,
bottom: i32,
max_white_run: i32,
) -> Result<ResultPoint, NotFoundException> {
let last_range: Vec<i32> = null; let last_range: Vec<i32> = null;
{ {
let mut y: i32 = center_y; let mut y: i32 = center_y;
@@ -166,7 +223,10 @@ impl MonochromeRectangleDetector {
if last_range[0] < center_x { if last_range[0] < center_x {
if last_range[1] > center_x { if last_range[1] > center_x {
// straddle, choose one or the other based on direction // straddle, choose one or the other based on direction
return Ok(ResultPoint::new(last_range[ if delta_y > 0 { 0 } else { 1 }], last_y)); return Ok(ResultPoint::new(
last_range[if delta_y > 0 { 0 } else { 1 }],
last_y,
));
} }
return Ok(ResultPoint::new(last_range[0], last_y)); return Ok(ResultPoint::new(last_range[0], last_y));
} else { } else {
@@ -176,7 +236,10 @@ impl MonochromeRectangleDetector {
let last_x: i32 = x - delta_x; let last_x: i32 = x - delta_x;
if last_range[0] < center_y { if last_range[0] < center_y {
if last_range[1] > center_y { if last_range[1] > center_y {
return Ok(ResultPoint::new(last_x, last_range[ if delta_x < 0 { 0 } else { 1 }])); return Ok(ResultPoint::new(
last_x,
last_range[if delta_x < 0 { 0 } else { 1 }],
));
} }
return Ok(ResultPoint::new(last_x, last_range[0])); return Ok(ResultPoint::new(last_x, last_range[0]));
} else { } else {
@@ -208,20 +271,40 @@ impl MonochromeRectangleDetector {
* @return int[] with start and end of found range, or null if no such range is found * @return int[] with start and end of found range, or null if no such range is found
* (e.g. only white was found) * (e.g. only white was found)
*/ */
fn black_white_range(&self, fixed_dimension: i32, max_white_run: i32, min_dim: i32, max_dim: i32, horizontal: bool) -> Option<Vec<i32>> { fn black_white_range(
&self,
fixed_dimension: i32,
max_white_run: i32,
min_dim: i32,
max_dim: i32,
horizontal: bool,
) -> Option<Vec<i32>> {
let center: i32 = (min_dim + max_dim) / 2; let center: i32 = (min_dim + max_dim) / 2;
// Scan left/up first // Scan left/up first
let mut start: i32 = center; let mut start: i32 = center;
while start >= min_dim { while start >= min_dim {
if if horizontal { self.image.get(start, fixed_dimension) } else { self.image.get(fixed_dimension, start) } { if if horizontal {
self.image.get(start, fixed_dimension)
} else {
self.image.get(fixed_dimension, start)
} {
start -= 1; start -= 1;
} else { } else {
let white_run_start: i32 = start; let white_run_start: i32 = start;
loop { { loop {
{
start -= 1; start -= 1;
}if !(start >= min_dim && !( if horizontal { self.image.get(start, fixed_dimension) } else { self.image.get(fixed_dimension, start) })) { }
if !(start >= min_dim
&& !(if horizontal {
self.image.get(start, fixed_dimension)
} else {
self.image.get(fixed_dimension, start)
}))
{
break; break;
} } }
}
let white_run_size: i32 = white_run_start - start; let white_run_size: i32 = white_run_start - start;
if start < min_dim || white_run_size > max_white_run { if start < min_dim || white_run_size > max_white_run {
start = white_run_start; start = white_run_start;
@@ -233,13 +316,28 @@ impl MonochromeRectangleDetector {
// Then try right/down // Then try right/down
let mut end: i32 = center; let mut end: i32 = center;
while end < max_dim { while end < max_dim {
if if horizontal { self.image.get(end, fixed_dimension) } else { self.image.get(fixed_dimension, end) } { if if horizontal {
self.image.get(end, fixed_dimension)
} else {
self.image.get(fixed_dimension, end)
} {
end += 1; end += 1;
} else { } else {
let white_run_start: i32 = end; let white_run_start: i32 = end;
loop { { loop {
{
end += 1; end += 1;
}if !(end < max_dim && !( if horizontal { self.image.get(end, fixed_dimension) } else { self.image.get(fixed_dimension, end) })) {break;}} }
if !(end < max_dim
&& !(if horizontal {
self.image.get(end, fixed_dimension)
} else {
self.image.get(fixed_dimension, end)
}))
{
break;
}
}
let white_run_size: i32 = end - white_run_start; let white_run_size: i32 = end - white_run_start;
if end >= max_dim || white_run_size > max_white_run { if end >= max_dim || white_run_size > max_white_run {
end = white_run_start; end = white_run_start;
@@ -248,8 +346,11 @@ impl MonochromeRectangleDetector {
} }
} }
end -= 1; end -= 1;
return if end > start { Some(vec![start, end, ]) return if end > start {
} else { null }; Some(vec![start, end])
} else {
null
};
} }
} }
@@ -269,7 +370,6 @@ const INIT_SIZE: i32 = 10;
const CORR: i32 = 1; const CORR: i32 = 1;
pub struct WhiteRectangleDetector { pub struct WhiteRectangleDetector {
image: BitMatrix, image: BitMatrix,
height: i32, height: i32,
@@ -282,13 +382,17 @@ pub struct WhiteRectangleDetector {
down_init: i32, down_init: i32,
up_init: i32 up_init: i32,
} }
impl WhiteRectangleDetector { impl WhiteRectangleDetector {
pub fn new(image: &BitMatrix) -> Result<Self, NotFoundException> { pub fn new(image: &BitMatrix) -> Result<Self, NotFoundException> {
this(image, INIT_SIZE, image.get_width() / 2, image.get_height() / 2) this(
image,
INIT_SIZE,
image.get_width() / 2,
image.get_height() / 2,
)
} }
/** /**
@@ -298,7 +402,12 @@ impl WhiteRectangleDetector {
* @param y y position of search center * @param y y position of search center
* @throws NotFoundException if image is too small to accommodate {@code initSize} * @throws NotFoundException if image is too small to accommodate {@code initSize}
*/ */
pub fn new( image: &BitMatrix, init_size: i32, x: i32, y: i32) -> Result<Self,NotFoundException> { pub fn new(
image: &BitMatrix,
init_size: i32,
x: i32,
y: i32,
) -> Result<Self, NotFoundException> {
let mut new_wrd: Self; let mut new_wrd: Self;
new_wrd.image = image; new_wrd.image = image;
new_wrd.height = image.get_height(); new_wrd.height = image.get_height();
@@ -345,7 +454,9 @@ impl WhiteRectangleDetector {
// . | // . |
// ..... // .....
let right_border_not_white: bool = true; let right_border_not_white: bool = true;
while (right_border_not_white || !at_least_one_black_point_found_on_right) && right < self.width { while (right_border_not_white || !at_least_one_black_point_found_on_right)
&& right < self.width
{
right_border_not_white = self.contains_black_point(up, down, right, false); right_border_not_white = self.contains_black_point(up, down, right, false);
if right_border_not_white { if right_border_not_white {
right += 1; right += 1;
@@ -363,7 +474,9 @@ impl WhiteRectangleDetector {
// . . // . .
// .___. // .___.
let bottom_border_not_white: bool = true; let bottom_border_not_white: bool = true;
while (bottom_border_not_white || !at_least_one_black_point_found_on_bottom) && down < self.height { while (bottom_border_not_white || !at_least_one_black_point_found_on_bottom)
&& down < self.height
{
bottom_border_not_white = self.contains_black_point(left, right, down, true); bottom_border_not_white = self.contains_black_point(left, right, down, true);
if bottom_border_not_white { if bottom_border_not_white {
down += 1; down += 1;
@@ -481,7 +594,13 @@ impl WhiteRectangleDetector {
} }
} }
fn get_black_point_on_segment(&self, a_x: f32, a_y: f32, b_x: f32, b_y: f32) -> Option<ResultPoint> { fn get_black_point_on_segment(
&self,
a_x: f32,
a_y: f32,
b_x: f32,
b_y: f32,
) -> Option<ResultPoint> {
let dist: i32 = MathUtils::round(&MathUtils::distance(a_x, a_y, b_x, b_y)); let dist: i32 = MathUtils::round(&MathUtils::distance(a_x, a_y, b_x, b_y));
let x_step: f32 = (b_x - a_x) / dist; let x_step: f32 = (b_x - a_x) / dist;
let y_step: f32 = (b_y - a_y) / dist; let y_step: f32 = (b_y - a_y) / dist;
@@ -515,7 +634,13 @@ impl WhiteRectangleDetector {
* point and the last, the bottommost. The second point will be * point and the last, the bottommost. The second point will be
* leftmost and the third, the rightmost * leftmost and the third, the rightmost
*/ */
fn center_edges(&self, y: &ResultPoint, z: &ResultPoint, x: &ResultPoint, t: &ResultPoint) -> Vec<ResultPoint> { fn center_edges(
&self,
y: &ResultPoint,
z: &ResultPoint,
x: &ResultPoint,
t: &ResultPoint,
) -> Vec<ResultPoint> {
// //
// t t // t t
// z x // z x
@@ -531,11 +656,19 @@ impl WhiteRectangleDetector {
let ti: f32 = t.get_x(); let ti: f32 = t.get_x();
let tj: f32 = t.get_y(); let tj: f32 = t.get_y();
if yi < self.width / 2.0f32 { if yi < self.width / 2.0f32 {
return vec![ResultPoint::new(ti - CORR, tj + CORR), ResultPoint::new(zi + CORR, zj + CORR), ResultPoint::new(xi - CORR, xj - CORR), ResultPoint::new(yi + CORR, yj - CORR), ] return vec![
; ResultPoint::new(ti - CORR, tj + CORR),
ResultPoint::new(zi + CORR, zj + CORR),
ResultPoint::new(xi - CORR, xj - CORR),
ResultPoint::new(yi + CORR, yj - CORR),
];
} else { } else {
return vec![ResultPoint::new(ti + CORR, tj + CORR), ResultPoint::new(zi + CORR, zj - CORR), ResultPoint::new(xi - CORR, xj + CORR), ResultPoint::new(yi - CORR, yj - CORR), ] return vec![
; ResultPoint::new(ti + CORR, tj + CORR),
ResultPoint::new(zi + CORR, zj - CORR),
ResultPoint::new(xi - CORR, xj + CORR),
ResultPoint::new(yi - CORR, yj - CORR),
];
} }
} }
@@ -561,7 +694,6 @@ impl WhiteRectangleDetector {
x += 1; x += 1;
} }
} }
} else { } else {
{ {
let mut y: i32 = a; let mut y: i32 = a;
@@ -574,9 +706,7 @@ impl WhiteRectangleDetector {
y += 1; y += 1;
} }
} }
} }
return false; return false;
} }
} }

View File

@@ -9,14 +9,12 @@
* @author Sean Owen * @author Sean Owen
*/ */
struct GenericGFPoly { struct GenericGFPoly {
field: GenericGF, field: GenericGF,
coefficients: Vec<i32> coefficients: Vec<i32>,
} }
impl GenericGFPoly { impl GenericGFPoly {
/** /**
* @param field the {@link GenericGF} instance representing the field to use * @param field the {@link GenericGF} instance representing the field to use
* to perform computations * to perform computations
@@ -40,7 +38,7 @@ impl GenericGFPoly {
first_non_zero += 1; first_non_zero += 1;
} }
if first_non_zero == coefficients_length { if first_non_zero == coefficients_length {
new_poly.coefficients = vec![0, ]; new_poly.coefficients = vec![0];
} else { } else {
new_poly.coefficients = coefficients; new_poly.coefficients = coefficients;
//System::arraycopy(&coefficients, first_non_zero, let .coefficients, 0, let .coefficients.len()); //System::arraycopy(&coefficients, first_non_zero, let .coefficients, 0, let .coefficients.len());
@@ -98,7 +96,10 @@ impl GenericGFPoly {
let mut i: i32 = 1; let mut i: i32 = 1;
while i < size { while i < size {
{ {
result = GenericGF::add_or_subtract(&self.field.multiply(a, result), self.coefficients[i]); result = GenericGF::add_or_subtract(
&self.field.multiply(a, result),
self.coefficients[i],
);
} }
i += 1; i += 1;
} }
@@ -107,9 +108,14 @@ impl GenericGFPoly {
return result; return result;
} }
fn add_or_subtract(&self, other: &GenericGFPoly) -> Result<GenericGFPoly,IllegalArgumentException> { fn add_or_subtract(
&self,
other: &GenericGFPoly,
) -> Result<GenericGFPoly, IllegalArgumentException> {
if !self.field.equals(other.field) { if !self.field.equals(other.field) {
return Err( IllegalArgumentException::new("GenericGFPolys do not have same GenericGF field") ); return Err(IllegalArgumentException::new(
"GenericGFPolys do not have same GenericGF field",
));
} }
if self.is_zero() { if self.is_zero() {
return other; return other;
@@ -132,7 +138,10 @@ impl GenericGFPoly {
let mut i: i32 = length_diff; let mut i: i32 = length_diff;
while i < larger_coefficients.len() { while i < larger_coefficients.len() {
{ {
sum_diff[i] = GenericGF::add_or_subtract(smaller_coefficients[i - length_diff], larger_coefficients[i]); sum_diff[i] = GenericGF::add_or_subtract(
smaller_coefficients[i - length_diff],
larger_coefficients[i],
);
} }
i += 1; i += 1;
} }
@@ -143,7 +152,9 @@ impl GenericGFPoly {
fn multiply(&self, other: &GenericGFPoly) -> Result<GenericGFPoly, IllegalArgumentException> { fn multiply(&self, other: &GenericGFPoly) -> Result<GenericGFPoly, IllegalArgumentException> {
if !self.field.equals(other.field) { if !self.field.equals(other.field) {
return Err(IllegalArgumentException::new("GenericGFPolys do not have same GenericGF field")); return Err(IllegalArgumentException::new(
"GenericGFPolys do not have same GenericGF field",
));
} }
if self.is_zero() || other.is_zero() { if self.is_zero() || other.is_zero() {
return Ok(self.field.get_zero()); return Ok(self.field.get_zero());
@@ -162,12 +173,14 @@ impl GenericGFPoly {
let mut j: i32 = 0; let mut j: i32 = 0;
while j < b_length { while j < b_length {
{ {
product[i + j] = GenericGF::add_or_subtract(product[i + j], &self.field.multiply(a_coeff, b_coefficients[j])); product[i + j] = GenericGF::add_or_subtract(
product[i + j],
&self.field.multiply(a_coeff, b_coefficients[j]),
);
} }
j += 1; j += 1;
} }
} }
} }
i += 1; i += 1;
} }
@@ -198,7 +211,11 @@ impl GenericGFPoly {
return GenericGFPoly::new(&self.field, &product); return GenericGFPoly::new(&self.field, &product);
} }
fn multiply_by_monomial(&self, degree: i32, coefficient: i32) -> Result<GenericGFPoly,IllegalArgumentException> { fn multiply_by_monomial(
&self,
degree: i32,
coefficient: i32,
) -> Result<GenericGFPoly, IllegalArgumentException> {
if degree < 0 { if degree < 0 {
return Err(IllegalArgumentException::new()); return Err(IllegalArgumentException::new());
} }
@@ -220,9 +237,14 @@ impl GenericGFPoly {
return GenericGFPoly::new(&self.field, &product); return GenericGFPoly::new(&self.field, &product);
} }
fn divide(&self, other: &GenericGFPoly) -> Result<Vec<GenericGFPoly>,IllegalArgumentException> { fn divide(
&self,
other: &GenericGFPoly,
) -> Result<Vec<GenericGFPoly>, IllegalArgumentException> {
if !self.field.equals(other.field) { if !self.field.equals(other.field) {
return Err( IllegalArgumentException::new("GenericGFPolys do not have same GenericGF field")); return Err(IllegalArgumentException::new(
"GenericGFPolys do not have same GenericGF field",
));
} }
if other.is_zero() { if other.is_zero() {
return Err(IllegalArgumentException::new("Divide by 0")); return Err(IllegalArgumentException::new("Divide by 0"));
@@ -233,13 +255,17 @@ impl GenericGFPoly {
let inverse_denominator_leading_term: i32 = self.field.inverse(denominator_leading_term); let inverse_denominator_leading_term: i32 = self.field.inverse(denominator_leading_term);
while remainder.get_degree() >= other.get_degree() && !remainder.is_zero() { while remainder.get_degree() >= other.get_degree() && !remainder.is_zero() {
let degree_difference: i32 = remainder.get_degree() - other.get_degree(); let degree_difference: i32 = remainder.get_degree() - other.get_degree();
let scale: i32 = self.field.multiply(&remainder.get_coefficient(&remainder.get_degree()), inverse_denominator_leading_term); let scale: i32 = self.field.multiply(
&remainder.get_coefficient(&remainder.get_degree()),
inverse_denominator_leading_term,
);
let term: GenericGFPoly = other.multiply_by_monomial(degree_difference, scale); let term: GenericGFPoly = other.multiply_by_monomial(degree_difference, scale);
let iteration_quotient: GenericGFPoly = self.field.build_monomial(degree_difference, scale); let iteration_quotient: GenericGFPoly =
self.field.build_monomial(degree_difference, scale);
quotient = quotient.add_or_subtract(&iteration_quotient); quotient = quotient.add_or_subtract(&iteration_quotient);
remainder = remainder.add_or_subtract(&term); remainder = remainder.add_or_subtract(&term);
} }
return Ok(vec![quotient, remainder, ]); return Ok(vec![quotient, remainder]);
} }
pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
@@ -330,7 +356,6 @@ const AZTEC_DATA_12: GenericGF = GenericGF::new(0x1069, 4096, 1);
const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6; const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6;
pub struct GenericGF { pub struct GenericGF {
exp_table: Vec<i32>, exp_table: Vec<i32>,
log_table: Vec<i32>, log_table: Vec<i32>,
@@ -343,11 +368,10 @@ pub struct GenericGF {
primitive: i32, primitive: i32,
generator_base: i32 generator_base: i32,
} }
impl GenericGF { impl GenericGF {
/** /**
* Create a representation of GF(size) using the given primitive polynomial. * Create a representation of GF(size) using the given primitive polynomial.
* *
@@ -394,8 +418,8 @@ impl GenericGF {
} }
// logTable[0] == 0 but this should never be used // logTable[0] == 0 but this should never be used
new_generic_gf.zero = GenericGFPoly::new( 0, &vec![0, ]); new_generic_gf.zero = GenericGFPoly::new(0, &vec![0]);
new_generic_gf.one = GenericGFPoly::new( 0, &vec![1, ]); new_generic_gf.one = GenericGFPoly::new(0, &vec![1]);
new_generic_gf new_generic_gf
} }
@@ -411,7 +435,11 @@ impl GenericGF {
/** /**
* @return the monomial representing coefficient * x^degree * @return the monomial representing coefficient * x^degree
*/ */
fn build_monomial(&self, degree: i32, coefficient: i32) -> Result<GenericGFPoly,IllegalArgumentException> { fn build_monomial(
&self,
degree: i32,
coefficient: i32,
) -> Result<GenericGFPoly, IllegalArgumentException> {
if degree < 0 { if degree < 0 {
return Err(IllegalArgumentException::new()); return Err(IllegalArgumentException::new());
} }
@@ -478,7 +506,11 @@ impl GenericGF {
} }
pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
return format!("GF(0x{},{})", Integer::to_hex_string(self.primitive), self.size); return format!(
"GF(0x{},{})",
Integer::to_hex_string(self.primitive),
self.size
);
} }
} }
@@ -506,12 +538,10 @@ impl GenericGF {
* @author sanfordsquires * @author sanfordsquires
*/ */
pub struct ReedSolomonDecoder { pub struct ReedSolomonDecoder {
field: GenericGF,
field: GenericGF
} }
impl ReedSolomonDecoder { impl ReedSolomonDecoder {
pub fn new(field: &GenericGF) -> Self { pub fn new(field: &GenericGF) -> Self {
Self { field } Self { field }
} }
@@ -533,7 +563,8 @@ impl ReedSolomonDecoder {
let mut i: i32 = 0; let mut i: i32 = 0;
while i < two_s { while i < two_s {
{ {
let eval: i32 = poly.evaluate_at(&self.field.exp(i + self.field.get_generator_base())); let eval: i32 =
poly.evaluate_at(&self.field.exp(i + self.field.get_generator_base()));
syndrome_coefficients[syndrome_coefficients.len() - 1 - i] = eval; syndrome_coefficients[syndrome_coefficients.len() - 1 - i] = eval;
if eval != 0 { if eval != 0 {
no_error = false; no_error = false;
@@ -547,7 +578,8 @@ impl ReedSolomonDecoder {
return; return;
} }
let syndrome: GenericGFPoly = GenericGFPoly::new(&self.field, &syndrome_coefficients); let syndrome: GenericGFPoly = GenericGFPoly::new(&self.field, &syndrome_coefficients);
let sigma_omega: Vec<GenericGFPoly> = self.run_euclidean_algorithm(&self.field.build_monomial(two_s, 1), &syndrome, two_s); let sigma_omega: Vec<GenericGFPoly> =
self.run_euclidean_algorithm(&self.field.build_monomial(two_s, 1), &syndrome, two_s);
let sigma: GenericGFPoly = sigma_omega[0]; let sigma: GenericGFPoly = sigma_omega[0];
let omega: GenericGFPoly = sigma_omega[1]; let omega: GenericGFPoly = sigma_omega[1];
let error_locations: Vec<i32> = self.find_error_locations(&sigma); let error_locations: Vec<i32> = self.find_error_locations(&sigma);
@@ -560,16 +592,21 @@ impl ReedSolomonDecoder {
if position < 0 { if position < 0 {
return Err(ReedSolomonException::new("Bad error location")); return Err(ReedSolomonException::new("Bad error location"));
} }
received[position] = GenericGF::add_or_subtract(received[position], error_magnitudes[i]); received[position] =
GenericGF::add_or_subtract(received[position], error_magnitudes[i]);
} }
i += 1; i += 1;
} }
} }
Ok(()) Ok(())
} }
fn run_euclidean_algorithm(&self, a: &GenericGFPoly, b: &GenericGFPoly, R: i32) -> Result<Vec<GenericGFPoly>, ReedSolomonException+IllegalStateException> { fn run_euclidean_algorithm(
&self,
a: &GenericGFPoly,
b: &GenericGFPoly,
R: i32,
) -> Result<Vec<GenericGFPoly>, ReedSolomonException + IllegalStateException> {
// Assume a's degree is >= b's // Assume a's degree is >= b's
if a.get_degree() < b.get_degree() { if a.get_degree() < b.get_degree() {
let temp: GenericGFPoly = a; let temp: GenericGFPoly = a;
@@ -597,13 +634,18 @@ impl ReedSolomonDecoder {
let dlt_inverse: i32 = self.field.inverse(denominator_leading_term); let dlt_inverse: i32 = self.field.inverse(denominator_leading_term);
while r.get_degree() >= r_last.get_degree() && !r.is_zero() { while r.get_degree() >= r_last.get_degree() && !r.is_zero() {
let degree_diff: i32 = r.get_degree() - r_last.get_degree(); let degree_diff: i32 = r.get_degree() - r_last.get_degree();
let scale: i32 = self.field.multiply(&r.get_coefficient(&r.get_degree()), dlt_inverse); let scale: i32 = self
.field
.multiply(&r.get_coefficient(&r.get_degree()), dlt_inverse);
q = q.add_or_subtract(&self.field.build_monomial(degree_diff, scale)); q = q.add_or_subtract(&self.field.build_monomial(degree_diff, scale));
r = r.add_or_subtract(&r_last.multiply_by_monomial(degree_diff, scale)); r = r.add_or_subtract(&r_last.multiply_by_monomial(degree_diff, scale));
} }
t = q.multiply(&t_last).add_or_subtract(t_last_last); t = q.multiply(&t_last).add_or_subtract(t_last_last);
if r.get_degree() >= r_last.get_degree() { if r.get_degree() >= r_last.get_degree() {
return Err( IllegalStateException::new(format!("Division algorithm failed to reduce polynomial? r: {}, rLast: {}", r, r_last))); return Err(IllegalStateException::new(format!(
"Division algorithm failed to reduce polynomial? r: {}, rLast: {}",
r, r_last
)));
} }
} }
let sigma_tilde_at_zero: i32 = t.get_coefficient(0); let sigma_tilde_at_zero: i32 = t.get_coefficient(0);
@@ -613,15 +655,18 @@ impl ReedSolomonDecoder {
let inverse: i32 = self.field.inverse(sigma_tilde_at_zero); let inverse: i32 = self.field.inverse(sigma_tilde_at_zero);
let sigma: GenericGFPoly = t.multiply(inverse); let sigma: GenericGFPoly = t.multiply(inverse);
let omega: GenericGFPoly = r.multiply(inverse); let omega: GenericGFPoly = r.multiply(inverse);
return Ok( vec![sigma, omega, ]); return Ok(vec![sigma, omega]);
} }
fn find_error_locations(&self, error_locator: &GenericGFPoly) -> Result<Vec<i32>, ReedSolomonException> { fn find_error_locations(
&self,
error_locator: &GenericGFPoly,
) -> Result<Vec<i32>, ReedSolomonException> {
// This is a direct application of Chien's search // This is a direct application of Chien's search
let num_errors: i32 = error_locator.get_degree(); let num_errors: i32 = error_locator.get_degree();
if num_errors == 1 { if num_errors == 1 {
// shortcut // shortcut
return Ok( vec![error_locator.get_coefficient(1), ]); return Ok(vec![error_locator.get_coefficient(1)]);
} }
let mut result: [i32; num_errors] = [0; num_errors]; let mut result: [i32; num_errors] = [0; num_errors];
let mut e: i32 = 0; let mut e: i32 = 0;
@@ -639,12 +684,18 @@ impl ReedSolomonDecoder {
} }
if e != num_errors { if e != num_errors {
return Err( ReedSolomonException::new("Error locator degree does not match number of roots")); return Err(ReedSolomonException::new(
"Error locator degree does not match number of roots",
));
} }
return Ok(result); return Ok(result);
} }
fn find_error_magnitudes(&self, error_evaluator: &GenericGFPoly, error_locations: &Vec<i32>) -> Vec<i32> { fn find_error_magnitudes(
&self,
error_evaluator: &GenericGFPoly,
error_locations: &Vec<i32>,
) -> Vec<i32> {
// This is directly applying Forney's Formula // This is directly applying Forney's Formula
let s: i32 = error_locations.len(); let s: i32 = error_locations.len();
let mut result: [i32; s] = [0; s]; let mut result: [i32; s] = [0; s];
@@ -663,8 +714,13 @@ impl ReedSolomonDecoder {
// GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse))); // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
// Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug. // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
// Below is a funny-looking workaround from Steven Parkes // Below is a funny-looking workaround from Steven Parkes
let term: i32 = self.field.multiply(error_locations[j], xi_inverse); let term: i32 =
let term_plus1: i32 = if (term & 0x1) == 0 { term | 1 } else { term & 1 }; self.field.multiply(error_locations[j], xi_inverse);
let term_plus1: i32 = if (term & 0x1) == 0 {
term | 1
} else {
term & 1
};
denominator = self.field.multiply(denominator, term_plus1); denominator = self.field.multiply(denominator, term_plus1);
} }
} }
@@ -672,7 +728,10 @@ impl ReedSolomonDecoder {
} }
} }
result[i] = self.field.multiply(&error_evaluator.evaluate_at(xi_inverse), &self.field.inverse(denominator)); result[i] = self.field.multiply(
&error_evaluator.evaluate_at(xi_inverse),
&self.field.inverse(denominator),
);
if self.field.get_generator_base() != 0 { if self.field.get_generator_base() != 0 {
result[i] = self.field.multiply(result[i], xi_inverse); result[i] = self.field.multiply(result[i], xi_inverse);
} }
@@ -693,42 +752,49 @@ impl ReedSolomonDecoder {
* @author William Rucklidge * @author William Rucklidge
*/ */
pub struct ReedSolomonEncoder { pub struct ReedSolomonEncoder {
field: GenericGF, field: GenericGF,
cached_generators: Vector<GenericGFPoly> cached_generators: Vector<GenericGFPoly>,
} }
impl ReedSolomonEncoder { impl ReedSolomonEncoder {
pub fn new(field: &GenericGF) -> Self { pub fn new(field: &GenericGF) -> Self {
let mut new_rse; let mut new_rse;
new_rse.field = field; new_rse.field = field;
new_rse.cachedGenerators = Vector::new(); new_rse.cachedGenerators = Vector::new();
cached_generators.add(GenericGFPoly::new(field, &vec![1, ])); cached_generators.add(GenericGFPoly::new(field, &vec![1]));
new_rse new_rse
} }
fn build_generator(&self, degree: i32) -> GenericGFPoly { fn build_generator(&self, degree: i32) -> GenericGFPoly {
if degree >= self.cached_generators.size() { if degree >= self.cached_generators.size() {
let last_generator: GenericGFPoly = self.cached_generators.get(self.cached_generators.size() - 1); let last_generator: GenericGFPoly = self
.cached_generators
.get(self.cached_generators.size() - 1);
{ {
let mut d: i32 = self.cached_generators.size(); let mut d: i32 = self.cached_generators.size();
while d <= degree { while d <= degree {
{ {
let next_generator: GenericGFPoly = last_generator.multiply(GenericGFPoly::new(&self.field, &vec![1, self.field.exp(d - 1 + self.field.get_generator_base()), ])); let next_generator: GenericGFPoly =
last_generator.multiply(GenericGFPoly::new(
&self.field,
&vec![1, self.field.exp(d - 1 + self.field.get_generator_base())],
));
self.cached_generators.add(next_generator); self.cached_generators.add(next_generator);
last_generator = next_generator; last_generator = next_generator;
} }
d += 1; d += 1;
} }
} }
} }
return self.cached_generators.get(degree); return self.cached_generators.get(degree);
} }
pub fn encode(&self, to_encode: &Vec<i32>, ec_bytes: i32) -> Result<(),IllegalArgumentException> { pub fn encode(
&self,
to_encode: &Vec<i32>,
ec_bytes: i32,
) -> Result<(), IllegalArgumentException> {
if ec_bytes == 0 { if ec_bytes == 0 {
return Err(IllegalArgumentException::new("No error correction bytes")); return Err(IllegalArgumentException::new("No error correction bytes"));
} }
@@ -754,7 +820,13 @@ impl ReedSolomonEncoder {
} }
} }
System::arraycopy(&coefficients, 0, &to_encode, data_bytes + num_zero_coefficients, coefficients.len()); System::arraycopy(
&coefficients,
0,
&to_encode,
data_bytes + num_zero_coefficients,
coefficients.len(),
);
Ok(()) Ok(())
} }
} }
@@ -767,11 +839,10 @@ impl ReedSolomonEncoder {
* @author Sean Owen * @author Sean Owen
*/ */
pub struct ReedSolomonException { pub struct ReedSolomonException {
message: String message: String,
} }
impl ReedSolomonException { impl ReedSolomonException {
pub fn new(message: &String) -> Self { pub fn new(message: &String) -> Self {
ReedSolomonException { message } ReedSolomonException { message }
} }