mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 12:22:34 +00:00
221 lines
9.8 KiB
Rust
221 lines
9.8 KiB
Rust
/*
|
|
* 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::datamatrix;
|
|
|
|
/**
|
|
* This object renders a Data Matrix code as a BitMatrix 2D array of greyscale values.
|
|
*
|
|
* @author dswitkin@google.com (Daniel Switkin)
|
|
* @author Guillaume Le Biller Added to zxing lib.
|
|
*/
|
|
#[derive(Writer)]
|
|
pub struct DataMatrixWriter {
|
|
}
|
|
|
|
impl DataMatrixWriter {
|
|
|
|
pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32) -> BitMatrix {
|
|
return self.encode(&contents, format, width, height, null);
|
|
}
|
|
|
|
pub fn encode(&self, contents: &String, format: &BarcodeFormat, width: i32, height: i32, hints: &Map<EncodeHintType, ?>) -> BitMatrix {
|
|
if contents.is_empty() {
|
|
throw IllegalArgumentException::new("Found empty contents");
|
|
}
|
|
if format != BarcodeFormat::DATA_MATRIX {
|
|
throw IllegalArgumentException::new(format!("Can only encode DATA_MATRIX, but got {}", format));
|
|
}
|
|
if width < 0 || height < 0 {
|
|
throw IllegalArgumentException::new(format!("Requested dimensions can't be negative: {}x{}", width, height));
|
|
}
|
|
// Try to get force shape & min / max size
|
|
let mut shape: SymbolShapeHint = SymbolShapeHint::FORCE_NONE;
|
|
let min_size: Dimension = null;
|
|
let max_size: Dimension = null;
|
|
if hints != null {
|
|
let requested_shape: SymbolShapeHint = hints.get(EncodeHintType::DATA_MATRIX_SHAPE) as SymbolShapeHint;
|
|
if requested_shape != null {
|
|
shape = requested_shape;
|
|
}
|
|
let requested_min_size: Dimension = hints.get(EncodeHintType::MIN_SIZE) as Dimension;
|
|
if requested_min_size != null {
|
|
min_size = requested_min_size;
|
|
}
|
|
let requested_max_size: Dimension = hints.get(EncodeHintType::MAX_SIZE) as Dimension;
|
|
if requested_max_size != null {
|
|
max_size = requested_max_size;
|
|
}
|
|
}
|
|
//1. step: Data encodation
|
|
let mut encoded: String;
|
|
let has_compaction_hint: bool = hints != null && hints.contains_key(EncodeHintType::DATA_MATRIX_COMPACT) && Boolean::parse_boolean(&hints.get(EncodeHintType::DATA_MATRIX_COMPACT).to_string());
|
|
if has_compaction_hint {
|
|
let has_g_s1_format_hint: bool = hints.contains_key(EncodeHintType::GS1_FORMAT) && Boolean::parse_boolean(&hints.get(EncodeHintType::GS1_FORMAT).to_string());
|
|
let mut charset: Charset = null;
|
|
let has_encoding_hint: bool = hints.contains_key(EncodeHintType::CHARACTER_SET);
|
|
if has_encoding_hint {
|
|
charset = Charset::for_name(&hints.get(EncodeHintType::CHARACTER_SET).to_string());
|
|
}
|
|
encoded = MinimalEncoder::encode_high_level(&contents, &charset, if has_g_s1_format_hint { 0x1D } else { -1 }, shape);
|
|
} else {
|
|
let has_force_c40_hint: bool = hints != null && hints.contains_key(EncodeHintType::FORCE_C40) && Boolean::parse_boolean(&hints.get(EncodeHintType::FORCE_C40).to_string());
|
|
encoded = HighLevelEncoder::encode_high_level(&contents, shape, min_size, max_size, has_force_c40_hint);
|
|
}
|
|
let symbol_info: SymbolInfo = SymbolInfo::lookup(&encoded.length(), shape, min_size, max_size, true);
|
|
//2. step: ECC generation
|
|
let codewords: String = ErrorCorrection::encode_e_c_c200(&encoded, symbol_info);
|
|
//3. step: Module placement in Matrix
|
|
let placement: DefaultPlacement = DefaultPlacement::new(&codewords, &symbol_info.get_symbol_data_width(), &symbol_info.get_symbol_data_height());
|
|
placement.place();
|
|
//4. step: low-level encoding
|
|
return ::encode_low_level(placement, symbol_info, width, height);
|
|
}
|
|
|
|
/**
|
|
* Encode the given symbol info to a bit matrix.
|
|
*
|
|
* @param placement The DataMatrix placement.
|
|
* @param symbolInfo The symbol info to encode.
|
|
* @return The bit matrix generated.
|
|
*/
|
|
fn encode_low_level( placement: &DefaultPlacement, symbol_info: &SymbolInfo, width: i32, height: i32) -> BitMatrix {
|
|
let symbol_width: i32 = symbol_info.get_symbol_data_width();
|
|
let symbol_height: i32 = symbol_info.get_symbol_data_height();
|
|
let matrix: ByteMatrix = ByteMatrix::new(&symbol_info.get_symbol_width(), &symbol_info.get_symbol_height());
|
|
let matrix_y: i32 = 0;
|
|
{
|
|
let mut y: i32 = 0;
|
|
while y < symbol_height {
|
|
{
|
|
// Fill the top edge with alternate 0 / 1
|
|
let matrix_x: i32;
|
|
if (y % symbol_info.matrixHeight) == 0 {
|
|
matrix_x = 0;
|
|
{
|
|
let mut x: i32 = 0;
|
|
while x < symbol_info.get_symbol_width() {
|
|
{
|
|
matrix.set(matrix_x, matrix_y, (x % 2) == 0);
|
|
matrix_x += 1;
|
|
}
|
|
x += 1;
|
|
}
|
|
}
|
|
|
|
matrix_y += 1;
|
|
}
|
|
matrix_x = 0;
|
|
{
|
|
let mut x: i32 = 0;
|
|
while x < symbol_width {
|
|
{
|
|
// Fill the right edge with full 1
|
|
if (x % symbol_info.matrixWidth) == 0 {
|
|
matrix.set(matrix_x, matrix_y, true);
|
|
matrix_x += 1;
|
|
}
|
|
matrix.set(matrix_x, matrix_y, &placement.get_bit(x, y));
|
|
matrix_x += 1;
|
|
// Fill the right edge with alternate 0 / 1
|
|
if (x % symbol_info.matrixWidth) == symbol_info.matrixWidth - 1 {
|
|
matrix.set(matrix_x, matrix_y, (y % 2) == 0);
|
|
matrix_x += 1;
|
|
}
|
|
}
|
|
x += 1;
|
|
}
|
|
}
|
|
|
|
matrix_y += 1;
|
|
// Fill the bottom edge with full 1
|
|
if (y % symbol_info.matrixHeight) == symbol_info.matrixHeight - 1 {
|
|
matrix_x = 0;
|
|
{
|
|
let mut x: i32 = 0;
|
|
while x < symbol_info.get_symbol_width() {
|
|
{
|
|
matrix.set(matrix_x, matrix_y, true);
|
|
matrix_x += 1;
|
|
}
|
|
x += 1;
|
|
}
|
|
}
|
|
|
|
matrix_y += 1;
|
|
}
|
|
}
|
|
y += 1;
|
|
}
|
|
}
|
|
|
|
return ::convert_byte_matrix_to_bit_matrix(matrix, width, height);
|
|
}
|
|
|
|
/**
|
|
* Convert the ByteMatrix to BitMatrix.
|
|
*
|
|
* @param reqHeight The requested height of the image (in pixels) with the Datamatrix code
|
|
* @param reqWidth The requested width of the image (in pixels) with the Datamatrix code
|
|
* @param matrix The input matrix.
|
|
* @return The output matrix.
|
|
*/
|
|
fn convert_byte_matrix_to_bit_matrix( matrix: &ByteMatrix, req_width: i32, req_height: i32) -> BitMatrix {
|
|
let matrix_width: i32 = matrix.get_width();
|
|
let matrix_height: i32 = matrix.get_height();
|
|
let output_width: i32 = Math::max(req_width, matrix_width);
|
|
let output_height: i32 = Math::max(req_height, matrix_height);
|
|
let multiple: i32 = Math::min(output_width / matrix_width, output_height / matrix_height);
|
|
let left_padding: i32 = (output_width - (matrix_width * multiple)) / 2;
|
|
let top_padding: i32 = (output_height - (matrix_height * multiple)) / 2;
|
|
let mut output: BitMatrix;
|
|
// remove padding if requested width and height are too small
|
|
if req_height < matrix_height || req_width < matrix_width {
|
|
left_padding = 0;
|
|
top_padding = 0;
|
|
output = BitMatrix::new(matrix_width, matrix_height);
|
|
} else {
|
|
output = BitMatrix::new(req_width, req_height);
|
|
}
|
|
output.clear();
|
|
{
|
|
let input_y: i32 = 0, let output_y: i32 = top_padding;
|
|
while input_y < matrix_height {
|
|
{
|
|
// Write the contents of this row of the bytematrix
|
|
{
|
|
let input_x: i32 = 0, let output_x: i32 = left_padding;
|
|
while input_x < matrix_width {
|
|
{
|
|
if matrix.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;
|
|
}
|
|
}
|
|
|