From 106eed172134e49a9f9e32f757927ddb296c3426 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Fri, 26 Aug 2022 17:21:46 -0500 Subject: [PATCH] working through errors to compile --- src/common/detector/MathUtils.rs | 2 +- src/common/detector/mod.rs | 167 ++++++------- src/common/mod.rs | 91 +++---- src/common/reedsolomon/ReedSolomonTestCase.rs | 122 +++++----- src/common/reedsolomon/mod.rs | 222 ++++++++++-------- 5 files changed, 317 insertions(+), 287 deletions(-) diff --git a/src/common/detector/MathUtils.rs b/src/common/detector/MathUtils.rs index dbc92e1..d7a3648 100644 --- a/src/common/detector/MathUtils.rs +++ b/src/common/detector/MathUtils.rs @@ -65,7 +65,7 @@ pub fn distance_int(aX: i32, aY: i32, bX: i32, bY: i32) -> f32 { * @return sum of values in array */ pub fn sum(array: &[i32]) -> i32 { - let count = 0; + let mut count = 0; for a in array { count += a; } diff --git a/src/common/detector/mod.rs b/src/common/detector/mod.rs index 4450fcb..01efcdf 100644 --- a/src/common/detector/mod.rs +++ b/src/common/detector/mod.rs @@ -36,7 +36,7 @@ pub struct MonochromeRectangleDetector { impl MonochromeRectangleDetector { pub fn new(image: &BitMatrix) -> Self { - Self { image: image } + Self { image: image.clone() } } /** @@ -50,18 +50,18 @@ impl MonochromeRectangleDetector { * @throws NotFoundException if no Data Matrix Code can be found */ pub fn detect(&self) -> Result, NotFoundException> { - let height = self.image.getHeight(); - let width = self.image.getWidth(); - let halfHeight = height / 2; + let height = self.image.getHeight() as i32; + let width = self.image.getWidth() as i32; + let halfHeight= height / 2; let halfWidth = width / 2; - let deltaY = 1.max(height / (MAX_MODULES * 8)); - let deltaX = 1.max(width / (MAX_MODULES * 8)); + let deltaY = 1.max(height as i32 / (MAX_MODULES * 8)); + let deltaX = 1.max(width as i32 / (MAX_MODULES * 8)); - let top = 0; - let bottom = height; - let left = 0; - let right = width; - let pointA = self.findCornerFromCenter( + let mut top = 0; + let mut bottom = height; + let mut left = 0; + let mut right = width; + let mut pointA = self.findCornerFromCenter( halfWidth, 0, left, @@ -156,9 +156,9 @@ impl MonochromeRectangleDetector { bottom: i32, maxWhiteRun: i32, ) -> Result { - let mut lastRange: Option> = None; - let y: i32 = centerY; - let x: i32 = centerX; + let mut lastRange_z: Option> = None; + let mut y: i32 = centerY; + let mut x: i32 = centerX; while y < bottom && y >= top && x < right && x >= left { let range: Option>; if deltaX == 0 { @@ -169,52 +169,52 @@ impl MonochromeRectangleDetector { range = self.blackWhiteRange(x, maxWhiteRun, top, bottom, false); } if range.is_none() { - if lastRange.is_none() { - return Err(NotFoundException {}); - } + if let Some(lastRange) = lastRange_z { // lastRange was found if deltaX == 0 { let lastY = y - deltaY; - if lastRange.unwrap()[0] < centerX { - if lastRange.unwrap()[1] > centerX { + if lastRange[0] < centerX { + if lastRange[1] > centerX { // straddle, choose one or the other based on direction return Ok(RXingResultPoint::new( - lastRange.unwrap()[if deltaY > 0 { 0 } else { 1 }] as f32, + lastRange[if deltaY > 0 { 0 } else { 1 }] as f32, lastY as f32, )); } return Ok(RXingResultPoint::new( - lastRange.unwrap()[0] as f32, + lastRange[0] as f32, lastY as f32, )); } else { return Ok(RXingResultPoint::new( - lastRange.unwrap()[1] as f32, + lastRange[1] as f32, lastY as f32, )); } } else { let lastX = x - deltaX; - if lastRange.unwrap()[0] < centerY { - if lastRange.unwrap()[1] > centerY { + if lastRange[0] < centerY { + if lastRange[1] > centerY { return Ok(RXingResultPoint::new( lastX as f32, - lastRange.unwrap()[if deltaX < 0 { 0 } else { 1 }] as f32, + lastRange[if deltaX < 0 { 0 } else { 1 }] as f32, )); } return Ok(RXingResultPoint::new( lastX as f32, - lastRange.unwrap()[0] as f32, + lastRange[0] as f32, )); } else { return Ok(RXingResultPoint::new( lastX as f32, - lastRange.unwrap()[1] as f32, + lastRange[1] as f32, )); } } + }}else { + return Err(NotFoundException {}); } - lastRange = range; + lastRange_z = range; y += deltaY; x += deltaX } @@ -246,28 +246,28 @@ impl MonochromeRectangleDetector { let center = (minDim + maxDim) / 2; // Scan left/up first - let start = center; + let mut start = center; while (start >= minDim) { - if (if horizontal { - self.image.get(start, fixedDimension) + if if horizontal { + self.image.get(start as u32, fixedDimension as u32) } else { - self.image.get(fixedDimension, start) - }) { + self.image.get(fixedDimension as u32, start as u32) + } { start = start - 1; } else { let whiteRunStart = start; start = start - 1; while start >= minDim && !(if horizontal { - self.image.get(start, fixedDimension) + self.image.get(start as u32, fixedDimension as u32) } else { - self.image.get(fixedDimension, start) + self.image.get(fixedDimension as u32, start as u32) }) { start = start - 1; } let whiteRunSize = whiteRunStart - start; - if (start < minDim || whiteRunSize > maxWhiteRun) { + if start < minDim || whiteRunSize > maxWhiteRun { start = whiteRunStart; break; } @@ -276,28 +276,28 @@ impl MonochromeRectangleDetector { start = start + 1; // Then try right/down - let end = center; + let mut end = center; while (end < maxDim) { - if (if horizontal { - self.image.get(end, fixedDimension) + if if horizontal { + self.image.get(end as u32, fixedDimension as u32) } else { - self.image.get(fixedDimension, end) - }) { + self.image.get(fixedDimension as u32, end as u32) + } { end = end + 1; } else { let whiteRunStart = end; end = end + 1; while end < maxDim && !(if horizontal { - self.image.get(end, fixedDimension) + self.image.get(end as u32, fixedDimension as u32) } else { - self.image.get(fixedDimension, end) + self.image.get(fixedDimension as u32, end as u32) }) { end = end + 1; } let whiteRunSize = end - whiteRunStart; - if (end >= maxDim || whiteRunSize > maxWhiteRun) { + if end >= maxDim || whiteRunSize > maxWhiteRun { end = whiteRunStart; break; } @@ -358,8 +358,8 @@ impl WhiteRectangleDetector { Self::new( image, INIT_SIZE, - image.getWidth() / 2, - image.getHeight() / 2, + image.getWidth() as i32 / 2, + image.getHeight() as i32 / 2, ) } @@ -376,24 +376,31 @@ impl WhiteRectangleDetector { x: i32, y: i32, ) -> Result { - let new_wrd: Self; - new_wrd.image = image; - new_wrd.height = image.getHeight(); - new_wrd.width = image.getWidth(); + let halfsize = initSize / 2; - new_wrd.leftInit = x - halfsize; - new_wrd.rightInit = x + halfsize; - new_wrd.upInit = y - halfsize; - new_wrd.downInit = y + halfsize; - if new_wrd.upInit < 0 - || new_wrd.leftInit < 0 - || new_wrd.downInit >= new_wrd.height - || new_wrd.rightInit >= new_wrd.width + + let leftInit = x - halfsize; + let rightInit = x + halfsize; + let upInit = y - halfsize; + let downInit = y + halfsize; + + if upInit < 0 + || leftInit < 0 + || downInit >= image.getHeight() as i32 + || rightInit >= image.getWidth() as i32 { return Err(NotFoundException {}); } - Ok(new_wrd) + Ok(Self{ + image: image.clone(), + height: image.getHeight() as i32, + width: image.getWidth() as i32, + leftInit: leftInit, + rightInit: rightInit, + downInit: downInit, + upInit: upInit, + }) } /** @@ -411,17 +418,17 @@ impl WhiteRectangleDetector { * @throws NotFoundException if no Data Matrix Code can be found */ pub fn detect(&self) -> Result, NotFoundException> { - let left: i32 = self.leftInit; - let right: i32 = self.rightInit; - let up: i32 = self.upInit; - let down: i32 = self.downInit; - let sizeExceeded = false; - let aBlackPointFoundOnBorder = true; + let mut left: i32 = self.leftInit; + let mut right: i32 = self.rightInit; + let mut up: i32 = self.upInit; + let mut down: i32 = self.downInit; + let mut sizeExceeded = false; + let mut aBlackPointFoundOnBorder = true; - let atLeastOneBlackPointFoundOnRight = false; - let atLeastOneBlackPointFoundOnBottom = false; - let atLeastOneBlackPointFoundOnLeft = false; - let atLeastOneBlackPointFoundOnTop = false; + let mut atLeastOneBlackPointFoundOnRight = false; + let mut atLeastOneBlackPointFoundOnBottom = false; + let mut atLeastOneBlackPointFoundOnLeft = false; + let mut atLeastOneBlackPointFoundOnTop = false; while aBlackPointFoundOnBorder { aBlackPointFoundOnBorder = false; @@ -429,7 +436,7 @@ impl WhiteRectangleDetector { // ..... // . | // ..... - let rightBorderNotWhite = true; + let mut rightBorderNotWhite = true; while (rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < self.width { rightBorderNotWhite = self.containsBlackPoint(up, down, right, false); if rightBorderNotWhite { @@ -449,7 +456,7 @@ impl WhiteRectangleDetector { // ..... // . . // .___. - let bottomBorderNotWhite = true; + let mut bottomBorderNotWhite = true; while (bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < self.height { bottomBorderNotWhite = self.containsBlackPoint(left, right, down, true); @@ -470,7 +477,7 @@ impl WhiteRectangleDetector { // ..... // | . // ..... - let leftBorderNotWhite = true; + let mut leftBorderNotWhite = true; while (leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0 { leftBorderNotWhite = self.containsBlackPoint(up, down, left, false); if leftBorderNotWhite { @@ -490,7 +497,7 @@ impl WhiteRectangleDetector { // .___. // . . // ..... - let topBorderNotWhite = true; + let mut topBorderNotWhite = true; while (topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0 { topBorderNotWhite = self.containsBlackPoint(left, right, up, true); if topBorderNotWhite { @@ -596,13 +603,13 @@ impl WhiteRectangleDetector { bY: f32, ) -> Option { let dist = MathUtils::round(MathUtils::distance_float(aX, aY, bX, bY)); - let xStep: f32 = (bX - aX) / dist.into(); - let yStep: f32 = (bY - aY) / dist.into(); + let xStep: f32 = (bX - aX) / dist as f32; + let yStep: f32 = (bY - aY) / dist as f32; for i in 0..dist { - let x = MathUtils::round(aX + i.into() * xStep); - let y = MathUtils::round(aY + i.into() * yStep); - if self.image.get(x, y) { + let x = MathUtils::round(aX + i as f32 * xStep); + let y = MathUtils::round(aY + i as f32 * yStep); + if self.image.get(x as u32, y as u32) { return Some(RXingResultPoint::new(x as f32, y as f32)); } } @@ -674,13 +681,13 @@ impl WhiteRectangleDetector { fn containsBlackPoint(&self, a: i32, b: i32, fixed: i32, horizontal: bool) -> bool { if horizontal { for x in a..=b { - if self.image.get(x, fixed) { + if self.image.get(x as u32, fixed as u32) { return true; } } } else { for y in a..=b { - if self.image.get(fixed, y) { + if self.image.get(fixed as u32, y as u32) { return true; } } diff --git a/src/common/mod.rs b/src/common/mod.rs index a44a5e7..cbf12f2 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -380,7 +380,7 @@ impl BitArray { return self.size; } let bitsOffset = from / 32; - let currentBits = self.bits[bitsOffset]; + let mut currentBits = self.bits[bitsOffset] as i32; // mask off lesser bits first currentBits &= -(1 << (from & 0x1F)); while currentBits == 0 { @@ -388,7 +388,7 @@ impl BitArray { if bitsOffset == self.bits.len() { return self.size; } - currentBits = self.bits[bitsOffset]; + currentBits = self.bits[bitsOffset] as i32; } let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize; cmp::min(result, self.size) @@ -404,15 +404,15 @@ impl BitArray { return self.size; } let bitsOffset = from / 32; - let currentBits = !self.bits[bitsOffset]; + let currentBits = !self.bits[bitsOffset] as i32; // mask off lesser bits first - currentBits &= -(1 << (from & 0x1F)); + currentBits &= -(1 << (from & 0x1F)) ; while currentBits == 0 { bitsOffset += 1; if bitsOffset == self.bits.len() { return self.size; } - currentBits = !self.bits[bitsOffset]; + currentBits = !self.bits[bitsOffset] as i32; } let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize; return cmp::min(result, self.size); @@ -836,14 +836,17 @@ impl BitMatrix { let bits = Vec::with_capacity(stringRepresentation.len()); let bitsPos = 0; let rowStartPos = 0; - let rowLength = -1; + let rowLength = 0;//-1; + let mut first_run = true; let nRows = 0; let pos = 0; while pos < stringRepresentation.len() { - if stringRepresentation.charAt(pos) == '\n' || stringRepresentation.charAt(pos) == '\r' + if stringRepresentation.chars().nth(pos).unwrap() == '\n' || stringRepresentation.chars().nth(pos).unwrap() == '\r' { if bitsPos > rowStartPos { - if rowLength == -1 { + //if rowLength == -1 { + if first_run { + first_run = false; rowLength = bitsPos - rowStartPos; } else if bitsPos - rowStartPos != rowLength { return Err(IllegalArgumentException::new("row lengths do not match")); @@ -852,25 +855,27 @@ impl BitMatrix { nRows += 1; } pos += 1; - } else if stringRepresentation.startsWith(setString, pos) { + } else if stringRepresentation[pos..].starts_with(setString) { pos += setString.len(); bits[bitsPos] = true; bitsPos += 1; - } else if stringRepresentation.startsWith(unsetString, pos) { + } else if stringRepresentation[pos..].starts_with(unsetString) { pos += unsetString.len(); bits[bitsPos] = false; bitsPos += 1; } else { return Err(IllegalArgumentException::new(&format!( "illegal character encountered: {}", - stringRepresentation.substring(pos) + stringRepresentation[pos..].to_owned() ))); } } // no EOL at end? if bitsPos > rowStartPos { - if rowLength == -1 { + //if rowLength == -1 { + if first_run { + first_run = false; rowLength = bitsPos - rowStartPos; } else if bitsPos - rowStartPos != rowLength { return Err(IllegalArgumentException::new("row lengths do not match")); @@ -878,14 +883,14 @@ impl BitMatrix { nRows += 1; } - let matrix = BitMatrix::new(rowLength, nRows); + let matrix = BitMatrix::new(rowLength.try_into().unwrap(), nRows)?; for i in 0..bitsPos { //for (int i = 0; i < bitsPos; i++) { if bits[i] { - matrix.set(i % rowLength, i / rowLength); + matrix.set((i % rowLength).try_into().unwrap(), (i / rowLength).try_into().unwrap()); } } - return matrix; + return Ok(matrix); } /** @@ -896,7 +901,7 @@ impl BitMatrix { * @return value of given bit in matrix */ pub fn get(&self, x: u32, y: u32) -> bool { - let offset = y * self.rowSize + (x / 32); + let offset = y as usize * self.rowSize + (x as usize / 32); return ((self.bits[offset] >> (x & 0x1f)) & 1) != 0; } @@ -907,12 +912,12 @@ impl BitMatrix { * @param y The vertical component (i.e. which row) */ pub fn set(&self, x: u32, y: u32) { - let offset = y * self.rowSize + (x / 32); + let offset = y as usize * self.rowSize + (x as usize / 32); self.bits[offset] |= 1 << (x & 0x1f); } pub fn unset(&self, x: u32, y: u32) { - let offset = y * self.rowSize + (x / 32); + let offset = y as usize * self.rowSize + (x as usize / 32); self.bits[offset] &= !(1 << (x & 0x1f)); } @@ -923,7 +928,7 @@ impl BitMatrix { * @param y The vertical component (i.e. which row) */ pub fn flip_coords(&self, x: u32, y: u32) { - let offset = y * self.rowSize + (x / 32); + let offset = y as usize * self.rowSize + (x as usize / 32); self.bits[offset] ^= 1 << (x & 0x1f); } @@ -950,11 +955,11 @@ impl BitMatrix { "input matrix dimensions do not match", )); } - let rowArray = BitArray::with_size(self.width); + let rowArray = BitArray::with_size(self.width as usize); for y in 0..self.height { //for (int y = 0; y < height; y++) { - let offset = y * self.rowSize; - let row = mask.getRow(y, self.rowArray).getBitArray(); + let offset = y as usize * self.rowSize; + let row = mask.getRow(y, &rowArray).getBitArray(); for x in 0..self.rowSize { //for (int x = 0; x < rowSize; x++) { self.bits[offset + x] ^= row[x]; @@ -1008,10 +1013,10 @@ impl BitMatrix { } for y in top..bottom { //for (int y = top; y < bottom; y++) { - let offset = y * self.rowSize; + let offset = y as usize* self.rowSize; for x in left..right { //for (int x = left; x < right; x++) { - self.bits[offset + (x / 32)] |= 1 << (x & 0x1f); + self.bits[offset + (x as usize / 32)] |= 1 << (x & 0x1f); } } Ok(()) @@ -1026,14 +1031,14 @@ impl BitMatrix { * your own row */ pub fn getRow(&self, y: u32, row: &BitArray) -> BitArray { - let rw: BitArray = if row.getSize() < self.width as u32 { + let rw: BitArray = if row.getSize() < self.width as usize { BitArray::with_size(self.width as usize) } else { row.clear(); *row }; - let offset = y * self.rowSize; + let offset = y as usize * self.rowSize; for x in 0..self.rowSize { //for (int x = 0; x < rowSize; x++) { rw.setBulk(x * 32, self.bits[offset + x]); @@ -1046,7 +1051,7 @@ impl BitMatrix { * @param row {@link BitArray} to copy from */ pub fn setRow(&self, y: u32, row: &BitArray) { - return self.bits[y * self.rowSize..self.rowSize] + return self.bits[y as usize* self.rowSize..self.rowSize] .clone_from_slice(&row.getBitArray()[0..self.rowSize]); //System.arraycopy(row.getBitArray(), 0, self.bits, y * self.rowSize, self.rowSize); } @@ -1110,16 +1115,16 @@ impl BitMatrix { //for (int y = 0; y < height; y++) { for x in 0..self.width { //for (int x = 0; x < width; x++) { - let offset = y * self.rowSize + (x / 32); + let offset = y as usize * self.rowSize + (x as usize / 32); if ((self.bits[offset] >> (x & 0x1f)) & 1) != 0 { - let newOffset = (newHeight - 1 - x) * newRowSize + (y / 32); + let newOffset:usize = ((newHeight - 1 - x) * newRowSize + (y / 32)).try_into().unwrap(); newBits[newOffset] |= 1 << (y & 0x1f); } } } self.width = newWidth; self.height = newHeight; - self.rowSize = newRowSize; + self.rowSize = newRowSize.try_into().unwrap(); self.bits = newBits; } @@ -1131,14 +1136,16 @@ impl BitMatrix { pub fn getEnclosingRectangle(&self) -> Option> { let left = self.width; let top = self.height; - let right = -1; - let bottom = -1; + // let right = -1; + // let bottom = -1; + let right:u32 = 0; + let bottom = 0; for y in 0..self.height { //for (int y = 0; y < height; y++) { for x32 in 0..self.rowSize { //for (int x32 = 0; x32 < rowSize; x32++) { - let theBits = self.bits[y * self.rowSize + x32]; + let theBits = self.bits[y as usize * self.rowSize + x32]; if theBits != 0 { if y < top { top = y; @@ -1146,22 +1153,22 @@ impl BitMatrix { if y > bottom { bottom = y; } - if x32 * 32 < left { + if x32 * 32 < left.try_into().unwrap() { let bit = 0; while (theBits << (31 - bit)) == 0 { bit += 1; } - if (x32 * 32 + bit) < left { - left = x32 * 32 + bit; + if (x32 * 32 + bit) < left.try_into().unwrap() { + left = (x32 * 32 + bit).try_into().unwrap(); } } - if x32 * 32 + 31 > right { + if x32 * 32 + 31 > right.try_into().unwrap() { let bit = 31; while (theBits >> bit) == 0 { bit -= 1; } - if (x32 * 32 + bit) > right { - right = x32 * 32 + bit; + if (x32 * 32 + bit) > right.try_into().unwrap() { + right =( x32 * 32 + bit).try_into().unwrap(); } } } @@ -1197,7 +1204,7 @@ impl BitMatrix { bit += 1; } x += bit; - return Some(vec![x, y]); + return Some(vec![x as u32, y as u32]); } pub fn getBottomRightOnBit(&self) -> Option> { @@ -1219,7 +1226,7 @@ impl BitMatrix { } x += bit; - return Some(vec![x, y]); + return Some(vec![x as u32, y as u32]); } /** @@ -1533,6 +1540,6 @@ impl BitSource { * @return number of bits that can be read successfully */ pub fn available(&self) -> usize { - return (8 * (self.bytes.len() - self.byteOffset) - self.bitOffset); + return 8 * (self.bytes.len() - self.byteOffset) - self.bitOffset; } } diff --git a/src/common/reedsolomon/ReedSolomonTestCase.rs b/src/common/reedsolomon/ReedSolomonTestCase.rs index 9cd6d7b..c32894a 100644 --- a/src/common/reedsolomon/ReedSolomonTestCase.rs +++ b/src/common/reedsolomon/ReedSolomonTestCase.rs @@ -38,18 +38,18 @@ const DECODER_TEST_ITERATIONS: i32 = 10; fn testDataMatrix() { // real life test cases testEncodeDecode( - super::DATA_MATRIX_FIELD_256, - vec![142, 164, 186], - vec![114, 25, 5, 88, 102], + &super::DATA_MATRIX_FIELD_256, + &vec![142, 164, 186], + &vec![114, 25, 5, 88, 102], ); testEncodeDecode( - super::DATA_MATRIX_FIELD_256, - vec![ + &super::DATA_MATRIX_FIELD_256, + &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, 0x6F, 0x68, 0x30, 0x81, 0xF0, 0x88, 0x1F, 0xB5, ], - vec![ + &vec![ 0x1C, 0x64, 0xEE, 0xEB, 0xD0, 0x1D, 0x00, 0x03, 0xF0, 0x1C, 0xF1, 0xD0, 0x6D, 0x00, 0x98, 0xDA, 0x80, 0x88, 0xBE, 0xFF, 0xB7, 0xFA, 0xA9, 0x95, ], @@ -64,21 +64,21 @@ fn testDataMatrix() { fn testQRCode() { // Test case from example given in ISO 18004, Annex I testEncodeDecode( - super::QR_CODE_FIELD_256, - vec![ + &super::QR_CODE_FIELD_256, + &vec![ 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, ], - vec![0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87, 0x2C, 0x55], + &vec![0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87, 0x2C, 0x55], ); testEncodeDecode( - super::QR_CODE_FIELD_256, - vec![ + &super::QR_CODE_FIELD_256, + &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, 0xEC, 0x11, 0xEC, 0x11, ], - vec![ + &vec![ 0xD8, 0xB8, 0xEF, 0x14, 0xEC, 0xD0, 0xCC, 0x85, 0x73, 0x40, 0x0B, 0xB5, 0x5A, 0xB8, 0x8B, 0x2E, 0x08, 0x62, ], @@ -94,35 +94,35 @@ fn testQRCode() { fn testAztec() { // real life test cases testEncodeDecode( - super::AZTEC_PARAM, - vec![0x5, 0x6], - vec![0x3, 0x2, 0xB, 0xB, 0x7], + &super::AZTEC_PARAM, + &vec![0x5, 0x6], + &vec![0x3, 0x2, 0xB, 0xB, 0x7], ); testEncodeDecode( - super::AZTEC_PARAM, - vec![0x0, 0x0, 0x0, 0x9], - vec![0xA, 0xD, 0x8, 0x6, 0x5, 0x6], + &super::AZTEC_PARAM, + &vec![0x0, 0x0, 0x0, 0x9], + &vec![0xA, 0xD, 0x8, 0x6, 0x5, 0x6], ); testEncodeDecode( - super::AZTEC_PARAM, - vec![0x2, 0x8, 0x8, 0x7], - vec![0xE, 0xC, 0xA, 0x9, 0x6, 0x8], + &super::AZTEC_PARAM, + &vec![0x2, 0x8, 0x8, 0x7], + &vec![0xE, 0xC, 0xA, 0x9, 0x6, 0x8], ); testEncodeDecode( - super::AZTEC_DATA_6, - vec![0x9, 0x32, 0x1, 0x29, 0x2F, 0x2, 0x27, 0x25, 0x1, 0x1B], - vec![0x2C, 0x2, 0xD, 0xD, 0xA, 0x16, 0x28, 0x9, 0x22, 0xA, 0x14], + &super::AZTEC_DATA_6, + &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, - vec![ + &super::AZTEC_DATA_8, + &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, 0xCA, 0x74, 0xAD, 0xAF, 0x8C, 0xEB, 0x7C, 0x10, 0xC8, 0x53, 0x1D, 0x09, 0x52, 0xD8, 0xD7, 0x3E, 0x11, 0x94, 0xE9, 0x5B, 0x5F, 0x19, 0xD6, 0xFB, 0xD1, 0x0C, 0x85, 0x31, 0xD0, 0x95, 0x2D, 0x8D, 0x73, 0xE1, 0x19, 0x4E, 0x95, 0xB5, 0xF1, 0x9D, 0x6F, ], - vec![ + &vec![ 0x31, 0xD7, 0x04, 0x46, 0xB2, 0xC1, 0x06, 0x94, 0x17, 0xE5, 0x0C, 0x2B, 0xA3, 0x99, 0x15, 0x7F, 0x16, 0x3C, 0x66, 0xBA, 0x33, 0xD9, 0xE8, 0x87, 0x86, 0xBB, 0x4B, 0x15, 0x4E, 0x4A, 0xDE, 0xD4, 0xED, 0xA1, 0xF8, 0x47, 0x2A, 0x50, 0xA6, 0xBC, 0x53, 0x7D, @@ -130,8 +130,8 @@ fn testAztec() { ], ); testEncodeDecode( - super::AZTEC_DATA_10, - vec![ + &super::AZTEC_DATA_10, + &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, 0x036, 0x1AD, 0x04E, 0x090, 0x271, 0x0D3, 0x02E, 0x0D5, 0x2D4, 0x032, 0x2CA, 0x281, @@ -161,7 +161,7 @@ fn testAztec() { 0x201, 0x0AA, 0x04E, 0x004, 0x1B0, 0x070, 0x275, 0x154, 0x026, 0x2C1, 0x2B3, 0x154, 0x2AA, 0x256, 0x0C1, 0x044, 0x004, 0x23F, ], - vec![ + &vec![ 0x379, 0x099, 0x348, 0x010, 0x090, 0x196, 0x09C, 0x1FF, 0x1B0, 0x32D, 0x244, 0x0DE, 0x201, 0x386, 0x163, 0x11F, 0x39B, 0x344, 0x3FE, 0x02F, 0x188, 0x113, 0x3D9, 0x102, 0x04A, 0x2E1, 0x1D1, 0x18E, 0x077, 0x262, 0x241, 0x20D, 0x1B8, 0x11D, 0x0D0, 0x0A5, @@ -177,8 +177,8 @@ fn testAztec() { ], ); testEncodeDecode( - super::AZTEC_DATA_12, - vec![ + &super::AZTEC_DATA_12, + &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, 0x4D3, 0x0B8, 0xD5B, 0x503, 0x2B2, 0xA81, 0x2A8, 0x4E0, 0x92D, 0x3A5, 0xA81, 0x388, @@ -283,7 +283,7 @@ fn testAztec() { 0x10C, 0x835, 0x429, 0x33C, 0xB33, 0x4D5, 0x509, 0xCCD, 0x550, 0x35B, 0x4E2, 0xAA0, 0x5E6, 0x205, 0xB09, 0x99C, 0x09F, ], - vec![ + &vec![ 0xD54, 0x221, 0x154, 0x7CD, 0xBF3, 0x112, 0x89B, 0xC5E, 0x9CD, 0x07E, 0xFB6, 0x78F, 0x7FA, 0x16F, 0x377, 0x4B4, 0x62D, 0x475, 0xBC2, 0x861, 0xB72, 0x9D0, 0x76A, 0x5A1, 0x22A, 0xF74, 0xDBA, 0x8B1, 0x139, 0xDCD, 0x012, 0x293, 0x705, 0xA34, 0xDD5, 0x3D2, @@ -335,11 +335,11 @@ fn testAztec() { testEncodeDecodeRandom(super::AZTEC_DATA_12, 3072, 1023); } -fn corrupt(received: &mut Vec, howMany: i32, random: &rand::rngs::ThreadRng, max: i32) { - let corrupted = vec![false; received.len()]; +fn corrupt(received: &mut Vec, howMany: i32, random: &mut rand::rngs::ThreadRng, max: i32) { + let mut corrupted = vec![false; received.len()]; //BitSet corrupted = new BitSet(received.length); let mut skip = false; - for j in 0..howMany { + for _j in 0..howMany { //for (int j = 0; j < howMany; j++) { if skip { skip = false; @@ -367,17 +367,17 @@ fn testEncodeDecodeRandom(field: GenericGF, dataSize: usize, ecSize: usize) { "Invalid ECC size for {}", field ); - let encoder = ReedSolomonEncoder::new(Box::new(field)); - let message = Vec::with_capacity(dataSize + ecSize); - let dataWords: Vec = Vec::with_capacity(dataSize); - let ecWords = Vec::with_capacity(ecSize); - let random = getPseudoRandom(); + let encoder = ReedSolomonEncoder::new(Box::new(field.clone())); + let mut message = Vec::with_capacity(dataSize + ecSize); + let mut dataWords: Vec = Vec::with_capacity(dataSize); + let mut ecWords = Vec::with_capacity(ecSize); + let mut random = getPseudoRandom(); let iterations = if field.getSize() > 256 { 1 } else { DECODER_RANDOM_TEST_ITERATIONS }; - for i in 0..iterations { + for _i in 0..iterations { //for (int i = 0; i < iterations; i++) { // generate random data for k in 0..dataSize { @@ -391,19 +391,19 @@ fn testEncodeDecodeRandom(field: GenericGF, dataSize: usize, ecSize: usize) { ecWords[0..ecSize].clone_from_slice(&message[dataSize..ecSize]); //System.arraycopy(message, dataSize, ecWords, 0, ecSize); // check to see if Decoder can fix up to ecWords/2 random errors - testDecoder(field, dataWords, ecWords); + testDecoder(&field, &dataWords, &ecWords); } } -fn testEncodeDecode(field: GenericGF, dataWords: Vec, ecWords: Vec) { +fn testEncodeDecode(field: &GenericGF, dataWords: &Vec, ecWords: &Vec) { testEncoder(field, dataWords, ecWords); testDecoder(field, dataWords, ecWords); } -fn testEncoder(field: GenericGF, dataWords: Vec, ecWords: Vec) { - let encoder = ReedSolomonEncoder::new(Box::new(field)); - let messageExpected = Vec::with_capacity(dataWords.len() + ecWords.len()); - let message = Vec::with_capacity(dataWords.len() + ecWords.len()); +fn testEncoder(field: &GenericGF, dataWords: &Vec, ecWords: &Vec) { + let encoder = ReedSolomonEncoder::new(Box::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()]); //System.arraycopy(dataWords, 0, messageExpected, 0, dataWords.len()); messageExpected[dataWords.len()..ecWords.len()].clone_from_slice(&ecWords[..ecWords.len()]); @@ -418,24 +418,24 @@ fn testEncoder(field: GenericGF, dataWords: Vec, ecWords: Vec) { dataWords.len(), ecWords.len() ), - messageExpected, - message, + &messageExpected, + &message, ); } -fn testDecoder(field: GenericGF, dataWords: Vec, ecWords: Vec) { - let decoder = ReedSolomonDecoder::new(field); - let message = Vec::with_capacity(dataWords.len() + ecWords.len()); +fn testDecoder(field: &GenericGF, dataWords: &Vec, ecWords: &Vec) { + let decoder = ReedSolomonDecoder::new(field.clone()); + let mut message = Vec::with_capacity(dataWords.len() + ecWords.len()); let maxErrors = ecWords.len() / 2; - let random = getPseudoRandom(); + let mut random = getPseudoRandom(); let iterations = if field.getSize() > 256 { 1 } else { DECODER_TEST_ITERATIONS }; - for j in 0..iterations { + for _j in 0..iterations { //for (int j = 0; j < iterations; j++) { - for i in 0..ecWords.len() { + for mut i in 0..ecWords.len() { //for (int i = 0; i < ecWords.length; i++) { if i > 10 && i < ecWords.len() / 2 - 10 { // performance improvement - skip intermediate cases in long-running tests @@ -448,7 +448,7 @@ fn testDecoder(field: GenericGF, dataWords: Vec, ecWords: Vec) { corrupt( &mut message, i.try_into().unwrap(), - &random, + &mut random, field.getSize().try_into().unwrap(), ); @@ -489,15 +489,15 @@ fn testDecoder(field: GenericGF, dataWords: Vec, ecWords: Vec) { ecWords.len(), i ), - dataWords, - message, + &dataWords, + &message, ); } } } } -fn assertDataEquals(message: String, expected: Vec, received: Vec) { +fn assertDataEquals(message: String, expected: &Vec, received: &Vec) { for i in 0..expected.len() { //for (int i = 0; i < expected.length; i++) { if expected[i] != received[i] { @@ -514,7 +514,7 @@ fn assertDataEquals(message: String, expected: Vec, received: Vec) { } fn arrayToString(data: &[i32]) -> String { - let sb = String::from("{"); + let mut sb = String::from("{"); for i in 0..data.len() { //for (int i = 0; i < data.length; i++) { //sb.append(String.format(i > 0 ? ",%X" : "%X", data[i])); diff --git a/src/common/reedsolomon/mod.rs b/src/common/reedsolomon/mod.rs index a2ea10a..7fa630a 100644 --- a/src/common/reedsolomon/mod.rs +++ b/src/common/reedsolomon/mod.rs @@ -89,12 +89,12 @@ pub const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6; * @author Sean Owen * @author David Olivier */ -#[derive(Debug)] +#[derive(Debug,Clone)] pub struct GenericGF { expTable: Vec, logTable: Vec, - zero: Box, - one: Box, + // zero: Box, + // one: Box, size: usize, primitive: i32, generatorBase: i32, @@ -125,18 +125,12 @@ impl GenericGF { * In most cases it should be 1, but for QR code it is 0. */ pub fn new(primitive: i32, size: usize, b: i32) -> Self { - let mut new_ggf: Self; - - new_ggf.primitive = primitive; - new_ggf.size = size; - new_ggf.generatorBase = b; - - new_ggf.expTable = Vec::with_capacity(size); - new_ggf.logTable = Vec::with_capacity(size); + let mut expTable = Vec::with_capacity(size); + let mut logTable = Vec::with_capacity(size); let mut x = 1; for i in 0..size { //for (int i = 0; i < size; i++) { - new_ggf.expTable[i] = x; + expTable[i] = x; x *= 2; // we're assuming the generator alpha is 2 if x >= size.try_into().unwrap() { x ^= primitive; @@ -146,35 +140,43 @@ impl GenericGF { } for i in 0..size { //for (int i = 0; i < size - 1; i++) { - let loc: usize = new_ggf.expTable[i].try_into().unwrap(); - new_ggf.logTable[loc] = i.try_into().unwrap(); + let loc: usize = expTable[i].try_into().unwrap(); + logTable[loc] = i.try_into().unwrap(); + } + + Self { + expTable, + logTable, + size, + primitive, + generatorBase: b, } // 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.one = Box::new(GenericGFPoly::new(Box::new(new_ggf), &vec![1]).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 + //new_ggf } - pub fn getZero(&self) -> Box { - return self.zero; - } + // pub fn getZero(&self) -> Box { + // return self.zero; + // } - pub fn getOne(&self) -> Box { - return self.one; - } + // pub fn getOne(&self) -> Box { + // return self.one; + // } /** * @return the monomial representing coefficient * x^degree */ - pub fn buildMonomial(&self, degree: usize, coefficient: i32) -> Box { + pub fn buildMonomial(&self, degree: usize, coefficient: i32) -> GenericGFPoly { if coefficient == 0 { - return self.zero; + return GenericGFPoly::new(self.clone(), &vec![0]).unwrap(); } - let coefficients = Vec::with_capacity(degree + 1); + let mut coefficients = Vec::with_capacity(degree + 1); coefficients[0] = coefficient; - return Box::new(GenericGFPoly::new(Box::new(*self), &coefficients).unwrap()); + return GenericGFPoly::new(self.clone(), &coefficients).unwrap(); } /** @@ -276,9 +278,9 @@ impl fmt::Display for GenericGF { * * @author Sean Owen */ -#[derive(Debug)] +#[derive(Debug,Clone)] pub struct GenericGFPoly { - field: Box, + field: GenericGF, coefficients: Vec, } @@ -300,7 +302,7 @@ impl GenericGFPoly { * constant polynomial (that is, it is not the monomial "0") */ pub fn new( - field: Box, + field: GenericGF, coefficients: &Vec, ) -> Result { if coefficients.len() == 0 { @@ -321,8 +323,9 @@ impl GenericGFPoly { } else { let mut new_coefficients = Vec::with_capacity(coefficientsLength - firstNonZero); - new_coefficients[0..new_coefficients.len()] - .clone_from_slice(&coefficients[firstNonZero..new_coefficients.len()]); + let l = new_coefficients.len(); + new_coefficients[0..l] + .clone_from_slice(&coefficients[firstNonZero..l]); // System.arraycopy(coefficients, // firstNonZero, // this.coefficients, @@ -337,8 +340,8 @@ impl GenericGFPoly { }) } - pub fn getCoefficients(&self) -> Vec { - return self.coefficients; + pub fn getCoefficients(&self) -> &Vec { + return &self.coefficients; } /** @@ -373,9 +376,9 @@ impl GenericGFPoly { if a == 1 { // Just the sum of the coefficients let mut result = 0; - for coefficient in self.coefficients { + for coefficient in &self.coefficients { //for (int coefficient : coefficients) { - result = GenericGF::addOrSubtract(result, coefficient); + result = GenericGF::addOrSubtract(result, *coefficient); } return result; } @@ -396,22 +399,22 @@ impl GenericGFPoly { pub fn addOrSubtract( &self, - other: Box, - ) -> Result, IllegalArgumentException> { + other: &GenericGFPoly, + ) -> Result { if self.field != other.field { return Err(IllegalArgumentException::new( "GenericGFPolys do not have same GenericGF field", )); } if self.isZero() { - return Ok(other); + return Ok(other.clone()); } if other.isZero() { - return Ok(Box::new(*self)); + return Ok(self.clone()); } - let mut smallerCoefficients = self.coefficients; - let mut largerCoefficients = other.coefficients; + let mut smallerCoefficients = self.coefficients.clone(); + let mut largerCoefficients = other.coefficients.clone(); if smallerCoefficients.len() > largerCoefficients.len() { let temp = smallerCoefficients; smallerCoefficients = largerCoefficients; @@ -432,13 +435,13 @@ impl GenericGFPoly { ); } - return Ok(Box::new(GenericGFPoly::new(self.field, &sumDiff)?)); + return Ok(GenericGFPoly::new(self.field.clone(), &sumDiff)?); } pub fn multiply( &self, other: &GenericGFPoly, - ) -> Result, IllegalArgumentException> { + ) -> Result { if self.field != other.field { //if (!field.equals(other.field)) { return Err(IllegalArgumentException::new( @@ -446,13 +449,13 @@ impl GenericGFPoly { )); } if self.isZero() || other.isZero() { - return Ok(self.field.getZero()); + return Ok(self.getZero()); } - let aCoefficients = self.coefficients; + let aCoefficients = self.coefficients.clone(); let aLength = aCoefficients.len(); - let bCoefficients = other.coefficients; + let bCoefficients = other.coefficients.clone(); let bLength = bCoefficients.len(); - let product = Vec::with_capacity(aLength + bLength - 1); + let mut product = Vec::with_capacity(aLength + bLength - 1); for i in 0..aLength { //for (int i = 0; i < aLength; i++) { let aCoeff = aCoefficients[i]; @@ -470,52 +473,60 @@ impl GenericGFPoly { ); } } - return Ok(Box::new(GenericGFPoly::new(self.field, &product)?)); + return Ok(GenericGFPoly::new(self.field.clone(), &product)?); } - pub fn multiply_with_scalar(&self, scalar: i32) -> Box { + pub fn multiply_with_scalar(&self, scalar: i32) -> GenericGFPoly { if scalar == 0 { - return self.field.getZero(); + return self.getZero(); } if scalar == 1 { - return Box::new(*self); + return self.clone(); } let size = self.coefficients.len(); - let product = Vec::with_capacity(size); + let mut product = Vec::with_capacity(size); for i in 0..size { //for (int i = 0; i < size; i++) { product[i] = self .field .multiply(self.coefficients[i], scalar.try_into().unwrap()); } - return Box::new(GenericGFPoly::new(self.field, &product).unwrap()); + return GenericGFPoly::new(self.field.clone(), &product).unwrap(); + } + + pub fn getZero(&self) -> Self{ + GenericGFPoly::new(self.field.clone(), &vec![0]).unwrap() + } + + pub fn getOne(&self) -> Self{ + GenericGFPoly::new(self.field.clone(), &vec![1]).unwrap() } pub fn multiplyByMonomial( &self, degree: usize, coefficient: i32, - ) -> Result, IllegalArgumentException> { + ) -> Result { if degree < 0 { return Err(IllegalArgumentException::new("")); } if coefficient == 0 { - return Ok(self.field.getZero()); + return Ok(self.getZero()); } let size = self.coefficients.len(); - let product = Vec::with_capacity(size + degree); + let mut product = Vec::with_capacity(size + degree); for i in 0..size { //for (int i = 0; i < size; i++) { product[i] = self.field.multiply(self.coefficients[i], coefficient); } - return Ok(Box::new(GenericGFPoly::new(self.field, &product)?)); + return Ok(GenericGFPoly::new(self.field.clone(), &product)?); } pub fn divide( &self, other: &GenericGFPoly, - ) -> Result>, IllegalArgumentException> { + ) -> Result, IllegalArgumentException> { if self.field != other.field { //if (!field.equals(other.field)) { return Err(IllegalArgumentException::new( @@ -526,8 +537,8 @@ impl GenericGFPoly { return Err(IllegalArgumentException::new("Divide by 0")); } - let mut quotient = self.field.getZero(); - let mut remainder = self; + let mut quotient = self.getZero(); + let mut remainder = self.clone(); let denominatorLeadingTerm = other.getCoefficient(other.getDegree()); let inverseDenominatorLeadingTerm = match self.field.inverse(denominatorLeadingTerm) { @@ -543,11 +554,11 @@ impl GenericGFPoly { ); let term = other.multiplyByMonomial(degreeDifference, scale)?; let iterationQuotient = self.field.buildMonomial(degreeDifference, scale); - quotient = quotient.addOrSubtract(iterationQuotient)?; - remainder = &*remainder.addOrSubtract(term)?; + quotient = quotient.addOrSubtract(&iterationQuotient)?; + remainder = remainder.addOrSubtract(&term)?; } - return Ok(vec![quotient, Box::new(*remainder)]); + return Ok(vec![quotient, remainder]); } } @@ -556,10 +567,10 @@ impl fmt::Display for GenericGFPoly { if self.isZero() { return write!(f, "0"); } - let result = String::with_capacity(8 * self.getDegree()); + let mut result = String::with_capacity(8 * self.getDegree()); for degree in (0..self.getDegree()).rev() { //for (int degree = getDegree(); degree >= 0; degree--) { - let coefficient = self.getCoefficient(degree); + let mut coefficient = self.getCoefficient(degree); if coefficient != 0 { if coefficient < 0 { if degree == self.getDegree() { @@ -567,23 +578,23 @@ impl fmt::Display for GenericGFPoly { } else { result.push_str(" - "); } - //coefficient = -coefficient; - todo!("probably coefficient should be unsigned but what a mess"); + coefficient = -coefficient; + //todo!("probably coefficient should be unsigned but what a mess"); } else { if result.len() > 0 { result.push_str(" + "); } } if degree == 0 || coefficient != 1 { - let alphaPower = self.field.log(coefficient); - if alphaPower.unwrap() == 0 { + if let Ok(alphaPower) = self.field.log(coefficient){ + if alphaPower == 0 { result.push_str("1"); - } else if alphaPower.unwrap() == 1 { + } else if alphaPower == 1 { result.push_str("a"); } else { result.push_str("a^"); - result.push_str(&format!("{}", alphaPower.unwrap())); - } + result.push_str(&format!("{}", alphaPower)); + }} } if degree != 0 { if degree == 1 { @@ -639,13 +650,13 @@ impl fmt::Display for GenericGFPoly { * @author sanfordsquires */ pub struct ReedSolomonDecoder { - field: Box, + field: GenericGF, } impl ReedSolomonDecoder { pub fn new(field: GenericGF) -> Self { Self { - field: Box::new(field), + field: field, } } @@ -659,18 +670,19 @@ impl ReedSolomonDecoder { * @throws ReedSolomonException if decoding fails for any reason */ pub fn decode(&self, received: &mut Vec, twoS: i32) -> Result<(), ReedSolomonException> { - let poly = GenericGFPoly::new(self.field, received); - let syndromeCoefficients = Vec::with_capacity(twoS.try_into().unwrap()); + let poly = GenericGFPoly::new(self.field.clone(), received).unwrap(); + let mut syndromeCoefficients = Vec::with_capacity(twoS.try_into().unwrap()); let mut noError = true; for i in 0..twoS { //for (int i = 0; i < twoS; i++) { - let eval = poly.unwrap().evaluateAt( + let eval = poly.evaluateAt( self.field .exp(i + self.field.getGeneratorBase()) .try_into() .unwrap(), ); - syndromeCoefficients[syndromeCoefficients.len() - 1 - i as usize] = eval; + let len = syndromeCoefficients.len(); + syndromeCoefficients[len - 1 - i as usize] = eval; if eval != 0 { noError = false; } @@ -678,17 +690,17 @@ impl ReedSolomonDecoder { if noError { return Ok(()); } - let syndrome = match GenericGFPoly::new(self.field, &syndromeCoefficients) { + let syndrome = match GenericGFPoly::new(self.field.clone(), &syndromeCoefficients) { Ok(res) => res, Err(fail) => return Err(ReedSolomonException::new("IllegalArgumentException")), }; let sigmaOmega = self.runEuclideanAlgorithm( - self.field.buildMonomial(twoS.try_into().unwrap(), 1), - Box::new(syndrome), + &self.field.buildMonomial(twoS.try_into().unwrap(), 1), + &syndrome, twoS.try_into().unwrap(), - ); - let sigma = sigmaOmega?[0]; - let omega = sigmaOmega?[1]; + )?; + let sigma = &sigmaOmega[0]; + let omega = &sigmaOmega[1]; let errorLocations = self.findErrorLocations(&sigma)?; let errorMagnitudes = self.findErrorMagnitudes(&omega, &errorLocations); for i in 0..errorLocations.len() { @@ -709,21 +721,25 @@ impl ReedSolomonDecoder { fn runEuclideanAlgorithm( &self, - a: Box, - b: Box, + a: &GenericGFPoly, + b: &GenericGFPoly, R: usize, ) -> Result, ReedSolomonException> { // Assume a's degree is >= b's + let mut a = a; + let mut b = b; if a.getDegree() < b.getDegree() { let temp = a; a = b; b = temp; } - let rLast = a; - let r = b; - let tLast = self.field.getZero(); - let t = self.field.getOne(); + let mut rLast = a; + let mut r = b; + // let tLast = self.field.getZero(); + // let t = self.field.getOne(); + let mut tLast = a.getZero(); + let mut t = a.getOne(); // Run Euclidean algorithm until r's degree is less than R/2 while 2 * r.getDegree() >= R { @@ -738,7 +754,7 @@ impl ReedSolomonDecoder { return Err(ReedSolomonException::new("r_{i-1} was zero")); } r = rLastLast; - let q = self.field.getZero(); + let q = a.getZero(); let denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree()); let dltInverse = match self.field.inverse(denominatorLeadingTerm) { Ok(inv) => inv, @@ -749,15 +765,15 @@ impl ReedSolomonDecoder { 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, Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")), }; r = match r.addOrSubtract(match rLast.multiplyByMonomial(degreeDiff, scale) { - Ok(res) => res, + Ok(res) => &res, Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")), }) { - Ok(res) => res, + Ok(res) =>&res, Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")), }; } @@ -766,7 +782,7 @@ impl ReedSolomonDecoder { Ok(res) => res, Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")), }) - .addOrSubtract(tLastLast) + .addOrSubtract(&tLastLast) { Ok(res) => res, Err(err) => return Err(ReedSolomonException::new("IllegalArgumentException")), @@ -791,7 +807,7 @@ impl ReedSolomonDecoder { }; let sigma = t.multiply_with_scalar(inverse); let omega = r.multiply_with_scalar(inverse); - return Ok(vec![*sigma, *omega]); + return Ok(vec![sigma, omega]); } fn findErrorLocations( @@ -898,12 +914,12 @@ impl ReedSolomonDecoder { * @author William Rucklidge */ pub struct ReedSolomonEncoder { - field: Box, + field: GenericGF, cachedGenerators: Vec, } impl ReedSolomonEncoder { - pub fn new(field: Box) -> Self { + pub fn new(field: GenericGF) -> Self { Self { field: field, cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()], @@ -918,7 +934,7 @@ impl ReedSolomonEncoder { .unwrap(); for d in self.cachedGenerators.len()..=degree { //for (int d = cachedGenerators.size(); d <= degree; d++) { - let nextGenerator = *lastGenerator + let nextGenerator = lastGenerator .multiply( &GenericGFPoly::new( self.field, @@ -950,11 +966,11 @@ impl ReedSolomonEncoder { return Err(IllegalArgumentException::new("No data bytes provided")); } let generator = self.buildGenerator(ecBytes); - let infoCoefficients: Vec = Vec::with_capacity(dataBytes); + let mut infoCoefficients: Vec = Vec::with_capacity(dataBytes); infoCoefficients[0..dataBytes].clone_from_slice(&toEncode[0..dataBytes]); //System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes); - let info = GenericGFPoly::new(self.field, &infoCoefficients)?; - info = *info.multiplyByMonomial(ecBytes.try_into().unwrap(), 1)?; + let mut info = GenericGFPoly::new(self.field.clone(), &infoCoefficients)?; + info = info.multiplyByMonomial(ecBytes.try_into().unwrap(), 1)?; let remainder = info.divide(&generator)?[1]; let coefficients = remainder.getCoefficients(); let numZeroCoefficients = ecBytes - coefficients.len();