mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-28 05:12:34 +00:00
working through errors to compile
This commit is contained in:
@@ -65,7 +65,7 @@ pub fn distance_int(aX: i32, aY: i32, bX: i32, bY: i32) -> f32 {
|
|||||||
* @return sum of values in array
|
* @return sum of values in array
|
||||||
*/
|
*/
|
||||||
pub fn sum(array: &[i32]) -> i32 {
|
pub fn sum(array: &[i32]) -> i32 {
|
||||||
let count = 0;
|
let mut count = 0;
|
||||||
for a in array {
|
for a in array {
|
||||||
count += a;
|
count += a;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub struct MonochromeRectangleDetector {
|
|||||||
|
|
||||||
impl MonochromeRectangleDetector {
|
impl MonochromeRectangleDetector {
|
||||||
pub fn new(image: &BitMatrix) -> Self {
|
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
|
* @throws NotFoundException if no Data Matrix Code can be found
|
||||||
*/
|
*/
|
||||||
pub fn detect(&self) -> Result<Vec<RXingResultPoint>, NotFoundException> {
|
pub fn detect(&self) -> Result<Vec<RXingResultPoint>, NotFoundException> {
|
||||||
let height = self.image.getHeight();
|
let height = self.image.getHeight() as i32;
|
||||||
let width = self.image.getWidth();
|
let width = self.image.getWidth() as i32;
|
||||||
let halfHeight= height / 2;
|
let halfHeight= height / 2;
|
||||||
let halfWidth = width / 2;
|
let halfWidth = width / 2;
|
||||||
let deltaY = 1.max(height / (MAX_MODULES * 8));
|
let deltaY = 1.max(height as i32 / (MAX_MODULES * 8));
|
||||||
let deltaX = 1.max(width / (MAX_MODULES * 8));
|
let deltaX = 1.max(width as i32 / (MAX_MODULES * 8));
|
||||||
|
|
||||||
let top = 0;
|
let mut top = 0;
|
||||||
let bottom = height;
|
let mut bottom = height;
|
||||||
let left = 0;
|
let mut left = 0;
|
||||||
let right = width;
|
let mut right = width;
|
||||||
let pointA = self.findCornerFromCenter(
|
let mut pointA = self.findCornerFromCenter(
|
||||||
halfWidth,
|
halfWidth,
|
||||||
0,
|
0,
|
||||||
left,
|
left,
|
||||||
@@ -156,9 +156,9 @@ impl MonochromeRectangleDetector {
|
|||||||
bottom: i32,
|
bottom: i32,
|
||||||
maxWhiteRun: i32,
|
maxWhiteRun: i32,
|
||||||
) -> Result<RXingResultPoint, NotFoundException> {
|
) -> Result<RXingResultPoint, NotFoundException> {
|
||||||
let mut lastRange: Option<Vec<i32>> = None;
|
let mut lastRange_z: Option<Vec<i32>> = None;
|
||||||
let y: i32 = centerY;
|
let mut y: i32 = centerY;
|
||||||
let x: i32 = centerX;
|
let mut x: i32 = centerX;
|
||||||
while y < bottom && y >= top && x < right && x >= left {
|
while y < bottom && y >= top && x < right && x >= left {
|
||||||
let range: Option<Vec<i32>>;
|
let range: Option<Vec<i32>>;
|
||||||
if deltaX == 0 {
|
if deltaX == 0 {
|
||||||
@@ -169,52 +169,52 @@ impl MonochromeRectangleDetector {
|
|||||||
range = self.blackWhiteRange(x, maxWhiteRun, top, bottom, false);
|
range = self.blackWhiteRange(x, maxWhiteRun, top, bottom, false);
|
||||||
}
|
}
|
||||||
if range.is_none() {
|
if range.is_none() {
|
||||||
if lastRange.is_none() {
|
if let Some(lastRange) = lastRange_z {
|
||||||
return Err(NotFoundException {});
|
|
||||||
}
|
|
||||||
// lastRange was found
|
// lastRange was found
|
||||||
if deltaX == 0 {
|
if deltaX == 0 {
|
||||||
let lastY = y - deltaY;
|
let lastY = y - deltaY;
|
||||||
if lastRange.unwrap()[0] < centerX {
|
if lastRange[0] < centerX {
|
||||||
if lastRange.unwrap()[1] > centerX {
|
if lastRange[1] > centerX {
|
||||||
// straddle, choose one or the other based on direction
|
// straddle, choose one or the other based on direction
|
||||||
return Ok(RXingResultPoint::new(
|
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,
|
lastY as f32,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return Ok(RXingResultPoint::new(
|
return Ok(RXingResultPoint::new(
|
||||||
lastRange.unwrap()[0] as f32,
|
lastRange[0] as f32,
|
||||||
lastY as f32,
|
lastY as f32,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
return Ok(RXingResultPoint::new(
|
return Ok(RXingResultPoint::new(
|
||||||
lastRange.unwrap()[1] as f32,
|
lastRange[1] as f32,
|
||||||
lastY as f32,
|
lastY as f32,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let lastX = x - deltaX;
|
let lastX = x - deltaX;
|
||||||
if lastRange.unwrap()[0] < centerY {
|
if lastRange[0] < centerY {
|
||||||
if lastRange.unwrap()[1] > centerY {
|
if lastRange[1] > centerY {
|
||||||
return Ok(RXingResultPoint::new(
|
return Ok(RXingResultPoint::new(
|
||||||
lastX as f32,
|
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(
|
return Ok(RXingResultPoint::new(
|
||||||
lastX as f32,
|
lastX as f32,
|
||||||
lastRange.unwrap()[0] as f32,
|
lastRange[0] as f32,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
return Ok(RXingResultPoint::new(
|
return Ok(RXingResultPoint::new(
|
||||||
lastX as f32,
|
lastX as f32,
|
||||||
lastRange.unwrap()[1] as f32,
|
lastRange[1] as f32,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}}else {
|
||||||
|
return Err(NotFoundException {});
|
||||||
}
|
}
|
||||||
lastRange = range;
|
lastRange_z = range;
|
||||||
y += deltaY;
|
y += deltaY;
|
||||||
x += deltaX
|
x += deltaX
|
||||||
}
|
}
|
||||||
@@ -246,28 +246,28 @@ impl MonochromeRectangleDetector {
|
|||||||
let center = (minDim + maxDim) / 2;
|
let center = (minDim + maxDim) / 2;
|
||||||
|
|
||||||
// Scan left/up first
|
// Scan left/up first
|
||||||
let start = center;
|
let mut start = center;
|
||||||
while (start >= minDim) {
|
while (start >= minDim) {
|
||||||
if (if horizontal {
|
if if horizontal {
|
||||||
self.image.get(start, fixedDimension)
|
self.image.get(start as u32, fixedDimension as u32)
|
||||||
} else {
|
} else {
|
||||||
self.image.get(fixedDimension, start)
|
self.image.get(fixedDimension as u32, start as u32)
|
||||||
}) {
|
} {
|
||||||
start = start - 1;
|
start = start - 1;
|
||||||
} else {
|
} else {
|
||||||
let whiteRunStart = start;
|
let whiteRunStart = start;
|
||||||
start = start - 1;
|
start = start - 1;
|
||||||
while start >= minDim
|
while start >= minDim
|
||||||
&& !(if horizontal {
|
&& !(if horizontal {
|
||||||
self.image.get(start, fixedDimension)
|
self.image.get(start as u32, fixedDimension as u32)
|
||||||
} else {
|
} else {
|
||||||
self.image.get(fixedDimension, start)
|
self.image.get(fixedDimension as u32, start as u32)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
start = start - 1;
|
start = start - 1;
|
||||||
}
|
}
|
||||||
let whiteRunSize = whiteRunStart - start;
|
let whiteRunSize = whiteRunStart - start;
|
||||||
if (start < minDim || whiteRunSize > maxWhiteRun) {
|
if start < minDim || whiteRunSize > maxWhiteRun {
|
||||||
start = whiteRunStart;
|
start = whiteRunStart;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -276,28 +276,28 @@ impl MonochromeRectangleDetector {
|
|||||||
start = start + 1;
|
start = start + 1;
|
||||||
|
|
||||||
// Then try right/down
|
// Then try right/down
|
||||||
let end = center;
|
let mut end = center;
|
||||||
while (end < maxDim) {
|
while (end < maxDim) {
|
||||||
if (if horizontal {
|
if if horizontal {
|
||||||
self.image.get(end, fixedDimension)
|
self.image.get(end as u32, fixedDimension as u32)
|
||||||
} else {
|
} else {
|
||||||
self.image.get(fixedDimension, end)
|
self.image.get(fixedDimension as u32, end as u32)
|
||||||
}) {
|
} {
|
||||||
end = end + 1;
|
end = end + 1;
|
||||||
} else {
|
} else {
|
||||||
let whiteRunStart = end;
|
let whiteRunStart = end;
|
||||||
end = end + 1;
|
end = end + 1;
|
||||||
while end < maxDim
|
while end < maxDim
|
||||||
&& !(if horizontal {
|
&& !(if horizontal {
|
||||||
self.image.get(end, fixedDimension)
|
self.image.get(end as u32, fixedDimension as u32)
|
||||||
} else {
|
} else {
|
||||||
self.image.get(fixedDimension, end)
|
self.image.get(fixedDimension as u32, end as u32)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
end = end + 1;
|
end = end + 1;
|
||||||
}
|
}
|
||||||
let whiteRunSize = end - whiteRunStart;
|
let whiteRunSize = end - whiteRunStart;
|
||||||
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
|
if end >= maxDim || whiteRunSize > maxWhiteRun {
|
||||||
end = whiteRunStart;
|
end = whiteRunStart;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -358,8 +358,8 @@ impl WhiteRectangleDetector {
|
|||||||
Self::new(
|
Self::new(
|
||||||
image,
|
image,
|
||||||
INIT_SIZE,
|
INIT_SIZE,
|
||||||
image.getWidth() / 2,
|
image.getWidth() as i32 / 2,
|
||||||
image.getHeight() / 2,
|
image.getHeight() as i32 / 2,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,24 +376,31 @@ impl WhiteRectangleDetector {
|
|||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
) -> Result<Self, NotFoundException> {
|
) -> Result<Self, NotFoundException> {
|
||||||
let new_wrd: Self;
|
|
||||||
new_wrd.image = image;
|
|
||||||
new_wrd.height = image.getHeight();
|
|
||||||
new_wrd.width = image.getWidth();
|
|
||||||
let halfsize = initSize / 2;
|
let halfsize = initSize / 2;
|
||||||
new_wrd.leftInit = x - halfsize;
|
|
||||||
new_wrd.rightInit = x + halfsize;
|
let leftInit = x - halfsize;
|
||||||
new_wrd.upInit = y - halfsize;
|
let rightInit = x + halfsize;
|
||||||
new_wrd.downInit = y + halfsize;
|
let upInit = y - halfsize;
|
||||||
if new_wrd.upInit < 0
|
let downInit = y + halfsize;
|
||||||
|| new_wrd.leftInit < 0
|
|
||||||
|| new_wrd.downInit >= new_wrd.height
|
if upInit < 0
|
||||||
|| new_wrd.rightInit >= new_wrd.width
|
|| leftInit < 0
|
||||||
|
|| downInit >= image.getHeight() as i32
|
||||||
|
|| rightInit >= image.getWidth() as i32
|
||||||
{
|
{
|
||||||
return Err(NotFoundException {});
|
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
|
* @throws NotFoundException if no Data Matrix Code can be found
|
||||||
*/
|
*/
|
||||||
pub fn detect(&self) -> Result<Vec<RXingResultPoint>, NotFoundException> {
|
pub fn detect(&self) -> Result<Vec<RXingResultPoint>, NotFoundException> {
|
||||||
let left: i32 = self.leftInit;
|
let mut left: i32 = self.leftInit;
|
||||||
let right: i32 = self.rightInit;
|
let mut right: i32 = self.rightInit;
|
||||||
let up: i32 = self.upInit;
|
let mut up: i32 = self.upInit;
|
||||||
let down: i32 = self.downInit;
|
let mut down: i32 = self.downInit;
|
||||||
let sizeExceeded = false;
|
let mut sizeExceeded = false;
|
||||||
let aBlackPointFoundOnBorder = true;
|
let mut aBlackPointFoundOnBorder = true;
|
||||||
|
|
||||||
let atLeastOneBlackPointFoundOnRight = false;
|
let mut atLeastOneBlackPointFoundOnRight = false;
|
||||||
let atLeastOneBlackPointFoundOnBottom = false;
|
let mut atLeastOneBlackPointFoundOnBottom = false;
|
||||||
let atLeastOneBlackPointFoundOnLeft = false;
|
let mut atLeastOneBlackPointFoundOnLeft = false;
|
||||||
let atLeastOneBlackPointFoundOnTop = false;
|
let mut atLeastOneBlackPointFoundOnTop = false;
|
||||||
|
|
||||||
while aBlackPointFoundOnBorder {
|
while aBlackPointFoundOnBorder {
|
||||||
aBlackPointFoundOnBorder = false;
|
aBlackPointFoundOnBorder = false;
|
||||||
@@ -429,7 +436,7 @@ impl WhiteRectangleDetector {
|
|||||||
// .....
|
// .....
|
||||||
// . |
|
// . |
|
||||||
// .....
|
// .....
|
||||||
let rightBorderNotWhite = true;
|
let mut rightBorderNotWhite = true;
|
||||||
while (rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < self.width {
|
while (rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < self.width {
|
||||||
rightBorderNotWhite = self.containsBlackPoint(up, down, right, false);
|
rightBorderNotWhite = self.containsBlackPoint(up, down, right, false);
|
||||||
if rightBorderNotWhite {
|
if rightBorderNotWhite {
|
||||||
@@ -449,7 +456,7 @@ impl WhiteRectangleDetector {
|
|||||||
// .....
|
// .....
|
||||||
// . .
|
// . .
|
||||||
// .___.
|
// .___.
|
||||||
let bottomBorderNotWhite = true;
|
let mut bottomBorderNotWhite = true;
|
||||||
while (bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < self.height
|
while (bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < self.height
|
||||||
{
|
{
|
||||||
bottomBorderNotWhite = self.containsBlackPoint(left, right, down, true);
|
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 {
|
while (leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0 {
|
||||||
leftBorderNotWhite = self.containsBlackPoint(up, down, left, false);
|
leftBorderNotWhite = self.containsBlackPoint(up, down, left, false);
|
||||||
if leftBorderNotWhite {
|
if leftBorderNotWhite {
|
||||||
@@ -490,7 +497,7 @@ impl WhiteRectangleDetector {
|
|||||||
// .___.
|
// .___.
|
||||||
// . .
|
// . .
|
||||||
// .....
|
// .....
|
||||||
let topBorderNotWhite = true;
|
let mut topBorderNotWhite = true;
|
||||||
while (topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0 {
|
while (topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0 {
|
||||||
topBorderNotWhite = self.containsBlackPoint(left, right, up, true);
|
topBorderNotWhite = self.containsBlackPoint(left, right, up, true);
|
||||||
if topBorderNotWhite {
|
if topBorderNotWhite {
|
||||||
@@ -596,13 +603,13 @@ impl WhiteRectangleDetector {
|
|||||||
bY: f32,
|
bY: f32,
|
||||||
) -> Option<RXingResultPoint> {
|
) -> Option<RXingResultPoint> {
|
||||||
let dist = MathUtils::round(MathUtils::distance_float(aX, aY, bX, bY));
|
let dist = MathUtils::round(MathUtils::distance_float(aX, aY, bX, bY));
|
||||||
let xStep: f32 = (bX - aX) / dist.into();
|
let xStep: f32 = (bX - aX) / dist as f32;
|
||||||
let yStep: f32 = (bY - aY) / dist.into();
|
let yStep: f32 = (bY - aY) / dist as f32;
|
||||||
|
|
||||||
for i in 0..dist {
|
for i in 0..dist {
|
||||||
let x = MathUtils::round(aX + i.into() * xStep);
|
let x = MathUtils::round(aX + i as f32 * xStep);
|
||||||
let y = MathUtils::round(aY + i.into() * yStep);
|
let y = MathUtils::round(aY + i as f32 * yStep);
|
||||||
if self.image.get(x, y) {
|
if self.image.get(x as u32, y as u32) {
|
||||||
return Some(RXingResultPoint::new(x as f32, y as f32));
|
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 {
|
fn containsBlackPoint(&self, a: i32, b: i32, fixed: i32, horizontal: bool) -> bool {
|
||||||
if horizontal {
|
if horizontal {
|
||||||
for x in a..=b {
|
for x in a..=b {
|
||||||
if self.image.get(x, fixed) {
|
if self.image.get(x as u32, fixed as u32) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for y in a..=b {
|
for y in a..=b {
|
||||||
if self.image.get(fixed, y) {
|
if self.image.get(fixed as u32, y as u32) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ impl BitArray {
|
|||||||
return self.size;
|
return self.size;
|
||||||
}
|
}
|
||||||
let bitsOffset = from / 32;
|
let bitsOffset = from / 32;
|
||||||
let currentBits = self.bits[bitsOffset];
|
let mut currentBits = self.bits[bitsOffset] as i32;
|
||||||
// mask off lesser bits first
|
// mask off lesser bits first
|
||||||
currentBits &= -(1 << (from & 0x1F));
|
currentBits &= -(1 << (from & 0x1F));
|
||||||
while currentBits == 0 {
|
while currentBits == 0 {
|
||||||
@@ -388,7 +388,7 @@ impl BitArray {
|
|||||||
if bitsOffset == self.bits.len() {
|
if bitsOffset == self.bits.len() {
|
||||||
return self.size;
|
return self.size;
|
||||||
}
|
}
|
||||||
currentBits = self.bits[bitsOffset];
|
currentBits = self.bits[bitsOffset] as i32;
|
||||||
}
|
}
|
||||||
let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize;
|
let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize;
|
||||||
cmp::min(result, self.size)
|
cmp::min(result, self.size)
|
||||||
@@ -404,7 +404,7 @@ impl BitArray {
|
|||||||
return self.size;
|
return self.size;
|
||||||
}
|
}
|
||||||
let bitsOffset = from / 32;
|
let bitsOffset = from / 32;
|
||||||
let currentBits = !self.bits[bitsOffset];
|
let currentBits = !self.bits[bitsOffset] as i32;
|
||||||
// mask off lesser bits first
|
// mask off lesser bits first
|
||||||
currentBits &= -(1 << (from & 0x1F)) ;
|
currentBits &= -(1 << (from & 0x1F)) ;
|
||||||
while currentBits == 0 {
|
while currentBits == 0 {
|
||||||
@@ -412,7 +412,7 @@ impl BitArray {
|
|||||||
if bitsOffset == self.bits.len() {
|
if bitsOffset == self.bits.len() {
|
||||||
return self.size;
|
return self.size;
|
||||||
}
|
}
|
||||||
currentBits = !self.bits[bitsOffset];
|
currentBits = !self.bits[bitsOffset] as i32;
|
||||||
}
|
}
|
||||||
let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize;
|
let result = (bitsOffset * 32) + currentBits.trailing_zeros() as usize;
|
||||||
return cmp::min(result, self.size);
|
return cmp::min(result, self.size);
|
||||||
@@ -836,14 +836,17 @@ impl BitMatrix {
|
|||||||
let bits = Vec::with_capacity(stringRepresentation.len());
|
let bits = Vec::with_capacity(stringRepresentation.len());
|
||||||
let bitsPos = 0;
|
let bitsPos = 0;
|
||||||
let rowStartPos = 0;
|
let rowStartPos = 0;
|
||||||
let rowLength = -1;
|
let rowLength = 0;//-1;
|
||||||
|
let mut first_run = true;
|
||||||
let nRows = 0;
|
let nRows = 0;
|
||||||
let pos = 0;
|
let pos = 0;
|
||||||
while pos < stringRepresentation.len() {
|
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 bitsPos > rowStartPos {
|
||||||
if rowLength == -1 {
|
//if rowLength == -1 {
|
||||||
|
if first_run {
|
||||||
|
first_run = false;
|
||||||
rowLength = bitsPos - rowStartPos;
|
rowLength = bitsPos - rowStartPos;
|
||||||
} else if bitsPos - rowStartPos != rowLength {
|
} else if bitsPos - rowStartPos != rowLength {
|
||||||
return Err(IllegalArgumentException::new("row lengths do not match"));
|
return Err(IllegalArgumentException::new("row lengths do not match"));
|
||||||
@@ -852,25 +855,27 @@ impl BitMatrix {
|
|||||||
nRows += 1;
|
nRows += 1;
|
||||||
}
|
}
|
||||||
pos += 1;
|
pos += 1;
|
||||||
} else if stringRepresentation.startsWith(setString, pos) {
|
} else if stringRepresentation[pos..].starts_with(setString) {
|
||||||
pos += setString.len();
|
pos += setString.len();
|
||||||
bits[bitsPos] = true;
|
bits[bitsPos] = true;
|
||||||
bitsPos += 1;
|
bitsPos += 1;
|
||||||
} else if stringRepresentation.startsWith(unsetString, pos) {
|
} else if stringRepresentation[pos..].starts_with(unsetString) {
|
||||||
pos += unsetString.len();
|
pos += unsetString.len();
|
||||||
bits[bitsPos] = false;
|
bits[bitsPos] = false;
|
||||||
bitsPos += 1;
|
bitsPos += 1;
|
||||||
} else {
|
} else {
|
||||||
return Err(IllegalArgumentException::new(&format!(
|
return Err(IllegalArgumentException::new(&format!(
|
||||||
"illegal character encountered: {}",
|
"illegal character encountered: {}",
|
||||||
stringRepresentation.substring(pos)
|
stringRepresentation[pos..].to_owned()
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no EOL at end?
|
// no EOL at end?
|
||||||
if bitsPos > rowStartPos {
|
if bitsPos > rowStartPos {
|
||||||
if rowLength == -1 {
|
//if rowLength == -1 {
|
||||||
|
if first_run {
|
||||||
|
first_run = false;
|
||||||
rowLength = bitsPos - rowStartPos;
|
rowLength = bitsPos - rowStartPos;
|
||||||
} else if bitsPos - rowStartPos != rowLength {
|
} else if bitsPos - rowStartPos != rowLength {
|
||||||
return Err(IllegalArgumentException::new("row lengths do not match"));
|
return Err(IllegalArgumentException::new("row lengths do not match"));
|
||||||
@@ -878,14 +883,14 @@ impl BitMatrix {
|
|||||||
nRows += 1;
|
nRows += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let matrix = BitMatrix::new(rowLength, nRows);
|
let matrix = BitMatrix::new(rowLength.try_into().unwrap(), nRows)?;
|
||||||
for i in 0..bitsPos {
|
for i in 0..bitsPos {
|
||||||
//for (int i = 0; i < bitsPos; i++) {
|
//for (int i = 0; i < bitsPos; i++) {
|
||||||
if bits[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
|
* @return value of given bit in matrix
|
||||||
*/
|
*/
|
||||||
pub fn get(&self, x: u32, y: u32) -> bool {
|
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;
|
return ((self.bits[offset] >> (x & 0x1f)) & 1) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,12 +912,12 @@ impl BitMatrix {
|
|||||||
* @param y The vertical component (i.e. which row)
|
* @param y The vertical component (i.e. which row)
|
||||||
*/
|
*/
|
||||||
pub fn set(&self, x: u32, y: u32) {
|
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);
|
self.bits[offset] |= 1 << (x & 0x1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unset(&self, x: u32, y: u32) {
|
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));
|
self.bits[offset] &= !(1 << (x & 0x1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,7 +928,7 @@ impl BitMatrix {
|
|||||||
* @param y The vertical component (i.e. which row)
|
* @param y The vertical component (i.e. which row)
|
||||||
*/
|
*/
|
||||||
pub fn flip_coords(&self, x: u32, y: u32) {
|
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);
|
self.bits[offset] ^= 1 << (x & 0x1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -950,11 +955,11 @@ impl BitMatrix {
|
|||||||
"input matrix dimensions do not match",
|
"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 y in 0..self.height {
|
||||||
//for (int y = 0; y < height; y++) {
|
//for (int y = 0; y < height; y++) {
|
||||||
let offset = y * self.rowSize;
|
let offset = y as usize * self.rowSize;
|
||||||
let row = mask.getRow(y, self.rowArray).getBitArray();
|
let row = mask.getRow(y, &rowArray).getBitArray();
|
||||||
for x in 0..self.rowSize {
|
for x in 0..self.rowSize {
|
||||||
//for (int x = 0; x < rowSize; x++) {
|
//for (int x = 0; x < rowSize; x++) {
|
||||||
self.bits[offset + x] ^= row[x];
|
self.bits[offset + x] ^= row[x];
|
||||||
@@ -1008,10 +1013,10 @@ impl BitMatrix {
|
|||||||
}
|
}
|
||||||
for y in top..bottom {
|
for y in top..bottom {
|
||||||
//for (int y = top; y < bottom; y++) {
|
//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 x in left..right {
|
||||||
//for (int x = left; x < right; x++) {
|
//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(())
|
Ok(())
|
||||||
@@ -1026,14 +1031,14 @@ impl BitMatrix {
|
|||||||
* your own row
|
* your own row
|
||||||
*/
|
*/
|
||||||
pub fn getRow(&self, y: u32, row: &BitArray) -> BitArray {
|
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)
|
BitArray::with_size(self.width as usize)
|
||||||
} else {
|
} else {
|
||||||
row.clear();
|
row.clear();
|
||||||
*row
|
*row
|
||||||
};
|
};
|
||||||
|
|
||||||
let offset = y * self.rowSize;
|
let offset = y as usize * self.rowSize;
|
||||||
for x in 0..self.rowSize {
|
for x in 0..self.rowSize {
|
||||||
//for (int x = 0; x < rowSize; x++) {
|
//for (int x = 0; x < rowSize; x++) {
|
||||||
rw.setBulk(x * 32, self.bits[offset + x]);
|
rw.setBulk(x * 32, self.bits[offset + x]);
|
||||||
@@ -1046,7 +1051,7 @@ impl BitMatrix {
|
|||||||
* @param row {@link BitArray} to copy from
|
* @param row {@link BitArray} to copy from
|
||||||
*/
|
*/
|
||||||
pub fn setRow(&self, y: u32, row: &BitArray) {
|
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]);
|
.clone_from_slice(&row.getBitArray()[0..self.rowSize]);
|
||||||
//System.arraycopy(row.getBitArray(), 0, self.bits, y * self.rowSize, 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 (int y = 0; y < height; y++) {
|
||||||
for x in 0..self.width {
|
for x in 0..self.width {
|
||||||
//for (int x = 0; x < width; x++) {
|
//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 {
|
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);
|
newBits[newOffset] |= 1 << (y & 0x1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.width = newWidth;
|
self.width = newWidth;
|
||||||
self.height = newHeight;
|
self.height = newHeight;
|
||||||
self.rowSize = newRowSize;
|
self.rowSize = newRowSize.try_into().unwrap();
|
||||||
self.bits = newBits;
|
self.bits = newBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1131,14 +1136,16 @@ impl BitMatrix {
|
|||||||
pub fn getEnclosingRectangle(&self) -> Option<Vec<u32>> {
|
pub fn getEnclosingRectangle(&self) -> Option<Vec<u32>> {
|
||||||
let left = self.width;
|
let left = self.width;
|
||||||
let top = self.height;
|
let top = self.height;
|
||||||
let right = -1;
|
// let right = -1;
|
||||||
let bottom = -1;
|
// let bottom = -1;
|
||||||
|
let right:u32 = 0;
|
||||||
|
let bottom = 0;
|
||||||
|
|
||||||
for y in 0..self.height {
|
for y in 0..self.height {
|
||||||
//for (int y = 0; y < height; y++) {
|
//for (int y = 0; y < height; y++) {
|
||||||
for x32 in 0..self.rowSize {
|
for x32 in 0..self.rowSize {
|
||||||
//for (int x32 = 0; x32 < rowSize; x32++) {
|
//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 theBits != 0 {
|
||||||
if y < top {
|
if y < top {
|
||||||
top = y;
|
top = y;
|
||||||
@@ -1146,22 +1153,22 @@ impl BitMatrix {
|
|||||||
if y > bottom {
|
if y > bottom {
|
||||||
bottom = y;
|
bottom = y;
|
||||||
}
|
}
|
||||||
if x32 * 32 < left {
|
if x32 * 32 < left.try_into().unwrap() {
|
||||||
let bit = 0;
|
let bit = 0;
|
||||||
while (theBits << (31 - bit)) == 0 {
|
while (theBits << (31 - bit)) == 0 {
|
||||||
bit += 1;
|
bit += 1;
|
||||||
}
|
}
|
||||||
if (x32 * 32 + bit) < left {
|
if (x32 * 32 + bit) < left.try_into().unwrap() {
|
||||||
left = x32 * 32 + bit;
|
left = (x32 * 32 + bit).try_into().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if x32 * 32 + 31 > right {
|
if x32 * 32 + 31 > right.try_into().unwrap() {
|
||||||
let bit = 31;
|
let bit = 31;
|
||||||
while (theBits >> bit) == 0 {
|
while (theBits >> bit) == 0 {
|
||||||
bit -= 1;
|
bit -= 1;
|
||||||
}
|
}
|
||||||
if (x32 * 32 + bit) > right {
|
if (x32 * 32 + bit) > right.try_into().unwrap() {
|
||||||
right = x32 * 32 + bit;
|
right =( x32 * 32 + bit).try_into().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1197,7 +1204,7 @@ impl BitMatrix {
|
|||||||
bit += 1;
|
bit += 1;
|
||||||
}
|
}
|
||||||
x += bit;
|
x += bit;
|
||||||
return Some(vec![x, y]);
|
return Some(vec![x as u32, y as u32]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getBottomRightOnBit(&self) -> Option<Vec<u32>> {
|
pub fn getBottomRightOnBit(&self) -> Option<Vec<u32>> {
|
||||||
@@ -1219,7 +1226,7 @@ impl BitMatrix {
|
|||||||
}
|
}
|
||||||
x += bit;
|
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
|
* @return number of bits that can be read successfully
|
||||||
*/
|
*/
|
||||||
pub fn available(&self) -> usize {
|
pub fn available(&self) -> usize {
|
||||||
return (8 * (self.bytes.len() - self.byteOffset) - self.bitOffset);
|
return 8 * (self.bytes.len() - self.byteOffset) - self.bitOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,18 +38,18 @@ const DECODER_TEST_ITERATIONS: i32 = 10;
|
|||||||
fn testDataMatrix() {
|
fn testDataMatrix() {
|
||||||
// real life test cases
|
// real life test cases
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::DATA_MATRIX_FIELD_256,
|
&super::DATA_MATRIX_FIELD_256,
|
||||||
vec![142, 164, 186],
|
&vec![142, 164, 186],
|
||||||
vec![114, 25, 5, 88, 102],
|
&vec![114, 25, 5, 88, 102],
|
||||||
);
|
);
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::DATA_MATRIX_FIELD_256,
|
&super::DATA_MATRIX_FIELD_256,
|
||||||
vec![
|
&vec![
|
||||||
0x69, 0x75, 0x75, 0x71, 0x3B, 0x30, 0x30, 0x64, 0x70, 0x65, 0x66, 0x2F, 0x68, 0x70,
|
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,
|
0x70, 0x68, 0x6D, 0x66, 0x2F, 0x64, 0x70, 0x6E, 0x30, 0x71, 0x30, 0x7B, 0x79, 0x6A,
|
||||||
0x6F, 0x68, 0x30, 0x81, 0xF0, 0x88, 0x1F, 0xB5,
|
0x6F, 0x68, 0x30, 0x81, 0xF0, 0x88, 0x1F, 0xB5,
|
||||||
],
|
],
|
||||||
vec![
|
&vec![
|
||||||
0x1C, 0x64, 0xEE, 0xEB, 0xD0, 0x1D, 0x00, 0x03, 0xF0, 0x1C, 0xF1, 0xD0, 0x6D, 0x00,
|
0x1C, 0x64, 0xEE, 0xEB, 0xD0, 0x1D, 0x00, 0x03, 0xF0, 0x1C, 0xF1, 0xD0, 0x6D, 0x00,
|
||||||
0x98, 0xDA, 0x80, 0x88, 0xBE, 0xFF, 0xB7, 0xFA, 0xA9, 0x95,
|
0x98, 0xDA, 0x80, 0x88, 0xBE, 0xFF, 0xB7, 0xFA, 0xA9, 0x95,
|
||||||
],
|
],
|
||||||
@@ -64,21 +64,21 @@ fn testDataMatrix() {
|
|||||||
fn testQRCode() {
|
fn testQRCode() {
|
||||||
// Test case from example given in ISO 18004, Annex I
|
// Test case from example given in ISO 18004, Annex I
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::QR_CODE_FIELD_256,
|
&super::QR_CODE_FIELD_256,
|
||||||
vec![
|
&vec![
|
||||||
0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11,
|
0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11, 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(
|
testEncodeDecode(
|
||||||
super::QR_CODE_FIELD_256,
|
&super::QR_CODE_FIELD_256,
|
||||||
vec![
|
&vec![
|
||||||
0x72, 0x67, 0x2F, 0x77, 0x69, 0x6B, 0x69, 0x2F, 0x4D, 0x61, 0x69, 0x6E, 0x5F, 0x50,
|
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,
|
0x61, 0x67, 0x65, 0x3B, 0x3B, 0x00, 0xEC, 0x11, 0xEC, 0x11, 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,
|
0xD8, 0xB8, 0xEF, 0x14, 0xEC, 0xD0, 0xCC, 0x85, 0x73, 0x40, 0x0B, 0xB5, 0x5A, 0xB8,
|
||||||
0x8B, 0x2E, 0x08, 0x62,
|
0x8B, 0x2E, 0x08, 0x62,
|
||||||
],
|
],
|
||||||
@@ -94,35 +94,35 @@ fn testQRCode() {
|
|||||||
fn testAztec() {
|
fn testAztec() {
|
||||||
// real life test cases
|
// real life test cases
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::AZTEC_PARAM,
|
&super::AZTEC_PARAM,
|
||||||
vec![0x5, 0x6],
|
&vec![0x5, 0x6],
|
||||||
vec![0x3, 0x2, 0xB, 0xB, 0x7],
|
&vec![0x3, 0x2, 0xB, 0xB, 0x7],
|
||||||
);
|
);
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::AZTEC_PARAM,
|
&super::AZTEC_PARAM,
|
||||||
vec![0x0, 0x0, 0x0, 0x9],
|
&vec![0x0, 0x0, 0x0, 0x9],
|
||||||
vec![0xA, 0xD, 0x8, 0x6, 0x5, 0x6],
|
&vec![0xA, 0xD, 0x8, 0x6, 0x5, 0x6],
|
||||||
);
|
);
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::AZTEC_PARAM,
|
&super::AZTEC_PARAM,
|
||||||
vec![0x2, 0x8, 0x8, 0x7],
|
&vec![0x2, 0x8, 0x8, 0x7],
|
||||||
vec![0xE, 0xC, 0xA, 0x9, 0x6, 0x8],
|
&vec![0xE, 0xC, 0xA, 0x9, 0x6, 0x8],
|
||||||
);
|
);
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::AZTEC_DATA_6,
|
&super::AZTEC_DATA_6,
|
||||||
vec![0x9, 0x32, 0x1, 0x29, 0x2F, 0x2, 0x27, 0x25, 0x1, 0x1B],
|
&vec![0x9, 0x32, 0x1, 0x29, 0x2F, 0x2, 0x27, 0x25, 0x1, 0x1B],
|
||||||
vec![0x2C, 0x2, 0xD, 0xD, 0xA, 0x16, 0x28, 0x9, 0x22, 0xA, 0x14],
|
&vec![0x2C, 0x2, 0xD, 0xD, 0xA, 0x16, 0x28, 0x9, 0x22, 0xA, 0x14],
|
||||||
);
|
);
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::AZTEC_DATA_8,
|
&super::AZTEC_DATA_8,
|
||||||
vec![
|
&vec![
|
||||||
0xE0, 0x86, 0x42, 0x98, 0xE8, 0x4A, 0x96, 0xC6, 0xB9, 0xF0, 0x8C, 0xA7, 0x4A, 0xDA,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
0x4E, 0x4A, 0xDE, 0xD4, 0xED, 0xA1, 0xF8, 0x47, 0x2A, 0x50, 0xA6, 0xBC, 0x53, 0x7D,
|
||||||
@@ -130,8 +130,8 @@ fn testAztec() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::AZTEC_DATA_10,
|
&super::AZTEC_DATA_10,
|
||||||
vec![
|
&vec![
|
||||||
0x15C, 0x1E1, 0x2D5, 0x02E, 0x048, 0x1E2, 0x037, 0x0CD, 0x02E, 0x056, 0x26A, 0x281,
|
0x15C, 0x1E1, 0x2D5, 0x02E, 0x048, 0x1E2, 0x037, 0x0CD, 0x02E, 0x056, 0x26A, 0x281,
|
||||||
0x1C2, 0x1A6, 0x296, 0x045, 0x041, 0x0AA, 0x095, 0x2CE, 0x003, 0x38F, 0x2CD, 0x1A2,
|
0x1C2, 0x1A6, 0x296, 0x045, 0x041, 0x0AA, 0x095, 0x2CE, 0x003, 0x38F, 0x2CD, 0x1A2,
|
||||||
0x036, 0x1AD, 0x04E, 0x090, 0x271, 0x0D3, 0x02E, 0x0D5, 0x2D4, 0x032, 0x2CA, 0x281,
|
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,
|
0x201, 0x0AA, 0x04E, 0x004, 0x1B0, 0x070, 0x275, 0x154, 0x026, 0x2C1, 0x2B3, 0x154,
|
||||||
0x2AA, 0x256, 0x0C1, 0x044, 0x004, 0x23F,
|
0x2AA, 0x256, 0x0C1, 0x044, 0x004, 0x23F,
|
||||||
],
|
],
|
||||||
vec![
|
&vec![
|
||||||
0x379, 0x099, 0x348, 0x010, 0x090, 0x196, 0x09C, 0x1FF, 0x1B0, 0x32D, 0x244, 0x0DE,
|
0x379, 0x099, 0x348, 0x010, 0x090, 0x196, 0x09C, 0x1FF, 0x1B0, 0x32D, 0x244, 0x0DE,
|
||||||
0x201, 0x386, 0x163, 0x11F, 0x39B, 0x344, 0x3FE, 0x02F, 0x188, 0x113, 0x3D9, 0x102,
|
0x201, 0x386, 0x163, 0x11F, 0x39B, 0x344, 0x3FE, 0x02F, 0x188, 0x113, 0x3D9, 0x102,
|
||||||
0x04A, 0x2E1, 0x1D1, 0x18E, 0x077, 0x262, 0x241, 0x20D, 0x1B8, 0x11D, 0x0D0, 0x0A5,
|
0x04A, 0x2E1, 0x1D1, 0x18E, 0x077, 0x262, 0x241, 0x20D, 0x1B8, 0x11D, 0x0D0, 0x0A5,
|
||||||
@@ -177,8 +177,8 @@ fn testAztec() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
testEncodeDecode(
|
testEncodeDecode(
|
||||||
super::AZTEC_DATA_12,
|
&super::AZTEC_DATA_12,
|
||||||
vec![
|
&vec![
|
||||||
0x571, 0xE1B, 0x542, 0xE12, 0x1E2, 0x0DC, 0xCD0, 0xB85, 0x69A, 0xA81, 0x709, 0xA6A,
|
0x571, 0xE1B, 0x542, 0xE12, 0x1E2, 0x0DC, 0xCD0, 0xB85, 0x69A, 0xA81, 0x709, 0xA6A,
|
||||||
0x584, 0x510, 0x4AA, 0x256, 0xCE0, 0x0F8, 0xFB3, 0x5A2, 0x0D9, 0xAD1, 0x389, 0x09C,
|
0x584, 0x510, 0x4AA, 0x256, 0xCE0, 0x0F8, 0xFB3, 0x5A2, 0x0D9, 0xAD1, 0x389, 0x09C,
|
||||||
0x4D3, 0x0B8, 0xD5B, 0x503, 0x2B2, 0xA81, 0x2A8, 0x4E0, 0x92D, 0x3A5, 0xA81, 0x388,
|
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,
|
0x10C, 0x835, 0x429, 0x33C, 0xB33, 0x4D5, 0x509, 0xCCD, 0x550, 0x35B, 0x4E2, 0xAA0,
|
||||||
0x5E6, 0x205, 0xB09, 0x99C, 0x09F,
|
0x5E6, 0x205, 0xB09, 0x99C, 0x09F,
|
||||||
],
|
],
|
||||||
vec![
|
&vec![
|
||||||
0xD54, 0x221, 0x154, 0x7CD, 0xBF3, 0x112, 0x89B, 0xC5E, 0x9CD, 0x07E, 0xFB6, 0x78F,
|
0xD54, 0x221, 0x154, 0x7CD, 0xBF3, 0x112, 0x89B, 0xC5E, 0x9CD, 0x07E, 0xFB6, 0x78F,
|
||||||
0x7FA, 0x16F, 0x377, 0x4B4, 0x62D, 0x475, 0xBC2, 0x861, 0xB72, 0x9D0, 0x76A, 0x5A1,
|
0x7FA, 0x16F, 0x377, 0x4B4, 0x62D, 0x475, 0xBC2, 0x861, 0xB72, 0x9D0, 0x76A, 0x5A1,
|
||||||
0x22A, 0xF74, 0xDBA, 0x8B1, 0x139, 0xDCD, 0x012, 0x293, 0x705, 0xA34, 0xDD5, 0x3D2,
|
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);
|
testEncodeDecodeRandom(super::AZTEC_DATA_12, 3072, 1023);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn corrupt(received: &mut Vec<i32>, howMany: i32, random: &rand::rngs::ThreadRng, max: i32) {
|
fn corrupt(received: &mut Vec<i32>, howMany: i32, random: &mut rand::rngs::ThreadRng, max: i32) {
|
||||||
let corrupted = vec![false; received.len()];
|
let mut corrupted = vec![false; received.len()];
|
||||||
//BitSet corrupted = new BitSet(received.length);
|
//BitSet corrupted = new BitSet(received.length);
|
||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
for j in 0..howMany {
|
for _j in 0..howMany {
|
||||||
//for (int j = 0; j < howMany; j++) {
|
//for (int j = 0; j < howMany; j++) {
|
||||||
if skip {
|
if skip {
|
||||||
skip = false;
|
skip = false;
|
||||||
@@ -367,17 +367,17 @@ fn testEncodeDecodeRandom(field: GenericGF, dataSize: usize, ecSize: usize) {
|
|||||||
"Invalid ECC size for {}",
|
"Invalid ECC size for {}",
|
||||||
field
|
field
|
||||||
);
|
);
|
||||||
let encoder = ReedSolomonEncoder::new(Box::new(field));
|
let encoder = ReedSolomonEncoder::new(Box::new(field.clone()));
|
||||||
let message = Vec::with_capacity(dataSize + ecSize);
|
let mut message = Vec::with_capacity(dataSize + ecSize);
|
||||||
let dataWords: Vec<i32> = Vec::with_capacity(dataSize);
|
let mut dataWords: Vec<i32> = Vec::with_capacity(dataSize);
|
||||||
let ecWords = Vec::with_capacity(ecSize);
|
let mut ecWords = Vec::with_capacity(ecSize);
|
||||||
let random = getPseudoRandom();
|
let mut random = getPseudoRandom();
|
||||||
let iterations = if field.getSize() > 256 {
|
let iterations = if field.getSize() > 256 {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
DECODER_RANDOM_TEST_ITERATIONS
|
DECODER_RANDOM_TEST_ITERATIONS
|
||||||
};
|
};
|
||||||
for i in 0..iterations {
|
for _i in 0..iterations {
|
||||||
//for (int i = 0; i < iterations; i++) {
|
//for (int i = 0; i < iterations; i++) {
|
||||||
// generate random data
|
// generate random data
|
||||||
for k in 0..dataSize {
|
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]);
|
ecWords[0..ecSize].clone_from_slice(&message[dataSize..ecSize]);
|
||||||
//System.arraycopy(message, dataSize, ecWords, 0, ecSize);
|
//System.arraycopy(message, dataSize, ecWords, 0, ecSize);
|
||||||
// check to see if Decoder can fix up to ecWords/2 random errors
|
// 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<i32>, ecWords: Vec<i32>) {
|
fn testEncodeDecode(field: &GenericGF, dataWords: &Vec<i32>, ecWords: &Vec<i32>) {
|
||||||
testEncoder(field, dataWords, ecWords);
|
testEncoder(field, dataWords, ecWords);
|
||||||
testDecoder(field, dataWords, ecWords);
|
testDecoder(field, dataWords, ecWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testEncoder(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));
|
let encoder = ReedSolomonEncoder::new(Box::new(field.clone()));
|
||||||
let messageExpected = Vec::with_capacity(dataWords.len() + ecWords.len());
|
let mut messageExpected = Vec::with_capacity(dataWords.len() + ecWords.len());
|
||||||
let message = 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()]);
|
messageExpected[0..dataWords.len()].clone_from_slice(&dataWords[0..dataWords.len()]);
|
||||||
//System.arraycopy(dataWords, 0, messageExpected, 0, dataWords.len());
|
//System.arraycopy(dataWords, 0, messageExpected, 0, dataWords.len());
|
||||||
messageExpected[dataWords.len()..ecWords.len()].clone_from_slice(&ecWords[..ecWords.len()]);
|
messageExpected[dataWords.len()..ecWords.len()].clone_from_slice(&ecWords[..ecWords.len()]);
|
||||||
@@ -418,24 +418,24 @@ fn testEncoder(field: GenericGF, dataWords: Vec<i32>, ecWords: Vec<i32>) {
|
|||||||
dataWords.len(),
|
dataWords.len(),
|
||||||
ecWords.len()
|
ecWords.len()
|
||||||
),
|
),
|
||||||
messageExpected,
|
&messageExpected,
|
||||||
message,
|
&message,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testDecoder(field: GenericGF, dataWords: Vec<i32>, ecWords: Vec<i32>) {
|
fn testDecoder(field: &GenericGF, dataWords: &Vec<i32>, ecWords: &Vec<i32>) {
|
||||||
let decoder = ReedSolomonDecoder::new(field);
|
let decoder = ReedSolomonDecoder::new(field.clone());
|
||||||
let message = Vec::with_capacity(dataWords.len() + ecWords.len());
|
let mut message = Vec::with_capacity(dataWords.len() + ecWords.len());
|
||||||
let maxErrors = ecWords.len() / 2;
|
let maxErrors = ecWords.len() / 2;
|
||||||
let random = getPseudoRandom();
|
let mut random = getPseudoRandom();
|
||||||
let iterations = if field.getSize() > 256 {
|
let iterations = if field.getSize() > 256 {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
DECODER_TEST_ITERATIONS
|
DECODER_TEST_ITERATIONS
|
||||||
};
|
};
|
||||||
for j in 0..iterations {
|
for _j in 0..iterations {
|
||||||
//for (int j = 0; j < iterations; j++) {
|
//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++) {
|
//for (int i = 0; i < ecWords.length; i++) {
|
||||||
if i > 10 && i < ecWords.len() / 2 - 10 {
|
if i > 10 && i < ecWords.len() / 2 - 10 {
|
||||||
// performance improvement - skip intermediate cases in long-running tests
|
// performance improvement - skip intermediate cases in long-running tests
|
||||||
@@ -448,7 +448,7 @@ fn testDecoder(field: GenericGF, dataWords: Vec<i32>, ecWords: Vec<i32>) {
|
|||||||
corrupt(
|
corrupt(
|
||||||
&mut message,
|
&mut message,
|
||||||
i.try_into().unwrap(),
|
i.try_into().unwrap(),
|
||||||
&random,
|
&mut random,
|
||||||
field.getSize().try_into().unwrap(),
|
field.getSize().try_into().unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -489,15 +489,15 @@ fn testDecoder(field: GenericGF, dataWords: Vec<i32>, ecWords: Vec<i32>) {
|
|||||||
ecWords.len(),
|
ecWords.len(),
|
||||||
i
|
i
|
||||||
),
|
),
|
||||||
dataWords,
|
&dataWords,
|
||||||
message,
|
&message,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assertDataEquals(message: String, expected: Vec<i32>, received: Vec<i32>) {
|
fn assertDataEquals(message: String, expected: &Vec<i32>, received: &Vec<i32>) {
|
||||||
for i in 0..expected.len() {
|
for i in 0..expected.len() {
|
||||||
//for (int i = 0; i < expected.length; i++) {
|
//for (int i = 0; i < expected.length; i++) {
|
||||||
if expected[i] != received[i] {
|
if expected[i] != received[i] {
|
||||||
@@ -514,7 +514,7 @@ fn assertDataEquals(message: String, expected: Vec<i32>, received: Vec<i32>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn arrayToString(data: &[i32]) -> String {
|
fn arrayToString(data: &[i32]) -> String {
|
||||||
let sb = String::from("{");
|
let mut sb = String::from("{");
|
||||||
for i in 0..data.len() {
|
for i in 0..data.len() {
|
||||||
//for (int i = 0; i < data.length; i++) {
|
//for (int i = 0; i < data.length; i++) {
|
||||||
//sb.append(String.format(i > 0 ? ",%X" : "%X", data[i]));
|
//sb.append(String.format(i > 0 ? ",%X" : "%X", data[i]));
|
||||||
|
|||||||
@@ -89,12 +89,12 @@ pub const MAXICODE_FIELD_64: GenericGF = AZTEC_DATA_6;
|
|||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
* @author David Olivier
|
* @author David Olivier
|
||||||
*/
|
*/
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Clone)]
|
||||||
pub struct GenericGF {
|
pub struct GenericGF {
|
||||||
expTable: Vec<i32>,
|
expTable: Vec<i32>,
|
||||||
logTable: Vec<i32>,
|
logTable: Vec<i32>,
|
||||||
zero: Box<GenericGFPoly>,
|
// zero: Box<GenericGFPoly>,
|
||||||
one: Box<GenericGFPoly>,
|
// one: Box<GenericGFPoly>,
|
||||||
size: usize,
|
size: usize,
|
||||||
primitive: i32,
|
primitive: i32,
|
||||||
generatorBase: i32,
|
generatorBase: i32,
|
||||||
@@ -125,18 +125,12 @@ impl GenericGF {
|
|||||||
* 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: i32, size: usize, b: i32) -> Self {
|
pub fn new(primitive: i32, size: usize, b: i32) -> Self {
|
||||||
let mut new_ggf: Self;
|
let mut expTable = Vec::with_capacity(size);
|
||||||
|
let mut logTable = Vec::with_capacity(size);
|
||||||
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 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++) {
|
||||||
new_ggf.expTable[i] = x;
|
expTable[i] = x;
|
||||||
x *= 2; // we're assuming the generator alpha is 2
|
x *= 2; // we're assuming the generator alpha is 2
|
||||||
if x >= size.try_into().unwrap() {
|
if x >= size.try_into().unwrap() {
|
||||||
x ^= primitive;
|
x ^= primitive;
|
||||||
@@ -146,35 +140,43 @@ impl GenericGF {
|
|||||||
}
|
}
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
//for (int i = 0; i < size - 1; i++) {
|
//for (int i = 0; i < size - 1; i++) {
|
||||||
let loc: usize = new_ggf.expTable[i].try_into().unwrap();
|
let loc: usize = expTable[i].try_into().unwrap();
|
||||||
new_ggf.logTable[loc] = 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
|
// 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;
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn getOne(&self) -> Box<GenericGFPoly> {
|
// pub fn getOne(&self) -> Box<GenericGFPoly> {
|
||||||
return self.one;
|
// return self.one;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the monomial representing coefficient * x^degree
|
* @return the monomial representing coefficient * x^degree
|
||||||
*/
|
*/
|
||||||
pub fn buildMonomial(&self, degree: usize, coefficient: i32) -> Box<GenericGFPoly> {
|
pub fn buildMonomial(&self, degree: usize, coefficient: i32) -> GenericGFPoly {
|
||||||
if coefficient == 0 {
|
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;
|
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
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Clone)]
|
||||||
pub struct GenericGFPoly {
|
pub struct GenericGFPoly {
|
||||||
field: Box<GenericGF>,
|
field: GenericGF,
|
||||||
coefficients: Vec<i32>,
|
coefficients: Vec<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +302,7 @@ impl GenericGFPoly {
|
|||||||
* constant polynomial (that is, it is not the monomial "0")
|
* constant polynomial (that is, it is not the monomial "0")
|
||||||
*/
|
*/
|
||||||
pub fn new(
|
pub fn new(
|
||||||
field: Box<GenericGF>,
|
field: GenericGF,
|
||||||
coefficients: &Vec<i32>,
|
coefficients: &Vec<i32>,
|
||||||
) -> Result<Self, IllegalArgumentException> {
|
) -> Result<Self, IllegalArgumentException> {
|
||||||
if coefficients.len() == 0 {
|
if coefficients.len() == 0 {
|
||||||
@@ -321,8 +323,9 @@ impl GenericGFPoly {
|
|||||||
} 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()]
|
let l = new_coefficients.len();
|
||||||
.clone_from_slice(&coefficients[firstNonZero..new_coefficients.len()]);
|
new_coefficients[0..l]
|
||||||
|
.clone_from_slice(&coefficients[firstNonZero..l]);
|
||||||
// System.arraycopy(coefficients,
|
// System.arraycopy(coefficients,
|
||||||
// firstNonZero,
|
// firstNonZero,
|
||||||
// this.coefficients,
|
// this.coefficients,
|
||||||
@@ -337,8 +340,8 @@ impl GenericGFPoly {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getCoefficients(&self) -> Vec<i32> {
|
pub fn getCoefficients(&self) -> &Vec<i32> {
|
||||||
return self.coefficients;
|
return &self.coefficients;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -373,9 +376,9 @@ impl GenericGFPoly {
|
|||||||
if a == 1 {
|
if a == 1 {
|
||||||
// Just the sum of the coefficients
|
// Just the sum of the coefficients
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
for coefficient in self.coefficients {
|
for coefficient in &self.coefficients {
|
||||||
//for (int coefficient : coefficients) {
|
//for (int coefficient : coefficients) {
|
||||||
result = GenericGF::addOrSubtract(result, coefficient);
|
result = GenericGF::addOrSubtract(result, *coefficient);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -396,22 +399,22 @@ impl GenericGFPoly {
|
|||||||
|
|
||||||
pub fn addOrSubtract(
|
pub fn addOrSubtract(
|
||||||
&self,
|
&self,
|
||||||
other: Box<GenericGFPoly>,
|
other: &GenericGFPoly,
|
||||||
) -> Result<Box<GenericGFPoly>, IllegalArgumentException> {
|
) -> Result<GenericGFPoly, IllegalArgumentException> {
|
||||||
if self.field != other.field {
|
if self.field != other.field {
|
||||||
return Err(IllegalArgumentException::new(
|
return Err(IllegalArgumentException::new(
|
||||||
"GenericGFPolys do not have same GenericGF field",
|
"GenericGFPolys do not have same GenericGF field",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if self.isZero() {
|
if self.isZero() {
|
||||||
return Ok(other);
|
return Ok(other.clone());
|
||||||
}
|
}
|
||||||
if other.isZero() {
|
if other.isZero() {
|
||||||
return Ok(Box::new(*self));
|
return Ok(self.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut smallerCoefficients = self.coefficients;
|
let mut smallerCoefficients = self.coefficients.clone();
|
||||||
let mut largerCoefficients = other.coefficients;
|
let mut largerCoefficients = other.coefficients.clone();
|
||||||
if smallerCoefficients.len() > largerCoefficients.len() {
|
if smallerCoefficients.len() > largerCoefficients.len() {
|
||||||
let temp = smallerCoefficients;
|
let temp = smallerCoefficients;
|
||||||
smallerCoefficients = largerCoefficients;
|
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(
|
pub fn multiply(
|
||||||
&self,
|
&self,
|
||||||
other: &GenericGFPoly,
|
other: &GenericGFPoly,
|
||||||
) -> Result<Box<GenericGFPoly>, IllegalArgumentException> {
|
) -> Result<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(
|
return Err(IllegalArgumentException::new(
|
||||||
@@ -446,13 +449,13 @@ impl GenericGFPoly {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
if self.isZero() || other.isZero() {
|
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 aLength = aCoefficients.len();
|
||||||
let bCoefficients = other.coefficients;
|
let bCoefficients = other.coefficients.clone();
|
||||||
let bLength = bCoefficients.len();
|
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 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];
|
||||||
@@ -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<GenericGFPoly> {
|
pub fn multiply_with_scalar(&self, scalar: i32) -> GenericGFPoly {
|
||||||
if scalar == 0 {
|
if scalar == 0 {
|
||||||
return self.field.getZero();
|
return self.getZero();
|
||||||
}
|
}
|
||||||
if scalar == 1 {
|
if scalar == 1 {
|
||||||
return Box::new(*self);
|
return self.clone();
|
||||||
}
|
}
|
||||||
let size = self.coefficients.len();
|
let size = self.coefficients.len();
|
||||||
|
|
||||||
let product = Vec::with_capacity(size);
|
let mut product = Vec::with_capacity(size);
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
//for (int i = 0; i < size; i++) {
|
//for (int i = 0; i < size; i++) {
|
||||||
product[i] = self
|
product[i] = self
|
||||||
.field
|
.field
|
||||||
.multiply(self.coefficients[i], scalar.try_into().unwrap());
|
.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(
|
pub fn multiplyByMonomial(
|
||||||
&self,
|
&self,
|
||||||
degree: usize,
|
degree: usize,
|
||||||
coefficient: i32,
|
coefficient: i32,
|
||||||
) -> Result<Box<GenericGFPoly>, IllegalArgumentException> {
|
) -> Result<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.getZero());
|
||||||
}
|
}
|
||||||
let size = self.coefficients.len();
|
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 i in 0..size {
|
||||||
//for (int i = 0; i < size; i++) {
|
//for (int i = 0; i < size; i++) {
|
||||||
product[i] = self.field.multiply(self.coefficients[i], coefficient);
|
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(
|
pub fn divide(
|
||||||
&self,
|
&self,
|
||||||
other: &GenericGFPoly,
|
other: &GenericGFPoly,
|
||||||
) -> Result<Vec<Box<GenericGFPoly>>, IllegalArgumentException> {
|
) -> Result<Vec<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(
|
return Err(IllegalArgumentException::new(
|
||||||
@@ -526,8 +537,8 @@ impl GenericGFPoly {
|
|||||||
return Err(IllegalArgumentException::new("Divide by 0"));
|
return Err(IllegalArgumentException::new("Divide by 0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut quotient = self.field.getZero();
|
let mut quotient = self.getZero();
|
||||||
let mut remainder = self;
|
let mut remainder = self.clone();
|
||||||
|
|
||||||
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) {
|
||||||
@@ -543,11 +554,11 @@ impl GenericGFPoly {
|
|||||||
);
|
);
|
||||||
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, remainder]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,10 +567,10 @@ impl fmt::Display for GenericGFPoly {
|
|||||||
if self.isZero() {
|
if self.isZero() {
|
||||||
return write!(f, "0");
|
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 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 mut coefficient = self.getCoefficient(degree);
|
||||||
if coefficient != 0 {
|
if coefficient != 0 {
|
||||||
if coefficient < 0 {
|
if coefficient < 0 {
|
||||||
if degree == self.getDegree() {
|
if degree == self.getDegree() {
|
||||||
@@ -567,23 +578,23 @@ impl fmt::Display for GenericGFPoly {
|
|||||||
} else {
|
} else {
|
||||||
result.push_str(" - ");
|
result.push_str(" - ");
|
||||||
}
|
}
|
||||||
//coefficient = -coefficient;
|
coefficient = -coefficient;
|
||||||
todo!("probably coefficient should be unsigned but what a mess");
|
//todo!("probably coefficient should be unsigned but what a mess");
|
||||||
} else {
|
} else {
|
||||||
if result.len() > 0 {
|
if result.len() > 0 {
|
||||||
result.push_str(" + ");
|
result.push_str(" + ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if degree == 0 || coefficient != 1 {
|
if degree == 0 || coefficient != 1 {
|
||||||
let alphaPower = self.field.log(coefficient);
|
if let Ok(alphaPower) = self.field.log(coefficient){
|
||||||
if alphaPower.unwrap() == 0 {
|
if alphaPower == 0 {
|
||||||
result.push_str("1");
|
result.push_str("1");
|
||||||
} else if alphaPower.unwrap() == 1 {
|
} else if alphaPower == 1 {
|
||||||
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));
|
||||||
}
|
}}
|
||||||
}
|
}
|
||||||
if degree != 0 {
|
if degree != 0 {
|
||||||
if degree == 1 {
|
if degree == 1 {
|
||||||
@@ -639,13 +650,13 @@ impl fmt::Display for GenericGFPoly {
|
|||||||
* @author sanfordsquires
|
* @author sanfordsquires
|
||||||
*/
|
*/
|
||||||
pub struct ReedSolomonDecoder {
|
pub struct ReedSolomonDecoder {
|
||||||
field: Box<GenericGF>,
|
field: GenericGF,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReedSolomonDecoder {
|
impl ReedSolomonDecoder {
|
||||||
pub fn new(field: GenericGF) -> Self {
|
pub fn new(field: GenericGF) -> Self {
|
||||||
Self {
|
Self {
|
||||||
field: Box::new(field),
|
field: field,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,18 +670,19 @@ impl ReedSolomonDecoder {
|
|||||||
* @throws ReedSolomonException if decoding fails for any reason
|
* @throws ReedSolomonException if decoding fails for any reason
|
||||||
*/
|
*/
|
||||||
pub fn decode(&self, received: &mut Vec<i32>, twoS: i32) -> Result<(), ReedSolomonException> {
|
pub fn decode(&self, received: &mut Vec<i32>, twoS: i32) -> Result<(), ReedSolomonException> {
|
||||||
let poly = GenericGFPoly::new(self.field, received);
|
let poly = GenericGFPoly::new(self.field.clone(), received).unwrap();
|
||||||
let syndromeCoefficients = Vec::with_capacity(twoS.try_into().unwrap());
|
let mut syndromeCoefficients = Vec::with_capacity(twoS.try_into().unwrap());
|
||||||
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(
|
let eval = poly.evaluateAt(
|
||||||
self.field
|
self.field
|
||||||
.exp(i + self.field.getGeneratorBase())
|
.exp(i + self.field.getGeneratorBase())
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
syndromeCoefficients[syndromeCoefficients.len() - 1 - i as usize] = eval;
|
let len = syndromeCoefficients.len();
|
||||||
|
syndromeCoefficients[len - 1 - i as usize] = eval;
|
||||||
if eval != 0 {
|
if eval != 0 {
|
||||||
noError = false;
|
noError = false;
|
||||||
}
|
}
|
||||||
@@ -678,17 +690,17 @@ impl ReedSolomonDecoder {
|
|||||||
if noError {
|
if noError {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let syndrome = match GenericGFPoly::new(self.field, &syndromeCoefficients) {
|
let syndrome = match GenericGFPoly::new(self.field.clone(), &syndromeCoefficients) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(fail) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
Err(fail) => return Err(ReedSolomonException::new("IllegalArgumentException")),
|
||||||
};
|
};
|
||||||
let sigmaOmega = self.runEuclideanAlgorithm(
|
let sigmaOmega = self.runEuclideanAlgorithm(
|
||||||
self.field.buildMonomial(twoS.try_into().unwrap(), 1),
|
&self.field.buildMonomial(twoS.try_into().unwrap(), 1),
|
||||||
Box::new(syndrome),
|
&syndrome,
|
||||||
twoS.try_into().unwrap(),
|
twoS.try_into().unwrap(),
|
||||||
);
|
)?;
|
||||||
let sigma = sigmaOmega?[0];
|
let sigma = &sigmaOmega[0];
|
||||||
let omega = sigmaOmega?[1];
|
let omega = &sigmaOmega[1];
|
||||||
let errorLocations = self.findErrorLocations(&sigma)?;
|
let errorLocations = self.findErrorLocations(&sigma)?;
|
||||||
let errorMagnitudes = self.findErrorMagnitudes(&omega, &errorLocations);
|
let errorMagnitudes = self.findErrorMagnitudes(&omega, &errorLocations);
|
||||||
for i in 0..errorLocations.len() {
|
for i in 0..errorLocations.len() {
|
||||||
@@ -709,21 +721,25 @@ impl ReedSolomonDecoder {
|
|||||||
|
|
||||||
fn runEuclideanAlgorithm(
|
fn runEuclideanAlgorithm(
|
||||||
&self,
|
&self,
|
||||||
a: Box<GenericGFPoly>,
|
a: &GenericGFPoly,
|
||||||
b: Box<GenericGFPoly>,
|
b: &GenericGFPoly,
|
||||||
R: usize,
|
R: usize,
|
||||||
) -> Result<Vec<GenericGFPoly>, ReedSolomonException> {
|
) -> Result<Vec<GenericGFPoly>, ReedSolomonException> {
|
||||||
// Assume a's degree is >= b's
|
// Assume a's degree is >= b's
|
||||||
|
let mut a = a;
|
||||||
|
let mut b = b;
|
||||||
if a.getDegree() < b.getDegree() {
|
if a.getDegree() < b.getDegree() {
|
||||||
let temp = a;
|
let temp = a;
|
||||||
a = b;
|
a = b;
|
||||||
b = temp;
|
b = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rLast = a;
|
let mut rLast = a;
|
||||||
let r = b;
|
let mut r = b;
|
||||||
let tLast = self.field.getZero();
|
// let tLast = self.field.getZero();
|
||||||
let t = self.field.getOne();
|
// 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
|
// Run Euclidean algorithm until r's degree is less than R/2
|
||||||
while 2 * r.getDegree() >= R {
|
while 2 * r.getDegree() >= R {
|
||||||
@@ -738,7 +754,7 @@ impl ReedSolomonDecoder {
|
|||||||
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 = a.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,
|
||||||
@@ -749,15 +765,15 @@ impl ReedSolomonDecoder {
|
|||||||
let scale = self
|
let scale = self
|
||||||
.field
|
.field
|
||||||
.multiply(r.getCoefficient(r.getDegree()), dltInverse);
|
.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")),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -766,7 +782,7 @@ impl ReedSolomonDecoder {
|
|||||||
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")),
|
||||||
@@ -791,7 +807,7 @@ impl ReedSolomonDecoder {
|
|||||||
};
|
};
|
||||||
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(
|
fn findErrorLocations(
|
||||||
@@ -898,12 +914,12 @@ impl ReedSolomonDecoder {
|
|||||||
* @author William Rucklidge
|
* @author William Rucklidge
|
||||||
*/
|
*/
|
||||||
pub struct ReedSolomonEncoder {
|
pub struct ReedSolomonEncoder {
|
||||||
field: Box<GenericGF>,
|
field: GenericGF,
|
||||||
cachedGenerators: Vec<GenericGFPoly>,
|
cachedGenerators: Vec<GenericGFPoly>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReedSolomonEncoder {
|
impl ReedSolomonEncoder {
|
||||||
pub fn new(field: Box<GenericGF>) -> Self {
|
pub fn new(field: GenericGF) -> Self {
|
||||||
Self {
|
Self {
|
||||||
field: field,
|
field: field,
|
||||||
cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()],
|
cachedGenerators: vec![GenericGFPoly::new(field, &vec![1]).unwrap()],
|
||||||
@@ -918,7 +934,7 @@ impl ReedSolomonEncoder {
|
|||||||
.unwrap();
|
.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
|
let nextGenerator = lastGenerator
|
||||||
.multiply(
|
.multiply(
|
||||||
&GenericGFPoly::new(
|
&GenericGFPoly::new(
|
||||||
self.field,
|
self.field,
|
||||||
@@ -950,11 +966,11 @@ impl ReedSolomonEncoder {
|
|||||||
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<i32> = Vec::with_capacity(dataBytes);
|
let mut infoCoefficients: Vec<i32> = Vec::with_capacity(dataBytes);
|
||||||
infoCoefficients[0..dataBytes].clone_from_slice(&toEncode[0..dataBytes]);
|
infoCoefficients[0..dataBytes].clone_from_slice(&toEncode[0..dataBytes]);
|
||||||
//System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
|
//System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);
|
||||||
let info = GenericGFPoly::new(self.field, &infoCoefficients)?;
|
let mut info = GenericGFPoly::new(self.field.clone(), &infoCoefficients)?;
|
||||||
info = *info.multiplyByMonomial(ecBytes.try_into().unwrap(), 1)?;
|
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 coefficients = remainder.getCoefficients();
|
||||||
let numZeroCoefficients = ecBytes - coefficients.len();
|
let numZeroCoefficients = ecBytes - coefficients.len();
|
||||||
|
|||||||
Reference in New Issue
Block a user