pdf417 ec + test

This commit is contained in:
Henry Schimke
2022-12-19 12:01:11 -06:00
parent 5b616fe710
commit 75026d6936
14 changed files with 870 additions and 695 deletions

View File

@@ -0,0 +1,321 @@
/*
* Copyright 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use std::rc::Rc;
use crate::Exceptions;
use super::ModulusGF;
/**
* @author Sean Owen
*/
#[derive(Clone, Debug)]
pub struct ModulusPoly {
field: Rc<&'static ModulusGF>,
coefficients: Vec<u32>,
// zero: Option<Rc<ModulusPoly>>,
// one: Option<Rc<ModulusPoly>>,
}
impl ModulusPoly {
pub fn new(
field: Rc<&'static ModulusGF>,
coefficients: Vec<u32>,
) -> Result<ModulusPoly, Exceptions> {
if coefficients.is_empty() {
return Err(Exceptions::IllegalArgumentException("".to_owned()));
}
let orig_coefs = coefficients.clone();
let mut coefficients = coefficients;
let coefficientsLength = coefficients.len();
if coefficientsLength > 1 && coefficients[0] == 0 {
// Leading term must be non-zero for anything except the constant polynomial "0"
let mut firstNonZero = 1;
while firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0 {
firstNonZero += 1;
}
if firstNonZero == coefficientsLength {
coefficients = vec![0];
} else {
coefficients = vec![0u32; coefficientsLength - firstNonZero];
coefficients[..].copy_from_slice(&&orig_coefs[firstNonZero..]);
// System.arraycopy(coefficients,
// firstNonZero,
// this.coefficients,
// 0,
// this.coefficients.length);
}
} else {
coefficients = coefficients;
}
Ok(ModulusPoly {
field: field.clone(),
coefficients: coefficients,
// zero: Some(Self::getZero(field.clone())),
// one: Some(Self::getOne(field.clone())),
})
}
pub fn getCoefficients(&self) -> &[u32] {
&self.coefficients
}
/**
* @return degree of this polynomial
*/
pub fn getDegree(&self) -> u32 {
self.coefficients.len() as u32 - 1
}
/**
* @return true iff this polynomial is the monomial "0"
*/
pub fn isZero(&self) -> bool {
self.coefficients[0] == 0
}
/**
* @return coefficient of x^degree term in this polynomial
*/
pub fn getCoefficient(&self, degree: usize) -> u32 {
self.coefficients[self.coefficients.len() - 1 - degree]
}
/**
* @return evaluation of this polynomial at a given point
*/
pub fn evaluateAt(&self, a: u32) -> u32 {
if a == 0 {
// Just return the x^0 coefficient
return self.getCoefficient(0);
}
if a == 1 {
// Just the sum of the coefficients
let mut result = 0;
for coefficient in self.coefficients.iter() {
// for (int coefficient : coefficients) {
result = self.field.add(result, *coefficient);
}
return result;
}
let mut result = self.coefficients[0];
let size = self.coefficients.len();
for i in 1..size {
// for (int i = 1; i < size; i++) {
result = self
.field
.add(self.field.multiply(a, result), self.coefficients[i]);
}
return result;
}
pub fn add(&self, other: Rc<ModulusPoly>) -> Result<Rc<ModulusPoly>, Exceptions> {
if self.field != other.field {
return Err(Exceptions::IllegalArgumentException(
"ModulusPolys do not have same ModulusGF field".to_owned(),
));
}
if self.isZero() {
return Ok(other);
}
if other.isZero() {
return Ok(Rc::new(self.clone()));
}
let mut smallerCoefficients = &self.coefficients;
let mut largerCoefficients = &other.coefficients;
if smallerCoefficients.len() > largerCoefficients.len() {
let temp = smallerCoefficients;
smallerCoefficients = largerCoefficients;
largerCoefficients = temp;
}
let mut sumDiff = vec![0032; largerCoefficients.len()];
let lengthDiff = largerCoefficients.len() - smallerCoefficients.len();
// Copy high-order terms only found in higher-degree polynomial's coefficients
sumDiff[..lengthDiff].copy_from_slice(&largerCoefficients[..lengthDiff]);
// System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
for i in lengthDiff..largerCoefficients.len() {
// for (int i = lengthDiff; i < largerCoefficients.length; i++) {
sumDiff[i] = self
.field
.add(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
}
Ok(Rc::new(
ModulusPoly::new(self.field.clone(), sumDiff)
.expect("should always generate with known goods"),
))
}
pub fn subtract(&self, other: Rc<ModulusPoly>) -> Result<Rc<ModulusPoly>, Exceptions> {
if self.field != other.field {
return Err(Exceptions::IllegalArgumentException(
"ModulusPolys do not have same ModulusGF field".to_owned(),
));
}
if other.isZero() {
return Ok(Rc::new(self.clone()));
};
self.add(other.negative().clone())
}
pub fn multiply(&self, other: Rc<ModulusPoly>) -> Result<Rc<ModulusPoly>, Exceptions> {
if !(self.field == other.field) {
return Err(Exceptions::IllegalArgumentException(
"ModulusPolys do not have same ModulusGF field".to_owned(),
));
}
if self.isZero() || other.isZero() {
return Ok(Self::getZero(self.field.clone()).clone());
}
let aCoefficients = &self.coefficients;
let aLength = aCoefficients.len();
let bCoefficients = &other.coefficients;
let bLength = bCoefficients.len();
let mut product = vec![0u32; aLength + bLength - 1];
for i in 0..aLength {
// for (int i = 0; i < aLength; i++) {
let aCoeff = aCoefficients[i];
for j in 0..bLength {
// for (int j = 0; j < bLength; j++) {
product[i + j] = self.field.add(
product[i + j],
self.field.multiply(aCoeff, bCoefficients[j]),
);
}
}
Ok(Rc::new(
ModulusPoly::new(self.field.clone(), product)
.expect("should always generate with known goods"),
))
}
pub fn negative(&self) -> Rc<ModulusPoly> {
let size = self.coefficients.len();
let mut negativeCoefficients = vec![0u32; size];
for i in 0..size {
// for (int i = 0; i < size; i++) {
negativeCoefficients[i] = self.field.subtract(0, self.coefficients[i]);
}
Rc::new(
ModulusPoly::new(self.field.clone(), negativeCoefficients)
.expect("should always generate with known goods"),
)
}
pub fn multiplyByScaler(&self, scalar: u32) -> Rc<ModulusPoly> {
if scalar == 0 {
return Self::getZero(self.field.clone()).clone();
}
if scalar == 1 {
return Rc::new(self.clone());
}
let size = self.coefficients.len();
let mut product = vec![0u32; size];
for i in 0..size {
// for (int i = 0; i < size; i++) {
product[i] = self.field.multiply(self.coefficients[i], scalar);
}
Rc::new(
ModulusPoly::new(self.field.clone(), product)
.expect("should always generate with known goods"),
)
}
pub fn multiplyByMonomial(&self, degree: usize, coefficient: u32) -> Rc<ModulusPoly> {
if coefficient == 0 {
return Self::getZero(self.field.clone()).clone();
}
let size = self.coefficients.len();
let mut product = vec![0u32; size + degree];
for i in 0..size {
// for (int i = 0; i < size; i++) {
product[i] = self.field.multiply(self.coefficients[i], coefficient);
}
Rc::new(
ModulusPoly::new(self.field.clone(), product)
.expect("should always generate with known goods"),
)
}
pub fn getZero(field: Rc<&'static ModulusGF>) -> Rc<ModulusPoly> {
Rc::new(
ModulusPoly::new(field.clone(), vec![0])
.expect("should always generate with known goods"),
)
}
pub fn getOne(field: Rc<&'static ModulusGF>) -> Rc<ModulusPoly> {
Rc::new(
ModulusPoly::new(field.clone(), vec![1])
.expect("should always generate with known goods"),
)
}
pub fn buildMonomial(
field: Rc<&'static ModulusGF>,
degree: usize,
coefficient: u32,
) -> Rc<ModulusPoly> {
// if degree < 0 {
// throw new IllegalArgumentException();
// }
if coefficient == 0 {
return Self::getZero(field);
}
let mut coefficients = vec![0_u32; degree + 1];
coefficients[0] = coefficient;
Rc::new(
ModulusPoly::new(field.clone(), coefficients)
.expect("should always generate with known goods"),
)
}
// @Override
// public String toString() {
// StringBuilder result = new StringBuilder(8 * getDegree());
// for (int degree = getDegree(); degree >= 0; degree--) {
// int coefficient = getCoefficient(degree);
// if (coefficient != 0) {
// if (coefficient < 0) {
// result.append(" - ");
// coefficient = -coefficient;
// } else {
// if (result.length() > 0) {
// result.append(" + ");
// }
// }
// if (degree == 0 || coefficient != 1) {
// result.append(coefficient);
// }
// if (degree != 0) {
// if (degree == 1) {
// result.append('x');
// } else {
// result.append("x^");
// result.append(degree);
// }
// }
// }
// }
// return result.toString();
// }
}