detector passes

This commit is contained in:
Henry Schimke
2022-09-28 16:46:22 -05:00
parent ad9ef3fee9
commit b4c59deb01
4 changed files with 220 additions and 183 deletions

View File

@@ -71,10 +71,11 @@ fn test_error_in_parameter_locator_not_compact() {
fn test_error_in_parameter_locator(data: &str) { fn test_error_in_parameter_locator(data: &str) {
let aztec = encoder::encoder::encode(data, 25, encoder::encoder::DEFAULT_AZTEC_LAYERS) let aztec = encoder::encoder::encode(data, 25, encoder::encoder::DEFAULT_AZTEC_LAYERS)
.expect("encode should create"); .expect("encode should create");
// dbg!(aztec.getMatrix().to_string());
let mut random = rand::thread_rng(); //Random(aztec.getMatrix().hashCode()); // pseudo-random, but deterministic let mut random = rand::thread_rng(); //Random(aztec.getMatrix().hashCode()); // pseudo-random, but deterministic
let layers = aztec.getLayers(); let layers = aztec.getLayers();
let compact = aztec.isCompact(); let compact = aztec.isCompact();
let orientation_points = getOrientationPoints(&aztec); let orientation_points = get_orientation_points(&aztec);
for isMirror in [false, true] { for isMirror in [false, true] {
// for (boolean isMirror : new boolean[] { false, true }) { // for (boolean isMirror : new boolean[] { false, true }) {
for matrix in get_rotations(aztec.getMatrix()) { for matrix in get_rotations(aztec.getMatrix()) {
@@ -90,16 +91,18 @@ fn test_error_in_parameter_locator(data: &str) {
clone(&matrix) clone(&matrix)
}; };
copy.flip_coords( copy.flip_coords(
orientation_points.get(error1).unwrap().get_x() as u32, orientation_points.get(error1).unwrap().get_x().abs() as u32,
orientation_points.get(error1).unwrap().get_y() as u32, orientation_points.get(error1).unwrap().get_y().abs() as u32,
); );
if error2 > error1 { if error2 > error1 {
// if error2 == error1, we only test a single error // if error2 == error1, we only test a single error
copy.flip_coords( copy.flip_coords(
orientation_points.get(error2).unwrap().get_x() as u32, orientation_points.get(error2).unwrap().get_x().abs() as u32,
orientation_points.get(error2).unwrap().get_y() as u32, orientation_points.get(error2).unwrap().get_y().abs() as u32,
); );
} }
// dbg!(copy.to_string());
// dbg!(make_larger(&copy, 3).to_string());
// The detector doesn't seem to work when matrix bits are only 1x1. So magnify. // The detector doesn't seem to work when matrix bits are only 1x1. So magnify.
let r = Detector::new(make_larger(&copy, 3)).detect(isMirror); let r = Detector::new(make_larger(&copy, 3)).detect(isMirror);
assert!(r.is_ok()); assert!(r.is_ok());
@@ -117,7 +120,7 @@ fn test_error_in_parameter_locator(data: &str) {
let mut errors = Vec::new(); let mut errors = Vec::new();
while errors.len() < 3 { while errors.len() < 3 {
// Quick and dirty way of getting three distinct integers between 1 and n. // Quick and dirty way of getting three distinct integers between 1 and n.
errors.push(random.gen_range(0..=orientation_points.len())); errors.push(random.gen_range(0..orientation_points.len()));
} }
for error in errors { for error in errors {
// for (int error : errors) { // for (int error : errors) {
@@ -125,22 +128,28 @@ fn test_error_in_parameter_locator(data: &str) {
orientation_points.get(error).unwrap().get_x() as u32, orientation_points.get(error).unwrap().get_x() as u32,
orientation_points.get(error).unwrap().get_y() as u32, orientation_points.get(error).unwrap().get_y() as u32,
); );
// copy.flip_coords(
// orientation_points.get(error).unwrap().get_x().abs() as u32,
// orientation_points.get(error).unwrap().get_y().abs() as u32,
// );
} }
// try { // try {
if let Err(res) = detector::Detector::new(make_larger(&copy, 3)).detect(false) { if let Err(res) = detector::Detector::new(make_larger(&copy, 3)).detect(false) {
if let Exceptions::NotFoundException(_msg) = res { if let Exceptions::NotFoundException(_msg) = res {
// all ok // all ok
} else { } else {
panic!("Should not reach here"); panic!("Only Exceptions::NotFoundException allowed, got {}", res);
} }
} else { } else {
panic!("Should not reach here"); let r = Detector::new(make_larger(&copy, 3)).detect(false);
assert!(r.is_ok());
let r = r.expect("result already tested as ok");
assert_eq!(r.getNbLayers(), layers);
assert_eq!(r.isCompact(), compact);
let res = decoder::decode(&r).expect("decode should be ok");
assert_eq!(data, res.getText());
//panic!("Should be unable to detect given value.");
} }
// // new Detector(makeLarger(copy, 3)).detect(false);
// fail("Should not reach here");
// } catch (NotFoundException expected) {
// // continue
// }
} }
} }
} }
@@ -155,7 +164,9 @@ fn make_larger(input: &BitMatrix, factor: u32) -> BitMatrix {
for inputX in 0..width { for inputX in 0..width {
// for (int inputX = 0; inputX < width; inputX++) { // for (int inputX = 0; inputX < width; inputX++) {
if input.get(inputX, inputY) { if input.get(inputX, inputY) {
output.setRegion(inputX * factor, inputY * factor, factor, factor).expect("region set should be ok"); output
.setRegion(inputX * factor, inputY * factor, factor, factor)
.expect("region set should be ok");
} }
} }
} }
@@ -168,6 +179,11 @@ fn get_rotations(matrix0: &BitMatrix) -> Vec<BitMatrix> {
let matrix180 = rotate_right(&matrix90); let matrix180 = rotate_right(&matrix90);
let matrix270 = rotate_right(&matrix180); let matrix270 = rotate_right(&matrix180);
vec![matrix0.clone(), matrix90, matrix180, matrix270] vec![matrix0.clone(), matrix90, matrix180, matrix270]
// vec![matrix0.clone()]
// vec![matrix90]
// vec![matrix180]
// vec![matrix270]
// vec![matrix0.clone(), matrix90, matrix270, matrix180 ]
} }
// Rotates a square BitMatrix to the right by 90 degrees // Rotates a square BitMatrix to the right by 90 degrees
@@ -178,7 +194,7 @@ fn rotate_right(input: &BitMatrix) -> BitMatrix {
// for (int x = 0; x < width; x++) { // for (int x = 0; x < width; x++) {
for y in 0..width { for y in 0..width {
// for (int y = 0; y < width; y++) { // for (int y = 0; y < width; y++) {
if (input.get(x, y)) { if input.get(x, y) {
result.set(y, width - x - 1); result.set(y, width - x - 1);
} }
} }
@@ -195,7 +211,7 @@ fn transpose(input: &BitMatrix) -> BitMatrix {
// for (int x = 0; x < width; x++) { // for (int x = 0; x < width; x++) {
for y in 0..width { for y in 0..width {
// for (int y = 0; y < width; y++) { // for (int y = 0; y < width; y++) {
if (input.get(x, y)) { if input.get(x, y) {
result.set(y, x); result.set(y, x);
} }
} }
@@ -218,7 +234,7 @@ fn clone(input: &BitMatrix) -> BitMatrix {
result result
} }
fn getOrientationPoints(code: &AztecCode) -> Vec<Point> { fn get_orientation_points(code: &AztecCode) -> Vec<Point> {
let center = code.getMatrix().getWidth() as i32 / 2; let center = code.getMatrix().getWidth() as i32 / 2;
let offset = if code.isCompact() { 5 } else { 7 }; let offset = if code.isCompact() { 5 } else { 7 };
let mut result = Vec::new(); let mut result = Vec::new();

View File

@@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
use std::fmt; use std::fmt;
use crate::{ use crate::{
@@ -91,7 +90,7 @@ impl Detector {
} }
// 3. Get the size of the matrix and other parameters from the bull's eye // 3. Get the size of the matrix and other parameters from the bull's eye
self.extractParameters(&bulls_eye_corners).expect("paramater extraction must succeed"); self.extractParameters(&bulls_eye_corners)?;
// 4. Sample the grid // 4. Sample the grid
let bits = self.sample_grid( let bits = self.sample_grid(
@@ -221,7 +220,7 @@ impl Detector {
* @throws NotFoundException if the array contains too many errors * @throws NotFoundException if the array contains too many errors
*/ */
fn get_corrected_parameter_data(parameterData: u64, compact: bool) -> Result<u32, Exceptions> { fn get_corrected_parameter_data(parameterData: u64, compact: bool) -> Result<u32, Exceptions> {
let mut parameterData = parameterData; let mut parameter_data = parameterData;
let num_codewords: i32; let num_codewords: i32;
let num_data_codewords: i32; let num_data_codewords: i32;
@@ -236,10 +235,10 @@ impl Detector {
let num_eccodewords = num_codewords - num_data_codewords; let num_eccodewords = num_codewords - num_data_codewords;
let mut parameterWords = vec![0i32; num_codewords as usize]; let mut parameterWords = vec![0i32; num_codewords as usize];
for i in (0..num_codewords - 1).rev() { for i in (0..num_codewords).rev() {
// for (int i = numCodewords - 1; i >= 0; --i) { // for (int i = numCodewords - 1; i >= 0; --i) {
parameterWords[i as usize] = (parameterData & 0xF) as i32; parameterWords[i as usize] = (parameter_data & 0xF) as i32;
parameterData >>= 4; parameter_data >>= 4;
} }
//try { //try {
let field = let field =
@@ -267,7 +266,10 @@ impl Detector {
* @return The corners of the bull-eye * @return The corners of the bull-eye
* @throws NotFoundException If no valid bull-eye can be found * @throws NotFoundException If no valid bull-eye can be found
*/ */
fn get_bulls_eye_corners(&mut self, pCenter: Point) -> Result<Vec<RXingResultPoint>, Exceptions> { fn get_bulls_eye_corners(
&mut self,
pCenter: Point,
) -> Result<Vec<RXingResultPoint>, Exceptions> {
let mut pina = pCenter; let mut pina = pCenter;
let mut pinb = pCenter; let mut pinb = pCenter;
let mut pinc = pCenter; let mut pinc = pCenter;
@@ -275,7 +277,10 @@ impl Detector {
let mut color = true; let mut color = true;
for nbCenterLayers in 1..9 { self.nb_center_layers = 1;
while self.nb_center_layers < 9 {
// for nbCenterLayers in 1..9 {
// for (nbCenterLayers = 1; nbCenterLayers < 9; nbCenterLayers++) { // for (nbCenterLayers = 1; nbCenterLayers < 9; nbCenterLayers++) {
let pouta = self.get_first_different(&pina, color, 1, -1); let pouta = self.get_first_different(&pina, color, 1, -1);
let poutb = self.get_first_different(&pinb, color, 1, 1); let poutb = self.get_first_different(&pinb, color, 1, 1);
@@ -286,12 +291,18 @@ impl Detector {
// //
//c b //c b
if nbCenterLayers > 2 { if self.nb_center_layers > 2 {
let q: f32 = let q: f32 = Self::distance_points(&poutd, &pouta) * self.nb_center_layers as f32
Self::distance(&poutd.to_rxing_result_point(), &pouta.to_rxing_result_point()) / (Self::distance_points(&pind, &pina) * (self.nb_center_layers + 2) as f32);
* nbCenterLayers as f32
/ (Self::distance(&pind.to_rxing_result_point(), &pina.to_rxing_result_point()) // let q: f32 = Self::distance(
* (nbCenterLayers + 2) as f32); // &poutd.to_rxing_result_point(),
// &pouta.to_rxing_result_point(),
// ) * nbCenterLayers as f32
// / (Self::distance(
// &pind.to_rxing_result_point(),
// &pina.to_rxing_result_point(),
// ) * (nbCenterLayers + 2) as f32);
if q < 0.75 if q < 0.75
|| q > 1.25 || q > 1.25
|| !self.is_white_or_black_rectangle(&pouta, &poutb, &poutc, &poutd) || !self.is_white_or_black_rectangle(&pouta, &poutb, &poutc, &poutd)
@@ -306,6 +317,8 @@ impl Detector {
pind = poutd; pind = poutd;
color = !color; color = !color;
self.nb_center_layers+=1;
} }
if self.nb_center_layers != 5 && self.nb_center_layers != 7 { if self.nb_center_layers != 5 && self.nb_center_layers != 7 {
@@ -316,10 +329,14 @@ impl Detector {
// Expand the square by .5 pixel in each direction so that we're on the border // Expand the square by .5 pixel in each direction so that we're on the border
// between the white square and the black square // between the white square and the black square
let pinax = RXingResultPoint::new(pina.get_x() as f32 + 0.5f32, pina.get_y() as f32 - 0.5f32); let pinax =
let pinbx = RXingResultPoint::new(pinb.get_x() as f32 + 0.5f32, pinb.get_y() as f32 + 0.5f32); RXingResultPoint::new(pina.get_x() as f32 + 0.5f32, pina.get_y() as f32 - 0.5f32);
let pincx = RXingResultPoint::new(pinc.get_x() as f32 - 0.5f32, pinc.get_y() as f32 + 0.5f32); let pinbx =
let pindx = RXingResultPoint::new(pind.get_x() as f32 - 0.5f32, pind.get_y() as f32 - 0.5f32); RXingResultPoint::new(pinb.get_x() as f32 + 0.5f32, pinb.get_y() as f32 + 0.5f32);
let pincx =
RXingResultPoint::new(pinc.get_x() as f32 - 0.5f32, pinc.get_y() as f32 + 0.5f32);
let pindx =
RXingResultPoint::new(pind.get_x() as f32 - 0.5f32, pind.get_y() as f32 - 0.5f32);
// Expand the square so that its corners are the centers of the points // Expand the square so that its corners are the centers of the points
// just outside the bull's eye. // just outside the bull's eye.
@@ -462,7 +479,10 @@ impl Detector {
* @param bullsEyeCorners the array of bull's eye corners * @param bullsEyeCorners the array of bull's eye corners
* @return the array of aztec code corners * @return the array of aztec code corners
*/ */
fn get_matrix_corner_points(&self, bulls_eye_corners: &[RXingResultPoint]) -> Vec<RXingResultPoint> { fn get_matrix_corner_points(
&self,
bulls_eye_corners: &[RXingResultPoint],
) -> Vec<RXingResultPoint> {
Self::expand_square( Self::expand_square(
bulls_eye_corners, bulls_eye_corners,
2 * self.nb_center_layers, 2 * self.nb_center_layers,
@@ -562,33 +582,33 @@ impl Detector {
// let p3 = Point::new(Math.min(image.getWidth() - 1, p3.getX() + corr), // let p3 = Point::new(Math.min(image.getWidth() - 1, p3.getX() + corr),
// Math.max(0, Math.min(image.getHeight() - 1, p3.getY() - corr))); // Math.max(0, Math.min(image.getHeight() - 1, p3.getY() - corr)));
let p4 = Point::new( let p4 = Point::new(
self.image.getWidth() as i32 - 1.min(p4.get_x() + corr), (self.image.getWidth() as i32 - 1).min(p4.get_x() + corr),
(self.image.getHeight() as i32 - 1).min(p4.get_y() + corr), (self.image.getHeight() as i32 - 1).min(p4.get_y() + corr),
); );
// let p4 = Point::new(Math.min(image.getWidth() - 1, p4.getX() + corr), // let p4 = Point::new(Math.min(image.getWidth() - 1, p4.getX() + corr),
// Math.min(image.getHeight() - 1, p4.getY() + corr)); // Math.min(image.getHeight() - 1, p4.getY() + corr));
let cInit = self.get_color(&p4, &p1); let c_init = self.get_color(&p4, &p1);
if cInit == 0 { if c_init == 0 {
return false; return false;
} }
let c = self.get_color(&p1, &p2); let c = self.get_color(&p1, &p2);
if c != cInit { if c != c_init {
return false; return false;
} }
let c = self.get_color(&p2, &p3); let c = self.get_color(&p2, &p3);
if c != cInit { if c != c_init {
return false; return false;
} }
let c = self.get_color(&p3, &p4); let c = self.get_color(&p3, &p4);
return c == cInit; return c == c_init;
} }
/** /**
@@ -605,19 +625,20 @@ impl Detector {
let dy = (p2.get_y() - p1.get_y()) as f32 / d; let dy = (p2.get_y() - p1.get_y()) as f32 / d;
let mut error = 0; let mut error = 0;
let mut px = p1.get_x(); let mut px = p1.get_x() as f32;
let mut py = p1.get_y(); let mut py = p1.get_y() as f32;
let color_model = self.image.get(p1.get_x() as u32, p1.get_y() as u32); let color_model = self.image.get(p1.get_x() as u32, p1.get_y() as u32);
let i_max = d.floor() as u32; //(int) Math.floor(d); let i_max = d.floor() as u32; //(int) Math.floor(d);
for _i in 0..i_max { for _i in 0..i_max {
// for (int i = 0; i < iMax; i++) { // for (int i = 0; i < iMax; i++) {
if self.image.get(px as u32, py as u32) != color_model {
if self.image.get(MathUtils::round(px) as u32, MathUtils::round(py) as u32) != color_model {
error += 1; error += 1;
} }
px += dx.floor() as i32; px += dx;
py += dy.floor() as i32; py += dy;
} }
let err_ratio = error as f32 / d; let err_ratio = error as f32 / d;

View File

@@ -422,107 +422,107 @@ impl WhiteRectangleDetector {
let mut right: i32 = self.rightInit; let mut right: i32 = self.rightInit;
let mut up: i32 = self.upInit; let mut up: i32 = self.upInit;
let mut down: i32 = self.downInit; let mut down: i32 = self.downInit;
let mut sizeExceeded = false; let mut size_exceeded = false;
let mut aBlackPointFoundOnBorder = true; let mut a_black_point_found_on_border = true;
let mut atLeastOneBlackPointFoundOnRight = false; let mut at_least_one_black_point_found_on_right = false;
let mut atLeastOneBlackPointFoundOnBottom = false; let mut at_least_one_black_point_found_on_bottom = false;
let mut atLeastOneBlackPointFoundOnLeft = false; let mut at_least_one_black_point_found_on_left = false;
let mut atLeastOneBlackPointFoundOnTop = false; let mut at_least_one_black_point_found_on_top = false;
while aBlackPointFoundOnBorder { while a_black_point_found_on_border {
aBlackPointFoundOnBorder = false; a_black_point_found_on_border = false;
// ..... // .....
// . | // . |
// ..... // .....
let mut rightBorderNotWhite = true; let mut right_border_not_white = true;
while (rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < self.width { while (right_border_not_white || !at_least_one_black_point_found_on_right) && right < self.width {
rightBorderNotWhite = self.containsBlackPoint(up, down, right, false); right_border_not_white = self.contains_black_point(up, down, right, false);
if rightBorderNotWhite { if right_border_not_white {
right += 1; right += 1;
aBlackPointFoundOnBorder = true; a_black_point_found_on_border = true;
atLeastOneBlackPointFoundOnRight = true; at_least_one_black_point_found_on_right = true;
} else if !atLeastOneBlackPointFoundOnRight { } else if !at_least_one_black_point_found_on_right {
right += 1; right += 1;
} }
} }
if right >= self.width { if right >= self.width {
sizeExceeded = true; size_exceeded = true;
break; break;
} }
// ..... // .....
// . . // . .
// .___. // .___.
let mut bottomBorderNotWhite = true; let mut bottom_border_not_white = true;
while (bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < self.height while (bottom_border_not_white || !at_least_one_black_point_found_on_bottom) && down < self.height
{ {
bottomBorderNotWhite = self.containsBlackPoint(left, right, down, true); bottom_border_not_white = self.contains_black_point(left, right, down, true);
if bottomBorderNotWhite { if bottom_border_not_white {
down += 1; down += 1;
aBlackPointFoundOnBorder = true; a_black_point_found_on_border = true;
atLeastOneBlackPointFoundOnBottom = true; at_least_one_black_point_found_on_bottom = true;
} else if !atLeastOneBlackPointFoundOnBottom { } else if !at_least_one_black_point_found_on_bottom {
down += 1; down += 1;
} }
} }
if down >= self.height { if down >= self.height {
sizeExceeded = true; size_exceeded = true;
break; break;
} }
// ..... // .....
// | . // | .
// ..... // .....
let mut leftBorderNotWhite = true; let mut left_border_not_white = true;
while (leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0 { while (left_border_not_white || !at_least_one_black_point_found_on_left) && left >= 0 {
leftBorderNotWhite = self.containsBlackPoint(up, down, left, false); left_border_not_white = self.contains_black_point(up, down, left, false);
if leftBorderNotWhite { if left_border_not_white {
left -= 1; left -= 1;
aBlackPointFoundOnBorder = true; a_black_point_found_on_border = true;
atLeastOneBlackPointFoundOnLeft = true; at_least_one_black_point_found_on_left = true;
} else if !atLeastOneBlackPointFoundOnLeft { } else if !at_least_one_black_point_found_on_left {
left -= 1; left -= 1;
} }
} }
if left < 0 { if left < 0 {
sizeExceeded = true; size_exceeded = true;
break; break;
} }
// .___. // .___.
// . . // . .
// ..... // .....
let mut topBorderNotWhite = true; let mut top_border_not_white = true;
while (topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0 { while (top_border_not_white || !at_least_one_black_point_found_on_top) && up >= 0 {
topBorderNotWhite = self.containsBlackPoint(left, right, up, true); top_border_not_white = self.contains_black_point(left, right, up, true);
if topBorderNotWhite { if top_border_not_white {
up -= 1; up -= 1;
aBlackPointFoundOnBorder = true; a_black_point_found_on_border = true;
atLeastOneBlackPointFoundOnTop = true; at_least_one_black_point_found_on_top = true;
} else if !atLeastOneBlackPointFoundOnTop { } else if !at_least_one_black_point_found_on_top {
up -= 1; up -= 1;
} }
} }
if up < 0 { if up < 0 {
sizeExceeded = true; size_exceeded = true;
break; break;
} }
} }
if !sizeExceeded { if !size_exceeded {
let maxSize = right - left; let max_size = right - left;
let mut z: Option<RXingResultPoint> = None; let mut z: Option<RXingResultPoint> = None;
let mut i = 1; let mut i = 1;
while z.is_none() && i < maxSize { while z.is_none() && i < max_size {
//for (int i = 1; z == null && i < maxSize; i++) { //for (int i = 1; z == null && i < maxSize; i++) {
z = self.getBlackPointOnSegment( z = self.get_black_point_on_segment(
left as f32, left as f32,
(down - i) as f32, (down - i) as f32,
(left + i) as f32, (left + i) as f32,
@@ -538,9 +538,9 @@ impl WhiteRectangleDetector {
let mut t: Option<RXingResultPoint> = None; let mut t: Option<RXingResultPoint> = None;
//go down right //go down right
let mut i = 1; let mut i = 1;
while t.is_none() && i < maxSize { while t.is_none() && i < max_size {
//for (int i = 1; t == null && i < maxSize; i++) { //for (int i = 1; t == null && i < maxSize; i++) {
t = self.getBlackPointOnSegment( t = self.get_black_point_on_segment(
left as f32, left as f32,
(up + i) as f32, (up + i) as f32,
(left + i) as f32, (left + i) as f32,
@@ -556,9 +556,9 @@ impl WhiteRectangleDetector {
let mut x: Option<RXingResultPoint> = None; let mut x: Option<RXingResultPoint> = None;
//go down left //go down left
let mut i = 1; let mut i = 1;
while x.is_none() && i < maxSize { while x.is_none() && i < max_size {
//for (int i = 1; x == null && i < maxSize; i++) { //for (int i = 1; x == null && i < maxSize; i++) {
x = self.getBlackPointOnSegment( x = self.get_black_point_on_segment(
right as f32, right as f32,
(up + i) as f32, (up + i) as f32,
(right - i) as f32, (right - i) as f32,
@@ -574,9 +574,9 @@ impl WhiteRectangleDetector {
let mut y: Option<RXingResultPoint> = None; let mut y: Option<RXingResultPoint> = None;
//go up left //go up left
let mut i = 1; let mut i = 1;
while y.is_none() && i < maxSize { while y.is_none() && i < max_size {
//for (int i = 1; y == null && i < maxSize; i++) { //for (int i = 1; y == null && i < maxSize; i++) {
y = self.getBlackPointOnSegment( y = self.get_black_point_on_segment(
right as f32, right as f32,
(down - i) as f32, (down - i) as f32,
(right - i) as f32, (right - i) as f32,
@@ -589,26 +589,26 @@ impl WhiteRectangleDetector {
return Err(Exceptions::NotFoundException("".to_owned())); return Err(Exceptions::NotFoundException("".to_owned()));
} }
return Ok(self.centerEdges(&y.unwrap(), &z.unwrap(), &x.unwrap(), &t.unwrap())); return Ok(self.center_edges(&y.unwrap(), &z.unwrap(), &x.unwrap(), &t.unwrap()));
} else { } else {
return Err(Exceptions::NotFoundException("".to_owned())); return Err(Exceptions::NotFoundException("".to_owned()));
} }
} }
fn getBlackPointOnSegment( fn get_black_point_on_segment(
&self, &self,
aX: f32, a_x: f32,
aY: f32, a_y: f32,
bX: f32, b_x: f32,
bY: f32, b_y: f32,
) -> Option<RXingResultPoint> { ) -> Option<RXingResultPoint> {
let dist = MathUtils::round(MathUtils::distance_float(aX, aY, bX, bY)); let dist = MathUtils::round(MathUtils::distance_float(a_x, a_y, b_x, b_y));
let xStep: f32 = (bX - aX) / dist as f32; let x_step: f32 = (b_x - a_x) / dist as f32;
let yStep: f32 = (bY - aY) / dist as f32; let y_step: f32 = (b_y - a_y) / dist as f32;
for i in 0..dist { for i in 0..dist {
let x = MathUtils::round(aX + i as f32 * xStep); let x = MathUtils::round(a_x + i as f32 * x_step);
let y = MathUtils::round(aY + i as f32 * yStep); let y = MathUtils::round(a_y + i as f32 * y_step);
if self.image.get(x as u32, y as u32) { 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));
} }
@@ -629,7 +629,7 @@ impl WhiteRectangleDetector {
* point and the last, the bottommost. The second point will be * point and the last, the bottommost. The second point will be
* leftmost and the third, the rightmost * leftmost and the third, the rightmost
*/ */
fn centerEdges( fn center_edges(
&self, &self,
y: &RXingResultPoint, y: &RXingResultPoint,
z: &RXingResultPoint, z: &RXingResultPoint,
@@ -678,7 +678,7 @@ impl WhiteRectangleDetector {
* @param horizontal set to true if scan must be horizontal, false if vertical * @param horizontal set to true if scan must be horizontal, false if vertical
* @return true if a black point has been found, else false. * @return true if a black point has been found, else false.
*/ */
fn containsBlackPoint(&self, a: i32, b: i32, fixed: i32, horizontal: bool) -> bool { fn contains_black_point(&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 as u32, fixed as u32) { if self.image.get(x as u32, fixed as u32) {

View File

@@ -146,20 +146,20 @@ impl StringUtils {
// For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS, // For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS,
// which should be by far the most common encodings. // which should be by far the most common encodings.
let length = bytes.len(); let length = bytes.len();
let mut canBeISO88591 = true; let mut can_be_iso88591 = true;
let mut canBeShiftJIS = true; let mut can_be_shift_jis = true;
let mut canBeUTF8 = true; let mut can_be_utf8 = true;
let mut utf8BytesLeft = 0; let mut utf8_bytes_left = 0;
let mut utf2BytesChars = 0; let mut utf2_bytes_chars = 0;
let mut utf3BytesChars = 0; let mut utf3_bytes_chars = 0;
let mut utf4BytesChars = 0; let mut utf4_bytes_chars = 0;
let mut sjisBytesLeft = 0; let mut sjis_bytes_left = 0;
let mut sjisKatakanaChars = 0; let mut sjis_katakana_chars = 0;
let mut sjisCurKatakanaWordLength = 0; let mut sjis_cur_katakana_word_length = 0;
let mut sjisCurDoubleBytesWordLength = 0; let mut sjis_cur_double_bytes_word_length = 0;
let mut sjisMaxKatakanaWordLength = 0; let mut sjis_max_katakana_word_length = 0;
let mut sjisMaxDoubleBytesWordLength = 0; let mut sjis_max_double_bytes_word_length = 0;
let mut isoHighOther = 0; let mut iso_high_other = 0;
let utf8bom = bytes.len() > 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF; let utf8bom = bytes.len() > 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF;
@@ -167,37 +167,37 @@ impl StringUtils {
// for (int i = 0; // for (int i = 0;
// i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8); // i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8);
// i++) { // i++) {
if !(canBeISO88591 || canBeShiftJIS || canBeUTF8) { if !(can_be_iso88591 || can_be_shift_jis || can_be_utf8) {
break; break;
} }
let value = bytes[i] & 0xFF; let value = bytes[i] & 0xFF;
// UTF-8 stuff // UTF-8 stuff
if canBeUTF8 { if can_be_utf8 {
if utf8BytesLeft > 0 { if utf8_bytes_left > 0 {
if (value & 0x80) == 0 { if (value & 0x80) == 0 {
canBeUTF8 = false; can_be_utf8 = false;
} else { } else {
utf8BytesLeft -= 1; utf8_bytes_left -= 1;
} }
} else if (value & 0x80) != 0 { } else if (value & 0x80) != 0 {
if (value & 0x40) == 0 { if (value & 0x40) == 0 {
canBeUTF8 = false; can_be_utf8 = false;
} else { } else {
utf8BytesLeft += 1; utf8_bytes_left += 1;
if (value & 0x20) == 0 { if (value & 0x20) == 0 {
utf2BytesChars += 1; utf2_bytes_chars += 1;
} else { } else {
utf8BytesLeft += 1; utf8_bytes_left += 1;
if (value & 0x10) == 0 { if (value & 0x10) == 0 {
utf3BytesChars += 1; utf3_bytes_chars += 1;
} else { } else {
utf8BytesLeft += 1; utf8_bytes_left += 1;
if (value & 0x08) == 0 { if (value & 0x08) == 0 {
utf4BytesChars += 1; utf4_bytes_chars += 1;
} else { } else {
canBeUTF8 = false; can_be_utf8 = false;
} }
} }
} }
@@ -206,63 +206,63 @@ impl StringUtils {
} }
// ISO-8859-1 stuff // ISO-8859-1 stuff
if canBeISO88591 { if can_be_iso88591 {
if value > 0x7F && value < 0xA0 { if value > 0x7F && value < 0xA0 {
canBeISO88591 = false; can_be_iso88591 = false;
} else if value > 0x9F && (value < 0xC0 || value == 0xD7 || value == 0xF7) { } else if value > 0x9F && (value < 0xC0 || value == 0xD7 || value == 0xF7) {
isoHighOther += 1; iso_high_other += 1;
} }
} }
// Shift_JIS stuff // Shift_JIS stuff
if canBeShiftJIS { if can_be_shift_jis {
if sjisBytesLeft > 0 { if sjis_bytes_left > 0 {
if value < 0x40 || value == 0x7F || value > 0xFC { if value < 0x40 || value == 0x7F || value > 0xFC {
canBeShiftJIS = false; can_be_shift_jis = false;
} else { } else {
sjisBytesLeft -= 1; sjis_bytes_left -= 1;
} }
} else if value == 0x80 || value == 0xA0 || value > 0xEF { } else if value == 0x80 || value == 0xA0 || value > 0xEF {
canBeShiftJIS = false; can_be_shift_jis = false;
} else if value > 0xA0 && value < 0xE0 { } else if value > 0xA0 && value < 0xE0 {
sjisKatakanaChars += 1; sjis_katakana_chars += 1;
sjisCurDoubleBytesWordLength = 0; sjis_cur_double_bytes_word_length = 0;
sjisCurKatakanaWordLength += 1; sjis_cur_katakana_word_length += 1;
if sjisCurKatakanaWordLength > sjisMaxKatakanaWordLength { if sjis_cur_katakana_word_length > sjis_max_katakana_word_length {
sjisMaxKatakanaWordLength = sjisCurKatakanaWordLength; sjis_max_katakana_word_length = sjis_cur_katakana_word_length;
} }
} else if value > 0x7F { } else if value > 0x7F {
sjisBytesLeft += 1; sjis_bytes_left += 1;
//sjisDoubleBytesChars++; //sjisDoubleBytesChars++;
sjisCurKatakanaWordLength = 0; sjis_cur_katakana_word_length = 0;
sjisCurDoubleBytesWordLength += 1; sjis_cur_double_bytes_word_length += 1;
if sjisCurDoubleBytesWordLength > sjisMaxDoubleBytesWordLength { if sjis_cur_double_bytes_word_length > sjis_max_double_bytes_word_length {
sjisMaxDoubleBytesWordLength = sjisCurDoubleBytesWordLength; sjis_max_double_bytes_word_length = sjis_cur_double_bytes_word_length;
} }
} else { } else {
//sjisLowChars++; //sjisLowChars++;
sjisCurKatakanaWordLength = 0; sjis_cur_katakana_word_length = 0;
sjisCurDoubleBytesWordLength = 0; sjis_cur_double_bytes_word_length = 0;
} }
} }
} }
if canBeUTF8 && utf8BytesLeft > 0 { if can_be_utf8 && utf8_bytes_left > 0 {
canBeUTF8 = false; can_be_utf8 = false;
} }
if canBeShiftJIS && sjisBytesLeft > 0 { if can_be_shift_jis && sjis_bytes_left > 0 {
canBeShiftJIS = false; can_be_shift_jis = false;
} }
// Easy -- if there is BOM or at least 1 valid not-single byte character (and no evidence it can't be UTF-8), done // Easy -- if there is BOM or at least 1 valid not-single byte character (and no evidence it can't be UTF-8), done
if canBeUTF8 && (utf8bom || utf2BytesChars + utf3BytesChars + utf4BytesChars > 0) { if can_be_utf8 && (utf8bom || utf2_bytes_chars + utf3_bytes_chars + utf4_bytes_chars > 0) {
return encoding::all::UTF_8; return encoding::all::UTF_8;
} }
// Easy -- if assuming Shift_JIS or >= 3 valid consecutive not-ascii characters (and no evidence it can't be), done // Easy -- if assuming Shift_JIS or >= 3 valid consecutive not-ascii characters (and no evidence it can't be), done
if canBeShiftJIS if can_be_shift_jis
&& (ASSUME_SHIFT_JIS && (ASSUME_SHIFT_JIS
|| sjisMaxKatakanaWordLength >= 3 || sjis_max_katakana_word_length >= 3
|| sjisMaxDoubleBytesWordLength >= 3) || sjis_max_double_bytes_word_length >= 3)
{ {
return encoding::label::encoding_from_whatwg_label("SJIS").unwrap(); return encoding::label::encoding_from_whatwg_label("SJIS").unwrap();
} }
@@ -271,9 +271,9 @@ impl StringUtils {
// - only two consecutive katakana chars in the whole text, or // - only two consecutive katakana chars in the whole text, or
// - at least 10% of bytes that could be "upper" not-alphanumeric Latin1, // - at least 10% of bytes that could be "upper" not-alphanumeric Latin1,
// - then we conclude Shift_JIS, else ISO-8859-1 // - then we conclude Shift_JIS, else ISO-8859-1
if canBeISO88591 && canBeShiftJIS { if can_be_iso88591 && can_be_shift_jis {
return if (sjisMaxKatakanaWordLength == 2 && sjisKatakanaChars == 2) return if (sjis_max_katakana_word_length == 2 && sjis_katakana_chars == 2)
|| isoHighOther * 10 >= length || iso_high_other * 10 >= length
{ {
encoding::label::encoding_from_whatwg_label("SJIS").unwrap() encoding::label::encoding_from_whatwg_label("SJIS").unwrap()
} else { } else {
@@ -282,13 +282,13 @@ impl StringUtils {
} }
// Otherwise, try in order ISO-8859-1, Shift JIS, UTF-8 and fall back to default platform encoding // Otherwise, try in order ISO-8859-1, Shift JIS, UTF-8 and fall back to default platform encoding
if canBeISO88591 { if can_be_iso88591 {
return encoding::all::ISO_8859_1; return encoding::all::ISO_8859_1;
} }
if canBeShiftJIS { if can_be_shift_jis {
return encoding::label::encoding_from_whatwg_label("SJIS").unwrap(); return encoding::label::encoding_from_whatwg_label("SJIS").unwrap();
} }
if canBeUTF8 { if can_be_utf8 {
return encoding::all::UTF_8; return encoding::all::UTF_8;
} }
// Otherwise, we take a wild guess with platform encoding // Otherwise, we take a wild guess with platform encoding
@@ -361,7 +361,7 @@ impl BitArray {
return (self.size + 7) / 8; return (self.size + 7) / 8;
} }
fn ensureCapacity(&mut self, newSize: usize) { fn ensure_capacity(&mut self, newSize: usize) {
if newSize > self.bits.len() * 32 { if newSize > self.bits.len() * 32 {
let mut newBits = BitArray::makeArray((newSize as f32 / LOAD_FACTOR).ceil() as usize); let mut newBits = BitArray::makeArray((newSize as f32 / LOAD_FACTOR).ceil() as usize);
//System.arraycopy(bits, 0, newBits, 0, bits.length); //System.arraycopy(bits, 0, newBits, 0, bits.length);
@@ -536,7 +536,7 @@ impl BitArray {
} }
pub fn appendBit(&mut self, bit: bool) { pub fn appendBit(&mut self, bit: bool) {
self.ensureCapacity(self.size + 1); self.ensure_capacity(self.size + 1);
if bit { if bit {
self.bits[self.size / 32] |= 1 << (self.size & 0x1F); self.bits[self.size / 32] |= 1 << (self.size & 0x1F);
} }
@@ -563,7 +563,7 @@ impl BitArray {
} }
let mut nextSize = self.size; let mut nextSize = self.size;
self.ensureCapacity(nextSize + numBits); self.ensure_capacity(nextSize + numBits);
for numBitsLeft in (0..(numBits)).rev() { for numBitsLeft in (0..(numBits)).rev() {
//for (int numBitsLeft = numBits - 1; numBitsLeft >= 0; numBitsLeft--) { //for (int numBitsLeft = numBits - 1; numBitsLeft >= 0; numBitsLeft--) {
if (value & (1 << numBitsLeft)) != 0 { if (value & (1 << numBitsLeft)) != 0 {
@@ -577,7 +577,7 @@ impl BitArray {
pub fn appendBitArray(&mut self, other: BitArray) { pub fn appendBitArray(&mut self, other: BitArray) {
let otherSize = other.size; let otherSize = other.size;
self.ensureCapacity(self.size + otherSize); self.ensure_capacity(self.size + otherSize);
for i in 0..otherSize { for i in 0..otherSize {
//for (int i = 0; i < otherSize; i++) { //for (int i = 0; i < otherSize; i++) {
self.appendBit(other.get(i)); self.appendBit(other.get(i));
@@ -1663,10 +1663,10 @@ impl PerspectiveTransform {
x3p: f32, x3p: f32,
y3p: f32, y3p: f32,
) -> Self { ) -> Self {
let qToS = PerspectiveTransform::quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3); let q_to_s = PerspectiveTransform::quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);
let sToQ = let s_to_q =
PerspectiveTransform::squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p); PerspectiveTransform::squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);
return sToQ.times(&qToS); return s_to_q.times(&q_to_s);
} }
pub fn transform_points_single(&self, points: &mut [f32]) { pub fn transform_points_single(&self, points: &mut [f32]) {
@@ -2335,27 +2335,27 @@ impl GridSampler for DefaultGridSampler {
for y in 0..dimensionY { for y in 0..dimensionY {
// for (int y = 0; y < dimensionY; y++) { // for (int y = 0; y < dimensionY; y++) {
let max = points.len(); let max = points.len();
let iValue = y as f32 + 0.5f32; let i_value = y as f32 + 0.5f32;
let mut x = 0; let mut x = 0;
while x < max { while x < max {
// for (int x = 0; x < max; x += 2) { // for (int x = 0; x < max; x += 2) {
points[x] = (x as f32 / 2.0) + 0.5f32; points[x] = (x as f32 / 2.0) + 0.5f32;
points[x + 1] = iValue; points[x + 1] = i_value;
x += 2; x += 2;
} }
transform.transform_points_single(&mut points); transform.transform_points_single(&mut points);
// Quick check to see if points transformed to something inside the image; // Quick check to see if points transformed to something inside the image;
// sufficient to check the endpoints // sufficient to check the endpoints
self.checkAndNudgePoints(image, &mut points); self.checkAndNudgePoints(image, &mut points)?;
// try { // try {
let mut x = 0; let mut x = 0;
while x < max { while x < max {
// for (int x = 0; x < max; x += 2) { // for (int x = 0; x < max; x += 2) {
if image.get(points[x] as u32, points[x + 1] as u32) { if image.get(points[x].floor() as u32, points[x + 1].floor() as u32) {
// Black(-ish) pixel // Black(-ish) pixel
bits.set(x as u32 / 2, y); bits.set(x as u32 / 2, y);
x += 2;
} }
x += 2;
} }
// } catch (ArrayIndexOutOfBoundsException aioobe) { // } catch (ArrayIndexOutOfBoundsException aioobe) {
// // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting // // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting