mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-27 21:02:35 +00:00
reedsolomon format
This commit is contained in:
@@ -57,14 +57,14 @@ impl ReedSolomonException {
|
|||||||
|
|
||||||
//package com.google.zxing.common.reedsolomon;
|
//package com.google.zxing.common.reedsolomon;
|
||||||
|
|
||||||
pub const AZTEC_DATA_12:GenericGF = GenericGF::new(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1
|
pub const AZTEC_DATA_12: GenericGF = GenericGF::new(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1
|
||||||
pub const AZTEC_DATA_10:GenericGF = GenericGF::new(0x409, 1024, 1); // x^10 + x^3 + 1
|
pub const AZTEC_DATA_10: GenericGF = GenericGF::new(0x409, 1024, 1); // x^10 + x^3 + 1
|
||||||
pub const AZTEC_DATA_6:GenericGF = GenericGF::new(0x43, 64, 1); // x^6 + x + 1
|
pub const AZTEC_DATA_6: GenericGF = GenericGF::new(0x43, 64, 1); // x^6 + x + 1
|
||||||
pub const AZTEC_PARAM:GenericGF = GenericGF::new(0x13, 16, 1); // x^4 + x + 1
|
pub const AZTEC_PARAM: GenericGF = GenericGF::new(0x13, 16, 1); // x^4 + x + 1
|
||||||
pub const QR_CODE_FIELD_256:GenericGF = GenericGF::new(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
|
pub const QR_CODE_FIELD_256: GenericGF = GenericGF::new(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
|
||||||
pub const DATA_MATRIX_FIELD_256:GenericGF = GenericGF::new(0x012D, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1
|
pub const DATA_MATRIX_FIELD_256: GenericGF = GenericGF::new(0x012D, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1
|
||||||
pub const AZTEC_DATA_8:GenericGF = DATA_MATRIX_FIELD_256;
|
pub const AZTEC_DATA_8: GenericGF = DATA_MATRIX_FIELD_256;
|
||||||
pub const MAXICODE_FIELD_64:GenericGF = AZTEC_DATA_6;
|
pub const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>This class contains utility methods for performing mathematical operations over
|
* <p>This class contains utility methods for performing mathematical operations over
|
||||||
@@ -77,15 +77,14 @@ pub const MAXICODE_FIELD_64:GenericGF = AZTEC_DATA_6;
|
|||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
* @author David Olivier
|
* @author David Olivier
|
||||||
*/
|
*/
|
||||||
pub struct GenericGF {
|
pub struct GenericGF {
|
||||||
|
expTable: Vec<usize>,
|
||||||
expTable : Vec<usize>,
|
|
||||||
logTable: Vec<usize>,
|
logTable: Vec<usize>,
|
||||||
zero: Box<GenericGFPoly>,
|
zero: Box<GenericGFPoly>,
|
||||||
one: Box<GenericGFPoly>,
|
one: Box<GenericGFPoly>,
|
||||||
size:usize,
|
size: usize,
|
||||||
primitive:usize,
|
primitive: usize,
|
||||||
generatorBase:usize,
|
generatorBase: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for GenericGF {
|
impl Hash for GenericGF {
|
||||||
@@ -100,8 +99,7 @@ impl PartialEq for GenericGF {
|
|||||||
}
|
}
|
||||||
impl Eq for GenericGF {}
|
impl Eq for GenericGF {}
|
||||||
|
|
||||||
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.
|
||||||
*
|
*
|
||||||
@@ -113,16 +111,15 @@ impl GenericGF{
|
|||||||
* (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
|
* (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
|
||||||
* In most cases it should be 1, but for QR code it is 0.
|
* In most cases it should be 1, but for QR code it is 0.
|
||||||
*/
|
*/
|
||||||
pub fn new( primitive:usize, size:usize, b:usize) -> Self{
|
pub fn new(primitive: usize, size: usize, b: usize) -> Self {
|
||||||
let mut new_ggf :Self;
|
let mut new_ggf: Self;
|
||||||
|
|
||||||
|
new_ggf.primitive = primitive;
|
||||||
|
new_ggf.size = size;
|
||||||
|
new_ggf.generatorBase = b;
|
||||||
|
|
||||||
new_ggf. primitive = primitive;
|
new_ggf.expTable = Vec::with_capacity(size);
|
||||||
new_ggf. size = size;
|
new_ggf.logTable = Vec::with_capacity(size);
|
||||||
new_ggf. generatorBase = b;
|
|
||||||
|
|
||||||
new_ggf. expTable = Vec::with_capacity(size);
|
|
||||||
new_ggf. logTable = Vec::with_capacity(size);
|
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
//for (int i = 0; i < size; i++) {
|
//for (int i = 0; i < size; i++) {
|
||||||
@@ -139,13 +136,13 @@ impl GenericGF{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// logTable[0] == 0 but this should never be used
|
// logTable[0] == 0 but this should never be used
|
||||||
new_ggf. zero = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![0]).unwrap());
|
new_ggf.zero = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![0]).unwrap());
|
||||||
new_ggf. one = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![1]).unwrap());
|
new_ggf.one = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![1]).unwrap());
|
||||||
|
|
||||||
new_ggf
|
new_ggf
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getZero(&self) -> Box<GenericGFPoly>{
|
pub fn getZero(&self) -> Box<GenericGFPoly> {
|
||||||
return self.zero;
|
return self.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +153,7 @@ impl GenericGF{
|
|||||||
/**
|
/**
|
||||||
* @return the monomial representing coefficient * x^degree
|
* @return the monomial representing coefficient * x^degree
|
||||||
*/
|
*/
|
||||||
pub fn buildMonomial(&self, degree :usize, coefficient:usize) -> Box<GenericGFPoly>{
|
pub fn buildMonomial(&self, degree: usize, coefficient: usize) -> Box<GenericGFPoly> {
|
||||||
if (coefficient == 0) {
|
if (coefficient == 0) {
|
||||||
return self.zero;
|
return self.zero;
|
||||||
}
|
}
|
||||||
@@ -170,23 +167,23 @@ impl GenericGF{
|
|||||||
*
|
*
|
||||||
* @return sum/difference of a and b
|
* @return sum/difference of a and b
|
||||||
*/
|
*/
|
||||||
pub fn addOrSubtract( a:usize, b:usize) -> usize {
|
pub fn addOrSubtract(a: usize, b: usize) -> usize {
|
||||||
return a ^ b;
|
return a ^ b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 2 to the power of a in GF(size)
|
* @return 2 to the power of a in GF(size)
|
||||||
*/
|
*/
|
||||||
pub fn exp(&self, a:usize) -> usize{
|
pub fn exp(&self, a: usize) -> usize {
|
||||||
return self.expTable[a];
|
return self.expTable[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return base 2 log of a in GF(size)
|
* @return base 2 log of a in GF(size)
|
||||||
*/
|
*/
|
||||||
pub fn log(&self, a:usize) -> Result<usize,IllegalArgumentException> {
|
pub fn log(&self, a: usize) -> Result<usize, IllegalArgumentException> {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
return Err( IllegalArgumentException::new(""));
|
return Err(IllegalArgumentException::new(""));
|
||||||
}
|
}
|
||||||
return Ok(self.logTable[a]);
|
return Ok(self.logTable[a]);
|
||||||
}
|
}
|
||||||
@@ -194,9 +191,9 @@ impl GenericGF{
|
|||||||
/**
|
/**
|
||||||
* @return multiplicative inverse of a
|
* @return multiplicative inverse of a
|
||||||
*/
|
*/
|
||||||
pub fn inverse(&self, a:usize) -> Result<usize,ArithmeticException>{
|
pub fn inverse(&self, a: usize) -> Result<usize, ArithmeticException> {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
return Err( ArithmeticException::new(""));
|
return Err(ArithmeticException::new(""));
|
||||||
}
|
}
|
||||||
let loc = self.size - self.logTable[a] - 1;
|
let loc = self.size - self.logTable[a] - 1;
|
||||||
return Ok(self.expTable[loc]);
|
return Ok(self.expTable[loc]);
|
||||||
@@ -205,30 +202,28 @@ impl GenericGF{
|
|||||||
/**
|
/**
|
||||||
* @return product of a and b in GF(size)
|
* @return product of a and b in GF(size)
|
||||||
*/
|
*/
|
||||||
pub fn multiply(&self, a:usize, b:usize) -> usize {
|
pub fn multiply(&self, a: usize, b: usize) -> usize {
|
||||||
if (a == 0 || b == 0) {
|
if (a == 0 || b == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return self.expTable[(self.logTable[a] + self.logTable[b]) % (self.size - 1)];
|
return self.expTable[(self.logTable[a] + self.logTable[b]) % (self.size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSize(&self) -> usize{
|
pub fn getSize(&self) -> usize {
|
||||||
return self.size;
|
return self.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getGeneratorBase(&self) -> usize {
|
pub fn getGeneratorBase(&self) -> usize {
|
||||||
return self.generatorBase;
|
return self.generatorBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for GenericGF {
|
impl fmt::Display for GenericGF {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f,"GF({:#06x},{}" ,self.primitive , self.size )
|
write!(f, "GF({:#06x},{}", self.primitive, self.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007 ZXing authors
|
* Copyright 2007 ZXing authors
|
||||||
*
|
*
|
||||||
@@ -257,10 +252,8 @@ impl fmt::Display for GenericGF {
|
|||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
pub struct GenericGFPoly {
|
pub struct GenericGFPoly {
|
||||||
|
|
||||||
field: Box<GenericGF>,
|
field: Box<GenericGF>,
|
||||||
coefficients: Vec<usize>,
|
coefficients: Vec<usize>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenericGFPoly {
|
impl GenericGFPoly {
|
||||||
@@ -273,11 +266,14 @@ impl GenericGFPoly {
|
|||||||
* or if leading coefficient is 0 and this is not a
|
* or if leading coefficient is 0 and this is not a
|
||||||
* constant polynomial (that is, it is not the monomial "0")
|
* constant polynomial (that is, it is not the monomial "0")
|
||||||
*/
|
*/
|
||||||
pub fn new( field :Box<GenericGF>, coefficients: &Vec<usize>) -> Result<Self,IllegalArgumentException> {
|
pub fn new(
|
||||||
|
field: Box<GenericGF>,
|
||||||
|
coefficients: &Vec<usize>,
|
||||||
|
) -> Result<Self, IllegalArgumentException> {
|
||||||
if (coefficients.len() == 0) {
|
if (coefficients.len() == 0) {
|
||||||
return Err (IllegalArgumentException::new(""));
|
return Err(IllegalArgumentException::new(""));
|
||||||
}
|
}
|
||||||
Ok(Self{
|
Ok(Self {
|
||||||
field: field,
|
field: field,
|
||||||
coefficients: {
|
coefficients: {
|
||||||
let coefficientsLength = coefficients.len();
|
let coefficientsLength = coefficients.len();
|
||||||
@@ -290,9 +286,10 @@ impl GenericGFPoly {
|
|||||||
if (firstNonZero == coefficientsLength) {
|
if (firstNonZero == coefficientsLength) {
|
||||||
vec![0]
|
vec![0]
|
||||||
} else {
|
} else {
|
||||||
|
let mut new_coefficients =
|
||||||
let mut new_coefficients = Vec::with_capacity(coefficientsLength - firstNonZero);
|
Vec::with_capacity(coefficientsLength - firstNonZero);
|
||||||
new_coefficients[0..new_coefficients.len()].clone_from_slice(&coefficients[firstNonZero..new_coefficients.len()]);
|
new_coefficients[0..new_coefficients.len()]
|
||||||
|
.clone_from_slice(&coefficients[firstNonZero..new_coefficients.len()]);
|
||||||
// System.arraycopy(coefficients,
|
// System.arraycopy(coefficients,
|
||||||
// firstNonZero,
|
// firstNonZero,
|
||||||
// this.coefficients,
|
// this.coefficients,
|
||||||
@@ -307,7 +304,7 @@ impl GenericGFPoly {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getCoefficients(&self)->Vec<usize> {
|
pub fn getCoefficients(&self) -> Vec<usize> {
|
||||||
return self.coefficients;
|
return self.coefficients;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,21 +318,21 @@ impl GenericGFPoly {
|
|||||||
/**
|
/**
|
||||||
* @return true iff this polynomial is the monomial "0"
|
* @return true iff this polynomial is the monomial "0"
|
||||||
*/
|
*/
|
||||||
pub fn isZero(&self) -> bool{
|
pub fn isZero(&self) -> bool {
|
||||||
return self.coefficients[0] == 0;
|
return self.coefficients[0] == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return coefficient of x^degree term in this polynomial
|
* @return coefficient of x^degree term in this polynomial
|
||||||
*/
|
*/
|
||||||
pub fn getCoefficient(&self, degree:usize) -> usize {
|
pub fn getCoefficient(&self, degree: usize) -> usize {
|
||||||
return self.coefficients[self.coefficients.len() - 1 - degree];
|
return self.coefficients[self.coefficients.len() - 1 - degree];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return evaluation of this polynomial at a given point
|
* @return evaluation of this polynomial at a given point
|
||||||
*/
|
*/
|
||||||
pub fn evaluateAt(&self, a:usize) -> usize {
|
pub fn evaluateAt(&self, a: usize) -> usize {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
// Just return the x^0 coefficient
|
// Just return the x^0 coefficient
|
||||||
return self.getCoefficient(0);
|
return self.getCoefficient(0);
|
||||||
@@ -353,14 +350,25 @@ impl GenericGFPoly {
|
|||||||
let size = self.coefficients.len();
|
let size = self.coefficients.len();
|
||||||
for i in 1..size {
|
for i in 1..size {
|
||||||
//for (int i = 1; i < size; i++) {
|
//for (int i = 1; i < size; i++) {
|
||||||
result = GenericGF::addOrSubtract(self.field.multiply(a, result.try_into().unwrap()).try_into().unwrap(), self.coefficients[i]);
|
result = GenericGF::addOrSubtract(
|
||||||
|
self.field
|
||||||
|
.multiply(a, result.try_into().unwrap())
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
self.coefficients[i],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addOrSubtract(&self, other:Box<GenericGFPoly>) -> Result<Box<GenericGFPoly>,IllegalArgumentException>{
|
pub fn addOrSubtract(
|
||||||
|
&self,
|
||||||
|
other: Box<GenericGFPoly>,
|
||||||
|
) -> Result<Box<GenericGFPoly>, IllegalArgumentException> {
|
||||||
if self.field != other.field {
|
if self.field != 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.isZero()) {
|
if (self.isZero()) {
|
||||||
return Ok(other);
|
return Ok(other);
|
||||||
@@ -383,18 +391,26 @@ impl GenericGFPoly {
|
|||||||
sumDiff[0..lengthDiff].clone_from_slice(&largerCoefficients[0..lengthDiff]);
|
sumDiff[0..lengthDiff].clone_from_slice(&largerCoefficients[0..lengthDiff]);
|
||||||
//System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
|
//System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
|
||||||
|
|
||||||
for i in lengthDiff..largerCoefficients.len(){
|
for i in lengthDiff..largerCoefficients.len() {
|
||||||
//for (int i = lengthDiff; i < largerCoefficients.length; i++) {
|
//for (int i = lengthDiff; i < largerCoefficients.length; i++) {
|
||||||
sumDiff[i] = GenericGF::addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
|
sumDiff[i] = GenericGF::addOrSubtract(
|
||||||
|
smallerCoefficients[i - lengthDiff],
|
||||||
|
largerCoefficients[i],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(Box::new(GenericGFPoly::new(self.field, &sumDiff)?));
|
return Ok(Box::new(GenericGFPoly::new(self.field, &sumDiff)?));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multiply(&self, other:&GenericGFPoly) -> Result<Box<GenericGFPoly>,IllegalArgumentException> {
|
pub fn multiply(
|
||||||
if self.field != other.field{
|
&self,
|
||||||
|
other: &GenericGFPoly,
|
||||||
|
) -> Result<Box<GenericGFPoly>, IllegalArgumentException> {
|
||||||
|
if self.field != other.field {
|
||||||
//if (!field.equals(other.field)) {
|
//if (!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.isZero() || other.isZero()) {
|
if (self.isZero() || other.isZero()) {
|
||||||
return Ok(self.field.getZero());
|
return Ok(self.field.getZero());
|
||||||
@@ -404,19 +420,27 @@ impl GenericGFPoly {
|
|||||||
let bCoefficients = other.coefficients;
|
let bCoefficients = other.coefficients;
|
||||||
let bLength = bCoefficients.len();
|
let bLength = bCoefficients.len();
|
||||||
let product = Vec::with_capacity(aLength + bLength - 1);
|
let product = Vec::with_capacity(aLength + bLength - 1);
|
||||||
for i in 0 ..aLength {
|
for i in 0..aLength {
|
||||||
//for (int i = 0; i < aLength; i++) {
|
//for (int i = 0; i < aLength; i++) {
|
||||||
let aCoeff = aCoefficients[i];
|
let aCoeff = aCoefficients[i];
|
||||||
for j in 0..bLength {
|
for j in 0..bLength {
|
||||||
//for (int j = 0; j < bLength; j++) {
|
//for (int j = 0; j < bLength; j++) {
|
||||||
product[i + j] = GenericGF::addOrSubtract(product[i + j],
|
product[i + j] = GenericGF::addOrSubtract(
|
||||||
self.field.multiply(aCoeff.try_into().unwrap(), bCoefficients[j].try_into().unwrap()).try_into().unwrap());
|
product[i + j],
|
||||||
|
self.field
|
||||||
|
.multiply(
|
||||||
|
aCoeff.try_into().unwrap(),
|
||||||
|
bCoefficients[j].try_into().unwrap(),
|
||||||
|
)
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
|
return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multiply_with_scalar(&self, scalar:usize) -> Box<GenericGFPoly>{
|
pub fn multiply_with_scalar(&self, scalar: usize) -> Box<GenericGFPoly> {
|
||||||
if (scalar == 0) {
|
if (scalar == 0) {
|
||||||
return self.field.getZero();
|
return self.field.getZero();
|
||||||
}
|
}
|
||||||
@@ -433,9 +457,13 @@ impl GenericGFPoly {
|
|||||||
return Box::new(GenericGFPoly::new(self.field, &product).unwrap());
|
return Box::new(GenericGFPoly::new(self.field, &product).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn multiplyByMonomial(&self, degree:usize, coefficient:usize) -> Result<Box<GenericGFPoly>,IllegalArgumentException> {
|
pub fn multiplyByMonomial(
|
||||||
|
&self,
|
||||||
|
degree: usize,
|
||||||
|
coefficient: usize,
|
||||||
|
) -> Result<Box<GenericGFPoly>, IllegalArgumentException> {
|
||||||
if (degree < 0) {
|
if (degree < 0) {
|
||||||
return Err( IllegalArgumentException::new(""));
|
return Err(IllegalArgumentException::new(""));
|
||||||
}
|
}
|
||||||
if (coefficient == 0) {
|
if (coefficient == 0) {
|
||||||
return Ok(self.field.getZero());
|
return Ok(self.field.getZero());
|
||||||
@@ -449,45 +477,52 @@ impl GenericGFPoly {
|
|||||||
return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
|
return Ok(Box::new(GenericGFPoly::new(self.field, &product)?));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn divide(&self, other:&GenericGFPoly) -> Result<Vec<Box<GenericGFPoly>>,IllegalArgumentException>{
|
pub fn divide(
|
||||||
|
&self,
|
||||||
|
other: &GenericGFPoly,
|
||||||
|
) -> Result<Vec<Box<GenericGFPoly>>, IllegalArgumentException> {
|
||||||
if self.field != other.field {
|
if self.field != other.field {
|
||||||
//if (!field.equals(other.field)) {
|
//if (!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.isZero()) {
|
if (other.isZero()) {
|
||||||
return Err( IllegalArgumentException::new("Divide by 0"));
|
return Err(IllegalArgumentException::new("Divide by 0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut quotient = self.field.getZero();
|
let mut quotient = self.field.getZero();
|
||||||
let mut remainder = self;
|
let mut remainder = self;
|
||||||
|
|
||||||
let denominatorLeadingTerm = other.getCoefficient(other.getDegree());
|
let denominatorLeadingTerm = other.getCoefficient(other.getDegree());
|
||||||
let inverseDenominatorLeadingTerm = match self.field.inverse(denominatorLeadingTerm){
|
let inverseDenominatorLeadingTerm = match self.field.inverse(denominatorLeadingTerm) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(issue) => return Err(IllegalArgumentException::new("arithmetic issue")),
|
Err(issue) => return Err(IllegalArgumentException::new("arithmetic issue")),
|
||||||
};
|
};
|
||||||
|
|
||||||
while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
|
while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {
|
||||||
let degreeDifference = remainder.getDegree() - other.getDegree();
|
let degreeDifference = remainder.getDegree() - other.getDegree();
|
||||||
let scale = self.field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);
|
let scale = self.field.multiply(
|
||||||
|
remainder.getCoefficient(remainder.getDegree()),
|
||||||
|
inverseDenominatorLeadingTerm,
|
||||||
|
);
|
||||||
let term = other.multiplyByMonomial(degreeDifference, scale)?;
|
let term = other.multiplyByMonomial(degreeDifference, scale)?;
|
||||||
let iterationQuotient = self.field.buildMonomial(degreeDifference, scale);
|
let iterationQuotient = self.field.buildMonomial(degreeDifference, scale);
|
||||||
quotient = quotient.addOrSubtract(iterationQuotient)?;
|
quotient = quotient.addOrSubtract(iterationQuotient)?;
|
||||||
remainder = &*remainder.addOrSubtract(term)?;
|
remainder = &*remainder.addOrSubtract(term)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(vec! [ quotient, Box::new(*remainder) ]);
|
return Ok(vec![quotient, Box::new(*remainder)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for GenericGFPoly {
|
impl fmt::Display for GenericGFPoly {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
if (self.isZero()) {
|
if (self.isZero()) {
|
||||||
return write!(f,"0");
|
return write!(f, "0");
|
||||||
}
|
}
|
||||||
let result = String::with_capacity(8 * self.getDegree());
|
let result = String::with_capacity(8 * self.getDegree());
|
||||||
for degree in (0..self.getDegree()).rev(){
|
for degree in (0..self.getDegree()).rev() {
|
||||||
//for (int degree = getDegree(); degree >= 0; degree--) {
|
//for (int degree = getDegree(); degree >= 0; degree--) {
|
||||||
let coefficient = self.getCoefficient(degree);
|
let coefficient = self.getCoefficient(degree);
|
||||||
if (coefficient != 0) {
|
if (coefficient != 0) {
|
||||||
@@ -512,7 +547,7 @@ impl fmt::Display for GenericGFPoly {
|
|||||||
result.push_str("a");
|
result.push_str("a");
|
||||||
} else {
|
} else {
|
||||||
result.push_str("a^");
|
result.push_str("a^");
|
||||||
result.push_str(&format!("{}",alphaPower.unwrap()));
|
result.push_str(&format!("{}", alphaPower.unwrap()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (degree != 0) {
|
if (degree != 0) {
|
||||||
@@ -520,12 +555,12 @@ impl fmt::Display for GenericGFPoly {
|
|||||||
result.push_str("x");
|
result.push_str("x");
|
||||||
} else {
|
} else {
|
||||||
result.push_str("x^");
|
result.push_str("x^");
|
||||||
result.push_str(&format!("{}",degree));
|
result.push_str(&format!("{}", degree));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(f,"{}", result)
|
write!(f, "{}", result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -569,14 +604,14 @@ impl fmt::Display for GenericGFPoly {
|
|||||||
* @author sanfordsquires
|
* @author sanfordsquires
|
||||||
*/
|
*/
|
||||||
pub struct ReedSolomonDecoder {
|
pub struct ReedSolomonDecoder {
|
||||||
|
|
||||||
field: Box<GenericGF>,
|
field: Box<GenericGF>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReedSolomonDecoder{
|
impl ReedSolomonDecoder {
|
||||||
pub fn new ( field: GenericGF) -> Self {
|
pub fn new(field: GenericGF) -> Self {
|
||||||
Self { field: Box::new(field) }
|
Self {
|
||||||
|
field: Box::new(field),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -588,13 +623,19 @@ impl ReedSolomonDecoder{
|
|||||||
* @param twoS number of error-correction codewords available
|
* @param twoS number of error-correction codewords available
|
||||||
* @throws ReedSolomonException if decoding fails for any reason
|
* @throws ReedSolomonException if decoding fails for any reason
|
||||||
*/
|
*/
|
||||||
pub fn decode( &self,received: &mut Vec<usize>, twoS:usize) -> Result<(),ReedSolomonException> {
|
pub fn decode(
|
||||||
|
&self,
|
||||||
|
received: &mut Vec<usize>,
|
||||||
|
twoS: usize,
|
||||||
|
) -> Result<(), ReedSolomonException> {
|
||||||
let poly = GenericGFPoly::new(self.field, received);
|
let poly = GenericGFPoly::new(self.field, received);
|
||||||
let syndromeCoefficients = Vec::with_capacity(twoS);
|
let syndromeCoefficients = Vec::with_capacity(twoS);
|
||||||
let mut noError = true;
|
let mut noError = true;
|
||||||
for i in 0..twoS {
|
for i in 0..twoS {
|
||||||
//for (int i = 0; i < twoS; i++) {
|
//for (int i = 0; i < twoS; i++) {
|
||||||
let eval = poly.unwrap().evaluateAt(self.field.exp(i + self.field.getGeneratorBase()));
|
let eval = poly
|
||||||
|
.unwrap()
|
||||||
|
.evaluateAt(self.field.exp(i + self.field.getGeneratorBase()));
|
||||||
syndromeCoefficients[syndromeCoefficients.len() - 1 - i] = eval;
|
syndromeCoefficients[syndromeCoefficients.len() - 1 - i] = eval;
|
||||||
if (eval != 0) {
|
if (eval != 0) {
|
||||||
noError = false;
|
noError = false;
|
||||||
@@ -605,7 +646,7 @@ impl ReedSolomonDecoder{
|
|||||||
}
|
}
|
||||||
let syndrome = match GenericGFPoly::new(self.field, &syndromeCoefficients) {
|
let syndrome = match GenericGFPoly::new(self.field, &syndromeCoefficients) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(fail) => return Err(ReedSolomonException::new("IllegalArgumentException"))
|
Err(fail) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
};
|
};
|
||||||
let sigmaOmega =
|
let sigmaOmega =
|
||||||
self.runEuclideanAlgorithm(self.field.buildMonomial(twoS, 1), Box::new(syndrome), twoS);
|
self.runEuclideanAlgorithm(self.field.buildMonomial(twoS, 1), Box::new(syndrome), twoS);
|
||||||
@@ -615,9 +656,11 @@ impl ReedSolomonDecoder{
|
|||||||
let errorMagnitudes = self.findErrorMagnitudes(&omega, &errorLocations);
|
let errorMagnitudes = self.findErrorMagnitudes(&omega, &errorLocations);
|
||||||
for i in 0..errorLocations.len() {
|
for i in 0..errorLocations.len() {
|
||||||
//for (int i = 0; i < errorLocations.length; i++) {
|
//for (int i = 0; i < errorLocations.length; i++) {
|
||||||
let position = received.len() - 1 - match self.field.log(errorLocations[i]) {
|
let position = received.len()
|
||||||
|
- 1
|
||||||
|
- match self.field.log(errorLocations[i]) {
|
||||||
Ok(size) => size,
|
Ok(size) => size,
|
||||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException"))
|
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
};
|
};
|
||||||
if (position < 0) {
|
if (position < 0) {
|
||||||
return Err(ReedSolomonException::new("Bad error location"));
|
return Err(ReedSolomonException::new("Bad error location"));
|
||||||
@@ -627,8 +670,12 @@ impl ReedSolomonDecoder{
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runEuclideanAlgorithm(&self, a: Box<GenericGFPoly>, b:Box<GenericGFPoly>, R:usize)
|
fn runEuclideanAlgorithm(
|
||||||
-> Result<Vec<GenericGFPoly>, ReedSolomonException> {
|
&self,
|
||||||
|
a: Box<GenericGFPoly>,
|
||||||
|
b: Box<GenericGFPoly>,
|
||||||
|
R: usize,
|
||||||
|
) -> Result<Vec<GenericGFPoly>, ReedSolomonException> {
|
||||||
// Assume a's degree is >= b's
|
// Assume a's degree is >= b's
|
||||||
if (a.getDegree() < b.getDegree()) {
|
if (a.getDegree() < b.getDegree()) {
|
||||||
let temp = a;
|
let temp = a;
|
||||||
@@ -651,86 +698,104 @@ impl ReedSolomonDecoder{
|
|||||||
// Divide rLastLast by rLast, with quotient in q and remainder in r
|
// Divide rLastLast by rLast, with quotient in q and remainder in r
|
||||||
if (rLast.isZero()) {
|
if (rLast.isZero()) {
|
||||||
// Oops, Euclidean algorithm already terminated?
|
// Oops, Euclidean algorithm already terminated?
|
||||||
return Err( ReedSolomonException::new("r_{i-1} was zero"));
|
return Err(ReedSolomonException::new("r_{i-1} was zero"));
|
||||||
}
|
}
|
||||||
r = rLastLast;
|
r = rLastLast;
|
||||||
let q = self.field.getZero();
|
let q = self.field.getZero();
|
||||||
let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
|
let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
|
||||||
let dltInverse = match self.field.inverse(denominatorLeadingTerm){
|
let dltInverse = match self.field.inverse(denominatorLeadingTerm) {
|
||||||
Ok(inv) => inv,
|
Ok(inv) => inv,
|
||||||
Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
||||||
};
|
};
|
||||||
while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
|
while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {
|
||||||
let degreeDiff = r.getDegree() - rLast.getDegree();
|
let degreeDiff = r.getDegree() - rLast.getDegree();
|
||||||
let scale = self.field.multiply(r.getCoefficient(r.getDegree()), dltInverse);
|
let scale = self
|
||||||
|
.field
|
||||||
|
.multiply(r.getCoefficient(r.getDegree()), dltInverse);
|
||||||
q = match q.addOrSubtract(self.field.buildMonomial(degreeDiff, scale)) {
|
q = match q.addOrSubtract(self.field.buildMonomial(degreeDiff, scale)) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
};
|
};
|
||||||
r = match r.addOrSubtract(match rLast.multiplyByMonomial(degreeDiff, scale)
|
r = match r.addOrSubtract(match rLast.multiplyByMonomial(degreeDiff, scale) {
|
||||||
{
|
Ok(res) => res,
|
||||||
Ok(res) => res,
|
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
}) {
|
||||||
}){
|
Ok(res) => res,
|
||||||
Ok(res)=> res,
|
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException"))
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
t = match (match q.multiply(&tLast){
|
t = match (match q.multiply(&tLast) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
}).addOrSubtract(tLastLast){
|
})
|
||||||
|
.addOrSubtract(tLastLast)
|
||||||
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (r.getDegree() >= rLast.getDegree()) {
|
if (r.getDegree() >= rLast.getDegree()) {
|
||||||
return Err( ReedSolomonException::new(&format!("Division algorithm failed to reduce polynomial? r: {}, rLast: {}" ,r, rLast)));
|
return Err(ReedSolomonException::new(&format!(
|
||||||
|
"Division algorithm failed to reduce polynomial? r: {}, rLast: {}",
|
||||||
|
r, rLast
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sigmaTildeAtZero = t.getCoefficient(0);
|
let sigmaTildeAtZero = t.getCoefficient(0);
|
||||||
if (sigmaTildeAtZero == 0) {
|
if (sigmaTildeAtZero == 0) {
|
||||||
return Err( ReedSolomonException::new("sigmaTilde(0) was zero"));
|
return Err(ReedSolomonException::new("sigmaTilde(0) was zero"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let inverse = match self.field.inverse(sigmaTildeAtZero) {
|
let inverse = match self.field.inverse(sigmaTildeAtZero) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
||||||
};
|
};
|
||||||
let sigma = t.multiply_with_scalar(inverse);
|
let sigma = t.multiply_with_scalar(inverse);
|
||||||
let omega = r.multiply_with_scalar(inverse);
|
let omega = r.multiply_with_scalar(inverse);
|
||||||
return Ok(vec![*sigma, *omega]);
|
return Ok(vec![*sigma, *omega]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn findErrorLocations(&self, errorLocator:&GenericGFPoly) -> Result<Vec<usize>, ReedSolomonException> {
|
fn findErrorLocations(
|
||||||
|
&self,
|
||||||
|
errorLocator: &GenericGFPoly,
|
||||||
|
) -> Result<Vec<usize>, ReedSolomonException> {
|
||||||
// This is a direct application of Chien's search
|
// This is a direct application of Chien's search
|
||||||
let numErrors = errorLocator.getDegree();
|
let numErrors = errorLocator.getDegree();
|
||||||
if (numErrors == 1) { // shortcut
|
if (numErrors == 1) {
|
||||||
return Ok(vec![ errorLocator.getCoefficient(1) ]);
|
// shortcut
|
||||||
|
return Ok(vec![errorLocator.getCoefficient(1)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = Vec::with_capacity(numErrors);
|
let result = Vec::with_capacity(numErrors);
|
||||||
let mut e = 0;
|
let mut e = 0;
|
||||||
for i in 1..self.field.getSize() {
|
for i in 1..self.field.getSize() {
|
||||||
//for (int i = 1; i < field.getSize() && e < numErrors; i++) {
|
//for (int i = 1; i < field.getSize() && e < numErrors; i++) {
|
||||||
if e < numErrors { break; }
|
if e < numErrors {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (errorLocator.evaluateAt(i) == 0) {
|
if (errorLocator.evaluateAt(i) == 0) {
|
||||||
result[e] = match self.field.inverse(i) {
|
result[e] = match self.field.inverse(i) {
|
||||||
Ok(res)=>res,
|
Ok(res) => res,
|
||||||
Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
||||||
};
|
};
|
||||||
e+=1;
|
e += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e != numErrors) {
|
if (e != numErrors) {
|
||||||
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 findErrorMagnitudes( &self,errorEvaluator:&GenericGFPoly, errorLocations:&Vec<usize>) -> Vec<usize> {
|
fn findErrorMagnitudes(
|
||||||
|
&self,
|
||||||
|
errorEvaluator: &GenericGFPoly,
|
||||||
|
errorLocations: &Vec<usize>,
|
||||||
|
) -> Vec<usize> {
|
||||||
// This is directly applying Forney's Formula
|
// This is directly applying Forney's Formula
|
||||||
let s = errorLocations.len();
|
let s = errorLocations.len();
|
||||||
let result = Vec::with_capacity(s);
|
let result = Vec::with_capacity(s);
|
||||||
@@ -738,30 +803,34 @@ Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
|||||||
//for (int i = 0; i < s; i++) {
|
//for (int i = 0; i < s; i++) {
|
||||||
let xiInverse = self.field.inverse(errorLocations[i]);
|
let xiInverse = self.field.inverse(errorLocations[i]);
|
||||||
let denominator = 1;
|
let denominator = 1;
|
||||||
for j in 0..s{
|
for j in 0..s {
|
||||||
//for (int j = 0; j < s; j++) {
|
//for (int j = 0; j < s; j++) {
|
||||||
if (i != j) {
|
if (i != j) {
|
||||||
//denominator = field.multiply(denominator,
|
//denominator = field.multiply(denominator,
|
||||||
// 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 =self. field.multiply(errorLocations[j], xiInverse.unwrap());
|
let term = self.field.multiply(errorLocations[j], xiInverse.unwrap());
|
||||||
let termPlus1 = if (term & 0x1) == 0 { term | 1} else { term & !1};
|
let termPlus1 = if (term & 0x1) == 0 {
|
||||||
|
term | 1
|
||||||
|
} else {
|
||||||
|
term & !1
|
||||||
|
};
|
||||||
denominator = self.field.multiply(denominator, termPlus1);
|
denominator = self.field.multiply(denominator, termPlus1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result[i] = self.field.multiply(errorEvaluator.evaluateAt(xiInverse.unwrap()),
|
result[i] = self.field.multiply(
|
||||||
self.field.inverse(denominator).unwrap());
|
errorEvaluator.evaluateAt(xiInverse.unwrap()),
|
||||||
|
self.field.inverse(denominator).unwrap(),
|
||||||
|
);
|
||||||
if (self.field.getGeneratorBase() != 0) {
|
if (self.field.getGeneratorBase() != 0) {
|
||||||
result[i] = self.field.multiply(result[i], xiInverse.unwrap());
|
result[i] = self.field.multiply(result[i], xiInverse.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2008 ZXing authors
|
* Copyright 2008 ZXing authors
|
||||||
*
|
*
|
||||||
@@ -790,27 +859,35 @@ Err(err) => return Err(ReedSolomonException::new("ArithmetricException")),
|
|||||||
* @author William Rucklidge
|
* @author William Rucklidge
|
||||||
*/
|
*/
|
||||||
pub struct ReedSolomonEncoder {
|
pub struct ReedSolomonEncoder {
|
||||||
|
field: Box<GenericGF>,
|
||||||
field : Box<GenericGF>,
|
|
||||||
cachedGenerators: Vec<GenericGFPoly>,
|
cachedGenerators: Vec<GenericGFPoly>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReedSolomonEncoder{
|
impl ReedSolomonEncoder {
|
||||||
pub fn new( field: Box<GenericGF>) -> Self{
|
pub fn new(field: Box<GenericGF>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
field: field,
|
field: field,
|
||||||
cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()],
|
cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buildGenerator( &self,degree:usize) -> GenericGFPoly{
|
fn buildGenerator(&self, degree: usize) -> GenericGFPoly {
|
||||||
if degree >= self.cachedGenerators.len() {
|
if degree >= self.cachedGenerators.len() {
|
||||||
let mut lastGenerator = self.cachedGenerators.get(self.cachedGenerators.len() - 1).unwrap();
|
let mut lastGenerator = self
|
||||||
|
.cachedGenerators
|
||||||
|
.get(self.cachedGenerators.len() - 1)
|
||||||
|
.unwrap();
|
||||||
for d in self.cachedGenerators.len()..=degree {
|
for d in self.cachedGenerators.len()..=degree {
|
||||||
//for (int d = cachedGenerators.size(); d <= degree; d++) {
|
//for (int d = cachedGenerators.size(); d <= degree; d++) {
|
||||||
let nextGenerator = *lastGenerator.multiply(
|
let nextGenerator = *lastGenerator
|
||||||
&GenericGFPoly::new(self.field, &vec![ 1, self.field.exp(d - 1 + self.field.getGeneratorBase()) ]).unwrap()).unwrap();
|
.multiply(
|
||||||
|
&GenericGFPoly::new(
|
||||||
|
self.field,
|
||||||
|
&vec![1, self.field.exp(d - 1 + self.field.getGeneratorBase())],
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
self.cachedGenerators.push(nextGenerator);
|
self.cachedGenerators.push(nextGenerator);
|
||||||
lastGenerator = &nextGenerator;
|
lastGenerator = &nextGenerator;
|
||||||
}
|
}
|
||||||
@@ -818,13 +895,17 @@ impl ReedSolomonEncoder{
|
|||||||
return *self.cachedGenerators.get(degree).unwrap();
|
return *self.cachedGenerators.get(degree).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode(&self,toEncode:&mut Vec<usize>, ecBytes:usize) -> Result<(),IllegalArgumentException>{
|
pub fn encode(
|
||||||
|
&self,
|
||||||
|
toEncode: &mut Vec<usize>,
|
||||||
|
ecBytes: usize,
|
||||||
|
) -> Result<(), IllegalArgumentException> {
|
||||||
if (ecBytes == 0) {
|
if (ecBytes == 0) {
|
||||||
return Err(IllegalArgumentException::new("No error correction bytes"));
|
return Err(IllegalArgumentException::new("No error correction bytes"));
|
||||||
}
|
}
|
||||||
let dataBytes = toEncode.len() - ecBytes;
|
let dataBytes = toEncode.len() - ecBytes;
|
||||||
if (dataBytes <= 0) {
|
if (dataBytes <= 0) {
|
||||||
return Err( IllegalArgumentException::new("No data bytes provided"));
|
return Err(IllegalArgumentException::new("No data bytes provided"));
|
||||||
}
|
}
|
||||||
let generator = self.buildGenerator(ecBytes);
|
let generator = self.buildGenerator(ecBytes);
|
||||||
let infoCoefficients = Vec::with_capacity(dataBytes);
|
let infoCoefficients = Vec::with_capacity(dataBytes);
|
||||||
@@ -839,9 +920,9 @@ impl ReedSolomonEncoder{
|
|||||||
//for (int i = 0; i < numZeroCoefficients; i++) {
|
//for (int i = 0; i < numZeroCoefficients; i++) {
|
||||||
toEncode[dataBytes + i] = 0;
|
toEncode[dataBytes + i] = 0;
|
||||||
}
|
}
|
||||||
toEncode[dataBytes + numZeroCoefficients..coefficients.len()].clone_from_slice(&coefficients[0..coefficients.len()]);
|
toEncode[dataBytes + numZeroCoefficients..coefficients.len()]
|
||||||
|
.clone_from_slice(&coefficients[0..coefficients.len()]);
|
||||||
//System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);
|
//System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user