Computes an average estimated module size based on estimated derived from the positions
- * of the three finder patterns.
- *
- * @param topLeft detected top-left finder pattern center
- * @param topRight detected top-right finder pattern center
- * @param bottomLeft detected bottom-left finder pattern center
- * @return estimated module size
- */
- pub fn calculate_module_size(&self, top_left: &ResultPoint, top_right: &ResultPoint, bottom_left: &ResultPoint) -> f32 {
- // Take the average
- return (self.calculate_module_size_one_way(top_left, top_right) + self.calculate_module_size_one_way(top_left, bottom_left)) / 2.0f;
- }
-
- /**
- * Estimates module size based on two finder patterns -- it uses
- * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
- * width of each, measuring along the axis between their centers.
- */
- fn calculate_module_size_one_way(&self, pattern: &ResultPoint, other_pattern: &ResultPoint) -> f32 {
- let module_size_est1: f32 = self.size_of_black_white_black_run_both_ways(pattern.get_x() as i32, pattern.get_y() as i32, other_pattern.get_x() as i32, other_pattern.get_y() as i32);
- let module_size_est2: f32 = self.size_of_black_white_black_run_both_ways(other_pattern.get_x() as i32, other_pattern.get_y() as i32, pattern.get_x() as i32, pattern.get_y() as i32);
- if Float::is_na_n(module_size_est1) {
- return module_size_est2 / 7.0f;
- }
- if Float::is_na_n(module_size_est2) {
- return module_size_est1 / 7.0f;
- }
- // and 1 white and 1 black module on either side. Ergo, divide sum by 14.
- return (module_size_est1 + module_size_est2) / 14.0f;
- }
-
- /**
- * See {@link #sizeOfBlackWhiteBlackRun(int, int, int, int)}; computes the total width of
- * a finder pattern by looking for a black-white-black run from the center in the direction
- * of another point (another finder pattern center), and in the opposite direction too.
- */
- fn size_of_black_white_black_run_both_ways(&self, from_x: i32, from_y: i32, to_x: i32, to_y: i32) -> f32 {
- let mut result: f32 = self.size_of_black_white_black_run(from_x, from_y, to_x, to_y);
- // Now count other way -- don't run off image though of course
- let mut scale: f32 = 1.0f;
- let other_to_x: i32 = from_x - (to_x - from_x);
- if other_to_x < 0 {
- scale = from_x / (from_x - other_to_x) as f32;
- other_to_x = 0;
- } else if other_to_x >= self.image.get_width() {
- scale = (self.image.get_width() - 1.0 - from_x) / (other_to_x - from_x) as f32;
- other_to_x = self.image.get_width() - 1;
- }
- let other_to_y: i32 = (from_y - (to_y - from_y) * scale) as i32;
- scale = 1.0f;
- if other_to_y < 0 {
- scale = from_y / (from_y - other_to_y) as f32;
- other_to_y = 0;
- } else if other_to_y >= self.image.get_height() {
- scale = (self.image.get_height() - 1.0 - from_y) / (other_to_y - from_y) as f32;
- other_to_y = self.image.get_height() - 1;
- }
- other_to_x = (from_x + (other_to_x - from_x) * scale) as i32;
- result += self.size_of_black_white_black_run(from_x, from_y, other_to_x, other_to_y);
- // Middle pixel is double-counted this way; subtract 1
- return result - 1.0f;
- }
-
- /**
- * This method traces a line from a point in the image, in the direction towards another point.
- * It begins in a black region, and keeps going until it finds white, then black, then white again.
- * It reports the distance from the start to this point.
- *
- * This is used when figuring out how wide a finder pattern is, when the finder pattern
- * may be skewed or rotated.
- */
- fn size_of_black_white_black_run(&self, from_x: i32, from_y: i32, to_x: i32, to_y: i32) -> f32 {
- // Mild variant of Bresenham's algorithm;
- // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
- let steep: bool = Math::abs(to_y - from_y) > Math::abs(to_x - from_x);
- if steep {
- let mut temp: i32 = from_x;
- from_x = from_y;
- from_y = temp;
- temp = to_x;
- to_x = to_y;
- to_y = temp;
- }
- let dx: i32 = Math::abs(to_x - from_x);
- let dy: i32 = Math::abs(to_y - from_y);
- let mut error: i32 = -dx / 2;
- let xstep: i32 = if from_x < to_x { 1 } else { -1 };
- let ystep: i32 = if from_y < to_y { 1 } else { -1 };
- // In black pixels, looking for white, first or second time.
- let mut state: i32 = 0;
- // Loop up until x == toX, but not beyond
- let x_limit: i32 = to_x + xstep;
- {
- let mut x: i32 = from_x, let mut y: i32 = from_y;
- while x != x_limit {
- {
- let real_x: i32 = if steep { y } else { x };
- let real_y: i32 = if steep { x } else { y };
- // color, advance to next state or end if we are in state 2 already
- if (state == 1) == self.image.get(real_x, real_y) {
- if state == 2 {
- return MathUtils::distance(x, y, from_x, from_y);
- }
- state += 1;
- }
- error += dy;
- if error > 0 {
- if y == to_y {
- break;
- }
- y += ystep;
- error -= dx;
- }
- }
- x += xstep;
- }
- }
-
- // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this.
- if state == 2 {
- return MathUtils::distance(to_x + xstep, to_y, from_x, from_y);
- }
- // else we didn't find even black-white-black; no estimate is really possible
- return Float::NaN;
- }
-
- /**
- * Attempts to locate an alignment pattern in a limited region of the image, which is
- * guessed to contain it. This method uses {@link AlignmentPattern}.
- *
- * @param overallEstModuleSize estimated module size so far
- * @param estAlignmentX x coordinate of center of area probably containing alignment pattern
- * @param estAlignmentY y coordinate of above
- * @param allowanceFactor number of pixels in all directions to search from the center
- * @return {@link AlignmentPattern} if found, or null otherwise
- * @throws NotFoundException if an unexpected error occurs during detection
- */
- pub fn find_alignment_in_region(&self, overall_est_module_size: f32, est_alignment_x: i32, est_alignment_y: i32, allowance_factor: f32) -> /* throws NotFoundException */Result> {
- // Look for an alignment pattern (3 modules in size) around where it
- // should be
- let allowance: i32 = (allowance_factor * overall_est_module_size) as i32;
- let alignment_area_left_x: i32 = Math::max(0, est_alignment_x - allowance);
- let alignment_area_right_x: i32 = Math::min(self.image.get_width() - 1, est_alignment_x + allowance);
- if alignment_area_right_x - alignment_area_left_x < overall_est_module_size * 3.0 {
- throw NotFoundException::get_not_found_instance();
- }
- let alignment_area_top_y: i32 = Math::max(0, est_alignment_y - allowance);
- let alignment_area_bottom_y: i32 = Math::min(self.image.get_height() - 1, est_alignment_y + allowance);
- if alignment_area_bottom_y - alignment_area_top_y < overall_est_module_size * 3.0 {
- throw NotFoundException::get_not_found_instance();
- }
- let alignment_finder: AlignmentPatternFinder = AlignmentPatternFinder::new(self.image, alignment_area_left_x, alignment_area_top_y, alignment_area_right_x - alignment_area_left_x, alignment_area_bottom_y - alignment_area_top_y, overall_est_module_size, self.result_point_callback);
- return Ok(alignment_finder.find());
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/detector/finder_pattern.rs b/port_src/output/zxing/qrcode/detector/finder_pattern.rs
deleted file mode 100644
index e5371a8..0000000
--- a/port_src/output/zxing/qrcode/detector/finder_pattern.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::detector;
-
-/**
- * Encapsulates a finder pattern, which are the three square patterns found in
- * the corners of QR Codes. It also encapsulates a count of similar finder patterns,
- * as a convenience to the finder's bookkeeping.
- *
- * @author Sean Owen
- */
-pub struct FinderPattern {
- super: ResultPoint;
-
- let estimated_module_size: f32;
-
- let count: i32;
-}
-
-impl FinderPattern {
-
- fn new( pos_x: f32, pos_y: f32, estimated_module_size: f32) -> FinderPattern {
- this(pos_x, pos_y, estimated_module_size, 1);
- }
-
- fn new( pos_x: f32, pos_y: f32, estimated_module_size: f32, count: i32) -> FinderPattern {
- super(pos_x, pos_y);
- let .estimatedModuleSize = estimated_module_size;
- let .count = count;
- }
-
- pub fn get_estimated_module_size(&self) -> f32 {
- return self.estimated_module_size;
- }
-
- pub fn get_count(&self) -> i32 {
- return self.count;
- }
-
- /**
- * Determines if this finder pattern "about equals" a finder pattern at the stated
- * position and size -- meaning, it is at nearly the same center with nearly the same size.
- */
- fn about_equals(&self, module_size: f32, i: f32, j: f32) -> bool {
- if Math::abs(i - get_y()) <= module_size && Math::abs(j - get_x()) <= module_size {
- let module_size_diff: f32 = Math::abs(module_size - self.estimated_module_size);
- return module_size_diff <= 1.0f || module_size_diff <= self.estimated_module_size;
- }
- return false;
- }
-
- /**
- * Combines this object's current estimate of a finder pattern position and module size
- * with a new estimate. It returns a new {@code FinderPattern} containing a weighted average
- * based on count.
- */
- fn combine_estimate(&self, i: f32, j: f32, new_module_size: f32) -> FinderPattern {
- let combined_count: i32 = self.count + 1;
- let combined_x: f32 = (self.count * get_x() + j) / combined_count;
- let combined_y: f32 = (self.count * get_y() + i) / combined_count;
- let combined_module_size: f32 = (self.count * self.estimated_module_size + new_module_size) / combined_count;
- return FinderPattern::new(combined_x, combined_y, combined_module_size, combined_count);
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/detector/finder_pattern_finder.rs b/port_src/output/zxing/qrcode/detector/finder_pattern_finder.rs
deleted file mode 100644
index 3432311..0000000
--- a/port_src/output/zxing/qrcode/detector/finder_pattern_finder.rs
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::detector;
-
-/**
- * This class attempts to find finder patterns in a QR Code. Finder patterns are the square
- * markers at three corners of a QR Code.
- *
- * This class is thread-safe but not reentrant. Each thread must allocate its own object.
- *
- * @author Sean Owen
- */
-
- const CENTER_QUORUM: i32 = 2;
-
- let module_comparator: EstimatedModuleComparator = EstimatedModuleComparator::new();
-
-// 1 pixel/module times 3 modules/center
- const MIN_SKIP: i32 = 3;
-
-// support up to version 20 for mobile clients
- const MAX_MODULES: i32 = 97;
-pub struct FinderPatternFinder {
-
- let image: BitMatrix;
-
- let possible_centers: List;
-
- let has_skipped: bool;
-
- let cross_check_state_count: Vec;
-
- let result_point_callback: ResultPointCallback;
-}
-
-impl FinderPatternFinder {
-
- /**
- * Creates a finder that will search the image for three finder patterns.
- *
- * @param image image to search
- */
- pub fn new( image: &BitMatrix) -> FinderPatternFinder {
- this(image, null);
- }
-
- pub fn new( image: &BitMatrix, result_point_callback: &ResultPointCallback) -> FinderPatternFinder {
- let .image = image;
- let .possibleCenters = ArrayList<>::new();
- let .crossCheckStateCount = : [i32; 5] = [0; 5];
- let .resultPointCallback = result_point_callback;
- }
-
- pub fn get_image(&self) -> BitMatrix {
- return self.image;
- }
-
- pub fn get_possible_centers(&self) -> List {
- return self.possible_centers;
- }
-
- fn find(&self, hints: &Map) -> /* throws NotFoundException */Result> {
- let try_harder: bool = hints != null && hints.contains_key(DecodeHintType::TRY_HARDER);
- let max_i: i32 = self.image.get_height();
- let max_j: i32 = self.image.get_width();
- // We are looking for black/white/black/white/black modules in
- // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
- // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
- // image, and then account for the center being 3 modules in size. This gives the smallest
- // number of pixels the center could be, so skip this often. When trying harder, look for all
- // QR versions regardless of how dense they are.
- let i_skip: i32 = (3 * max_i) / (4 * MAX_MODULES);
- if i_skip < MIN_SKIP || try_harder {
- i_skip = MIN_SKIP;
- }
- let mut done: bool = false;
- let state_count: [i32; 5] = [0; 5];
- {
- let mut i: i32 = i_skip - 1;
- while i < max_i && !done {
- {
- // Get a row of black/white values
- ::do_clear_counts(&state_count);
- let current_state: i32 = 0;
- {
- let mut j: i32 = 0;
- while j < max_j {
- {
- if self.image.get(j, i) {
- // Black pixel
- if (current_state & 1) == 1 {
- // Counting white pixels
- current_state += 1;
- }
- state_count[current_state] += 1;
- } else {
- // White pixel
- if (current_state & 1) == 0 {
- // Counting black pixels
- if current_state == 4 {
- // A winner?
- if ::found_pattern_cross(&state_count) {
- // Yes
- let confirmed: bool = self.handle_possible_center(&state_count, i, j);
- if confirmed {
- // Start examining every other line. Checking each line turned out to be too
- // expensive and didn't improve performance.
- i_skip = 2;
- if self.has_skipped {
- done = self.have_multiply_confirmed_centers();
- } else {
- let row_skip: i32 = self.find_row_skip();
- if row_skip > state_count[2] {
- // Skip rows between row of lower confirmed center
- // and top of presumed third confirmed center
- // but back up a bit to get a full chance of detecting
- // it, entire width of center of finder pattern
- // Skip by rowSkip, but back off by stateCount[2] (size of last center
- // of pattern we saw) to be conservative, and also back off by iSkip which
- // is about to be re-added
- i += row_skip - state_count[2] - i_skip;
- j = max_j - 1;
- }
- }
- } else {
- ::do_shift_counts2(&state_count);
- current_state = 3;
- continue;
- }
- // Clear state to start looking again
- current_state = 0;
- ::do_clear_counts(&state_count);
- } else {
- // No, shift counts back by two
- ::do_shift_counts2(&state_count);
- current_state = 3;
- }
- } else {
- state_count[current_state += 1] += 1;
- }
- } else {
- // Counting white pixels
- state_count[current_state] += 1;
- }
- }
- }
- j += 1;
- }
- }
-
- if ::found_pattern_cross(&state_count) {
- let confirmed: bool = self.handle_possible_center(&state_count, i, max_j);
- if confirmed {
- i_skip = state_count[0];
- if self.has_skipped {
- // Found a third one
- done = self.have_multiply_confirmed_centers();
- }
- }
- }
- }
- i += i_skip;
- }
- }
-
- let pattern_info: Vec = self.select_best_patterns();
- ResultPoint::order_best_patterns(pattern_info);
- return Ok(FinderPatternInfo::new(pattern_info));
- }
-
- /**
- * Given a count of black/white/black/white/black pixels just seen and an end position,
- * figures the location of the center of this run.
- */
- fn center_from_end( state_count: &Vec, end: i32) -> f32 {
- return (end - state_count[4] - state_count[3]) - state_count[2] / 2.0f;
- }
-
- /**
- * @param stateCount count of black/white/black/white/black pixels just read
- * @return true iff the proportions of the counts is close enough to the 1/1/3/1/1 ratios
- * used by finder patterns to be considered a match
- */
- pub fn found_pattern_cross( state_count: &Vec) -> bool {
- let total_module_size: i32 = 0;
- {
- let mut i: i32 = 0;
- while i < 5 {
- {
- let count: i32 = state_count[i];
- if count == 0 {
- return false;
- }
- total_module_size += count;
- }
- i += 1;
- }
- }
-
- if total_module_size < 7 {
- return false;
- }
- let module_size: f32 = total_module_size / 7.0f;
- let max_variance: f32 = module_size / 2.0f;
- // Allow less than 50% variance from 1-1-3-1-1 proportions
- return Math::abs(module_size - state_count[0]) < max_variance && Math::abs(module_size - state_count[1]) < max_variance && Math::abs(3.0f * module_size - state_count[2]) < 3.0 * max_variance && Math::abs(module_size - state_count[3]) < max_variance && Math::abs(module_size - state_count[4]) < max_variance;
- }
-
- /**
- * @param stateCount count of black/white/black/white/black pixels just read
- * @return true iff the proportions of the counts is close enough to the 1/1/3/1/1 ratios
- * used by finder patterns to be considered a match
- */
- pub fn found_pattern_diagonal( state_count: &Vec) -> bool {
- let total_module_size: i32 = 0;
- {
- let mut i: i32 = 0;
- while i < 5 {
- {
- let count: i32 = state_count[i];
- if count == 0 {
- return false;
- }
- total_module_size += count;
- }
- i += 1;
- }
- }
-
- if total_module_size < 7 {
- return false;
- }
- let module_size: f32 = total_module_size / 7.0f;
- let max_variance: f32 = module_size / 1.333f;
- // Allow less than 75% variance from 1-1-3-1-1 proportions
- return Math::abs(module_size - state_count[0]) < max_variance && Math::abs(module_size - state_count[1]) < max_variance && Math::abs(3.0f * module_size - state_count[2]) < 3.0 * max_variance && Math::abs(module_size - state_count[3]) < max_variance && Math::abs(module_size - state_count[4]) < max_variance;
- }
-
- fn get_cross_check_state_count(&self) -> Vec {
- ::do_clear_counts(&self.cross_check_state_count);
- return self.cross_check_state_count;
- }
-
- pub fn clear_counts(&self, counts: &Vec) {
- ::do_clear_counts(&counts);
- }
-
- pub fn shift_counts2(&self, state_count: &Vec) {
- ::do_shift_counts2(&state_count);
- }
-
- pub fn do_clear_counts( counts: &Vec) {
- Arrays::fill(&counts, 0);
- }
-
- pub fn do_shift_counts2( state_count: &Vec) {
- state_count[0] = state_count[2];
- state_count[1] = state_count[3];
- state_count[2] = state_count[4];
- state_count[3] = 1;
- state_count[4] = 0;
- }
-
- /**
- * After a vertical and horizontal scan finds a potential finder pattern, this method
- * "cross-cross-cross-checks" by scanning down diagonally through the center of the possible
- * finder pattern to see if the same proportion is detected.
- *
- * @param centerI row where a finder pattern was detected
- * @param centerJ center of the section that appears to cross a finder pattern
- * @return true if proportions are withing expected limits
- */
- fn cross_check_diagonal(&self, center_i: i32, center_j: i32) -> bool {
- let state_count: Vec = self.get_cross_check_state_count();
- // Start counting up, left from center finding black center mass
- let mut i: i32 = 0;
- while center_i >= i && center_j >= i && self.image.get(center_j - i, center_i - i) {
- state_count[2] += 1;
- i += 1;
- }
- if state_count[2] == 0 {
- return false;
- }
- // Continue up, left finding white space
- while center_i >= i && center_j >= i && !self.image.get(center_j - i, center_i - i) {
- state_count[1] += 1;
- i += 1;
- }
- if state_count[1] == 0 {
- return false;
- }
- // Continue up, left finding black border
- while center_i >= i && center_j >= i && self.image.get(center_j - i, center_i - i) {
- state_count[0] += 1;
- i += 1;
- }
- if state_count[0] == 0 {
- return false;
- }
- let max_i: i32 = self.image.get_height();
- let max_j: i32 = self.image.get_width();
- // Now also count down, right from center
- i = 1;
- while center_i + i < max_i && center_j + i < max_j && self.image.get(center_j + i, center_i + i) {
- state_count[2] += 1;
- i += 1;
- }
- while center_i + i < max_i && center_j + i < max_j && !self.image.get(center_j + i, center_i + i) {
- state_count[3] += 1;
- i += 1;
- }
- if state_count[3] == 0 {
- return false;
- }
- while center_i + i < max_i && center_j + i < max_j && self.image.get(center_j + i, center_i + i) {
- state_count[4] += 1;
- i += 1;
- }
- if state_count[4] == 0 {
- return false;
- }
- return ::found_pattern_diagonal(&state_count);
- }
-
- /**
- * After a horizontal scan finds a potential finder pattern, this method
- * "cross-checks" by scanning down vertically through the center of the possible
- * finder pattern to see if the same proportion is detected.
- *
- * @param startI row where a finder pattern was detected
- * @param centerJ center of the section that appears to cross a finder pattern
- * @param maxCount maximum reasonable number of modules that should be
- * observed in any reading state, based on the results of the horizontal scan
- * @return vertical center of finder pattern, or {@link Float#NaN} if not found
- */
- fn cross_check_vertical(&self, start_i: i32, center_j: i32, max_count: i32, original_state_count_total: i32) -> f32 {
- let image: BitMatrix = self.image;
- let max_i: i32 = image.get_height();
- let state_count: Vec = self.get_cross_check_state_count();
- // Start counting up from center
- let mut i: i32 = start_i;
- while i >= 0 && image.get(center_j, i) {
- state_count[2] += 1;
- i -= 1;
- }
- if i < 0 {
- return Float::NaN;
- }
- while i >= 0 && !image.get(center_j, i) && state_count[1] <= max_count {
- state_count[1] += 1;
- i -= 1;
- }
- // If already too many modules in this state or ran off the edge:
- if i < 0 || state_count[1] > max_count {
- return Float::NaN;
- }
- while i >= 0 && image.get(center_j, i) && state_count[0] <= max_count {
- state_count[0] += 1;
- i -= 1;
- }
- if state_count[0] > max_count {
- return Float::NaN;
- }
- // Now also count down from center
- i = start_i + 1;
- while i < max_i && image.get(center_j, i) {
- state_count[2] += 1;
- i += 1;
- }
- if i == max_i {
- return Float::NaN;
- }
- while i < max_i && !image.get(center_j, i) && state_count[3] < max_count {
- state_count[3] += 1;
- i += 1;
- }
- if i == max_i || state_count[3] >= max_count {
- return Float::NaN;
- }
- while i < max_i && image.get(center_j, i) && state_count[4] < max_count {
- state_count[4] += 1;
- i += 1;
- }
- if state_count[4] >= max_count {
- return Float::NaN;
- }
- // If we found a finder-pattern-like section, but its size is more than 40% different than
- // the original, assume it's a false positive
- let state_count_total: i32 = state_count[0] + state_count[1] + state_count[2] + state_count[3] + state_count[4];
- if 5 * Math::abs(state_count_total - original_state_count_total) >= 2 * original_state_count_total {
- return Float::NaN;
- }
- return if ::found_pattern_cross(&state_count) { ::center_from_end(&state_count, i) } else { Float::NaN };
- }
-
- /**
- * Like {@link #crossCheckVertical(int, int, int, int)}, and in fact is basically identical,
- * except it reads horizontally instead of vertically. This is used to cross-cross
- * check a vertical cross check and locate the real center of the alignment pattern.
- */
- fn cross_check_horizontal(&self, start_j: i32, center_i: i32, max_count: i32, original_state_count_total: i32) -> f32 {
- let image: BitMatrix = self.image;
- let max_j: i32 = image.get_width();
- let state_count: Vec = self.get_cross_check_state_count();
- let mut j: i32 = start_j;
- while j >= 0 && image.get(j, center_i) {
- state_count[2] += 1;
- j -= 1;
- }
- if j < 0 {
- return Float::NaN;
- }
- while j >= 0 && !image.get(j, center_i) && state_count[1] <= max_count {
- state_count[1] += 1;
- j -= 1;
- }
- if j < 0 || state_count[1] > max_count {
- return Float::NaN;
- }
- while j >= 0 && image.get(j, center_i) && state_count[0] <= max_count {
- state_count[0] += 1;
- j -= 1;
- }
- if state_count[0] > max_count {
- return Float::NaN;
- }
- j = start_j + 1;
- while j < max_j && image.get(j, center_i) {
- state_count[2] += 1;
- j += 1;
- }
- if j == max_j {
- return Float::NaN;
- }
- while j < max_j && !image.get(j, center_i) && state_count[3] < max_count {
- state_count[3] += 1;
- j += 1;
- }
- if j == max_j || state_count[3] >= max_count {
- return Float::NaN;
- }
- while j < max_j && image.get(j, center_i) && state_count[4] < max_count {
- state_count[4] += 1;
- j += 1;
- }
- if state_count[4] >= max_count {
- return Float::NaN;
- }
- // If we found a finder-pattern-like section, but its size is significantly different than
- // the original, assume it's a false positive
- let state_count_total: i32 = state_count[0] + state_count[1] + state_count[2] + state_count[3] + state_count[4];
- if 5 * Math::abs(state_count_total - original_state_count_total) >= original_state_count_total {
- return Float::NaN;
- }
- return if ::found_pattern_cross(&state_count) { ::center_from_end(&state_count, j) } else { Float::NaN };
- }
-
- /**
- * @param stateCount reading state module counts from horizontal scan
- * @param i row where finder pattern may be found
- * @param j end of possible finder pattern in row
- * @param pureBarcode ignored
- * @return true if a finder pattern candidate was found this time
- * @deprecated only exists for backwards compatibility
- * @see #handlePossibleCenter(int[], int, int)
- */
- pub fn handle_possible_center(&self, state_count: &Vec, i: i32, j: i32, pure_barcode: bool) -> bool {
- return self.handle_possible_center(&state_count, i, j);
- }
-
- /**
- * This is called when a horizontal scan finds a possible alignment pattern. It will
- * cross check with a vertical scan, and if successful, will, ah, cross-cross-check
- * with another horizontal scan. This is needed primarily to locate the real horizontal
- * center of the pattern in cases of extreme skew.
- * And then we cross-cross-cross check with another diagonal scan.
- *
- * If that succeeds the finder pattern location is added to a list that tracks
- * the number of times each location has been nearly-matched as a finder pattern.
- * Each additional find is more evidence that the location is in fact a finder
- * pattern center
- *
- * @param stateCount reading state module counts from horizontal scan
- * @param i row where finder pattern may be found
- * @param j end of possible finder pattern in row
- * @return true if a finder pattern candidate was found this time
- */
- pub fn handle_possible_center(&self, state_count: &Vec, i: i32, j: i32) -> bool {
- let state_count_total: i32 = state_count[0] + state_count[1] + state_count[2] + state_count[3] + state_count[4];
- let center_j: f32 = ::center_from_end(&state_count, j);
- let center_i: f32 = self.cross_check_vertical(i, center_j as i32, state_count[2], state_count_total);
- if !Float::is_na_n(center_i) {
- // Re-cross check
- center_j = self.cross_check_horizontal(center_j as i32, center_i as i32, state_count[2], state_count_total);
- if !Float::is_na_n(center_j) && self.cross_check_diagonal(center_i as i32, center_j as i32) {
- let estimated_module_size: f32 = state_count_total / 7.0f;
- let mut found: bool = false;
- {
- let mut index: i32 = 0;
- while index < self.possible_centers.size() {
- {
- let center: FinderPattern = self.possible_centers.get(index);
- // Look for about the same center and module size:
- if center.about_equals(estimated_module_size, center_i, center_j) {
- self.possible_centers.set(index, ¢er.combine_estimate(center_i, center_j, estimated_module_size));
- found = true;
- break;
- }
- }
- index += 1;
- }
- }
-
- if !found {
- let point: FinderPattern = FinderPattern::new(center_j, center_i, estimated_module_size);
- self.possible_centers.add(point);
- if self.result_point_callback != null {
- self.result_point_callback.found_possible_result_point(point);
- }
- }
- return true;
- }
- }
- return false;
- }
-
- /**
- * @return number of rows we could safely skip during scanning, based on the first
- * two finder patterns that have been located. In some cases their position will
- * allow us to infer that the third pattern must lie below a certain point farther
- * down in the image.
- */
- fn find_row_skip(&self) -> i32 {
- let max: i32 = self.possible_centers.size();
- if max <= 1 {
- return 0;
- }
- let first_confirmed_center: ResultPoint = null;
- for let center: FinderPattern in self.possible_centers {
- if center.get_count() >= CENTER_QUORUM {
- if first_confirmed_center == null {
- first_confirmed_center = center;
- } else {
- // We have two confirmed centers
- // How far down can we skip before resuming looking for the next
- // pattern? In the worst case, only the difference between the
- // difference in the x / y coordinates of the two centers.
- // This is the case where you find top left last.
- self.has_skipped = true;
- return (Math::abs(first_confirmed_center.get_x() - center.get_x()) - Math::abs(first_confirmed_center.get_y() - center.get_y())) as i32 / 2;
- }
- }
- }
- return 0;
- }
-
- /**
- * @return true iff we have found at least 3 finder patterns that have been detected
- * at least {@link #CENTER_QUORUM} times each, and, the estimated module size of the
- * candidates is "pretty similar"
- */
- fn have_multiply_confirmed_centers(&self) -> bool {
- let confirmed_count: i32 = 0;
- let total_module_size: f32 = 0.0f;
- let max: i32 = self.possible_centers.size();
- for let pattern: FinderPattern in self.possible_centers {
- if pattern.get_count() >= CENTER_QUORUM {
- confirmed_count += 1;
- total_module_size += pattern.get_estimated_module_size();
- }
- }
- if confirmed_count < 3 {
- return false;
- }
- // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive"
- // and that we need to keep looking. We detect this by asking if the estimated module sizes
- // vary too much. We arbitrarily say that when the total deviation from average exceeds
- // 5% of the total module size estimates, it's too much.
- let average: f32 = total_module_size / max;
- let total_deviation: f32 = 0.0f;
- for let pattern: FinderPattern in self.possible_centers {
- total_deviation += Math::abs(pattern.get_estimated_module_size() - average);
- }
- return total_deviation <= 0.05f * total_module_size;
- }
-
- /**
- * Get square of distance between a and b.
- */
- fn squared_distance( a: &FinderPattern, b: &FinderPattern) -> f64 {
- let x: f64 = a.get_x() - b.get_x();
- let y: f64 = a.get_y() - b.get_y();
- return x * x + y * y;
- }
-
- /**
- * @return the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
- * those have similar module size and form a shape closer to a isosceles right triangle.
- * @throws NotFoundException if 3 such finder patterns do not exist
- */
- fn select_best_patterns(&self) -> /* throws NotFoundException */Result, Rc> {
- let start_size: i32 = self.possible_centers.size();
- if start_size < 3 {
- // Couldn't find enough finder patterns
- throw NotFoundException::get_not_found_instance();
- }
- self.possible_centers.sort(module_comparator);
- let mut distortion: f64 = Double::MAX_VALUE;
- let best_patterns: [Option; 3] = [None; 3];
- {
- let mut i: i32 = 0;
- while i < self.possible_centers.size() - 2 {
- {
- let fpi: FinderPattern = self.possible_centers.get(i);
- let min_module_size: f32 = fpi.get_estimated_module_size();
- {
- let mut j: i32 = i + 1;
- while j < self.possible_centers.size() - 1 {
- {
- let fpj: FinderPattern = self.possible_centers.get(j);
- let squares0: f64 = ::squared_distance(fpi, fpj);
- {
- let mut k: i32 = j + 1;
- while k < self.possible_centers.size() {
- {
- let fpk: FinderPattern = self.possible_centers.get(k);
- let max_module_size: f32 = fpk.get_estimated_module_size();
- if max_module_size > min_module_size * 1.4f {
- // module size is not similar
- continue;
- }
- let mut a: f64 = squares0;
- let mut b: f64 = ::squared_distance(fpj, fpk);
- let mut c: f64 = ::squared_distance(fpi, fpk);
- // sorts ascending - inlined
- if a < b {
- if b > c {
- if a < c {
- let temp: f64 = b;
- b = c;
- c = temp;
- } else {
- let temp: f64 = a;
- a = c;
- c = b;
- b = temp;
- }
- }
- } else {
- if b < c {
- if a < c {
- let temp: f64 = a;
- a = b;
- b = temp;
- } else {
- let temp: f64 = a;
- a = b;
- b = c;
- c = temp;
- }
- } else {
- let temp: f64 = a;
- a = c;
- c = temp;
- }
- }
- // a^2 + b^2 = c^2 (Pythagorean theorem), and a = b (isosceles triangle).
- // Since any right triangle satisfies the formula c^2 - b^2 - a^2 = 0,
- // we need to check both two equal sides separately.
- // The value of |c^2 - 2 * b^2| + |c^2 - 2 * a^2| increases as dissimilarity
- // from isosceles right triangle.
- let d: f64 = Math::abs(c - 2.0 * b) + Math::abs(c - 2.0 * a);
- if d < distortion {
- distortion = d;
- best_patterns[0] = fpi;
- best_patterns[1] = fpj;
- best_patterns[2] = fpk;
- }
- }
- k += 1;
- }
- }
-
- }
- j += 1;
- }
- }
-
- }
- i += 1;
- }
- }
-
- if distortion == Double::MAX_VALUE {
- throw NotFoundException::get_not_found_instance();
- }
- return Ok(best_patterns);
- }
-
- /**
- * Orders by {@link FinderPattern#getEstimatedModuleSize()}
- */
- #[derive(Comparator, Serializable)]
- struct EstimatedModuleComparator {
- }
-
- impl EstimatedModuleComparator {
-
- pub fn compare(&self, center1: &FinderPattern, center2: &FinderPattern) -> i32 {
- return Float::compare(¢er1.get_estimated_module_size(), ¢er2.get_estimated_module_size());
- }
- }
-
-}
-
diff --git a/port_src/output/zxing/qrcode/detector/finder_pattern_info.rs b/port_src/output/zxing/qrcode/detector/finder_pattern_info.rs
deleted file mode 100644
index 9712c03..0000000
--- a/port_src/output/zxing/qrcode/detector/finder_pattern_info.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::detector;
-
-/**
- * Encapsulates information about finder patterns in an image, including the location of
- * the three finder patterns, and their estimated module size.
- *
- * @author Sean Owen
- */
-pub struct FinderPatternInfo {
-
- let bottom_left: FinderPattern;
-
- let top_left: FinderPattern;
-
- let top_right: FinderPattern;
-}
-
-impl FinderPatternInfo {
-
- pub fn new( pattern_centers: &Vec) -> FinderPatternInfo {
- let .bottomLeft = pattern_centers[0];
- let .topLeft = pattern_centers[1];
- let .topRight = pattern_centers[2];
- }
-
- pub fn get_bottom_left(&self) -> FinderPattern {
- return self.bottom_left;
- }
-
- pub fn get_top_left(&self) -> FinderPattern {
- return self.top_left;
- }
-
- pub fn get_top_right(&self) -> FinderPattern {
- return self.top_right;
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/encoder/block_pair.rs b/port_src/output/zxing/qrcode/encoder/block_pair.rs
deleted file mode 100644
index d062c38..0000000
--- a/port_src/output/zxing/qrcode/encoder/block_pair.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::encoder;
-
-struct BlockPair {
-
- let data_bytes: Vec;
-
- let error_correction_bytes: Vec;
-}
-
-impl BlockPair {
-
- fn new( data: &Vec, error_correction: &Vec) -> BlockPair {
- data_bytes = data;
- error_correction_bytes = error_correction;
- }
-
- pub fn get_data_bytes(&self) -> Vec {
- return self.data_bytes;
- }
-
- pub fn get_error_correction_bytes(&self) -> Vec {
- return self.error_correction_bytes;
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/encoder/byte_matrix.rs b/port_src/output/zxing/qrcode/encoder/byte_matrix.rs
deleted file mode 100644
index c735da2..0000000
--- a/port_src/output/zxing/qrcode/encoder/byte_matrix.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::encoder;
-
-/**
- * JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned
- * -1, 0, and 1, I'm going to use less memory and go with bytes.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-pub struct ByteMatrix {
-
- let mut bytes: Vec>;
-
- let width: i32;
-
- let height: i32;
-}
-
-impl ByteMatrix {
-
- pub fn new( width: i32, height: i32) -> ByteMatrix {
- bytes = : [[i8; width]; height] = [[0; width]; height];
- let .width = width;
- let .height = height;
- }
-
- pub fn get_height(&self) -> i32 {
- return self.height;
- }
-
- pub fn get_width(&self) -> i32 {
- return self.width;
- }
-
- pub fn get(&self, x: i32, y: i32) -> i8 {
- return self.bytes[y][x];
- }
-
- /**
- * @return an internal representation as bytes, in row-major order. array[y][x] represents point (x,y)
- */
- pub fn get_array(&self) -> Vec> {
- return self.bytes;
- }
-
- pub fn set(&self, x: i32, y: i32, value: i8) {
- self.bytes[y][x] = value;
- }
-
- pub fn set(&self, x: i32, y: i32, value: i32) {
- self.bytes[y][x] = value as i8;
- }
-
- pub fn set(&self, x: i32, y: i32, value: bool) {
- self.bytes[y][x] = ( if value { 1 } else { 0 }) as i8;
- }
-
- pub fn clear(&self, value: i8) {
- for let a_byte: Vec in self.bytes {
- Arrays::fill(&a_byte, value);
- }
- }
-
- pub fn to_string(&self) -> String {
- let result: StringBuilder = StringBuilder::new(2 * self.width * self.height + 2);
- {
- let mut y: i32 = 0;
- while y < self.height {
- {
- let bytes_y: Vec = self.bytes[y];
- {
- let mut x: i32 = 0;
- while x < self.width {
- {
- match bytes_y[x] {
- 0 =>
- {
- result.append(" 0");
- break;
- }
- 1 =>
- {
- result.append(" 1");
- break;
- }
- _ =>
- {
- result.append(" ");
- break;
- }
- }
- }
- x += 1;
- }
- }
-
- result.append('\n');
- }
- y += 1;
- }
- }
-
- return result.to_string();
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/encoder/encoder.rs b/port_src/output/zxing/qrcode/encoder/encoder.rs
deleted file mode 100644
index 01357d3..0000000
--- a/port_src/output/zxing/qrcode/encoder/encoder.rs
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::encoder;
-
-/**
- * @author satorux@google.com (Satoru Takabayashi) - creator
- * @author dswitkin@google.com (Daniel Switkin) - ported from C++
- */
-
-// The original table is defined in the table 5 of JISX0510:2004 (p.19).
- const ALPHANUMERIC_TABLE: vec![Vec; 96] = vec![// 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x00-0x0f
-// 0x00-0x0f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x10-0x1f
-// 0x10-0x1f
--1, // 0x20-0x2f
-36, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-37, // 0x20-0x2f
-38, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-39, // 0x20-0x2f
-40, // 0x20-0x2f
-// 0x20-0x2f
--1, // 0x20-0x2f
-41, // 0x20-0x2f
-42, // 0x20-0x2f
-43, // 0x30-0x3f
-0, // 0x30-0x3f
-1, // 0x30-0x3f
-2, // 0x30-0x3f
-3, // 0x30-0x3f
-4, // 0x30-0x3f
-5, // 0x30-0x3f
-6, // 0x30-0x3f
-7, // 0x30-0x3f
-8, // 0x30-0x3f
-9, // 0x30-0x3f
-44, // 0x30-0x3f
-// 0x30-0x3f
--1, // 0x30-0x3f
-// 0x30-0x3f
--1, // 0x30-0x3f
-// 0x30-0x3f
--1, // 0x30-0x3f
-// 0x30-0x3f
--1, // 0x30-0x3f
-// 0x30-0x3f
--1, // 0x40-0x4f
-// 0x40-0x4f
--1, // 0x40-0x4f
-10, // 0x40-0x4f
-11, // 0x40-0x4f
-12, // 0x40-0x4f
-13, // 0x40-0x4f
-14, // 0x40-0x4f
-15, // 0x40-0x4f
-16, // 0x40-0x4f
-17, // 0x40-0x4f
-18, // 0x40-0x4f
-19, // 0x40-0x4f
-20, // 0x40-0x4f
-21, // 0x40-0x4f
-22, // 0x40-0x4f
-23, // 0x40-0x4f
-24, // 0x50-0x5f
-25, // 0x50-0x5f
-26, // 0x50-0x5f
-27, // 0x50-0x5f
-28, // 0x50-0x5f
-29, // 0x50-0x5f
-30, // 0x50-0x5f
-31, // 0x50-0x5f
-32, // 0x50-0x5f
-33, // 0x50-0x5f
-34, // 0x50-0x5f
-35, // 0x50-0x5f
-// 0x50-0x5f
--1, // 0x50-0x5f
-// 0x50-0x5f
--1, // 0x50-0x5f
-// 0x50-0x5f
--1, // 0x50-0x5f
-// 0x50-0x5f
--1, // 0x50-0x5f
-// 0x50-0x5f
--1, ]
-;
-
- const DEFAULT_BYTE_MODE_ENCODING: Charset = StandardCharsets::ISO_8859_1;
-pub struct Encoder {
-}
-
-impl Encoder {
-
- fn new() -> Encoder {
- }
-
- // The mask penalty calculation is complicated. See Table 21 of JISX0510:2004 (p.45) for details.
- // Basically it applies four rules and summate all penalties.
- fn calculate_mask_penalty( matrix: &ByteMatrix) -> i32 {
- return MaskUtil::apply_mask_penalty_rule1(matrix) + MaskUtil::apply_mask_penalty_rule2(matrix) + MaskUtil::apply_mask_penalty_rule3(matrix) + MaskUtil::apply_mask_penalty_rule4(matrix);
- }
-
- /**
- * @param content text to encode
- * @param ecLevel error correction level to use
- * @return {@link QRCode} representing the encoded QR code
- * @throws WriterException if encoding can't succeed, because of for example invalid content
- * or configuration
- */
- pub fn encode( content: &String, ec_level: &ErrorCorrectionLevel) -> /* throws WriterException */Result> {
- return Ok(::encode(&content, ec_level, null));
- }
-
- pub fn encode( content: &String, ec_level: &ErrorCorrectionLevel, hints: &Map) -> /* throws WriterException */Result> {
- let mut version: Version;
- let header_and_data_bits: BitArray;
- let mut mode: Mode;
- let has_g_s1_format_hint: bool = hints != null && hints.contains_key(EncodeHintType::GS1_FORMAT) && Boolean::parse_boolean(&hints.get(EncodeHintType::GS1_FORMAT).to_string());
- let has_compaction_hint: bool = hints != null && hints.contains_key(EncodeHintType::QR_COMPACT) && Boolean::parse_boolean(&hints.get(EncodeHintType::QR_COMPACT).to_string());
- // Determine what character encoding has been specified by the caller, if any
- let mut encoding: Charset = DEFAULT_BYTE_MODE_ENCODING;
- let has_encoding_hint: bool = hints != null && hints.contains_key(EncodeHintType::CHARACTER_SET);
- if has_encoding_hint {
- encoding = Charset::for_name(&hints.get(EncodeHintType::CHARACTER_SET).to_string());
- }
- if has_compaction_hint {
- mode = Mode::BYTE;
- let priority_encoding: Charset = if encoding.equals(&DEFAULT_BYTE_MODE_ENCODING) { null } else { encoding };
- let rn: MinimalEncoder.ResultList = MinimalEncoder::encode(&content, null, &priority_encoding, has_g_s1_format_hint, ec_level);
- header_and_data_bits = BitArray::new();
- rn.get_bits(header_and_data_bits);
- version = rn.get_version();
- } else {
- // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
- // multiple modes / segments even if that were more efficient.
- mode = ::choose_mode(&content, &encoding);
- // This will store the header information, like mode and
- // length, as well as "header" segments like an ECI segment.
- let header_bits: BitArray = BitArray::new();
- // Append ECI segment if applicable
- if mode == Mode::BYTE && has_encoding_hint {
- let eci: CharacterSetECI = CharacterSetECI::get_character_set_e_c_i(&encoding);
- if eci != null {
- ::append_e_c_i(eci, header_bits);
- }
- }
- // Append the FNC1 mode header for GS1 formatted data if applicable
- if has_g_s1_format_hint {
- // GS1 formatted codes are prefixed with a FNC1 in first position mode header
- ::append_mode_info(Mode::FNC1_FIRST_POSITION, header_bits);
- }
- // (With ECI in place,) Write the mode marker
- ::append_mode_info(mode, header_bits);
- // Collect data within the main segment, separately, to count its size if needed. Don't add it to
- // main payload yet.
- let data_bits: BitArray = BitArray::new();
- ::append_bytes(&content, mode, data_bits, &encoding);
- if hints != null && hints.contains_key(EncodeHintType::QR_VERSION) {
- let version_number: i32 = Integer::parse_int(&hints.get(EncodeHintType::QR_VERSION).to_string());
- version = Version::get_version_for_number(version_number);
- let bits_needed: i32 = ::calculate_bits_needed(mode, header_bits, data_bits, version);
- if !::will_fit(bits_needed, version, ec_level) {
- throw WriterException::new("Data too big for requested version");
- }
- } else {
- version = ::recommend_version(ec_level, mode, header_bits, data_bits);
- }
- header_and_data_bits = BitArray::new();
- header_and_data_bits.append_bit_array(header_bits);
- // Find "length" of main segment and write it
- let num_letters: i32 = if mode == Mode::BYTE { data_bits.get_size_in_bytes() } else { content.length() };
- ::append_length_info(num_letters, version, mode, header_and_data_bits);
- // Put data together into the overall payload
- header_and_data_bits.append_bit_array(data_bits);
- }
- let ec_blocks: Version.ECBlocks = version.get_e_c_blocks_for_level(ec_level);
- let num_data_bytes: i32 = version.get_total_codewords() - ec_blocks.get_total_e_c_codewords();
- // Terminate the bits properly.
- ::terminate_bits(num_data_bytes, header_and_data_bits);
- // Interleave data bits with error correction code.
- let final_bits: BitArray = ::interleave_with_e_c_bytes(header_and_data_bits, &version.get_total_codewords(), num_data_bytes, &ec_blocks.get_num_blocks());
- let qr_code: QRCode = QRCode::new();
- qr_code.set_e_c_level(ec_level);
- qr_code.set_mode(mode);
- qr_code.set_version(version);
- // Choose the mask pattern and set to "qrCode".
- let dimension: i32 = version.get_dimension_for_version();
- let matrix: ByteMatrix = ByteMatrix::new(dimension, dimension);
- // Enable manual selection of the pattern to be used via hint
- let mask_pattern: i32 = -1;
- if hints != null && hints.contains_key(EncodeHintType::QR_MASK_PATTERN) {
- let hint_mask_pattern: i32 = Integer::parse_int(&hints.get(EncodeHintType::QR_MASK_PATTERN).to_string());
- mask_pattern = if QRCode::is_valid_mask_pattern(hint_mask_pattern) { hint_mask_pattern } else { -1 };
- }
- if mask_pattern == -1 {
- mask_pattern = ::choose_mask_pattern(final_bits, ec_level, version, matrix);
- }
- qr_code.set_mask_pattern(mask_pattern);
- // Build the matrix and set it to "qrCode".
- MatrixUtil::build_matrix(final_bits, ec_level, version, mask_pattern, matrix);
- qr_code.set_matrix(matrix);
- return Ok(qr_code);
- }
-
- /**
- * Decides the smallest version of QR code that will contain all of the provided data.
- *
- * @throws WriterException if the data cannot fit in any version
- */
- fn recommend_version( ec_level: &ErrorCorrectionLevel, mode: &Mode, header_bits: &BitArray, data_bits: &BitArray) -> /* throws WriterException */Result> {
- // Hard part: need to know version to know how many bits length takes. But need to know how many
- // bits it takes to know version. First we take a guess at version by assuming version will be
- // the minimum, 1:
- let provisional_bits_needed: i32 = ::calculate_bits_needed(mode, header_bits, data_bits, &Version::get_version_for_number(1));
- let provisional_version: Version = ::choose_version(provisional_bits_needed, ec_level);
- // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
- let bits_needed: i32 = ::calculate_bits_needed(mode, header_bits, data_bits, provisional_version);
- return Ok(::choose_version(bits_needed, ec_level));
- }
-
- fn calculate_bits_needed( mode: &Mode, header_bits: &BitArray, data_bits: &BitArray, version: &Version) -> i32 {
- return header_bits.get_size() + mode.get_character_count_bits(version) + data_bits.get_size();
- }
-
- /**
- * @return the code point of the table used in alphanumeric mode or
- * -1 if there is no corresponding code in the table.
- */
- fn get_alphanumeric_code( code: i32) -> i32 {
- if code < ALPHANUMERIC_TABLE.len() {
- return ALPHANUMERIC_TABLE[code];
- }
- return -1;
- }
-
- pub fn choose_mode( content: &String) -> Mode {
- return ::choose_mode(&content, null);
- }
-
- /**
- * Choose the best mode by examining the content. Note that 'encoding' is used as a hint;
- * if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}.
- */
- fn choose_mode( content: &String, encoding: &Charset) -> Mode {
- if StringUtils::SHIFT_JIS_CHARSET::equals(&encoding) && ::is_only_double_byte_kanji(&content) {
- // Choose Kanji mode if all input are double-byte characters
- return Mode::KANJI;
- }
- let has_numeric: bool = false;
- let has_alphanumeric: bool = false;
- {
- let mut i: i32 = 0;
- while i < content.length() {
- {
- let c: char = content.char_at(i);
- if c >= '0' && c <= '9' {
- has_numeric = true;
- } else if ::get_alphanumeric_code(c) != -1 {
- has_alphanumeric = true;
- } else {
- return Mode::BYTE;
- }
- }
- i += 1;
- }
- }
-
- if has_alphanumeric {
- return Mode::ALPHANUMERIC;
- }
- if has_numeric {
- return Mode::NUMERIC;
- }
- return Mode::BYTE;
- }
-
- fn is_only_double_byte_kanji( content: &String) -> bool {
- let bytes: Vec = content.get_bytes(StringUtils::SHIFT_JIS_CHARSET);
- let length: i32 = bytes.len();
- if length % 2 != 0 {
- return false;
- }
- {
- let mut i: i32 = 0;
- while i < length {
- {
- let byte1: i32 = bytes[i] & 0xFF;
- if (byte1 < 0x81 || byte1 > 0x9F) && (byte1 < 0xE0 || byte1 > 0xEB) {
- return false;
- }
- }
- i += 2;
- }
- }
-
- return true;
- }
-
- fn choose_mask_pattern( bits: &BitArray, ec_level: &ErrorCorrectionLevel, version: &Version, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- // Lower penalty is better.
- let min_penalty: i32 = Integer::MAX_VALUE;
- let best_mask_pattern: i32 = -1;
- // We try all mask patterns to choose the best one.
- {
- let mask_pattern: i32 = 0;
- while mask_pattern < QRCode.NUM_MASK_PATTERNS {
- {
- MatrixUtil::build_matrix(bits, ec_level, version, mask_pattern, matrix);
- let penalty: i32 = ::calculate_mask_penalty(matrix);
- if penalty < min_penalty {
- min_penalty = penalty;
- best_mask_pattern = mask_pattern;
- }
- }
- mask_pattern += 1;
- }
- }
-
- return Ok(best_mask_pattern);
- }
-
- fn choose_version( num_input_bits: i32, ec_level: &ErrorCorrectionLevel) -> /* throws WriterException */Result> {
- {
- let version_num: i32 = 1;
- while version_num <= 40 {
- {
- let version: Version = Version::get_version_for_number(version_num);
- if ::will_fit(num_input_bits, version, ec_level) {
- return Ok(version);
- }
- }
- version_num += 1;
- }
- }
-
- throw WriterException::new("Data too big");
- }
-
- /**
- * @return true if the number of input bits will fit in a code with the specified version and
- * error correction level.
- */
- fn will_fit( num_input_bits: i32, version: &Version, ec_level: &ErrorCorrectionLevel) -> bool {
- // In the following comments, we use numbers of Version 7-H.
- // numBytes = 196
- let num_bytes: i32 = version.get_total_codewords();
- // getNumECBytes = 130
- let ec_blocks: Version.ECBlocks = version.get_e_c_blocks_for_level(ec_level);
- let num_ec_bytes: i32 = ec_blocks.get_total_e_c_codewords();
- // getNumDataBytes = 196 - 130 = 66
- let num_data_bytes: i32 = num_bytes - num_ec_bytes;
- let total_input_bytes: i32 = (num_input_bits + 7) / 8;
- return num_data_bytes >= total_input_bytes;
- }
-
- /**
- * Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24).
- */
- fn terminate_bits( num_data_bytes: i32, bits: &BitArray) -> /* throws WriterException */Result> {
- let capacity: i32 = num_data_bytes * 8;
- if bits.get_size() > capacity {
- throw WriterException::new(format!("data bits cannot fit in the QR Code{} > {}", bits.get_size(), capacity));
- }
- // Append Mode.TERMINATE if there is enough space (value is 0000)
- {
- let mut i: i32 = 0;
- while i < 4 && bits.get_size() < capacity {
- {
- bits.append_bit(false);
- }
- i += 1;
- }
- }
-
- // Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details.
- // If the last byte isn't 8-bit aligned, we'll add padding bits.
- let num_bits_in_last_byte: i32 = bits.get_size() & 0x07;
- if num_bits_in_last_byte > 0 {
- {
- let mut i: i32 = num_bits_in_last_byte;
- while i < 8 {
- {
- bits.append_bit(false);
- }
- i += 1;
- }
- }
-
- }
- // If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24).
- let num_padding_bytes: i32 = num_data_bytes - bits.get_size_in_bytes();
- {
- let mut i: i32 = 0;
- while i < num_padding_bytes {
- {
- bits.append_bits( if (i & 0x01) == 0 { 0xEC } else { 0x11 }, 8);
- }
- i += 1;
- }
- }
-
- if bits.get_size() != capacity {
- throw WriterException::new("Bits size does not equal capacity");
- }
- }
-
- /**
- * Get number of data bytes and number of error correction bytes for block id "blockID". Store
- * the result in "numDataBytesInBlock", and "numECBytesInBlock". See table 12 in 8.5.1 of
- * JISX0510:2004 (p.30)
- */
- fn get_num_data_bytes_and_num_e_c_bytes_for_block_i_d( num_total_bytes: i32, num_data_bytes: i32, num_r_s_blocks: i32, block_i_d: i32, num_data_bytes_in_block: &Vec, num_e_c_bytes_in_block: &Vec) -> /* throws WriterException */Result> {
- if block_i_d >= num_r_s_blocks {
- throw WriterException::new("Block ID too large");
- }
- // numRsBlocksInGroup2 = 196 % 5 = 1
- let num_rs_blocks_in_group2: i32 = num_total_bytes % num_r_s_blocks;
- // numRsBlocksInGroup1 = 5 - 1 = 4
- let num_rs_blocks_in_group1: i32 = num_r_s_blocks - num_rs_blocks_in_group2;
- // numTotalBytesInGroup1 = 196 / 5 = 39
- let num_total_bytes_in_group1: i32 = num_total_bytes / num_r_s_blocks;
- // numTotalBytesInGroup2 = 39 + 1 = 40
- let num_total_bytes_in_group2: i32 = num_total_bytes_in_group1 + 1;
- // numDataBytesInGroup1 = 66 / 5 = 13
- let num_data_bytes_in_group1: i32 = num_data_bytes / num_r_s_blocks;
- // numDataBytesInGroup2 = 13 + 1 = 14
- let num_data_bytes_in_group2: i32 = num_data_bytes_in_group1 + 1;
- // numEcBytesInGroup1 = 39 - 13 = 26
- let num_ec_bytes_in_group1: i32 = num_total_bytes_in_group1 - num_data_bytes_in_group1;
- // numEcBytesInGroup2 = 40 - 14 = 26
- let num_ec_bytes_in_group2: i32 = num_total_bytes_in_group2 - num_data_bytes_in_group2;
- // 26 = 26
- if num_ec_bytes_in_group1 != num_ec_bytes_in_group2 {
- throw WriterException::new("EC bytes mismatch");
- }
- // 5 = 4 + 1.
- if num_r_s_blocks != num_rs_blocks_in_group1 + num_rs_blocks_in_group2 {
- throw WriterException::new("RS blocks mismatch");
- }
- // 196 = (13 + 26) * 4 + (14 + 26) * 1
- if num_total_bytes != ((num_data_bytes_in_group1 + num_ec_bytes_in_group1) * num_rs_blocks_in_group1) + ((num_data_bytes_in_group2 + num_ec_bytes_in_group2) * num_rs_blocks_in_group2) {
- throw WriterException::new("Total bytes mismatch");
- }
- if block_i_d < num_rs_blocks_in_group1 {
- num_data_bytes_in_block[0] = num_data_bytes_in_group1;
- num_e_c_bytes_in_block[0] = num_ec_bytes_in_group1;
- } else {
- num_data_bytes_in_block[0] = num_data_bytes_in_group2;
- num_e_c_bytes_in_block[0] = num_ec_bytes_in_group2;
- }
- }
-
- /**
- * Interleave "bits" with corresponding error correction bytes. On success, store the result in
- * "result". The interleave rule is complicated. See 8.6 of JISX0510:2004 (p.37) for details.
- */
- fn interleave_with_e_c_bytes( bits: &BitArray, num_total_bytes: i32, num_data_bytes: i32, num_r_s_blocks: i32) -> /* throws WriterException */Result> {
- // "bits" must have "getNumDataBytes" bytes of data.
- if bits.get_size_in_bytes() != num_data_bytes {
- throw WriterException::new("Number of bits and data bytes does not match");
- }
- // Step 1. Divide data bytes into blocks and generate error correction bytes for them. We'll
- // store the divided data bytes blocks and error correction bytes blocks into "blocks".
- let data_bytes_offset: i32 = 0;
- let max_num_data_bytes: i32 = 0;
- let max_num_ec_bytes: i32 = 0;
- // Since, we know the number of reedsolmon blocks, we can initialize the vector with the number.
- let blocks: Collection = ArrayList<>::new(num_r_s_blocks);
- {
- let mut i: i32 = 0;
- while i < num_r_s_blocks {
- {
- let num_data_bytes_in_block: [i32; 1] = [0; 1];
- let num_ec_bytes_in_block: [i32; 1] = [0; 1];
- ::get_num_data_bytes_and_num_e_c_bytes_for_block_i_d(num_total_bytes, num_data_bytes, num_r_s_blocks, i, &num_data_bytes_in_block, &num_ec_bytes_in_block);
- let size: i32 = num_data_bytes_in_block[0];
- let data_bytes: [i8; size] = [0; size];
- bits.to_bytes(8 * data_bytes_offset, &data_bytes, 0, size);
- let ec_bytes: Vec = ::generate_e_c_bytes(&data_bytes, num_ec_bytes_in_block[0]);
- blocks.add(BlockPair::new(&data_bytes, &ec_bytes));
- max_num_data_bytes = Math::max(max_num_data_bytes, size);
- max_num_ec_bytes = Math::max(max_num_ec_bytes, ec_bytes.len());
- data_bytes_offset += num_data_bytes_in_block[0];
- }
- i += 1;
- }
- }
-
- if num_data_bytes != data_bytes_offset {
- throw WriterException::new("Data bytes does not match offset");
- }
- let result: BitArray = BitArray::new();
- // First, place data blocks.
- {
- let mut i: i32 = 0;
- while i < max_num_data_bytes {
- {
- for let block: BlockPair in blocks {
- let data_bytes: Vec = block.get_data_bytes();
- if i < data_bytes.len() {
- result.append_bits(data_bytes[i], 8);
- }
- }
- }
- i += 1;
- }
- }
-
- // Then, place error correction blocks.
- {
- let mut i: i32 = 0;
- while i < max_num_ec_bytes {
- {
- for let block: BlockPair in blocks {
- let ec_bytes: Vec = block.get_error_correction_bytes();
- if i < ec_bytes.len() {
- result.append_bits(ec_bytes[i], 8);
- }
- }
- }
- i += 1;
- }
- }
-
- if num_total_bytes != result.get_size_in_bytes() {
- // Should be same.
- throw WriterException::new(format!("Interleaving error: {} and {} differ.", num_total_bytes, result.get_size_in_bytes()));
- }
- return Ok(result);
- }
-
- fn generate_e_c_bytes( data_bytes: &Vec, num_ec_bytes_in_block: i32) -> Vec {
- let num_data_bytes: i32 = data_bytes.len();
- let to_encode: [i32; num_data_bytes + num_ec_bytes_in_block] = [0; num_data_bytes + num_ec_bytes_in_block];
- {
- let mut i: i32 = 0;
- while i < num_data_bytes {
- {
- to_encode[i] = data_bytes[i] & 0xFF;
- }
- i += 1;
- }
- }
-
- ReedSolomonEncoder::new(GenericGF::QR_CODE_FIELD_256).encode(&to_encode, num_ec_bytes_in_block);
- let ec_bytes: [i8; num_ec_bytes_in_block] = [0; num_ec_bytes_in_block];
- {
- let mut i: i32 = 0;
- while i < num_ec_bytes_in_block {
- {
- ec_bytes[i] = to_encode[num_data_bytes + i] as i8;
- }
- i += 1;
- }
- }
-
- return ec_bytes;
- }
-
- /**
- * Append mode info. On success, store the result in "bits".
- */
- fn append_mode_info( mode: &Mode, bits: &BitArray) {
- bits.append_bits(&mode.get_bits(), 4);
- }
-
- /**
- * Append length info. On success, store the result in "bits".
- */
- fn append_length_info( num_letters: i32, version: &Version, mode: &Mode, bits: &BitArray) -> /* throws WriterException */Result> {
- let num_bits: i32 = mode.get_character_count_bits(version);
- if num_letters >= (1 << num_bits) {
- throw WriterException::new(format!("{} is bigger than {}", num_letters, ((1 << num_bits) - 1)));
- }
- bits.append_bits(num_letters, num_bits);
- }
-
- /**
- * Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
- */
- fn append_bytes( content: &String, mode: &Mode, bits: &BitArray, encoding: &Charset) -> /* throws WriterException */Result> {
- match mode {
- NUMERIC =>
- {
- ::append_numeric_bytes(&content, bits);
- break;
- }
- ALPHANUMERIC =>
- {
- ::append_alphanumeric_bytes(&content, bits);
- break;
- }
- BYTE =>
- {
- ::append8_bit_bytes(&content, bits, &encoding);
- break;
- }
- KANJI =>
- {
- ::append_kanji_bytes(&content, bits);
- break;
- }
- _ =>
- {
- throw WriterException::new(format!("Invalid mode: {}", mode));
- }
- }
- }
-
- fn append_numeric_bytes( content: &CharSequence, bits: &BitArray) {
- let length: i32 = content.length();
- let mut i: i32 = 0;
- while i < length {
- let num1: i32 = content.char_at(i) - '0';
- if i + 2 < length {
- // Encode three numeric letters in ten bits.
- let num2: i32 = content.char_at(i + 1) - '0';
- let num3: i32 = content.char_at(i + 2) - '0';
- bits.append_bits(num1 * 100 + num2 * 10 + num3, 10);
- i += 3;
- } else if i + 1 < length {
- // Encode two numeric letters in seven bits.
- let num2: i32 = content.char_at(i + 1) - '0';
- bits.append_bits(num1 * 10 + num2, 7);
- i += 2;
- } else {
- // Encode one numeric letter in four bits.
- bits.append_bits(num1, 4);
- i += 1;
- }
- }
- }
-
- fn append_alphanumeric_bytes( content: &CharSequence, bits: &BitArray) -> /* throws WriterException */Result> {
- let length: i32 = content.length();
- let mut i: i32 = 0;
- while i < length {
- let code1: i32 = ::get_alphanumeric_code(&content.char_at(i));
- if code1 == -1 {
- throw WriterException::new();
- }
- if i + 1 < length {
- let code2: i32 = ::get_alphanumeric_code(&content.char_at(i + 1));
- if code2 == -1 {
- throw WriterException::new();
- }
- // Encode two alphanumeric letters in 11 bits.
- bits.append_bits(code1 * 45 + code2, 11);
- i += 2;
- } else {
- // Encode one alphanumeric letter in six bits.
- bits.append_bits(code1, 6);
- i += 1;
- }
- }
- }
-
- fn append8_bit_bytes( content: &String, bits: &BitArray, encoding: &Charset) {
- let bytes: Vec = content.get_bytes(&encoding);
- for let b: i8 in bytes {
- bits.append_bits(b, 8);
- }
- }
-
- fn append_kanji_bytes( content: &String, bits: &BitArray) -> /* throws WriterException */Result> {
- let bytes: Vec = content.get_bytes(StringUtils::SHIFT_JIS_CHARSET);
- if bytes.len() % 2 != 0 {
- throw WriterException::new("Kanji byte size not even");
- }
- // bytes.length must be even
- let max_i: i32 = bytes.len() - 1;
- {
- let mut i: i32 = 0;
- while i < max_i {
- {
- let byte1: i32 = bytes[i] & 0xFF;
- let byte2: i32 = bytes[i + 1] & 0xFF;
- let code: i32 = (byte1 << 8) | byte2;
- let mut subtracted: i32 = -1;
- if code >= 0x8140 && code <= 0x9ffc {
- subtracted = code - 0x8140;
- } else if code >= 0xe040 && code <= 0xebbf {
- subtracted = code - 0xc140;
- }
- if subtracted == -1 {
- throw WriterException::new("Invalid byte sequence");
- }
- let encoded: i32 = ((subtracted >> 8) * 0xc0) + (subtracted & 0xff);
- bits.append_bits(encoded, 13);
- }
- i += 2;
- }
- }
-
- }
-
- fn append_e_c_i( eci: &CharacterSetECI, bits: &BitArray) {
- bits.append_bits(&Mode::ECI::get_bits(), 4);
- // This is correct for values up to 127, which is all we need now.
- bits.append_bits(&eci.get_value(), 8);
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/encoder/mask_util.rs b/port_src/output/zxing/qrcode/encoder/mask_util.rs
deleted file mode 100644
index 50239e3..0000000
--- a/port_src/output/zxing/qrcode/encoder/mask_util.rs
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::encoder;
-
-/**
- * @author Satoru Takabayashi
- * @author Daniel Switkin
- * @author Sean Owen
- */
-
-// Penalty weights from section 6.8.2.1
- const N1: i32 = 3;
-
- const N2: i32 = 3;
-
- const N3: i32 = 40;
-
- const N4: i32 = 10;
-struct MaskUtil {
-}
-
-impl MaskUtil {
-
- fn new() -> MaskUtil {
- // do nothing
- }
-
- /**
- * Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and
- * give penalty to them. Example: 00000 or 11111.
- */
- fn apply_mask_penalty_rule1( matrix: &ByteMatrix) -> i32 {
- return ::apply_mask_penalty_rule1_internal(matrix, true) + ::apply_mask_penalty_rule1_internal(matrix, false);
- }
-
- /**
- * Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give
- * penalty to them. This is actually equivalent to the spec's rule, which is to find MxN blocks and give a
- * penalty proportional to (M-1)x(N-1), because this is the number of 2x2 blocks inside such a block.
- */
- fn apply_mask_penalty_rule2( matrix: &ByteMatrix) -> i32 {
- let mut penalty: i32 = 0;
- let array: Vec> = matrix.get_array();
- let width: i32 = matrix.get_width();
- let height: i32 = matrix.get_height();
- {
- let mut y: i32 = 0;
- while y < height - 1 {
- {
- let array_y: Vec = array[y];
- {
- let mut x: i32 = 0;
- while x < width - 1 {
- {
- let value: i32 = array_y[x];
- if value == array_y[x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1] {
- penalty += 1;
- }
- }
- x += 1;
- }
- }
-
- }
- y += 1;
- }
- }
-
- return N2 * penalty;
- }
-
- /**
- * Apply mask penalty rule 3 and return the penalty. Find consecutive runs of 1:1:3:1:1:4
- * starting with black, or 4:1:1:3:1:1 starting with white, and give penalty to them. If we
- * find patterns like 000010111010000, we give penalty once.
- */
- fn apply_mask_penalty_rule3( matrix: &ByteMatrix) -> i32 {
- let num_penalties: i32 = 0;
- let array: Vec> = matrix.get_array();
- let width: i32 = matrix.get_width();
- let height: i32 = matrix.get_height();
- {
- let mut y: i32 = 0;
- while y < height {
- {
- {
- let mut x: i32 = 0;
- while x < width {
- {
- // We can at least optimize this access
- let array_y: Vec = array[y];
- if x + 6 < width && array_y[x] == 1 && array_y[x + 1] == 0 && array_y[x + 2] == 1 && array_y[x + 3] == 1 && array_y[x + 4] == 1 && array_y[x + 5] == 0 && array_y[x + 6] == 1 && (::is_white_horizontal(&array_y, x - 4, x) || ::is_white_horizontal(&array_y, x + 7, x + 11)) {
- num_penalties += 1;
- }
- if y + 6 < height && array[y][x] == 1 && array[y + 1][x] == 0 && array[y + 2][x] == 1 && array[y + 3][x] == 1 && array[y + 4][x] == 1 && array[y + 5][x] == 0 && array[y + 6][x] == 1 && (::is_white_vertical(&array, x, y - 4, y) || ::is_white_vertical(&array, x, y + 7, y + 11)) {
- num_penalties += 1;
- }
- }
- x += 1;
- }
- }
-
- }
- y += 1;
- }
- }
-
- return num_penalties * N3;
- }
-
- fn is_white_horizontal( row_array: &Vec, from: i32, to: i32) -> bool {
- if from < 0 || row_array.len() < to {
- return false;
- }
- {
- let mut i: i32 = from;
- while i < to {
- {
- if row_array[i] == 1 {
- return false;
- }
- }
- i += 1;
- }
- }
-
- return true;
- }
-
- fn is_white_vertical( array: &Vec>, col: i32, from: i32, to: i32) -> bool {
- if from < 0 || array.len() < to {
- return false;
- }
- {
- let mut i: i32 = from;
- while i < to {
- {
- if array[i][col] == 1 {
- return false;
- }
- }
- i += 1;
- }
- }
-
- return true;
- }
-
- /**
- * Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give
- * penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance.
- */
- fn apply_mask_penalty_rule4( matrix: &ByteMatrix) -> i32 {
- let num_dark_cells: i32 = 0;
- let array: Vec> = matrix.get_array();
- let width: i32 = matrix.get_width();
- let height: i32 = matrix.get_height();
- {
- let mut y: i32 = 0;
- while y < height {
- {
- let array_y: Vec = array[y];
- {
- let mut x: i32 = 0;
- while x < width {
- {
- if array_y[x] == 1 {
- num_dark_cells += 1;
- }
- }
- x += 1;
- }
- }
-
- }
- y += 1;
- }
- }
-
- let num_total_cells: i32 = matrix.get_height() * matrix.get_width();
- let five_percent_variances: i32 = Math::abs(num_dark_cells * 2 - num_total_cells) * 10 / num_total_cells;
- return five_percent_variances * N4;
- }
-
- /**
- * Return the mask bit for "getMaskPattern" at "x" and "y". See 8.8 of JISX0510:2004 for mask
- * pattern conditions.
- */
- fn get_data_mask_bit( mask_pattern: i32, x: i32, y: i32) -> bool {
- let mut intermediate: i32;
- let mut temp: i32;
- match mask_pattern {
- 0 =>
- {
- intermediate = (y + x) & 0x1;
- break;
- }
- 1 =>
- {
- intermediate = y & 0x1;
- break;
- }
- 2 =>
- {
- intermediate = x % 3;
- break;
- }
- 3 =>
- {
- intermediate = (y + x) % 3;
- break;
- }
- 4 =>
- {
- intermediate = ((y / 2) + (x / 3)) & 0x1;
- break;
- }
- 5 =>
- {
- temp = y * x;
- intermediate = (temp & 0x1) + (temp % 3);
- break;
- }
- 6 =>
- {
- temp = y * x;
- intermediate = ((temp & 0x1) + (temp % 3)) & 0x1;
- break;
- }
- 7 =>
- {
- temp = y * x;
- intermediate = ((temp % 3) + ((y + x) & 0x1)) & 0x1;
- break;
- }
- _ =>
- {
- throw IllegalArgumentException::new(format!("Invalid mask pattern: {}", mask_pattern));
- }
- }
- return intermediate == 0;
- }
-
- /**
- * Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both
- * vertical and horizontal orders respectively.
- */
- fn apply_mask_penalty_rule1_internal( matrix: &ByteMatrix, is_horizontal: bool) -> i32 {
- let mut penalty: i32 = 0;
- let i_limit: i32 = if is_horizontal { matrix.get_height() } else { matrix.get_width() };
- let j_limit: i32 = if is_horizontal { matrix.get_width() } else { matrix.get_height() };
- let array: Vec> = matrix.get_array();
- {
- let mut i: i32 = 0;
- while i < i_limit {
- {
- let num_same_bit_cells: i32 = 0;
- let prev_bit: i32 = -1;
- {
- let mut j: i32 = 0;
- while j < j_limit {
- {
- let bit: i32 = if is_horizontal { array[i][j] } else { array[j][i] };
- if bit == prev_bit {
- num_same_bit_cells += 1;
- } else {
- if num_same_bit_cells >= 5 {
- penalty += N1 + (num_same_bit_cells - 5);
- }
- // Include the cell itself.
- num_same_bit_cells = 1;
- prev_bit = bit;
- }
- }
- j += 1;
- }
- }
-
- if num_same_bit_cells >= 5 {
- penalty += N1 + (num_same_bit_cells - 5);
- }
- }
- i += 1;
- }
- }
-
- return penalty;
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/encoder/matrix_util.rs b/port_src/output/zxing/qrcode/encoder/matrix_util.rs
deleted file mode 100644
index 06107d2..0000000
--- a/port_src/output/zxing/qrcode/encoder/matrix_util.rs
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::encoder;
-
-/**
- * @author satorux@google.com (Satoru Takabayashi) - creator
- * @author dswitkin@google.com (Daniel Switkin) - ported from C++
- */
-
- const POSITION_DETECTION_PATTERN: vec![vec![Vec>; 7]; 7] = vec![vec![1, 1, 1, 1, 1, 1, 1, ]
-, vec![1, 0, 0, 0, 0, 0, 1, ]
-, vec![1, 0, 1, 1, 1, 0, 1, ]
-, vec![1, 0, 1, 1, 1, 0, 1, ]
-, vec![1, 0, 1, 1, 1, 0, 1, ]
-, vec![1, 0, 0, 0, 0, 0, 1, ]
-, vec![1, 1, 1, 1, 1, 1, 1, ]
-, ]
-;
-
- const POSITION_ADJUSTMENT_PATTERN: vec![vec![Vec>; 5]; 5] = vec![vec![1, 1, 1, 1, 1, ]
-, vec![1, 0, 0, 0, 1, ]
-, vec![1, 0, 1, 0, 1, ]
-, vec![1, 0, 0, 0, 1, ]
-, vec![1, 1, 1, 1, 1, ]
-, ]
-;
-
-// From Appendix E. Table 1, JIS0510X:2004 (p 71). The table was double-checked by komatsu.
- const POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE: vec![vec![Vec>; 7]; 40] = vec![// Version 1
-vec![-1, -1, -1, -1, -1, -1, -1, ]
-, // Version 2
-vec![6, 18, -1, -1, -1, -1, -1, ]
-, // Version 3
-vec![6, 22, -1, -1, -1, -1, -1, ]
-, // Version 4
-vec![6, 26, -1, -1, -1, -1, -1, ]
-, // Version 5
-vec![6, 30, -1, -1, -1, -1, -1, ]
-, // Version 6
-vec![6, 34, -1, -1, -1, -1, -1, ]
-, // Version 7
-vec![6, 22, 38, -1, -1, -1, -1, ]
-, // Version 8
-vec![6, 24, 42, -1, -1, -1, -1, ]
-, // Version 9
-vec![6, 26, 46, -1, -1, -1, -1, ]
-, // Version 10
-vec![6, 28, 50, -1, -1, -1, -1, ]
-, // Version 11
-vec![6, 30, 54, -1, -1, -1, -1, ]
-, // Version 12
-vec![6, 32, 58, -1, -1, -1, -1, ]
-, // Version 13
-vec![6, 34, 62, -1, -1, -1, -1, ]
-, // Version 14
-vec![6, 26, 46, 66, -1, -1, -1, ]
-, // Version 15
-vec![6, 26, 48, 70, -1, -1, -1, ]
-, // Version 16
-vec![6, 26, 50, 74, -1, -1, -1, ]
-, // Version 17
-vec![6, 30, 54, 78, -1, -1, -1, ]
-, // Version 18
-vec![6, 30, 56, 82, -1, -1, -1, ]
-, // Version 19
-vec![6, 30, 58, 86, -1, -1, -1, ]
-, // Version 20
-vec![6, 34, 62, 90, -1, -1, -1, ]
-, // Version 21
-vec![6, 28, 50, 72, 94, -1, -1, ]
-, // Version 22
-vec![6, 26, 50, 74, 98, -1, -1, ]
-, // Version 23
-vec![6, 30, 54, 78, 102, -1, -1, ]
-, // Version 24
-vec![6, 28, 54, 80, 106, -1, -1, ]
-, // Version 25
-vec![6, 32, 58, 84, 110, -1, -1, ]
-, // Version 26
-vec![6, 30, 58, 86, 114, -1, -1, ]
-, // Version 27
-vec![6, 34, 62, 90, 118, -1, -1, ]
-, // Version 28
-vec![6, 26, 50, 74, 98, 122, -1, ]
-, // Version 29
-vec![6, 30, 54, 78, 102, 126, -1, ]
-, // Version 30
-vec![6, 26, 52, 78, 104, 130, -1, ]
-, // Version 31
-vec![6, 30, 56, 82, 108, 134, -1, ]
-, // Version 32
-vec![6, 34, 60, 86, 112, 138, -1, ]
-, // Version 33
-vec![6, 30, 58, 86, 114, 142, -1, ]
-, // Version 34
-vec![6, 34, 62, 90, 118, 146, -1, ]
-, // Version 35
-vec![6, 30, 54, 78, 102, 126, 150, ]
-, // Version 36
-vec![6, 24, 50, 76, 102, 128, 154, ]
-, // Version 37
-vec![6, 28, 54, 80, 106, 132, 158, ]
-, // Version 38
-vec![6, 32, 58, 84, 110, 136, 162, ]
-, // Version 39
-vec![6, 26, 54, 82, 110, 138, 166, ]
-, // Version 40
-vec![6, 30, 58, 86, 114, 142, 170, ]
-, ]
-;
-
-// Type info cells at the left top corner.
- const TYPE_INFO_COORDINATES: vec![vec![Vec>; 2]; 15] = vec![vec![8, 0, ]
-, vec![8, 1, ]
-, vec![8, 2, ]
-, vec![8, 3, ]
-, vec![8, 4, ]
-, vec![8, 5, ]
-, vec![8, 7, ]
-, vec![8, 8, ]
-, vec![7, 8, ]
-, vec![5, 8, ]
-, vec![4, 8, ]
-, vec![3, 8, ]
-, vec![2, 8, ]
-, vec![1, 8, ]
-, vec![0, 8, ]
-, ]
-;
-
-// From Appendix D in JISX0510:2004 (p. 67)
-// 1 1111 0010 0101
- const VERSION_INFO_POLY: i32 = 0x1f25;
-
-// From Appendix C in JISX0510:2004 (p.65).
- const TYPE_INFO_POLY: i32 = 0x537;
-
- const TYPE_INFO_MASK_PATTERN: i32 = 0x5412;
-struct MatrixUtil {
-}
-
-impl MatrixUtil {
-
- fn new() -> MatrixUtil {
- // do nothing
- }
-
- // Set all cells to -1. -1 means that the cell is empty (not set yet).
- //
- // JAVAPORT: We shouldn't need to do this at all. The code should be rewritten to begin encoding
- // with the ByteMatrix initialized all to zero.
- fn clear_matrix( matrix: &ByteMatrix) {
- matrix.clear(-1 as i8);
- }
-
- // Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
- // success, store the result in "matrix" and return true.
- fn build_matrix( data_bits: &BitArray, ec_level: &ErrorCorrectionLevel, version: &Version, mask_pattern: i32, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- ::clear_matrix(matrix);
- ::embed_basic_patterns(version, matrix);
- // Type information appear with any version.
- ::embed_type_info(ec_level, mask_pattern, matrix);
- // Version info appear if version >= 7.
- ::maybe_embed_version_info(version, matrix);
- // Data should be embedded at end.
- ::embed_data_bits(data_bits, mask_pattern, matrix);
- }
-
- // Embed basic patterns. On success, modify the matrix and return true.
- // The basic patterns are:
- // - Position detection patterns
- // - Timing patterns
- // - Dark dot at the left bottom corner
- // - Position adjustment patterns, if need be
- fn embed_basic_patterns( version: &Version, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- // Let's get started with embedding big squares at corners.
- ::embed_position_detection_patterns_and_separators(matrix);
- // Then, embed the dark dot at the left bottom corner.
- ::embed_dark_dot_at_left_bottom_corner(matrix);
- // Position adjustment patterns appear if version >= 2.
- ::maybe_embed_position_adjustment_patterns(version, matrix);
- // Timing patterns should be embedded after position adj. patterns.
- ::embed_timing_patterns(matrix);
- }
-
- // Embed type information. On success, modify the matrix.
- fn embed_type_info( ec_level: &ErrorCorrectionLevel, mask_pattern: i32, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- let type_info_bits: BitArray = BitArray::new();
- ::make_type_info_bits(ec_level, mask_pattern, type_info_bits);
- {
- let mut i: i32 = 0;
- while i < type_info_bits.get_size() {
- {
- // Place bits in LSB to MSB order. LSB (least significant bit) is the last value in
- // "typeInfoBits".
- let bit: bool = type_info_bits.get(type_info_bits.get_size() - 1 - i);
- // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46).
- let coordinates: Vec = TYPE_INFO_COORDINATES[i];
- let x1: i32 = coordinates[0];
- let y1: i32 = coordinates[1];
- matrix.set(x1, y1, bit);
- let mut x2: i32;
- let mut y2: i32;
- if i < 8 {
- // Right top corner.
- x2 = matrix.get_width() - i - 1;
- y2 = 8;
- } else {
- // Left bottom corner.
- x2 = 8;
- y2 = matrix.get_height() - 7 + (i - 8);
- }
- matrix.set(x2, y2, bit);
- }
- i += 1;
- }
- }
-
- }
-
- // Embed version information if need be. On success, modify the matrix and return true.
- // See 8.10 of JISX0510:2004 (p.47) for how to embed version information.
- fn maybe_embed_version_info( version: &Version, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- if version.get_version_number() < 7 {
- // Don't need version info.
- return;
- }
- let version_info_bits: BitArray = BitArray::new();
- ::make_version_info_bits(version, version_info_bits);
- // It will decrease from 17 to 0.
- let bit_index: i32 = 6 * 3 - 1;
- {
- let mut i: i32 = 0;
- while i < 6 {
- {
- {
- let mut j: i32 = 0;
- while j < 3 {
- {
- // Place bits in LSB (least significant bit) to MSB order.
- let bit: bool = version_info_bits.get(bit_index);
- bit_index -= 1;
- // Left bottom corner.
- matrix.set(i, matrix.get_height() - 11 + j, bit);
- // Right bottom corner.
- matrix.set(matrix.get_height() - 11 + j, i, bit);
- }
- j += 1;
- }
- }
-
- }
- i += 1;
- }
- }
-
- }
-
- // Embed "dataBits" using "getMaskPattern". On success, modify the matrix and return true.
- // For debugging purposes, it skips masking process if "getMaskPattern" is -1.
- // See 8.7 of JISX0510:2004 (p.38) for how to embed data bits.
- fn embed_data_bits( data_bits: &BitArray, mask_pattern: i32, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- let bit_index: i32 = 0;
- let mut direction: i32 = -1;
- // Start from the right bottom cell.
- let mut x: i32 = matrix.get_width() - 1;
- let mut y: i32 = matrix.get_height() - 1;
- while x > 0 {
- // Skip the vertical timing pattern.
- if x == 6 {
- x -= 1;
- }
- while y >= 0 && y < matrix.get_height() {
- {
- let mut i: i32 = 0;
- while i < 2 {
- {
- let xx: i32 = x - i;
- // Skip the cell if it's not empty.
- if !::is_empty(&matrix.get(xx, y)) {
- continue;
- }
- let mut bit: bool;
- if bit_index < data_bits.get_size() {
- bit = data_bits.get(bit_index);
- bit_index += 1;
- } else {
- // Padding bit. If there is no bit left, we'll fill the left cells with 0, as described
- // in 8.4.9 of JISX0510:2004 (p. 24).
- bit = false;
- }
- // Skip masking if mask_pattern is -1.
- if mask_pattern != -1 && MaskUtil::get_data_mask_bit(mask_pattern, xx, y) {
- bit = !bit;
- }
- matrix.set(xx, y, bit);
- }
- i += 1;
- }
- }
-
- y += direction;
- }
- // Reverse the direction.
- direction = -direction;
- y += direction;
- // Move to the left.
- x -= 2;
- }
- // All bits should be consumed.
- if bit_index != data_bits.get_size() {
- throw WriterException::new(format!("Not all bits consumed: {}/{}", bit_index, data_bits.get_size()));
- }
- }
-
- // Return the position of the most significant bit set (to one) in the "value". The most
- // significant bit is position 32. If there is no bit set, return 0. Examples:
- // - findMSBSet(0) => 0
- // - findMSBSet(1) => 1
- // - findMSBSet(255) => 8
- fn find_m_s_b_set( value: i32) -> i32 {
- return 32 - Integer::number_of_leading_zeros(value);
- }
-
- // Calculate BCH (Bose-Chaudhuri-Hocquenghem) code for "value" using polynomial "poly". The BCH
- // code is used for encoding type information and version information.
- // Example: Calculation of version information of 7.
- // f(x) is created from 7.
- // - 7 = 000111 in 6 bits
- // - f(x) = x^2 + x^1 + x^0
- // g(x) is given by the standard (p. 67)
- // - g(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
- // Multiply f(x) by x^(18 - 6)
- // - f'(x) = f(x) * x^(18 - 6)
- // - f'(x) = x^14 + x^13 + x^12
- // Calculate the remainder of f'(x) / g(x)
- // x^2
- // __________________________________________________
- // g(x) )x^14 + x^13 + x^12
- // x^14 + x^13 + x^12 + x^11 + x^10 + x^7 + x^4 + x^2
- // --------------------------------------------------
- // x^11 + x^10 + x^7 + x^4 + x^2
- //
- // The remainder is x^11 + x^10 + x^7 + x^4 + x^2
- // Encode it in binary: 110010010100
- // The return value is 0xc94 (1100 1001 0100)
- //
- // Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit
- // operations. We don't care if coefficients are positive or negative.
- fn calculate_b_c_h_code( value: i32, poly: i32) -> i32 {
- if poly == 0 {
- throw IllegalArgumentException::new("0 polynomial");
- }
- // If poly is "1 1111 0010 0101" (version info poly), msbSetInPoly is 13. We'll subtract 1
- // from 13 to make it 12.
- let msb_set_in_poly: i32 = ::find_m_s_b_set(poly);
- value <<= msb_set_in_poly - 1;
- // Do the division business using exclusive-or operations.
- while ::find_m_s_b_set(value) >= msb_set_in_poly {
- value ^= poly << (::find_m_s_b_set(value) - msb_set_in_poly);
- }
- // Now the "value" is the remainder (i.e. the BCH code)
- return value;
- }
-
- // Make bit vector of type information. On success, store the result in "bits" and return true.
- // Encode error correction level and mask pattern. See 8.9 of
- // JISX0510:2004 (p.45) for details.
- fn make_type_info_bits( ec_level: &ErrorCorrectionLevel, mask_pattern: i32, bits: &BitArray) -> /* throws WriterException */Result> {
- if !QRCode::is_valid_mask_pattern(mask_pattern) {
- throw WriterException::new("Invalid mask pattern");
- }
- let type_info: i32 = (ec_level.get_bits() << 3) | mask_pattern;
- bits.append_bits(type_info, 5);
- let bch_code: i32 = ::calculate_b_c_h_code(type_info, TYPE_INFO_POLY);
- bits.append_bits(bch_code, 10);
- let mask_bits: BitArray = BitArray::new();
- mask_bits.append_bits(TYPE_INFO_MASK_PATTERN, 15);
- bits.xor(mask_bits);
- if bits.get_size() != 15 {
- // Just in case.
- throw WriterException::new(format!("should not happen but we got: {}", bits.get_size()));
- }
- }
-
- // Make bit vector of version information. On success, store the result in "bits" and return true.
- // See 8.10 of JISX0510:2004 (p.45) for details.
- fn make_version_info_bits( version: &Version, bits: &BitArray) -> /* throws WriterException */Result> {
- bits.append_bits(&version.get_version_number(), 6);
- let bch_code: i32 = ::calculate_b_c_h_code(&version.get_version_number(), VERSION_INFO_POLY);
- bits.append_bits(bch_code, 12);
- if bits.get_size() != 18 {
- // Just in case.
- throw WriterException::new(format!("should not happen but we got: {}", bits.get_size()));
- }
- }
-
- // Check if "value" is empty.
- fn is_empty( value: i32) -> bool {
- return value == -1;
- }
-
- fn embed_timing_patterns( matrix: &ByteMatrix) {
- // separation patterns (size 1). Thus, 8 = 7 + 1.
- {
- let mut i: i32 = 8;
- while i < matrix.get_width() - 8 {
- {
- let bit: i32 = (i + 1) % 2;
- // Horizontal line.
- if ::is_empty(&matrix.get(i, 6)) {
- matrix.set(i, 6, bit);
- }
- // Vertical line.
- if ::is_empty(&matrix.get(6, i)) {
- matrix.set(6, i, bit);
- }
- }
- i += 1;
- }
- }
-
- }
-
- // Embed the lonely dark dot at left bottom corner. JISX0510:2004 (p.46)
- fn embed_dark_dot_at_left_bottom_corner( matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- if matrix.get(8, matrix.get_height() - 8) == 0 {
- throw WriterException::new();
- }
- matrix.set(8, matrix.get_height() - 8, 1);
- }
-
- fn embed_horizontal_separation_pattern( x_start: i32, y_start: i32, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- {
- let mut x: i32 = 0;
- while x < 8 {
- {
- if !::is_empty(&matrix.get(x_start + x, y_start)) {
- throw WriterException::new();
- }
- matrix.set(x_start + x, y_start, 0);
- }
- x += 1;
- }
- }
-
- }
-
- fn embed_vertical_separation_pattern( x_start: i32, y_start: i32, matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- {
- let mut y: i32 = 0;
- while y < 7 {
- {
- if !::is_empty(&matrix.get(x_start, y_start + y)) {
- throw WriterException::new();
- }
- matrix.set(x_start, y_start + y, 0);
- }
- y += 1;
- }
- }
-
- }
-
- fn embed_position_adjustment_pattern( x_start: i32, y_start: i32, matrix: &ByteMatrix) {
- {
- let mut y: i32 = 0;
- while y < 5 {
- {
- let pattern_y: Vec = POSITION_ADJUSTMENT_PATTERN[y];
- {
- let mut x: i32 = 0;
- while x < 5 {
- {
- matrix.set(x_start + x, y_start + y, pattern_y[x]);
- }
- x += 1;
- }
- }
-
- }
- y += 1;
- }
- }
-
- }
-
- fn embed_position_detection_pattern( x_start: i32, y_start: i32, matrix: &ByteMatrix) {
- {
- let mut y: i32 = 0;
- while y < 7 {
- {
- let pattern_y: Vec = POSITION_DETECTION_PATTERN[y];
- {
- let mut x: i32 = 0;
- while x < 7 {
- {
- matrix.set(x_start + x, y_start + y, pattern_y[x]);
- }
- x += 1;
- }
- }
-
- }
- y += 1;
- }
- }
-
- }
-
- // Embed position detection patterns and surrounding vertical/horizontal separators.
- fn embed_position_detection_patterns_and_separators( matrix: &ByteMatrix) -> /* throws WriterException */Result> {
- // Embed three big squares at corners.
- let pdp_width: i32 = POSITION_DETECTION_PATTERN[0].len();
- // Left top corner.
- ::embed_position_detection_pattern(0, 0, matrix);
- // Right top corner.
- ::embed_position_detection_pattern(matrix.get_width() - pdp_width, 0, matrix);
- // Left bottom corner.
- ::embed_position_detection_pattern(0, matrix.get_width() - pdp_width, matrix);
- // Embed horizontal separation patterns around the squares.
- let hsp_width: i32 = 8;
- // Left top corner.
- ::embed_horizontal_separation_pattern(0, hsp_width - 1, matrix);
- // Right top corner.
- ::embed_horizontal_separation_pattern(matrix.get_width() - hsp_width, hsp_width - 1, matrix);
- // Left bottom corner.
- ::embed_horizontal_separation_pattern(0, matrix.get_width() - hsp_width, matrix);
- // Embed vertical separation patterns around the squares.
- let vsp_size: i32 = 7;
- // Left top corner.
- ::embed_vertical_separation_pattern(vsp_size, 0, matrix);
- // Right top corner.
- ::embed_vertical_separation_pattern(matrix.get_height() - vsp_size - 1, 0, matrix);
- // Left bottom corner.
- ::embed_vertical_separation_pattern(vsp_size, matrix.get_height() - vsp_size, matrix);
- }
-
- // Embed position adjustment patterns if need be.
- fn maybe_embed_position_adjustment_patterns( version: &Version, matrix: &ByteMatrix) {
- if version.get_version_number() < 2 {
- // The patterns appear if version >= 2
- return;
- }
- let index: i32 = version.get_version_number() - 1;
- let coordinates: Vec = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index];
- for let y: i32 in coordinates {
- if y >= 0 {
- for let x: i32 in coordinates {
- if x >= 0 && ::is_empty(&matrix.get(x, y)) {
- // If the cell is unset, we embed the position adjustment pattern here.
- // -2 is necessary since the x/y coordinates point to the center of the pattern, not the
- // left top corner.
- ::embed_position_adjustment_pattern(x - 2, y - 2, matrix);
- }
- }
- }
- }
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/encoder/minimal_encoder.rs b/port_src/output/zxing/qrcode/encoder/minimal_encoder.rs
deleted file mode 100644
index 5886df7..0000000
--- a/port_src/output/zxing/qrcode/encoder/minimal_encoder.rs
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright 2021 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::encoder;
-
-/**
- * Encoder that encodes minimally
- *
- * Algorithm:
- *
- * The eleventh commandment was "Thou Shalt Compute" or "Thou Shalt Not Compute" - I forget which (Alan Perilis).
- *
- * This implementation computes. As an alternative, the QR-Code specification suggests heuristics like this one:
- *
- * If initial input data is in the exclusive subset of the Alphanumeric character set AND if there are less than
- * [6,7,8] characters followed by data from the remainder of the 8-bit byte character set, THEN select the 8-
- * bit byte mode ELSE select Alphanumeric mode;
- *
- * This is probably right for 99.99% of cases but there is at least this one counter example: The string "AAAAAAa"
- * encodes 2 bits smaller as ALPHANUMERIC(AAAAAA), BYTE(a) than by encoding it as BYTE(AAAAAAa).
- * Perhaps that is the only counter example but without having proof, it remains unclear.
- *
- * ECI switching:
- *
- * In multi language content the algorithm selects the most compact representation using ECI modes.
- * For example the most compact representation of the string "\u0150\u015C" (O-double-acute, S-circumflex) is
- * ECI(UTF-8), BYTE(\u0150\u015C) while prepending one or more times the same leading character as in
- * "\u0150\u0150\u015C", the most compact representation uses two ECIs so that the string is encoded as
- * ECI(ISO-8859-2), BYTE(\u0150\u0150), ECI(ISO-8859-3), BYTE(\u015C).
- *
- * @author Alex Geller
- */
-struct MinimalEncoder {
-
- let string_to_encode: String;
-
- let is_g_s1: bool;
-
- let mut encoders: ECIEncoderSet;
-
- let ec_level: ErrorCorrectionLevel;
-}
-
-impl MinimalEncoder {
-
- enum VersionSize {
-
- SMALL("version 1-9"), MEDIUM("version 10-26"), LARGE("version 27-40");
-
- let description: String;
-
- fn new( description: &String) -> VersionSize {
- let .description = description;
- }
-
- pub fn to_string(&self) -> String {
- return self.description;
- }
- }
-
- /**
- * Creates a MinimalEncoder
- *
- * @param stringToEncode The string to encode
- * @param priorityCharset The preferred {@link Charset}. When the value of the argument is null, the algorithm
- * chooses charsets that leads to a minimal representation. Otherwise the algorithm will use the priority
- * charset to encode any character in the input that can be encoded by it if the charset is among the
- * supported charsets.
- * @param isGS1 {@code true} if a FNC1 is to be prepended; {@code false} otherwise
- * @param ecLevel The error correction level.
- * @see ResultList#getVersion
- */
- fn new( string_to_encode: &String, priority_charset: &Charset, is_g_s1: bool, ec_level: &ErrorCorrectionLevel) -> MinimalEncoder {
- let .stringToEncode = string_to_encode;
- let .isGS1 = is_g_s1;
- let .encoders = ECIEncoderSet::new(&string_to_encode, &priority_charset, -1);
- let .ecLevel = ec_level;
- }
-
- /**
- * Encodes the string minimally
- *
- * @param stringToEncode The string to encode
- * @param version The preferred {@link Version}. A minimal version is computed (see
- * {@link ResultList#getVersion method} when the value of the argument is null
- * @param priorityCharset The preferred {@link Charset}. When the value of the argument is null, the algorithm
- * chooses charsets that leads to a minimal representation. Otherwise the algorithm will use the priority
- * charset to encode any character in the input that can be encoded by it if the charset is among the
- * supported charsets.
- * @param isGS1 {@code true} if a FNC1 is to be prepended; {@code false} otherwise
- * @param ecLevel The error correction level.
- * @return An instance of {@code ResultList} representing the minimal solution.
- * @see ResultList#getBits
- * @see ResultList#getVersion
- * @see ResultList#getSize
- */
- fn encode( string_to_encode: &String, version: &Version, priority_charset: &Charset, is_g_s1: bool, ec_level: &ErrorCorrectionLevel) -> /* throws WriterException */Result> {
- return Ok(MinimalEncoder::new(&string_to_encode, &priority_charset, is_g_s1, ec_level).encode(version));
- }
-
- fn encode(&self, version: &Version) -> /* throws WriterException */Result> {
- if version == null {
- // compute minimal encoding trying the three version sizes.
- let versions: vec![Vec; 3] = vec![::get_version(VersionSize::SMALL), ::get_version(VersionSize::MEDIUM), ::get_version(VersionSize::LARGE), ]
- ;
- let results: vec![Vec; 3] = vec![self.encode_specific_version(versions[0]), self.encode_specific_version(versions[1]), self.encode_specific_version(versions[2]), ]
- ;
- let smallest_size: i32 = Integer::MAX_VALUE;
- let smallest_result: i32 = -1;
- {
- let mut i: i32 = 0;
- while i < 3 {
- {
- let size: i32 = results[i].get_size();
- if Encoder::will_fit(size, versions[i], self.ec_level) && size < smallest_size {
- smallest_size = size;
- smallest_result = i;
- }
- }
- i += 1;
- }
- }
-
- if smallest_result < 0 {
- throw WriterException::new("Data too big for any version");
- }
- return Ok(results[smallest_result]);
- } else {
- // compute minimal encoding for a given version
- let result: ResultList = self.encode_specific_version(version);
- if !Encoder::will_fit(&result.get_size(), &::get_version(&::get_version_size(&result.get_version())), self.ec_level) {
- throw WriterException::new(format!("Data too big for version{}", version));
- }
- return Ok(result);
- }
- }
-
- fn get_version_size( version: &Version) -> VersionSize {
- return if version.get_version_number() <= 9 { VersionSize::SMALL } else { if version.get_version_number() <= 26 { VersionSize::MEDIUM } else { VersionSize::LARGE } };
- }
-
- fn get_version( version_size: &VersionSize) -> Version {
- match version_size {
- SMALL =>
- {
- return Version::get_version_for_number(9);
- }
- MEDIUM =>
- {
- return Version::get_version_for_number(26);
- }
- LARGE =>
- {
- }
- _ =>
- {
- return Version::get_version_for_number(40);
- }
- }
- }
-
- fn is_numeric( c: char) -> bool {
- return c >= '0' && c <= '9';
- }
-
- fn is_double_byte_kanji( c: char) -> bool {
- return Encoder::is_only_double_byte_kanji(&String::value_of(c));
- }
-
- fn is_alphanumeric( c: char) -> bool {
- return Encoder::get_alphanumeric_code(c) != -1;
- }
-
- fn can_encode(&self, mode: &Mode, c: char) -> bool {
- match mode {
- KANJI =>
- {
- return ::is_double_byte_kanji(c);
- }
- ALPHANUMERIC =>
- {
- return ::is_alphanumeric(c);
- }
- NUMERIC =>
- {
- return ::is_numeric(c);
- }
- // any character can be encoded as byte(s). Up to the caller to manage splitting into
- BYTE =>
- {
- return true;
- }
- // multiple bytes when String.getBytes(Charset) return more than one byte.
- _ =>
- {
- return false;
- }
- }
- }
-
- fn get_compacted_ordinal( mode: &Mode) -> i32 {
- if mode == null {
- return 0;
- }
- match mode {
- KANJI =>
- {
- return 0;
- }
- ALPHANUMERIC =>
- {
- return 1;
- }
- NUMERIC =>
- {
- return 2;
- }
- BYTE =>
- {
- return 3;
- }
- _ =>
- {
- throw IllegalStateException::new(format!("Illegal mode {}", mode));
- }
- }
- }
-
- fn add_edge(&self, edges: &Vec>>, position: i32, edge: &Edge) {
- let vertex_index: i32 = position + edge.characterLength;
- let mode_edges: Vec = edges[vertex_index][edge.charsetEncoderIndex];
- let mode_ordinal: i32 = ::get_compacted_ordinal(edge.mode);
- if mode_edges[mode_ordinal] == null || mode_edges[mode_ordinal].cachedTotalSize > edge.cachedTotalSize {
- mode_edges[mode_ordinal] = edge;
- }
- }
-
- fn add_edges(&self, version: &Version, edges: &Vec>>, from: i32, previous: &Edge) {
- let mut start: i32 = 0;
- let mut end: i32 = self.encoders.length();
- let priority_encoder_index: i32 = self.encoders.get_priority_encoder_index();
- if priority_encoder_index >= 0 && self.encoders.can_encode(&self.string_to_encode.char_at(from), priority_encoder_index) {
- start = priority_encoder_index;
- end = priority_encoder_index + 1;
- }
- {
- let mut i: i32 = start;
- while i < end {
- {
- if self.encoders.can_encode(&self.string_to_encode.char_at(from), i) {
- self.add_edge(edges, from, Edge::new(Mode::BYTE, from, i, 1, previous, version));
- }
- }
- i += 1;
- }
- }
-
- if self.can_encode(Mode::KANJI, &self.string_to_encode.char_at(from)) {
- self.add_edge(edges, from, Edge::new(Mode::KANJI, from, 0, 1, previous, version));
- }
- let input_length: i32 = self.string_to_encode.length();
- if self.can_encode(Mode::ALPHANUMERIC, &self.string_to_encode.char_at(from)) {
- self.add_edge(edges, from, Edge::new(Mode::ALPHANUMERIC, from, 0, if from + 1 >= input_length || !self.can_encode(Mode::ALPHANUMERIC, &self.string_to_encode.char_at(from + 1)) { 1 } else { 2 }, previous, version));
- }
- if self.can_encode(Mode::NUMERIC, &self.string_to_encode.char_at(from)) {
- self.add_edge(edges, from, Edge::new(Mode::NUMERIC, from, 0, if from + 1 >= input_length || !self.can_encode(Mode::NUMERIC, &self.string_to_encode.char_at(from + 1)) { 1 } else { if from + 2 >= input_length || !self.can_encode(Mode::NUMERIC, &self.string_to_encode.char_at(from + 2)) { 2 } else { 3 } }, previous, version));
- }
- }
-
- fn encode_specific_version(&self, version: &Version) -> /* throws WriterException */Result> {
- let input_length: i32 = self.string_to_encode.length();
- // Array that represents vertices. There is a vertex for every character, encoding and mode. The vertex contains
- // a list of all edges that lead to it that have the same encoding and mode.
- // The lists are created lazily
- // The last dimension in the array below encodes the 4 modes KANJI, ALPHANUMERIC, NUMERIC and BYTE via the
- // function getCompactedOrdinal(Mode)
- let edges: [[[Option; 4]; self.encoders.length()]; input_length + 1] = [[[None; 4]; self.encoders.length()]; input_length + 1];
- self.add_edges(version, edges, 0, null);
- {
- let mut i: i32 = 1;
- while i <= input_length {
- {
- {
- let mut j: i32 = 0;
- while j < self.encoders.length() {
- {
- {
- let mut k: i32 = 0;
- while k < 4 {
- {
- if edges[i][j][k] != null && i < input_length {
- self.add_edges(version, edges, i, edges[i][j][k]);
- }
- }
- k += 1;
- }
- }
-
- }
- j += 1;
- }
- }
-
- }
- i += 1;
- }
- }
-
- let minimal_j: i32 = -1;
- let minimal_k: i32 = -1;
- let minimal_size: i32 = Integer::MAX_VALUE;
- {
- let mut j: i32 = 0;
- while j < self.encoders.length() {
- {
- {
- let mut k: i32 = 0;
- while k < 4 {
- {
- if edges[input_length][j][k] != null {
- let edge: Edge = edges[input_length][j][k];
- if edge.cachedTotalSize < minimal_size {
- minimal_size = edge.cachedTotalSize;
- minimal_j = j;
- minimal_k = k;
- }
- }
- }
- k += 1;
- }
- }
-
- }
- j += 1;
- }
- }
-
- if minimal_j < 0 {
- throw WriterException::new(format!("Internal error: failed to encode \"{}\"", self.string_to_encode));
- }
- return Ok(ResultList::new(version, edges[input_length][minimal_j][minimal_k]));
- }
-
- struct Edge {
-
- let mode: Mode;
-
- let from_position: i32;
-
- let charset_encoder_index: i32;
-
- let character_length: i32;
-
- let previous: Edge;
-
- let cached_total_size: i32;
- }
-
- impl Edge {
-
- fn new( mode: &Mode, from_position: i32, charset_encoder_index: i32, character_length: i32, previous: &Edge, version: &Version) -> Edge {
- let .mode = mode;
- let .fromPosition = from_position;
- let .charsetEncoderIndex = if mode == Mode::BYTE || previous == null { charset_encoder_index } else { // inherit the encoding if not of type BYTE
- previous.charsetEncoderIndex };
- let .characterLength = character_length;
- let .previous = previous;
- let mut size: i32 = if previous != null { previous.cachedTotalSize } else { 0 };
- let need_e_c_i: bool = mode == Mode::BYTE && // at the beginning and charset is not ISO-8859-1
- (previous == null && let .charsetEncoderIndex != 0) || (previous != null && let .charsetEncoderIndex != previous.charsetEncoderIndex);
- if previous == null || mode != previous.mode || need_e_c_i {
- size += 4 + mode.get_character_count_bits(version);
- }
- match mode {
- KANJI =>
- {
- size += 13;
- break;
- }
- ALPHANUMERIC =>
- {
- size += if character_length == 1 { 6 } else { 11 };
- break;
- }
- NUMERIC =>
- {
- size += if character_length == 1 { 4 } else { if character_length == 2 { 7 } else { 10 } };
- break;
- }
- BYTE =>
- {
- size += 8 * encoders.encode(&string_to_encode.substring(from_position, from_position + character_length), charset_encoder_index).len();
- if need_e_c_i {
- // the ECI assignment numbers for ISO-8859-x, UTF-8 and UTF-16 are all 8 bit long
- size += 4 + 8;
- }
- break;
- }
- }
- cached_total_size = size;
- }
- }
-
-
- struct ResultList {
-
- let list: List = ArrayList<>::new();
-
- let version: Version;
- }
-
- impl ResultList {
-
- fn new( version: &Version, solution: &Edge) -> ResultList {
- let mut length: i32 = 0;
- let mut current: Edge = solution;
- let contains_e_c_i: bool = false;
- while current != null {
- length += current.characterLength;
- let previous: Edge = current.previous;
- let need_e_c_i: bool = current.mode == Mode::BYTE && // at the beginning and charset is not ISO-8859-1
- (previous == null && current.charsetEncoderIndex != 0) || (previous != null && current.charsetEncoderIndex != previous.charsetEncoderIndex);
- if need_e_c_i {
- contains_e_c_i = true;
- }
- if previous == null || previous.mode != current.mode || need_e_c_i {
- list.add(0, ResultNode::new(current.mode, current.fromPosition, current.charsetEncoderIndex, length));
- length = 0;
- }
- if need_e_c_i {
- list.add(0, ResultNode::new(Mode::ECI, current.fromPosition, current.charsetEncoderIndex, 0));
- }
- current = previous;
- }
- // If there is no ECI at the beginning then we put an ECI to the default charset (ISO-8859-1)
- if is_g_s1 {
- let mut first: ResultNode = list.get(0);
- if first != null && first.mode != Mode::ECI && contains_e_c_i {
- // prepend a default character set ECI
- list.add(0, ResultNode::new(Mode::ECI, 0, 0, 0));
- }
- first = list.get(0);
- // prepend or insert a FNC1_FIRST_POSITION after the ECI (if any)
- list.add( if first.mode != Mode::ECI { 0 } else { 1 }, ResultNode::new(Mode::FNC1_FIRST_POSITION, 0, 0, 0));
- }
- // set version to smallest version into which the bits fit.
- let version_number: i32 = version.get_version_number();
- let lower_limit: i32;
- let upper_limit: i32;
- match ::get_version_size(version) {
- SMALL =>
- {
- lower_limit = 1;
- upper_limit = 9;
- break;
- }
- MEDIUM =>
- {
- lower_limit = 10;
- upper_limit = 26;
- break;
- }
- LARGE =>
- {
- }
- _ =>
- {
- lower_limit = 27;
- upper_limit = 40;
- break;
- }
- }
- let size: i32 = self.get_size(version);
- // increase version if needed
- while version_number < upper_limit && !Encoder::will_fit(size, &Version::get_version_for_number(version_number), ec_level) {
- version_number += 1;
- }
- // shrink version if possible
- while version_number > lower_limit && Encoder::will_fit(size, &Version::get_version_for_number(version_number - 1), ec_level) {
- version_number -= 1;
- }
- let .version = Version::get_version_for_number(version_number);
- }
-
- /**
- * returns the size in bits
- */
- fn get_size(&self) -> i32 {
- return self.get_size(self.version);
- }
-
- fn get_size(&self, version: &Version) -> i32 {
- let mut result: i32 = 0;
- for let result_node: ResultNode in self.list {
- result += result_node.get_size(version);
- }
- return result;
- }
-
- /**
- * appends the bits
- */
- fn get_bits(&self, bits: &BitArray) -> /* throws WriterException */Result> {
- for let result_node: ResultNode in self.list {
- result_node.get_bits(bits);
- }
- }
-
- fn get_version(&self) -> Version {
- return self.version;
- }
-
- pub fn to_string(&self) -> String {
- let result: StringBuilder = StringBuilder::new();
- let mut previous: ResultNode = null;
- for let current: ResultNode in self.list {
- if previous != null {
- result.append(",");
- }
- result.append(¤t.to_string());
- previous = current;
- }
- return result.to_string();
- }
-
- struct ResultNode {
-
- let mode: Mode;
-
- let from_position: i32;
-
- let charset_encoder_index: i32;
-
- let character_length: i32;
- }
-
- impl ResultNode {
-
- fn new( mode: &Mode, from_position: i32, charset_encoder_index: i32, character_length: i32) -> ResultNode {
- let .mode = mode;
- let .fromPosition = from_position;
- let .charsetEncoderIndex = charset_encoder_index;
- let .characterLength = character_length;
- }
-
- /**
- * returns the size in bits
- */
- fn get_size(&self, version: &Version) -> i32 {
- let mut size: i32 = 4 + self.mode.get_character_count_bits(version);
- match self.mode {
- KANJI =>
- {
- size += 13 * self.character_length;
- break;
- }
- ALPHANUMERIC =>
- {
- size += (self.character_length / 2) * 11;
- size += if (self.character_length % 2) == 1 { 6 } else { 0 };
- break;
- }
- NUMERIC =>
- {
- size += (self.character_length / 3) * 10;
- let rest: i32 = self.character_length % 3;
- size += if rest == 1 { 4 } else { if rest == 2 { 7 } else { 0 } };
- break;
- }
- BYTE =>
- {
- size += 8 * self.get_character_count_indicator();
- break;
- }
- ECI =>
- {
- // the ECI assignment numbers for ISO-8859-x, UTF-8 and UTF-16 are all 8 bit long
- size += 8;
- }
- }
- return size;
- }
-
- /**
- * returns the length in characters according to the specification (differs from getCharacterLength() in BYTE mode
- * for multi byte encoded characters)
- */
- fn get_character_count_indicator(&self) -> i32 {
- return if self.mode == Mode::BYTE { self.encoders.encode(&self.string_to_encode.substring(self.from_position, self.from_position + self.character_length), self.charset_encoder_index).len() } else { self.character_length };
- }
-
- /**
- * appends the bits
- */
- fn get_bits(&self, bits: &BitArray) -> /* throws WriterException */Result> {
- bits.append_bits(&self.mode.get_bits(), 4);
- if self.character_length > 0 {
- let length: i32 = self.get_character_count_indicator();
- bits.append_bits(length, &self.mode.get_character_count_bits(self.version));
- }
- if self.mode == Mode::ECI {
- bits.append_bits(&self.encoders.get_e_c_i_value(self.charset_encoder_index), 8);
- } else if self.character_length > 0 {
- // append data
- Encoder::append_bytes(&self.string_to_encode.substring(self.from_position, self.from_position + self.character_length), self.mode, bits, &self.encoders.get_charset(self.charset_encoder_index));
- }
- }
-
- pub fn to_string(&self) -> String {
- let result: StringBuilder = StringBuilder::new();
- result.append(self.mode).append('(');
- if self.mode == Mode::ECI {
- result.append(&self.encoders.get_charset(self.charset_encoder_index).display_name());
- } else {
- result.append(&self.make_printable(&self.string_to_encode.substring(self.from_position, self.from_position + self.character_length)));
- }
- result.append(')');
- return result.to_string();
- }
-
- fn make_printable(&self, s: &String) -> String {
- let result: StringBuilder = StringBuilder::new();
- {
- let mut i: i32 = 0;
- while i < s.length() {
- {
- if s.char_at(i) < 32 || s.char_at(i) > 126 {
- result.append('.');
- } else {
- result.append(&s.char_at(i));
- }
- }
- i += 1;
- }
- }
-
- return result.to_string();
- }
- }
-
- }
-
-}
-
diff --git a/port_src/output/zxing/qrcode/encoder/q_r_code.rs b/port_src/output/zxing/qrcode/encoder/q_r_code.rs
deleted file mode 100644
index 11b803a..0000000
--- a/port_src/output/zxing/qrcode/encoder/q_r_code.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode::encoder;
-
-/**
- * @author satorux@google.com (Satoru Takabayashi) - creator
- * @author dswitkin@google.com (Daniel Switkin) - ported from C++
- */
-
- const NUM_MASK_PATTERNS: i32 = 8;
-pub struct QRCode {
-
- let mut mode: Mode;
-
- let ec_level: ErrorCorrectionLevel;
-
- let version: Version;
-
- let mask_pattern: i32;
-
- let mut matrix: ByteMatrix;
-}
-
-impl QRCode {
-
- pub fn new() -> QRCode {
- mask_pattern = -1;
- }
-
- /**
- * @return the mode. Not relevant if {@link com.google.zxing.EncodeHintType#QR_COMPACT} is selected.
- */
- pub fn get_mode(&self) -> Mode {
- return self.mode;
- }
-
- pub fn get_e_c_level(&self) -> ErrorCorrectionLevel {
- return self.ec_level;
- }
-
- pub fn get_version(&self) -> Version {
- return self.version;
- }
-
- pub fn get_mask_pattern(&self) -> i32 {
- return self.mask_pattern;
- }
-
- pub fn get_matrix(&self) -> ByteMatrix {
- return self.matrix;
- }
-
- pub fn to_string(&self) -> String {
- let result: StringBuilder = StringBuilder::new(200);
- result.append("<<\n");
- result.append(" mode: ");
- result.append(self.mode);
- result.append("\n ecLevel: ");
- result.append(self.ec_level);
- result.append("\n version: ");
- result.append(self.version);
- result.append("\n maskPattern: ");
- result.append(self.mask_pattern);
- if self.matrix == null {
- result.append("\n matrix: null\n");
- } else {
- result.append("\n matrix:\n");
- result.append(self.matrix);
- }
- result.append(">>\n");
- return result.to_string();
- }
-
- pub fn set_mode(&self, value: &Mode) {
- self.mode = value;
- }
-
- pub fn set_e_c_level(&self, value: &ErrorCorrectionLevel) {
- self.ec_level = value;
- }
-
- pub fn set_version(&self, version: &Version) {
- self.version = version;
- }
-
- pub fn set_mask_pattern(&self, value: i32) {
- self.mask_pattern = value;
- }
-
- pub fn set_matrix(&self, value: &ByteMatrix) {
- self.matrix = value;
- }
-
- // Check if "mask_pattern" is valid.
- pub fn is_valid_mask_pattern( mask_pattern: i32) -> bool {
- return mask_pattern >= 0 && mask_pattern < NUM_MASK_PATTERNS;
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/q_r_code_reader.rs b/port_src/output/zxing/qrcode/q_r_code_reader.rs
deleted file mode 100644
index bbc6dd2..0000000
--- a/port_src/output/zxing/qrcode/q_r_code_reader.rs
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright 2007 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode;
-
-/**
- * This implementation can detect and decode QR Codes in an image.
- *
- * @author Sean Owen
- */
-
- const NO_POINTS: [Option; 0] = [None; 0];
-#[derive(Reader)]
-pub struct QRCodeReader {
-
- let decoder: Decoder = Decoder::new();
-}
-
-impl QRCodeReader {
-
- pub fn get_decoder(&self) -> Decoder {
- return self.decoder;
- }
-
- /**
- * Locates and decodes a QR code in an image.
- *
- * @return a String representing the content encoded by the QR code
- * @throws NotFoundException if a QR code cannot be found
- * @throws FormatException if a QR code cannot be decoded
- * @throws ChecksumException if error correction fails
- */
- pub fn decode(&self, image: &BinaryBitmap) -> /* throws NotFoundException, ChecksumException, FormatException */Result> {
- return Ok(self.decode(image, null));
- }
-
- pub fn decode(&self, image: &BinaryBitmap, hints: &Map) -> /* throws NotFoundException, ChecksumException, FormatException */Result> {
- let decoder_result: DecoderResult;
- let mut points: Vec;
- if hints != null && hints.contains_key(DecodeHintType::PURE_BARCODE) {
- let bits: BitMatrix = ::extract_pure_bits(&image.get_black_matrix());
- decoder_result = self.decoder.decode(bits, &hints);
- points = NO_POINTS;
- } else {
- let detector_result: DetectorResult = Detector::new(&image.get_black_matrix()).detect(&hints);
- decoder_result = self.decoder.decode(&detector_result.get_bits(), &hints);
- points = detector_result.get_points();
- }
- // If the code was mirrored: swap the bottom-left and the top-right points.
- if decoder_result.get_other() instanceof QRCodeDecoderMetaData {
- (decoder_result.get_other() as QRCodeDecoderMetaData).apply_mirrored_correction(points);
- }
- let result: Result = Result::new(&decoder_result.get_text(), &decoder_result.get_raw_bytes(), points, BarcodeFormat::QR_CODE);
- let byte_segments: List> = decoder_result.get_byte_segments();
- if byte_segments != null {
- result.put_metadata(ResultMetadataType::BYTE_SEGMENTS, &byte_segments);
- }
- let ec_level: String = decoder_result.get_e_c_level();
- if ec_level != null {
- result.put_metadata(ResultMetadataType::ERROR_CORRECTION_LEVEL, &ec_level);
- }
- if decoder_result.has_structured_append() {
- result.put_metadata(ResultMetadataType::STRUCTURED_APPEND_SEQUENCE, &decoder_result.get_structured_append_sequence_number());
- result.put_metadata(ResultMetadataType::STRUCTURED_APPEND_PARITY, &decoder_result.get_structured_append_parity());
- }
- result.put_metadata(ResultMetadataType::SYMBOLOGY_IDENTIFIER, format!("]Q{}", decoder_result.get_symbology_modifier()));
- return Ok(result);
- }
-
- pub fn reset(&self) {
- // do nothing
- }
-
- /**
- * This method detects a code in a "pure" image -- that is, pure monochrome image
- * which contains only an unrotated, unskewed, image of a code, with some white border
- * around it. This is a specialized method that works exceptionally fast in this special
- * case.
- */
- fn extract_pure_bits( image: &BitMatrix) -> /* throws NotFoundException */Result> {
- let left_top_black: Vec = image.get_top_left_on_bit();
- let right_bottom_black: Vec = image.get_bottom_right_on_bit();
- if left_top_black == null || right_bottom_black == null {
- throw NotFoundException::get_not_found_instance();
- }
- let module_size: f32 = self.module_size(&left_top_black, image);
- let mut top: i32 = left_top_black[1];
- let bottom: i32 = right_bottom_black[1];
- let mut left: i32 = left_top_black[0];
- let mut right: i32 = right_bottom_black[0];
- // Sanity check!
- if left >= right || top >= bottom {
- throw NotFoundException::get_not_found_instance();
- }
- if bottom - top != right - left {
- // Special case, where bottom-right module wasn't black so we found something else in the last row
- // Assume it's a square, so use height as the width
- right = left + (bottom - top);
- if right >= image.get_width() {
- // Abort if that would not make sense -- off image
- throw NotFoundException::get_not_found_instance();
- }
- }
- let matrix_width: i32 = Math::round((right - left + 1.0) / module_size);
- let matrix_height: i32 = Math::round((bottom - top + 1.0) / module_size);
- if matrix_width <= 0 || matrix_height <= 0 {
- throw NotFoundException::get_not_found_instance();
- }
- if matrix_height != matrix_width {
- // Only possibly decode square regions
- throw NotFoundException::get_not_found_instance();
- }
- // Push in the "border" by half the module width so that we start
- // sampling in the middle of the module. Just in case the image is a
- // little off, this will help recover.
- let nudge: i32 = (module_size / 2.0f) as i32;
- top += nudge;
- left += nudge;
- // But careful that this does not sample off the edge
- // "right" is the farthest-right valid pixel location -- right+1 is not necessarily
- // This is positive by how much the inner x loop below would be too large
- let nudged_too_far_right: i32 = left + ((matrix_width - 1.0) * module_size) as i32 - right;
- if nudged_too_far_right > 0 {
- if nudged_too_far_right > nudge {
- // Neither way fits; abort
- throw NotFoundException::get_not_found_instance();
- }
- left -= nudged_too_far_right;
- }
- // See logic above
- let nudged_too_far_down: i32 = top + ((matrix_height - 1.0) * module_size) as i32 - bottom;
- if nudged_too_far_down > 0 {
- if nudged_too_far_down > nudge {
- // Neither way fits; abort
- throw NotFoundException::get_not_found_instance();
- }
- top -= nudged_too_far_down;
- }
- // Now just read off the bits
- let bits: BitMatrix = BitMatrix::new(matrix_width, matrix_height);
- {
- let mut y: i32 = 0;
- while y < matrix_height {
- {
- let i_offset: i32 = top + (y * module_size) as i32;
- {
- let mut x: i32 = 0;
- while x < matrix_width {
- {
- if image.get(left + (x * module_size) as i32, i_offset) {
- bits.set(x, y);
- }
- }
- x += 1;
- }
- }
-
- }
- y += 1;
- }
- }
-
- return Ok(bits);
- }
-
- fn module_size( left_top_black: &Vec, image: &BitMatrix) -> /* throws NotFoundException */Result> {
- let height: i32 = image.get_height();
- let width: i32 = image.get_width();
- let mut x: i32 = left_top_black[0];
- let mut y: i32 = left_top_black[1];
- let in_black: bool = true;
- let mut transitions: i32 = 0;
- while x < width && y < height {
- if in_black != image.get(x, y) {
- if transitions += 1 == 5 {
- break;
- }
- in_black = !in_black;
- }
- x += 1;
- y += 1;
- }
- if x == width || y == height {
- throw NotFoundException::get_not_found_instance();
- }
- return Ok((x - left_top_black[0]) / 7.0f);
- }
-}
-
diff --git a/port_src/output/zxing/qrcode/q_r_code_writer.rs b/port_src/output/zxing/qrcode/q_r_code_writer.rs
deleted file mode 100644
index b76a5f3..0000000
--- a/port_src/output/zxing/qrcode/q_r_code_writer.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2008 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// package com::google::zxing::qrcode;
-
-/**
- * This object renders a QR Code as a BitMatrix 2D array of greyscale values.
- *
- * @author dswitkin@google.com (Daniel Switkin)
- */
-
- const QUIET_ZONE_SIZE: i32 = 4;
-#[derive(Writer)]
-pub struct QRCodeWriter {
-}
-
-impl QRCodeWriter {
-
- pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32) -> /* throws WriterException */Result> {
- return Ok(self.encode(&contents, format, width, height, null));
- }
-
- pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32, hints: &Map) -> /* throws WriterException */Result> {
- if contents.is_empty() {
- throw IllegalArgumentException::new("Found empty contents");
- }
- if format != BarcodeFormat::QR_CODE {
- throw IllegalArgumentException::new(format!("Can only encode QR_CODE, but got {}", format));
- }
- if width < 0 || height < 0 {
- throw IllegalArgumentException::new(format!("Requested dimensions are too small: {}x{}", width, height));
- }
- let error_correction_level: ErrorCorrectionLevel = ErrorCorrectionLevel::L;
- let quiet_zone: i32 = QUIET_ZONE_SIZE;
- if hints != null {
- if hints.contains_key(EncodeHintType::ERROR_CORRECTION) {
- error_correction_level = ErrorCorrectionLevel::value_of(&hints.get(EncodeHintType::ERROR_CORRECTION).to_string());
- }
- if hints.contains_key(EncodeHintType::MARGIN) {
- quiet_zone = Integer::parse_int(&hints.get(EncodeHintType::MARGIN).to_string());
- }
- }
- let code: QRCode = Encoder::encode(&contents, error_correction_level, &hints);
- return Ok(::render_result(code, width, height, quiet_zone));
- }
-
- // Note that the input matrix uses 0 == white, 1 == black, while the output matrix uses
- // 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
- fn render_result( code: &QRCode, width: i32, height: i32, quiet_zone: i32) -> BitMatrix {
- let input: ByteMatrix = code.get_matrix();
- if input == null {
- throw IllegalStateException::new();
- }
- let input_width: i32 = input.get_width();
- let input_height: i32 = input.get_height();
- let qr_width: i32 = input_width + (quiet_zone * 2);
- let qr_height: i32 = input_height + (quiet_zone * 2);
- let output_width: i32 = Math::max(width, qr_width);
- let output_height: i32 = Math::max(height, qr_height);
- let multiple: i32 = Math::min(output_width / qr_width, output_height / qr_height);
- // Padding includes both the quiet zone and the extra white pixels to accommodate the requested
- // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
- // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
- // handle all the padding from 100x100 (the actual QR) up to 200x160.
- let left_padding: i32 = (output_width - (input_width * multiple)) / 2;
- let top_padding: i32 = (output_height - (input_height * multiple)) / 2;
- let output: BitMatrix = BitMatrix::new(output_width, output_height);
- {
- let input_y: i32 = 0, let output_y: i32 = top_padding;
- while input_y < input_height {
- {
- // Write the contents of this row of the barcode
- {
- let input_x: i32 = 0, let output_x: i32 = left_padding;
- while input_x < input_width {
- {
- if input.get(input_x, input_y) == 1 {
- output.set_region(output_x, output_y, multiple, multiple);
- }
- }
- input_x += 1;
- output_x += multiple;
- }
- }
-
- }
- input_y += 1;
- output_y += multiple;
- }
- }
-
- return output;
- }
-}
-