mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-27 21:02:35 +00:00
consider removing inverted
This commit is contained in:
@@ -25,28 +25,36 @@ use super::{GenericGF, GenericGFPoly};
|
||||
* Tests {@link GenericGFPoly}.
|
||||
*/
|
||||
|
||||
const FIELD: GenericGF = super::QR_CODE_FIELD_256;
|
||||
//const FIELD: GenericGF = super::QR_CODE_FIELD_256;
|
||||
|
||||
#[test]
|
||||
fn testPolynomialString() {
|
||||
assert_eq!("0", FIELD.getZero().to_string());
|
||||
let FIELD = super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256);
|
||||
let fz = super::GenericGFPoly::new(FIELD.clone(), &vec![0;0]).unwrap();
|
||||
|
||||
assert_eq!("0", fz.getZero().to_string());
|
||||
assert_eq!("-1", FIELD.buildMonomial(0, -1).to_string());
|
||||
let p = GenericGFPoly::new(Box::new(FIELD), &vec![3, 0, -2, 1, 1]).unwrap();
|
||||
let p = GenericGFPoly::new(FIELD.clone(), &vec![3, 0, -2, 1, 1]).unwrap();
|
||||
assert_eq!("a^25x^4 - ax^2 + x + 1", p.to_string());
|
||||
let p = GenericGFPoly::new(Box::new(FIELD), &vec![3]).unwrap();
|
||||
let p = GenericGFPoly::new(FIELD.clone(), &vec![3]).unwrap();
|
||||
assert_eq!("a^25", p.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testZero() {
|
||||
assert_eq!(*FIELD.getZero(), *FIELD.buildMonomial(1, 0));
|
||||
let FIELD = super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256);
|
||||
let fz = super::GenericGFPoly::new(FIELD.clone(), &vec![0;0]).unwrap();
|
||||
|
||||
assert_eq!(fz.getZero(), FIELD.buildMonomial(1, 0));
|
||||
assert_eq!(
|
||||
*FIELD.getZero(),
|
||||
*FIELD.buildMonomial(1, 2).multiply_with_scalar(0)
|
||||
fz.getZero(),
|
||||
FIELD.buildMonomial(1, 2).multiply_with_scalar(0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testEvaluate() {
|
||||
let FIELD = super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256);
|
||||
|
||||
assert_eq!(3, FIELD.buildMonomial(0, 3).evaluateAt(0));
|
||||
}
|
||||
|
||||
@@ -36,14 +36,15 @@ const DECODER_TEST_ITERATIONS: i32 = 10;
|
||||
|
||||
#[test]
|
||||
fn testDataMatrix() {
|
||||
let dm256 = super::get_predefined_genericgf(super::PredefinedGenericGF::DataMatrixField256);
|
||||
// real life test cases
|
||||
testEncodeDecode(
|
||||
&super::DATA_MATRIX_FIELD_256,
|
||||
&dm256,
|
||||
&vec![142, 164, 186],
|
||||
&vec![114, 25, 5, 88, 102],
|
||||
);
|
||||
testEncodeDecode(
|
||||
&super::DATA_MATRIX_FIELD_256,
|
||||
&dm256,
|
||||
&vec![
|
||||
0x69, 0x75, 0x75, 0x71, 0x3B, 0x30, 0x30, 0x64, 0x70, 0x65, 0x66, 0x2F, 0x68, 0x70,
|
||||
0x70, 0x68, 0x6D, 0x66, 0x2F, 0x64, 0x70, 0x6E, 0x30, 0x71, 0x30, 0x7B, 0x79, 0x6A,
|
||||
@@ -55,16 +56,17 @@ fn testDataMatrix() {
|
||||
],
|
||||
);
|
||||
// synthetic test cases
|
||||
testEncodeDecodeRandom(super::DATA_MATRIX_FIELD_256, 10, 240);
|
||||
testEncodeDecodeRandom(super::DATA_MATRIX_FIELD_256, 128, 127);
|
||||
testEncodeDecodeRandom(super::DATA_MATRIX_FIELD_256, 220, 35);
|
||||
testEncodeDecodeRandom(dm256.clone(), 10, 240);
|
||||
testEncodeDecodeRandom(dm256.clone(), 128, 127);
|
||||
testEncodeDecodeRandom(dm256.clone(), 220, 35);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testQRCode() {
|
||||
let qrcf256 = super::get_predefined_genericgf(super::PredefinedGenericGF::QrCodeField256);
|
||||
// Test case from example given in ISO 18004, Annex I
|
||||
testEncodeDecode(
|
||||
&super::QR_CODE_FIELD_256,
|
||||
&qrcf256,
|
||||
&vec![
|
||||
0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11,
|
||||
0xEC, 0x11,
|
||||
@@ -72,7 +74,7 @@ fn testQRCode() {
|
||||
&vec![0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87, 0x2C, 0x55],
|
||||
);
|
||||
testEncodeDecode(
|
||||
&super::QR_CODE_FIELD_256,
|
||||
&qrcf256,
|
||||
&vec![
|
||||
0x72, 0x67, 0x2F, 0x77, 0x69, 0x6B, 0x69, 0x2F, 0x4D, 0x61, 0x69, 0x6E, 0x5F, 0x50,
|
||||
0x61, 0x67, 0x65, 0x3B, 0x3B, 0x00, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11,
|
||||
@@ -85,36 +87,37 @@ fn testQRCode() {
|
||||
);
|
||||
// real life test cases
|
||||
// synthetic test cases
|
||||
testEncodeDecodeRandom(super::QR_CODE_FIELD_256, 10, 240);
|
||||
testEncodeDecodeRandom(super::QR_CODE_FIELD_256, 128, 127);
|
||||
testEncodeDecodeRandom(super::QR_CODE_FIELD_256, 220, 35);
|
||||
testEncodeDecodeRandom(qrcf256.clone(), 10, 240);
|
||||
testEncodeDecodeRandom(qrcf256.clone(), 128, 127);
|
||||
testEncodeDecodeRandom(qrcf256.clone(), 220, 35);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testAztec() {
|
||||
// real life test cases
|
||||
testEncodeDecode(
|
||||
&super::AZTEC_PARAM,
|
||||
&super::get_predefined_genericgf(super::PredefinedGenericGF::AztecParam),
|
||||
&vec![0x5, 0x6],
|
||||
&vec![0x3, 0x2, 0xB, 0xB, 0x7],
|
||||
);
|
||||
testEncodeDecode(
|
||||
&super::AZTEC_PARAM,
|
||||
&super::get_predefined_genericgf(super::PredefinedGenericGF::AztecParam),
|
||||
&vec![0x0, 0x0, 0x0, 0x9],
|
||||
&vec![0xA, 0xD, 0x8, 0x6, 0x5, 0x6],
|
||||
);
|
||||
testEncodeDecode(
|
||||
&super::AZTEC_PARAM,
|
||||
&super::get_predefined_genericgf(super::PredefinedGenericGF::AztecParam),
|
||||
&vec![0x2, 0x8, 0x8, 0x7],
|
||||
&vec![0xE, 0xC, 0xA, 0x9, 0x6, 0x8],
|
||||
);
|
||||
testEncodeDecode(
|
||||
&super::AZTEC_DATA_6,
|
||||
&super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData6),
|
||||
&vec![0x9, 0x32, 0x1, 0x29, 0x2F, 0x2, 0x27, 0x25, 0x1, 0x1B],
|
||||
&vec![0x2C, 0x2, 0xD, 0xD, 0xA, 0x16, 0x28, 0x9, 0x22, 0xA, 0x14],
|
||||
);
|
||||
|
||||
testEncodeDecode(
|
||||
&super::AZTEC_DATA_8,
|
||||
&super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData8),
|
||||
&vec![
|
||||
0xE0, 0x86, 0x42, 0x98, 0xE8, 0x4A, 0x96, 0xC6, 0xB9, 0xF0, 0x8C, 0xA7, 0x4A, 0xDA,
|
||||
0xF8, 0xCE, 0xB7, 0xDE, 0x88, 0x64, 0x29, 0x8E, 0x84, 0xA9, 0x6C, 0x6B, 0x9F, 0x08,
|
||||
@@ -130,7 +133,7 @@ fn testAztec() {
|
||||
],
|
||||
);
|
||||
testEncodeDecode(
|
||||
&super::AZTEC_DATA_10,
|
||||
&super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData10),
|
||||
&vec![
|
||||
0x15C, 0x1E1, 0x2D5, 0x02E, 0x048, 0x1E2, 0x037, 0x0CD, 0x02E, 0x056, 0x26A, 0x281,
|
||||
0x1C2, 0x1A6, 0x296, 0x045, 0x041, 0x0AA, 0x095, 0x2CE, 0x003, 0x38F, 0x2CD, 0x1A2,
|
||||
@@ -177,7 +180,7 @@ fn testAztec() {
|
||||
],
|
||||
);
|
||||
testEncodeDecode(
|
||||
&super::AZTEC_DATA_12,
|
||||
&super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData12),
|
||||
&vec![
|
||||
0x571, 0xE1B, 0x542, 0xE12, 0x1E2, 0x0DC, 0xCD0, 0xB85, 0x69A, 0xA81, 0x709, 0xA6A,
|
||||
0x584, 0x510, 0x4AA, 0x256, 0xCE0, 0x0F8, 0xFB3, 0x5A2, 0x0D9, 0xAD1, 0x389, 0x09C,
|
||||
@@ -324,15 +327,21 @@ fn testAztec() {
|
||||
],
|
||||
);
|
||||
// synthetic test cases
|
||||
testEncodeDecodeRandom(super::AZTEC_PARAM, 2, 5); // compact mode message
|
||||
testEncodeDecodeRandom(super::AZTEC_PARAM, 4, 6); // full mode message
|
||||
testEncodeDecodeRandom(super::AZTEC_DATA_6, 10, 7);
|
||||
testEncodeDecodeRandom(super::AZTEC_DATA_6, 20, 12);
|
||||
testEncodeDecodeRandom(super::AZTEC_DATA_8, 20, 11);
|
||||
testEncodeDecodeRandom(super::AZTEC_DATA_8, 128, 127);
|
||||
testEncodeDecodeRandom(super::AZTEC_DATA_10, 128, 128);
|
||||
testEncodeDecodeRandom(super::AZTEC_DATA_10, 768, 255);
|
||||
testEncodeDecodeRandom(super::AZTEC_DATA_12, 3072, 1023);
|
||||
let azp = super::get_predefined_genericgf(super::PredefinedGenericGF::AztecParam);
|
||||
let azd6 = super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData6);
|
||||
let azd8 = super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData8);
|
||||
let azd10 = super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData10);
|
||||
let azd12 = super::get_predefined_genericgf(super::PredefinedGenericGF::AztecData12);
|
||||
|
||||
testEncodeDecodeRandom(azp.clone(), 2, 5); // compact mode message
|
||||
testEncodeDecodeRandom(azp.clone(), 4, 6); // full mode message
|
||||
testEncodeDecodeRandom(azd6.clone(), 10, 7);
|
||||
testEncodeDecodeRandom(azd6.clone(), 20, 12);
|
||||
testEncodeDecodeRandom(azd8.clone(), 20, 11);
|
||||
testEncodeDecodeRandom(azd8.clone(), 128, 127);
|
||||
testEncodeDecodeRandom(azd10.clone(), 128, 128);
|
||||
testEncodeDecodeRandom(azd10.clone(), 768, 255);
|
||||
testEncodeDecodeRandom(azd12.clone(), 3072, 1023);
|
||||
}
|
||||
|
||||
fn corrupt(received: &mut Vec<i32>, howMany: i32, random: &mut rand::rngs::ThreadRng, max: i32) {
|
||||
@@ -367,7 +376,7 @@ fn testEncodeDecodeRandom(field: GenericGF, dataSize: usize, ecSize: usize) {
|
||||
"Invalid ECC size for {}",
|
||||
field
|
||||
);
|
||||
let encoder = ReedSolomonEncoder::new(Box::new(field.clone()));
|
||||
let mut encoder = ReedSolomonEncoder::new(field.clone());
|
||||
let mut message = Vec::with_capacity(dataSize + ecSize);
|
||||
let mut dataWords: Vec<i32> = Vec::with_capacity(dataSize);
|
||||
let mut ecWords = Vec::with_capacity(ecSize);
|
||||
@@ -401,7 +410,7 @@ fn testEncodeDecode(field: &GenericGF, dataWords: &Vec<i32>, ecWords: &Vec<i32>)
|
||||
}
|
||||
|
||||
fn testEncoder(field: &GenericGF, dataWords: &Vec<i32>, ecWords: &Vec<i32>) {
|
||||
let encoder = ReedSolomonEncoder::new(Box::new(field.clone()));
|
||||
let mut encoder = ReedSolomonEncoder::new(field.clone());
|
||||
let mut messageExpected = Vec::with_capacity(dataWords.len() + ecWords.len());
|
||||
let mut message = Vec::with_capacity(dataWords.len() + ecWords.len());
|
||||
messageExpected[0..dataWords.len()].clone_from_slice(&dataWords[0..dataWords.len()]);
|
||||
|
||||
@@ -69,14 +69,37 @@ impl fmt::Display for ReedSolomonException {
|
||||
|
||||
//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_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_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 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 MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6;
|
||||
// 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_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 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 AZTEC_DATA_8: GenericGF = DATA_MATRIX_FIELD_256;
|
||||
// pub const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6;
|
||||
|
||||
pub enum PredefinedGenericGF {
|
||||
AztecData12,
|
||||
AztecData10,
|
||||
AztecData6,
|
||||
AztecParam,
|
||||
QrCodeField256,
|
||||
DataMatrixField256,
|
||||
AztecData8,
|
||||
MaxicodeField64
|
||||
}
|
||||
|
||||
/// Replacement for old const options, has the downside of generating new versions whenever one is requested.
|
||||
pub fn get_predefined_genericgf(request:PredefinedGenericGF) -> GenericGF {
|
||||
match request {
|
||||
PredefinedGenericGF::AztecData12 => GenericGF::new(0x1069, 4096, 1), // x^12 + x^6 + x^5 + x^3 + 1,
|
||||
PredefinedGenericGF::AztecData10 => GenericGF::new(0x409, 1024, 1), // x^10 + x^3 + 1
|
||||
PredefinedGenericGF::AztecData6 | PredefinedGenericGF::MaxicodeField64 => GenericGF::new(0x43, 64, 1), // x^6 + x + 1
|
||||
PredefinedGenericGF::AztecParam => GenericGF::new(0x13, 16, 1), // x^4 + x + 1
|
||||
PredefinedGenericGF::QrCodeField256 => GenericGF::new(0x011D, 256, 0), // x^8 + x^4 + x^3 + x^2 + 1
|
||||
PredefinedGenericGF::DataMatrixField256 | PredefinedGenericGF::AztecData8 => GenericGF::new(0x012D, 256, 1), // x^8 + x^5 + x^3 + x^2 + 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>This class contains utility methods for performing mathematical operations over
|
||||
@@ -89,7 +112,7 @@ pub const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6;
|
||||
* @author Sean Owen
|
||||
* @author David Olivier
|
||||
*/
|
||||
#[derive(Debug,Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GenericGF {
|
||||
expTable: Vec<i32>,
|
||||
logTable: Vec<i32>,
|
||||
@@ -278,7 +301,7 @@ impl fmt::Display for GenericGF {
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
#[derive(Debug,Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GenericGFPoly {
|
||||
field: GenericGF,
|
||||
coefficients: Vec<i32>,
|
||||
@@ -323,9 +346,8 @@ impl GenericGFPoly {
|
||||
} else {
|
||||
let mut new_coefficients =
|
||||
Vec::with_capacity(coefficientsLength - firstNonZero);
|
||||
let l = new_coefficients.len();
|
||||
new_coefficients[0..l]
|
||||
.clone_from_slice(&coefficients[firstNonZero..l]);
|
||||
let l = new_coefficients.len();
|
||||
new_coefficients[0..l].clone_from_slice(&coefficients[firstNonZero..l]);
|
||||
// System.arraycopy(coefficients,
|
||||
// firstNonZero,
|
||||
// this.coefficients,
|
||||
@@ -495,11 +517,11 @@ impl GenericGFPoly {
|
||||
return GenericGFPoly::new(self.field.clone(), &product).unwrap();
|
||||
}
|
||||
|
||||
pub fn getZero(&self) -> Self{
|
||||
pub fn getZero(&self) -> Self {
|
||||
GenericGFPoly::new(self.field.clone(), &vec![0]).unwrap()
|
||||
}
|
||||
|
||||
pub fn getOne(&self) -> Self{
|
||||
pub fn getOne(&self) -> Self {
|
||||
GenericGFPoly::new(self.field.clone(), &vec![1]).unwrap()
|
||||
}
|
||||
|
||||
@@ -586,15 +608,16 @@ impl fmt::Display for GenericGFPoly {
|
||||
}
|
||||
}
|
||||
if degree == 0 || coefficient != 1 {
|
||||
if let Ok(alphaPower) = self.field.log(coefficient){
|
||||
if alphaPower == 0 {
|
||||
result.push_str("1");
|
||||
} else if alphaPower == 1 {
|
||||
result.push_str("a");
|
||||
} else {
|
||||
result.push_str("a^");
|
||||
result.push_str(&format!("{}", alphaPower));
|
||||
}}
|
||||
if let Ok(alphaPower) = self.field.log(coefficient) {
|
||||
if alphaPower == 0 {
|
||||
result.push_str("1");
|
||||
} else if alphaPower == 1 {
|
||||
result.push_str("a");
|
||||
} else {
|
||||
result.push_str("a^");
|
||||
result.push_str(&format!("{}", alphaPower));
|
||||
}
|
||||
}
|
||||
}
|
||||
if degree != 0 {
|
||||
if degree == 1 {
|
||||
@@ -655,9 +678,7 @@ pub struct ReedSolomonDecoder {
|
||||
|
||||
impl ReedSolomonDecoder {
|
||||
pub fn new(field: GenericGF) -> Self {
|
||||
Self {
|
||||
field: field,
|
||||
}
|
||||
Self { field: field }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -726,8 +747,8 @@ impl ReedSolomonDecoder {
|
||||
R: usize,
|
||||
) -> Result<Vec<GenericGFPoly>, ReedSolomonException> {
|
||||
// Assume a's degree is >= b's
|
||||
let mut a = a;
|
||||
let mut b = b;
|
||||
let mut a = a.clone();
|
||||
let mut b = b.clone();
|
||||
if a.getDegree() < b.getDegree() {
|
||||
let temp = a;
|
||||
a = b;
|
||||
@@ -738,8 +759,8 @@ impl ReedSolomonDecoder {
|
||||
let mut r = b;
|
||||
// let tLast = self.field.getZero();
|
||||
// let t = self.field.getOne();
|
||||
let mut tLast = a.getZero();
|
||||
let mut t = a.getOne();
|
||||
let mut tLast = rLast.getZero();
|
||||
let mut t = rLast.getOne();
|
||||
|
||||
// Run Euclidean algorithm until r's degree is less than R/2
|
||||
while 2 * r.getDegree() >= R {
|
||||
@@ -754,7 +775,7 @@ impl ReedSolomonDecoder {
|
||||
return Err(ReedSolomonException::new("r_{i-1} was zero"));
|
||||
}
|
||||
r = rLastLast;
|
||||
let q = a.getZero();
|
||||
let mut q = r.getZero();
|
||||
let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());
|
||||
let dltInverse = match self.field.inverse(denominatorLeadingTerm) {
|
||||
Ok(inv) => inv,
|
||||
@@ -769,11 +790,11 @@ impl ReedSolomonDecoder {
|
||||
Ok(res) => res,
|
||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||
};
|
||||
r = match r.addOrSubtract(match rLast.multiplyByMonomial(degreeDiff, scale) {
|
||||
Ok(res) => &res,
|
||||
r = match r.addOrSubtract(&match rLast.multiplyByMonomial(degreeDiff, scale) {
|
||||
Ok(res) => res,
|
||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||
}) {
|
||||
Ok(res) =>&res,
|
||||
Ok(res) => res,
|
||||
Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||
};
|
||||
}
|
||||
@@ -821,7 +842,7 @@ impl ReedSolomonDecoder {
|
||||
return Ok(vec![errorLocator.getCoefficient(1).try_into().unwrap()]);
|
||||
}
|
||||
|
||||
let result: Vec<usize> = Vec::with_capacity(numErrors);
|
||||
let mut result: Vec<usize> = Vec::with_capacity(numErrors);
|
||||
let mut e = 0;
|
||||
for i in 1..self.field.getSize() {
|
||||
//for (int i = 1; i < field.getSize() && e < numErrors; i++) {
|
||||
@@ -851,11 +872,14 @@ impl ReedSolomonDecoder {
|
||||
) -> Vec<i32> {
|
||||
// This is directly applying Forney's Formula
|
||||
let s = errorLocations.len();
|
||||
let result = Vec::with_capacity(s);
|
||||
let mut result = Vec::with_capacity(s);
|
||||
for i in 0..s {
|
||||
//for (int i = 0; i < s; i++) {
|
||||
let xiInverse = self.field.inverse(errorLocations[i].try_into().unwrap());
|
||||
let denominator = 1;
|
||||
let xiInverse = self
|
||||
.field
|
||||
.inverse(errorLocations[i].try_into().unwrap())
|
||||
.unwrap();
|
||||
let mut denominator = 1;
|
||||
for j in 0..s {
|
||||
//for (int j = 0; j < s; j++) {
|
||||
if i != j {
|
||||
@@ -865,7 +889,7 @@ impl ReedSolomonDecoder {
|
||||
// Below is a funny-looking workaround from Steven Parkes
|
||||
let term = self
|
||||
.field
|
||||
.multiply(errorLocations[j].try_into().unwrap(), xiInverse.unwrap());
|
||||
.multiply(errorLocations[j].try_into().unwrap(), xiInverse);
|
||||
let termPlus1 = if (term & 0x1) == 0 {
|
||||
term | 1
|
||||
} else {
|
||||
@@ -875,11 +899,11 @@ impl ReedSolomonDecoder {
|
||||
}
|
||||
}
|
||||
result[i] = self.field.multiply(
|
||||
errorEvaluator.evaluateAt(xiInverse.unwrap().try_into().unwrap()),
|
||||
errorEvaluator.evaluateAt(xiInverse.try_into().unwrap()),
|
||||
self.field.inverse(denominator).unwrap(),
|
||||
);
|
||||
if self.field.getGeneratorBase() != 0 {
|
||||
result[i] = self.field.multiply(result[i], xiInverse.unwrap());
|
||||
result[i] = self.field.multiply(result[i], xiInverse);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -921,23 +945,25 @@ pub struct ReedSolomonEncoder {
|
||||
impl ReedSolomonEncoder {
|
||||
pub fn new(field: GenericGF) -> Self {
|
||||
Self {
|
||||
cachedGenerators: vec![GenericGFPoly::new(field.clone(), &vec![1]).unwrap()],
|
||||
field: field,
|
||||
cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()],
|
||||
}
|
||||
}
|
||||
|
||||
fn buildGenerator(&self, degree: usize) -> GenericGFPoly {
|
||||
fn buildGenerator(&mut self, degree: usize) -> &GenericGFPoly {
|
||||
if degree >= self.cachedGenerators.len() {
|
||||
let mut lastGenerator = self
|
||||
.cachedGenerators
|
||||
.get(self.cachedGenerators.len() - 1)
|
||||
.unwrap();
|
||||
for d in self.cachedGenerators.len()..=degree {
|
||||
let cg_len = self.cachedGenerators.len();
|
||||
let mut nextGenerator;
|
||||
for d in cg_len..=degree {
|
||||
//for (int d = cachedGenerators.size(); d <= degree; d++) {
|
||||
let nextGenerator = lastGenerator
|
||||
nextGenerator = lastGenerator
|
||||
.multiply(
|
||||
&GenericGFPoly::new(
|
||||
self.field,
|
||||
self.field.clone(),
|
||||
&vec![
|
||||
1,
|
||||
self.field.exp(d as i32 - 1 + self.field.getGeneratorBase()),
|
||||
@@ -947,14 +973,16 @@ impl ReedSolomonEncoder {
|
||||
)
|
||||
.unwrap();
|
||||
self.cachedGenerators.push(nextGenerator);
|
||||
lastGenerator = &nextGenerator;
|
||||
lastGenerator = self.cachedGenerators.get(d).unwrap();
|
||||
//lastGenerator = &nextGenerator;
|
||||
}
|
||||
}
|
||||
return *self.cachedGenerators.get(degree).unwrap();
|
||||
let rv = self.cachedGenerators.get(degree).unwrap();
|
||||
return rv;
|
||||
}
|
||||
|
||||
pub fn encode(
|
||||
&self,
|
||||
&mut self,
|
||||
toEncode: &mut Vec<i32>,
|
||||
ecBytes: usize,
|
||||
) -> Result<(), IllegalArgumentException> {
|
||||
@@ -965,13 +993,14 @@ impl ReedSolomonEncoder {
|
||||
if dataBytes <= 0 {
|
||||
return Err(IllegalArgumentException::new("No data bytes provided"));
|
||||
}
|
||||
let fld = self.field.clone();
|
||||
let generator = self.buildGenerator(ecBytes);
|
||||
let mut infoCoefficients: Vec<i32> = Vec::with_capacity(dataBytes);
|
||||
infoCoefficients[0..dataBytes].clone_from_slice(&toEncode[0..dataBytes]);
|
||||
//System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
|
||||
let mut info = GenericGFPoly::new(self.field.clone(), &infoCoefficients)?;
|
||||
let mut info = GenericGFPoly::new(fld, &infoCoefficients)?;
|
||||
info = info.multiplyByMonomial(ecBytes.try_into().unwrap(), 1)?;
|
||||
let remainder = info.divide(&generator)?[1];
|
||||
let remainder = &info.divide(&generator)?[1];
|
||||
let coefficients = remainder.getCoefficients();
|
||||
let numZeroCoefficients = ecBytes - coefficients.len();
|
||||
for i in 0..numZeroCoefficients {
|
||||
|
||||
Reference in New Issue
Block a user