mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-27 21:02:35 +00:00
checkin for entire port source tree
This commit is contained in:
90
port_src/output/zxing/pdf417/encoder/barcode_matrix.rs
Normal file
90
port_src/output/zxing/pdf417/encoder/barcode_matrix.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2011 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::pdf417::encoder;
|
||||
|
||||
/**
|
||||
* Holds all of the information for a barcode in a format where it can be easily accessible
|
||||
*
|
||||
* @author Jacob Haynes
|
||||
*/
|
||||
pub struct BarcodeMatrix {
|
||||
|
||||
let mut matrix: Vec<BarcodeRow>;
|
||||
|
||||
let current_row: i32;
|
||||
|
||||
let height: i32;
|
||||
|
||||
let width: i32;
|
||||
}
|
||||
|
||||
impl BarcodeMatrix {
|
||||
|
||||
/**
|
||||
* @param height the height of the matrix (Rows)
|
||||
* @param width the width of the matrix (Cols)
|
||||
*/
|
||||
fn new( height: i32, width: i32) -> BarcodeMatrix {
|
||||
matrix = : [Option<BarcodeRow>; height] = [None; height];
|
||||
//Initializes the array to the correct width
|
||||
{
|
||||
let mut i: i32 = 0, let matrix_length: i32 = matrix.len();
|
||||
while i < matrix_length {
|
||||
{
|
||||
matrix[i] = BarcodeRow::new((width + 4) * 17 + 1);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let .width = width * 17;
|
||||
let .height = height;
|
||||
let .currentRow = -1;
|
||||
}
|
||||
|
||||
fn set(&self, x: i32, y: i32, value: i8) {
|
||||
self.matrix[y].set(x, value);
|
||||
}
|
||||
|
||||
fn start_row(&self) {
|
||||
self.current_row += 1;
|
||||
}
|
||||
|
||||
fn get_current_row(&self) -> BarcodeRow {
|
||||
return self.matrix[self.current_row];
|
||||
}
|
||||
|
||||
pub fn get_matrix(&self) -> Vec<Vec<i8>> {
|
||||
return self.get_scaled_matrix(1, 1);
|
||||
}
|
||||
|
||||
pub fn get_scaled_matrix(&self, x_scale: i32, y_scale: i32) -> Vec<Vec<i8>> {
|
||||
let matrix_out: [[i8; self.width * x_scale]; self.height * y_scale] = [[0; self.width * x_scale]; self.height * y_scale];
|
||||
let y_max: i32 = self.height * y_scale;
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < y_max {
|
||||
{
|
||||
matrix_out[y_max - i - 1] = self.matrix[i / y_scale].get_scaled_row(x_scale);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return matrix_out;
|
||||
}
|
||||
}
|
||||
|
||||
97
port_src/output/zxing/pdf417/encoder/barcode_row.rs
Normal file
97
port_src/output/zxing/pdf417/encoder/barcode_row.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2011 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::pdf417::encoder;
|
||||
|
||||
/**
|
||||
* @author Jacob Haynes
|
||||
*/
|
||||
struct BarcodeRow {
|
||||
|
||||
let mut row: Vec<i8>;
|
||||
|
||||
//A tacker for position in the bar
|
||||
let current_location: i32;
|
||||
}
|
||||
|
||||
impl BarcodeRow {
|
||||
|
||||
/**
|
||||
* Creates a Barcode row of the width
|
||||
*/
|
||||
fn new( width: i32) -> BarcodeRow {
|
||||
let .row = : [i8; width] = [0; width];
|
||||
current_location = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific location in the bar
|
||||
*
|
||||
* @param x The location in the bar
|
||||
* @param value Black if true, white if false;
|
||||
*/
|
||||
fn set(&self, x: i32, value: i8) {
|
||||
self.row[x] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific location in the bar
|
||||
*
|
||||
* @param x The location in the bar
|
||||
* @param black Black if true, white if false;
|
||||
*/
|
||||
fn set(&self, x: i32, black: bool) {
|
||||
self.row[x] = ( if black { 1 } else { 0 }) as i8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param black A boolean which is true if the bar black false if it is white
|
||||
* @param width How many spots wide the bar is.
|
||||
*/
|
||||
fn add_bar(&self, black: bool, width: i32) {
|
||||
{
|
||||
let mut ii: i32 = 0;
|
||||
while ii < width {
|
||||
{
|
||||
self.set(self.current_location += 1 !!!check!!! post increment, black);
|
||||
}
|
||||
ii += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function scales the row
|
||||
*
|
||||
* @param scale How much you want the image to be scaled, must be greater than or equal to 1.
|
||||
* @return the scaled row
|
||||
*/
|
||||
fn get_scaled_row(&self, scale: i32) -> Vec<i8> {
|
||||
let mut output: [i8; self.row.len() * scale] = [0; self.row.len() * scale];
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < output.len() {
|
||||
{
|
||||
output[i] = self.row[i / scale];
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
24
port_src/output/zxing/pdf417/encoder/compaction.rs
Normal file
24
port_src/output/zxing/pdf417/encoder/compaction.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2011 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::pdf417::encoder;
|
||||
|
||||
/**
|
||||
* Represents possible PDF417 barcode compaction types.
|
||||
*/
|
||||
pub enum Compaction {
|
||||
|
||||
AUTO(), TEXT(), BYTE(), NUMERIC()
|
||||
}
|
||||
59
port_src/output/zxing/pdf417/encoder/dimensions.rs
Normal file
59
port_src/output/zxing/pdf417/encoder/dimensions.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012 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::pdf417::encoder;
|
||||
|
||||
/**
|
||||
* Data object to specify the minimum and maximum number of rows and columns for a PDF417 barcode.
|
||||
*
|
||||
* @author qwandor@google.com (Andrew Walbran)
|
||||
*/
|
||||
pub struct Dimensions {
|
||||
|
||||
let min_cols: i32;
|
||||
|
||||
let max_cols: i32;
|
||||
|
||||
let min_rows: i32;
|
||||
|
||||
let max_rows: i32;
|
||||
}
|
||||
|
||||
impl Dimensions {
|
||||
|
||||
pub fn new( min_cols: i32, max_cols: i32, min_rows: i32, max_rows: i32) -> Dimensions {
|
||||
let .minCols = min_cols;
|
||||
let .maxCols = max_cols;
|
||||
let .minRows = min_rows;
|
||||
let .maxRows = max_rows;
|
||||
}
|
||||
|
||||
pub fn get_min_cols(&self) -> i32 {
|
||||
return self.min_cols;
|
||||
}
|
||||
|
||||
pub fn get_max_cols(&self) -> i32 {
|
||||
return self.max_cols;
|
||||
}
|
||||
|
||||
pub fn get_min_rows(&self) -> i32 {
|
||||
return self.min_rows;
|
||||
}
|
||||
|
||||
pub fn get_max_rows(&self) -> i32 {
|
||||
return self.max_rows;
|
||||
}
|
||||
}
|
||||
|
||||
335
port_src/output/zxing/pdf417/encoder/p_d_f417.rs
Normal file
335
port_src/output/zxing/pdf417/encoder/p_d_f417.rs
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
|
||||
*
|
||||
* 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::pdf417::encoder;
|
||||
|
||||
/**
|
||||
* PDF417 error correction code following the algorithm described in ISO/IEC 15438:2001(E) in
|
||||
* chapter 4.10.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tables of coefficients for calculating error correction words
|
||||
* (see annex F, ISO/IEC 15438:2001(E))
|
||||
*/
|
||||
const EC_COEFFICIENTS: vec![vec![Vec<Vec<i32>>; 512]; 9] = vec![vec![27, 917, ]
|
||||
, vec![522, 568, 723, 809, ]
|
||||
, vec![237, 308, 436, 284, 646, 653, 428, 379, ]
|
||||
, vec![274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65, ]
|
||||
, vec![361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410, ]
|
||||
, vec![539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543, ]
|
||||
, vec![521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898, 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539, ]
|
||||
, vec![524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521, 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10, ]
|
||||
, vec![352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741, 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263, ]
|
||||
, ]
|
||||
;
|
||||
struct PDF417ErrorCorrection {
|
||||
}
|
||||
|
||||
impl PDF417ErrorCorrection {
|
||||
|
||||
fn new() -> PDF417ErrorCorrection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the number of error correction codewords for a specified error correction
|
||||
* level.
|
||||
*
|
||||
* @param errorCorrectionLevel the error correction level (0-8)
|
||||
* @return the number of codewords generated for error correction
|
||||
*/
|
||||
fn get_error_correction_codeword_count( error_correction_level: i32) -> i32 {
|
||||
if error_correction_level < 0 || error_correction_level > 8 {
|
||||
throw IllegalArgumentException::new("Error correction level must be between 0 and 8!");
|
||||
}
|
||||
return 1 << (error_correction_level + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the recommended minimum error correction level as described in annex E of
|
||||
* ISO/IEC 15438:2001(E).
|
||||
*
|
||||
* @param n the number of data codewords
|
||||
* @return the recommended minimum error correction level
|
||||
*/
|
||||
fn get_recommended_minimum_error_correction_level( n: i32) -> /* throws WriterException */Result<i32, Rc<Exception>> {
|
||||
if n <= 0 {
|
||||
throw IllegalArgumentException::new("n must be > 0");
|
||||
}
|
||||
if n <= 40 {
|
||||
return Ok(2);
|
||||
}
|
||||
if n <= 160 {
|
||||
return Ok(3);
|
||||
}
|
||||
if n <= 320 {
|
||||
return Ok(4);
|
||||
}
|
||||
if n <= 863 {
|
||||
return Ok(5);
|
||||
}
|
||||
throw WriterException::new("No recommendation possible");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the error correction codewords according to 4.10 in ISO/IEC 15438:2001(E).
|
||||
*
|
||||
* @param dataCodewords the data codewords
|
||||
* @param errorCorrectionLevel the error correction level (0-8)
|
||||
* @return the String representing the error correction codewords
|
||||
*/
|
||||
fn generate_error_correction( data_codewords: &CharSequence, error_correction_level: i32) -> String {
|
||||
let k: i32 = ::get_error_correction_codeword_count(error_correction_level);
|
||||
let mut e: [Option<char>; k] = [None; k];
|
||||
let sld: i32 = data_codewords.length();
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < sld {
|
||||
{
|
||||
let t1: i32 = (data_codewords.char_at(i) + e[e.len() - 1]) % 929;
|
||||
let mut t2: i32;
|
||||
let mut t3: i32;
|
||||
{
|
||||
let mut j: i32 = k - 1;
|
||||
while j >= 1 {
|
||||
{
|
||||
t2 = (t1 * EC_COEFFICIENTS[error_correction_level][j]) % 929;
|
||||
t3 = 929 - t2;
|
||||
e[j] = ((e[j - 1] + t3) % 929) as char;
|
||||
}
|
||||
j -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
t2 = (t1 * EC_COEFFICIENTS[error_correction_level][0]) % 929;
|
||||
t3 = 929 - t2;
|
||||
e[0] = (t3 % 929) as char;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let sb: StringBuilder = StringBuilder::new(k);
|
||||
{
|
||||
let mut j: i32 = k - 1;
|
||||
while j >= 0 {
|
||||
{
|
||||
if e[j] != 0 {
|
||||
e[j] = (929 - e[j]) as char;
|
||||
}
|
||||
sb.append(e[j]);
|
||||
}
|
||||
j -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return sb.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,778 @@
|
||||
/*
|
||||
* Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
|
||||
*
|
||||
* 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::pdf417::encoder;
|
||||
|
||||
/**
|
||||
* PDF417 high-level encoder following the algorithm described in ISO/IEC 15438:2001(E) in
|
||||
* annex P.
|
||||
*/
|
||||
|
||||
/**
|
||||
* code for Text compaction
|
||||
*/
|
||||
const TEXT_COMPACTION: i32 = 0;
|
||||
|
||||
/**
|
||||
* code for Byte compaction
|
||||
*/
|
||||
const BYTE_COMPACTION: i32 = 1;
|
||||
|
||||
/**
|
||||
* code for Numeric compaction
|
||||
*/
|
||||
const NUMERIC_COMPACTION: i32 = 2;
|
||||
|
||||
/**
|
||||
* Text compaction submode Alpha
|
||||
*/
|
||||
const SUBMODE_ALPHA: i32 = 0;
|
||||
|
||||
/**
|
||||
* Text compaction submode Lower
|
||||
*/
|
||||
const SUBMODE_LOWER: i32 = 1;
|
||||
|
||||
/**
|
||||
* Text compaction submode Mixed
|
||||
*/
|
||||
const SUBMODE_MIXED: i32 = 2;
|
||||
|
||||
/**
|
||||
* Text compaction submode Punctuation
|
||||
*/
|
||||
const SUBMODE_PUNCTUATION: i32 = 3;
|
||||
|
||||
/**
|
||||
* mode latch to Text Compaction mode
|
||||
*/
|
||||
const LATCH_TO_TEXT: i32 = 900;
|
||||
|
||||
/**
|
||||
* mode latch to Byte Compaction mode (number of characters NOT a multiple of 6)
|
||||
*/
|
||||
const LATCH_TO_BYTE_PADDED: i32 = 901;
|
||||
|
||||
/**
|
||||
* mode latch to Numeric Compaction mode
|
||||
*/
|
||||
const LATCH_TO_NUMERIC: i32 = 902;
|
||||
|
||||
/**
|
||||
* mode shift to Byte Compaction mode
|
||||
*/
|
||||
const SHIFT_TO_BYTE: i32 = 913;
|
||||
|
||||
/**
|
||||
* mode latch to Byte Compaction mode (number of characters a multiple of 6)
|
||||
*/
|
||||
const LATCH_TO_BYTE: i32 = 924;
|
||||
|
||||
/**
|
||||
* identifier for a user defined Extended Channel Interpretation (ECI)
|
||||
*/
|
||||
const ECI_USER_DEFINED: i32 = 925;
|
||||
|
||||
/**
|
||||
* identifier for a general purpose ECO format
|
||||
*/
|
||||
const ECI_GENERAL_PURPOSE: i32 = 926;
|
||||
|
||||
/**
|
||||
* identifier for an ECI of a character set of code page
|
||||
*/
|
||||
const ECI_CHARSET: i32 = 927;
|
||||
|
||||
/**
|
||||
* Raw code table for text compaction Mixed sub-mode
|
||||
*/
|
||||
const TEXT_MIXED_RAW: vec![Vec<i8>; 30] = vec![48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 38, 13, 9, 44, 58, 35, 45, 46, 36, 47, 43, 37, 42, 61, 94, 0, 32, 0, 0, 0, ]
|
||||
;
|
||||
|
||||
/**
|
||||
* Raw code table for text compaction: Punctuation sub-mode
|
||||
*/
|
||||
const TEXT_PUNCTUATION_RAW: vec![Vec<i8>; 30] = vec![59, 60, 62, 64, 91, 92, 93, 95, 96, 126, 33, 13, 9, 44, 58, 10, 45, 46, 36, 47, 34, 124, 42, 40, 41, 63, 123, 125, 39, 0, ]
|
||||
;
|
||||
|
||||
const MIXED: [i8; 128] = [0; 128];
|
||||
|
||||
const PUNCTUATION: [i8; 128] = [0; 128];
|
||||
|
||||
const DEFAULT_ENCODING: Charset = StandardCharsets::ISO_8859_1;
|
||||
struct PDF417HighLevelEncoder {
|
||||
}
|
||||
|
||||
impl PDF417HighLevelEncoder {
|
||||
|
||||
fn new() -> PDF417HighLevelEncoder {
|
||||
}
|
||||
|
||||
static {
|
||||
//Construct inverse lookups
|
||||
Arrays::fill(&MIXED, -1 as i8);
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < TEXT_MIXED_RAW.len() {
|
||||
{
|
||||
let mut b: i8 = TEXT_MIXED_RAW[i];
|
||||
if b > 0 {
|
||||
MIXED[b] = i as i8;
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Arrays::fill(&PUNCTUATION, -1 as i8);
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < TEXT_PUNCTUATION_RAW.len() {
|
||||
{
|
||||
let mut b: i8 = TEXT_PUNCTUATION_RAW[i];
|
||||
if b > 0 {
|
||||
PUNCTUATION[b] = i as i8;
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs high-level encoding of a PDF417 message using the algorithm described in annex P
|
||||
* of ISO/IEC 15438:2001(E). If byte compaction has been selected, then only byte compaction
|
||||
* is used.
|
||||
*
|
||||
* @param msg the message
|
||||
* @param compaction compaction mode to use
|
||||
* @param encoding character encoding used to encode in default or byte compaction
|
||||
* or {@code null} for default / not applicable
|
||||
* @param autoECI encode input minimally using multiple ECIs if needed
|
||||
* If autoECI encoding is specified and additionally {@code encoding} is specified, then the encoder
|
||||
* will use the specified {@link Charset} for any character that can be encoded by it, regardless
|
||||
* if a different encoding would lead to a more compact encoding. When no {@code encoding} is specified
|
||||
* then charsets will be chosen so that the byte representation is minimal.
|
||||
* @return the encoded message (the char values range from 0 to 928)
|
||||
*/
|
||||
fn encode_high_level( msg: &String, compaction: &Compaction, encoding: &Charset, auto_e_c_i: bool) -> /* throws WriterException */Result<String, Rc<Exception>> {
|
||||
if msg.is_empty() {
|
||||
throw WriterException::new("Empty message not allowed");
|
||||
}
|
||||
if encoding == null && !auto_e_c_i {
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < msg.length() {
|
||||
{
|
||||
if msg.char_at(i) > 255 {
|
||||
throw WriterException::new(format!("Non-encodable character detected: {} (Unicode: {}). Consider specifying EncodeHintType.PDF417_AUTO_ECI and/or EncodeTypeHint.CHARACTER_SET.", msg.char_at(i), msg.char_at(i) as i32));
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//the codewords 0..928 are encoded as Unicode characters
|
||||
let sb: StringBuilder = StringBuilder::new(&msg.length());
|
||||
let mut input: ECIInput;
|
||||
if auto_e_c_i {
|
||||
input = MinimalECIInput::new(&msg, &encoding, -1);
|
||||
} else {
|
||||
input = NoECIInput::new(&msg);
|
||||
if encoding == null {
|
||||
encoding = DEFAULT_ENCODING;
|
||||
} else if !DEFAULT_ENCODING::equals(&encoding) {
|
||||
let eci: CharacterSetECI = CharacterSetECI::get_character_set_e_c_i(&encoding);
|
||||
if eci != null {
|
||||
::encoding_e_c_i(&eci.get_value(), &sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
let len: i32 = input.length();
|
||||
let mut p: i32 = 0;
|
||||
let text_sub_mode: i32 = SUBMODE_ALPHA;
|
||||
// User selected encoding mode
|
||||
match compaction {
|
||||
TEXT =>
|
||||
{
|
||||
::encode_text(input, p, len, &sb, text_sub_mode);
|
||||
break;
|
||||
}
|
||||
BYTE =>
|
||||
{
|
||||
if auto_e_c_i {
|
||||
::encode_multi_e_c_i_binary(input, 0, &input.length(), TEXT_COMPACTION, &sb);
|
||||
} else {
|
||||
let msg_bytes: Vec<i8> = input.to_string().get_bytes(&encoding);
|
||||
::encode_binary(&msg_bytes, p, msg_bytes.len(), BYTE_COMPACTION, &sb);
|
||||
}
|
||||
break;
|
||||
}
|
||||
NUMERIC =>
|
||||
{
|
||||
sb.append(LATCH_TO_NUMERIC as char);
|
||||
::encode_numeric(input, p, len, &sb);
|
||||
break;
|
||||
}
|
||||
_ =>
|
||||
{
|
||||
//Default mode, see 4.4.2.1
|
||||
let encoding_mode: i32 = TEXT_COMPACTION;
|
||||
while p < len {
|
||||
while p < len && input.is_e_c_i(p) {
|
||||
::encoding_e_c_i(&input.get_e_c_i_value(p), &sb);
|
||||
p += 1;
|
||||
}
|
||||
if p >= len {
|
||||
break;
|
||||
}
|
||||
let n: i32 = ::determine_consecutive_digit_count(input, p);
|
||||
if n >= 13 {
|
||||
sb.append(LATCH_TO_NUMERIC as char);
|
||||
encoding_mode = NUMERIC_COMPACTION;
|
||||
//Reset after latch
|
||||
text_sub_mode = SUBMODE_ALPHA;
|
||||
::encode_numeric(input, p, n, &sb);
|
||||
p += n;
|
||||
} else {
|
||||
let t: i32 = ::determine_consecutive_text_count(input, p);
|
||||
if t >= 5 || n == len {
|
||||
if encoding_mode != TEXT_COMPACTION {
|
||||
sb.append(LATCH_TO_TEXT as char);
|
||||
encoding_mode = TEXT_COMPACTION;
|
||||
//start with submode alpha after latch
|
||||
text_sub_mode = SUBMODE_ALPHA;
|
||||
}
|
||||
text_sub_mode = ::encode_text(input, p, t, &sb, text_sub_mode);
|
||||
p += t;
|
||||
} else {
|
||||
let mut b: i32 = ::determine_consecutive_binary_count(input, p, if auto_e_c_i { null } else { encoding });
|
||||
if b == 0 {
|
||||
b = 1;
|
||||
}
|
||||
let bytes: Vec<i8> = if auto_e_c_i { null } else { input.sub_sequence(p, p + b).to_string().get_bytes(&encoding) };
|
||||
if ((bytes == null && b == 1) || (bytes != null && bytes.len() == 1)) && encoding_mode == TEXT_COMPACTION {
|
||||
//Switch for one byte (instead of latch)
|
||||
if auto_e_c_i {
|
||||
::encode_multi_e_c_i_binary(input, p, 1, TEXT_COMPACTION, &sb);
|
||||
} else {
|
||||
::encode_binary(&bytes, 0, 1, TEXT_COMPACTION, &sb);
|
||||
}
|
||||
} else {
|
||||
//Mode latch performed by encodeBinary()
|
||||
if auto_e_c_i {
|
||||
::encode_multi_e_c_i_binary(input, p, p + b, encoding_mode, &sb);
|
||||
} else {
|
||||
::encode_binary(&bytes, 0, bytes.len(), encoding_mode, &sb);
|
||||
}
|
||||
encoding_mode = BYTE_COMPACTION;
|
||||
//Reset after latch
|
||||
text_sub_mode = SUBMODE_ALPHA;
|
||||
}
|
||||
p += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Ok(sb.to_string());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode parts of the message using Text Compaction as described in ISO/IEC 15438:2001(E),
|
||||
* chapter 4.4.2.
|
||||
*
|
||||
* @param input the input
|
||||
* @param startpos the start position within the message
|
||||
* @param count the number of characters to encode
|
||||
* @param sb receives the encoded codewords
|
||||
* @param initialSubmode should normally be SUBMODE_ALPHA
|
||||
* @return the text submode in which this method ends
|
||||
*/
|
||||
fn encode_text( input: &ECIInput, startpos: i32, count: i32, sb: &StringBuilder, initial_submode: i32) -> /* throws WriterException */Result<i32, Rc<Exception>> {
|
||||
let tmp: StringBuilder = StringBuilder::new(count);
|
||||
let mut submode: i32 = initial_submode;
|
||||
let mut idx: i32 = 0;
|
||||
while true {
|
||||
if input.is_e_c_i(startpos + idx) {
|
||||
::encoding_e_c_i(&input.get_e_c_i_value(startpos + idx), &sb);
|
||||
idx += 1;
|
||||
} else {
|
||||
let ch: char = input.char_at(startpos + idx);
|
||||
match submode {
|
||||
SUBMODE_ALPHA =>
|
||||
{
|
||||
if ::is_alpha_upper(ch) {
|
||||
if ch == ' ' {
|
||||
//space
|
||||
tmp.append(26 as char);
|
||||
} else {
|
||||
tmp.append((ch - 65) as char);
|
||||
}
|
||||
} else {
|
||||
if ::is_alpha_lower(ch) {
|
||||
submode = SUBMODE_LOWER;
|
||||
//ll
|
||||
tmp.append(27 as char);
|
||||
continue;
|
||||
} else if ::is_mixed(ch) {
|
||||
submode = SUBMODE_MIXED;
|
||||
//ml
|
||||
tmp.append(28 as char);
|
||||
continue;
|
||||
} else {
|
||||
//ps
|
||||
tmp.append(29 as char);
|
||||
tmp.append(PUNCTUATION[ch] as char);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
SUBMODE_LOWER =>
|
||||
{
|
||||
if ::is_alpha_lower(ch) {
|
||||
if ch == ' ' {
|
||||
//space
|
||||
tmp.append(26 as char);
|
||||
} else {
|
||||
tmp.append((ch - 97) as char);
|
||||
}
|
||||
} else {
|
||||
if ::is_alpha_upper(ch) {
|
||||
//as
|
||||
tmp.append(27 as char);
|
||||
tmp.append((ch - 65) as char);
|
||||
//space cannot happen here, it is also in "Lower"
|
||||
break;
|
||||
} else if ::is_mixed(ch) {
|
||||
submode = SUBMODE_MIXED;
|
||||
//ml
|
||||
tmp.append(28 as char);
|
||||
continue;
|
||||
} else {
|
||||
//ps
|
||||
tmp.append(29 as char);
|
||||
tmp.append(PUNCTUATION[ch] as char);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
SUBMODE_MIXED =>
|
||||
{
|
||||
if ::is_mixed(ch) {
|
||||
tmp.append(MIXED[ch] as char);
|
||||
} else {
|
||||
if ::is_alpha_upper(ch) {
|
||||
submode = SUBMODE_ALPHA;
|
||||
//al
|
||||
tmp.append(28 as char);
|
||||
continue;
|
||||
} else if ::is_alpha_lower(ch) {
|
||||
submode = SUBMODE_LOWER;
|
||||
//ll
|
||||
tmp.append(27 as char);
|
||||
continue;
|
||||
} else {
|
||||
if startpos + idx + 1 < count {
|
||||
if !input.is_e_c_i(startpos + idx + 1) && ::is_punctuation(&input.char_at(startpos + idx + 1)) {
|
||||
submode = SUBMODE_PUNCTUATION;
|
||||
//pl
|
||||
tmp.append(25 as char);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//ps
|
||||
tmp.append(29 as char);
|
||||
tmp.append(PUNCTUATION[ch] as char);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
_ =>
|
||||
{
|
||||
//SUBMODE_PUNCTUATION
|
||||
if ::is_punctuation(ch) {
|
||||
tmp.append(PUNCTUATION[ch] as char);
|
||||
} else {
|
||||
submode = SUBMODE_ALPHA;
|
||||
//al
|
||||
tmp.append(29 as char);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
idx += 1;
|
||||
if idx >= count {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut h: char = 0;
|
||||
let len: i32 = tmp.length();
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < len {
|
||||
{
|
||||
let odd: bool = (i % 2) != 0;
|
||||
if odd {
|
||||
h = ((h * 30) + tmp.char_at(i)) as char;
|
||||
sb.append(h);
|
||||
} else {
|
||||
h = tmp.char_at(i);
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (len % 2) != 0 {
|
||||
//ps
|
||||
sb.append(((h * 30) + 29) as char);
|
||||
}
|
||||
return Ok(submode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode all of the message using Byte Compaction as described in ISO/IEC 15438:2001(E)
|
||||
*
|
||||
* @param input the input
|
||||
* @param startpos the start position within the message
|
||||
* @param count the number of bytes to encode
|
||||
* @param startmode the mode from which this method starts
|
||||
* @param sb receives the encoded codewords
|
||||
*/
|
||||
fn encode_multi_e_c_i_binary( input: &ECIInput, startpos: i32, count: i32, startmode: i32, sb: &StringBuilder) -> /* throws WriterException */Result<Void, Rc<Exception>> {
|
||||
let end: i32 = Math::min(startpos + count, &input.length());
|
||||
let local_start: i32 = startpos;
|
||||
while true {
|
||||
//encode all leading ECIs and advance localStart
|
||||
while local_start < end && input.is_e_c_i(local_start) {
|
||||
::encoding_e_c_i(&input.get_e_c_i_value(local_start), &sb);
|
||||
local_start += 1;
|
||||
}
|
||||
let local_end: i32 = local_start;
|
||||
//advance end until before the next ECI
|
||||
while local_end < end && !input.is_e_c_i(local_end) {
|
||||
local_end += 1;
|
||||
}
|
||||
let local_count: i32 = local_end - local_start;
|
||||
if local_count <= 0 {
|
||||
//done
|
||||
break;
|
||||
} else {
|
||||
//encode the segment
|
||||
::encode_binary(&::sub_bytes(input, local_start, local_end), 0, local_count, if local_start == startpos { startmode } else { BYTE_COMPACTION }, &sb);
|
||||
local_start = local_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sub_bytes( input: &ECIInput, start: i32, end: i32) -> Vec<i8> {
|
||||
let count: i32 = end - start;
|
||||
let mut result: [i8; count] = [0; count];
|
||||
{
|
||||
let mut i: i32 = start;
|
||||
while i < end {
|
||||
{
|
||||
result[i - start] = (input.char_at(i) & 0xff) as i8;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode parts of the message using Byte Compaction as described in ISO/IEC 15438:2001(E),
|
||||
* chapter 4.4.3. The Unicode characters will be converted to binary using the cp437
|
||||
* codepage.
|
||||
*
|
||||
* @param bytes the message converted to a byte array
|
||||
* @param startpos the start position within the message
|
||||
* @param count the number of bytes to encode
|
||||
* @param startmode the mode from which this method starts
|
||||
* @param sb receives the encoded codewords
|
||||
*/
|
||||
fn encode_binary( bytes: &Vec<i8>, startpos: i32, count: i32, startmode: i32, sb: &StringBuilder) {
|
||||
if count == 1 && startmode == TEXT_COMPACTION {
|
||||
sb.append(SHIFT_TO_BYTE as char);
|
||||
} else {
|
||||
if (count % 6) == 0 {
|
||||
sb.append(LATCH_TO_BYTE as char);
|
||||
} else {
|
||||
sb.append(LATCH_TO_BYTE_PADDED as char);
|
||||
}
|
||||
}
|
||||
let mut idx: i32 = startpos;
|
||||
// Encode sixpacks
|
||||
if count >= 6 {
|
||||
let mut chars: [Option<char>; 5] = [None; 5];
|
||||
while (startpos + count - idx) >= 6 {
|
||||
let mut t: i64 = 0;
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < 6 {
|
||||
{
|
||||
t <<= 8;
|
||||
t += bytes[idx + i] & 0xff;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let mut i: i32 = 0;
|
||||
while i < 5 {
|
||||
{
|
||||
chars[i] = (t % 900) as char;
|
||||
t /= 900;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let mut i: i32 = chars.len() - 1;
|
||||
while i >= 0 {
|
||||
{
|
||||
sb.append(chars[i]);
|
||||
}
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
idx += 6;
|
||||
}
|
||||
}
|
||||
//Encode rest (remaining n<5 bytes if any)
|
||||
{
|
||||
let mut i: i32 = idx;
|
||||
while i < startpos + count {
|
||||
{
|
||||
let ch: i32 = bytes[i] & 0xff;
|
||||
sb.append(ch as char);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn encode_numeric( input: &ECIInput, startpos: i32, count: i32, sb: &StringBuilder) {
|
||||
let mut idx: i32 = 0;
|
||||
let tmp: StringBuilder = StringBuilder::new(count / 3 + 1);
|
||||
let num900: BigInteger = BigInteger::value_of(900);
|
||||
let num0: BigInteger = BigInteger::value_of(0);
|
||||
while idx < count {
|
||||
tmp.set_length(0);
|
||||
let len: i32 = Math::min(44, count - idx);
|
||||
let part: String = format!("1{}", input.sub_sequence(startpos + idx, startpos + idx + len));
|
||||
let mut bigint: BigInteger = BigInteger::new(&part);
|
||||
loop { {
|
||||
tmp.append(bigint.mod(&num900).int_value() as char);
|
||||
bigint = bigint.divide(&num900);
|
||||
}if !(!bigint.equals(&num0)) break;}
|
||||
//Reverse temporary string
|
||||
{
|
||||
let mut i: i32 = tmp.length() - 1;
|
||||
while i >= 0 {
|
||||
{
|
||||
sb.append(&tmp.char_at(i));
|
||||
}
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
idx += len;
|
||||
}
|
||||
}
|
||||
|
||||
fn is_digit( ch: char) -> bool {
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
|
||||
fn is_alpha_upper( ch: char) -> bool {
|
||||
return ch == ' ' || (ch >= 'A' && ch <= 'Z');
|
||||
}
|
||||
|
||||
fn is_alpha_lower( ch: char) -> bool {
|
||||
return ch == ' ' || (ch >= 'a' && ch <= 'z');
|
||||
}
|
||||
|
||||
fn is_mixed( ch: char) -> bool {
|
||||
return MIXED[ch] != -1;
|
||||
}
|
||||
|
||||
fn is_punctuation( ch: char) -> bool {
|
||||
return PUNCTUATION[ch] != -1;
|
||||
}
|
||||
|
||||
fn is_text( ch: char) -> bool {
|
||||
return ch == '\t' || ch == '\n' || ch == '\r' || (ch >= 32 && ch <= 126);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the number of consecutive characters that are encodable using numeric compaction.
|
||||
*
|
||||
* @param input the input
|
||||
* @param startpos the start position within the input
|
||||
* @return the requested character count
|
||||
*/
|
||||
fn determine_consecutive_digit_count( input: &ECIInput, startpos: i32) -> i32 {
|
||||
let mut count: i32 = 0;
|
||||
let len: i32 = input.length();
|
||||
let mut idx: i32 = startpos;
|
||||
if idx < len {
|
||||
while idx < len && !input.is_e_c_i(idx) && ::is_digit(&input.char_at(idx)) {
|
||||
count += 1;
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the number of consecutive characters that are encodable using text compaction.
|
||||
*
|
||||
* @param input the input
|
||||
* @param startpos the start position within the input
|
||||
* @return the requested character count
|
||||
*/
|
||||
fn determine_consecutive_text_count( input: &ECIInput, startpos: i32) -> i32 {
|
||||
let len: i32 = input.length();
|
||||
let mut idx: i32 = startpos;
|
||||
while idx < len {
|
||||
let numeric_count: i32 = 0;
|
||||
while numeric_count < 13 && idx < len && !input.is_e_c_i(idx) && ::is_digit(&input.char_at(idx)) {
|
||||
numeric_count += 1;
|
||||
idx += 1;
|
||||
}
|
||||
if numeric_count >= 13 {
|
||||
return idx - startpos - numeric_count;
|
||||
}
|
||||
if numeric_count > 0 {
|
||||
//Heuristic: All text-encodable chars or digits are binary encodable
|
||||
continue;
|
||||
}
|
||||
//Check if character is encodable
|
||||
if input.is_e_c_i(idx) || !::is_text(&input.char_at(idx)) {
|
||||
break;
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
return idx - startpos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the number of consecutive characters that are encodable using binary compaction.
|
||||
*
|
||||
* @param input the input
|
||||
* @param startpos the start position within the message
|
||||
* @param encoding the charset used to convert the message to a byte array
|
||||
* @return the requested character count
|
||||
*/
|
||||
fn determine_consecutive_binary_count( input: &ECIInput, startpos: i32, encoding: &Charset) -> /* throws WriterException */Result<i32, Rc<Exception>> {
|
||||
let encoder: CharsetEncoder = if encoding == null { null } else { encoding.new_encoder() };
|
||||
let len: i32 = input.length();
|
||||
let mut idx: i32 = startpos;
|
||||
while idx < len {
|
||||
let numeric_count: i32 = 0;
|
||||
let mut i: i32 = idx;
|
||||
while numeric_count < 13 && !input.is_e_c_i(i) && ::is_digit(&input.char_at(i)) {
|
||||
numeric_count += 1;
|
||||
//textCount++;
|
||||
i = idx + numeric_count;
|
||||
if i >= len {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if numeric_count >= 13 {
|
||||
return Ok(idx - startpos);
|
||||
}
|
||||
if encoder != null && !encoder.can_encode(&input.char_at(idx)) {
|
||||
assert!( input instanceof NoECIInput);
|
||||
let ch: char = input.char_at(idx);
|
||||
throw WriterException::new(format!("Non-encodable character detected: {} (Unicode: {})", ch, ch as i32));
|
||||
}
|
||||
idx += 1;
|
||||
}
|
||||
return Ok(idx - startpos);
|
||||
}
|
||||
|
||||
fn encoding_e_c_i( eci: i32, sb: &StringBuilder) -> /* throws WriterException */Result<Void, Rc<Exception>> {
|
||||
if eci >= 0 && eci < 900 {
|
||||
sb.append(ECI_CHARSET as char);
|
||||
sb.append(eci as char);
|
||||
} else if eci < 810900 {
|
||||
sb.append(ECI_GENERAL_PURPOSE as char);
|
||||
sb.append((eci / 900 - 1) as char);
|
||||
sb.append((eci % 900) as char);
|
||||
} else if eci < 811800 {
|
||||
sb.append(ECI_USER_DEFINED as char);
|
||||
sb.append((810900 - eci) as char);
|
||||
} else {
|
||||
throw WriterException::new(format!("ECI number not in valid range from 0..811799, but was {}", eci));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ECIInput)]
|
||||
struct NoECIInput {
|
||||
|
||||
let input: String;
|
||||
}
|
||||
|
||||
impl NoECIInput {
|
||||
|
||||
fn new( input: &String) -> NoECIInput {
|
||||
let .input = input;
|
||||
}
|
||||
|
||||
pub fn length(&self) -> i32 {
|
||||
return self.input.length();
|
||||
}
|
||||
|
||||
pub fn char_at(&self, index: i32) -> char {
|
||||
return self.input.char_at(index);
|
||||
}
|
||||
|
||||
pub fn is_e_c_i(&self, index: i32) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn get_e_c_i_value(&self, index: i32) -> i32 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pub fn have_n_characters(&self, index: i32, n: i32) -> bool {
|
||||
return index + n <= self.input.length();
|
||||
}
|
||||
|
||||
pub fn sub_sequence(&self, start: i32, end: i32) -> CharSequence {
|
||||
return self.input.sub_sequence(start, end);
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
return self.input;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2022 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::pdf417::encoder;
|
||||
|
||||
pub struct PDF417HighLevelEncoderTestAdapter {
|
||||
}
|
||||
|
||||
impl PDF417HighLevelEncoderTestAdapter {
|
||||
|
||||
fn new() -> PDF417HighLevelEncoderTestAdapter {
|
||||
}
|
||||
|
||||
pub fn encode_high_level( msg: &String, compaction: &Compaction, encoding: &Charset, auto_e_c_i: bool) -> /* throws WriterException */Result<String, Rc<Exception>> {
|
||||
return Ok(PDF417HighLevelEncoder::encode_high_level(&msg, compaction, &encoding, auto_e_c_i));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user