From 492fa0f09dd0b1f6294570984706344e58c81fe7 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Tue, 8 Nov 2022 16:38:32 -0600 Subject: [PATCH] port data_block --- src/datamatrix/decoder/DataBlock.java | 118 -------------------- src/datamatrix/decoder/data_block.rs | 151 ++++++++++++++++++++++++++ src/datamatrix/decoder/mod.rs | 4 +- 3 files changed, 154 insertions(+), 119 deletions(-) delete mode 100644 src/datamatrix/decoder/DataBlock.java create mode 100644 src/datamatrix/decoder/data_block.rs diff --git a/src/datamatrix/decoder/DataBlock.java b/src/datamatrix/decoder/DataBlock.java deleted file mode 100644 index 95b4b30..0000000 --- a/src/datamatrix/decoder/DataBlock.java +++ /dev/null @@ -1,118 +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.datamatrix.decoder; - -/** - *

Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into - * multiple blocks, each of which is a unit of data and error-correction codewords. Each - * is represented by an instance of this class.

- * - * @author bbrown@google.com (Brian Brown) - */ -final class DataBlock { - - private final int numDataCodewords; - private final byte[] codewords; - - private DataBlock(int numDataCodewords, byte[] codewords) { - this.numDataCodewords = numDataCodewords; - this.codewords = codewords; - } - - /** - *

When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them. - * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This - * method will separate the data into original blocks.

- * - * @param rawCodewords bytes as read directly from the Data Matrix Code - * @param version version of the Data Matrix Code - * @return DataBlocks containing original bytes, "de-interleaved" from representation in the - * Data Matrix Code - */ - static DataBlock[] getDataBlocks(byte[] rawCodewords, - Version version) { - // Figure out the number and size of data blocks used by this version - Version.ECBlocks ecBlocks = version.getECBlocks(); - - // First count the total number of data blocks - int totalBlocks = 0; - Version.ECB[] ecBlockArray = ecBlocks.getECBlocks(); - for (Version.ECB ecBlock : ecBlockArray) { - totalBlocks += ecBlock.getCount(); - } - - // Now establish DataBlocks of the appropriate size and number of data codewords - DataBlock[] result = new DataBlock[totalBlocks]; - int numRXingResultBlocks = 0; - for (Version.ECB ecBlock : ecBlockArray) { - for (int i = 0; i < ecBlock.getCount(); i++) { - int numDataCodewords = ecBlock.getDataCodewords(); - int numBlockCodewords = ecBlocks.getECCodewords() + numDataCodewords; - result[numRXingResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]); - } - } - - // All blocks have the same amount of data, except that the last n - // (where n may be 0) have 1 less byte. Figure out where these start. - // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144 - int longerBlocksTotalCodewords = result[0].codewords.length; - //int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1; - - int longerBlocksNumDataCodewords = longerBlocksTotalCodewords - ecBlocks.getECCodewords(); - int shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1; - // The last elements of result may be 1 element shorter for 144 matrix - // first fill out as many elements as all of them have minus 1 - int rawCodewordsOffset = 0; - for (int i = 0; i < shorterBlocksNumDataCodewords; i++) { - for (int j = 0; j < numRXingResultBlocks; j++) { - result[j].codewords[i] = rawCodewords[rawCodewordsOffset++]; - } - } - - // Fill out the last data block in the longer ones - boolean specialVersion = version.getVersionNumber() == 24; - int numLongerBlocks = specialVersion ? 8 : numRXingResultBlocks; - for (int j = 0; j < numLongerBlocks; j++) { - result[j].codewords[longerBlocksNumDataCodewords - 1] = rawCodewords[rawCodewordsOffset++]; - } - - // Now add in error correction blocks - int max = result[0].codewords.length; - for (int i = longerBlocksNumDataCodewords; i < max; i++) { - for (int j = 0; j < numRXingResultBlocks; j++) { - int jOffset = specialVersion ? (j + 8) % numRXingResultBlocks : j; - int iOffset = specialVersion && jOffset > 7 ? i - 1 : i; - result[jOffset].codewords[iOffset] = rawCodewords[rawCodewordsOffset++]; - } - } - - if (rawCodewordsOffset != rawCodewords.length) { - throw new IllegalArgumentException(); - } - - return result; - } - - int getNumDataCodewords() { - return numDataCodewords; - } - - byte[] getCodewords() { - return codewords; - } - -} diff --git a/src/datamatrix/decoder/data_block.rs b/src/datamatrix/decoder/data_block.rs new file mode 100644 index 0000000..5c87e96 --- /dev/null +++ b/src/datamatrix/decoder/data_block.rs @@ -0,0 +1,151 @@ +/* + * 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. + */ + +use crate::Exceptions; + +use super::Version; + +/** + *

Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into + * multiple blocks, each of which is a unit of data and error-correction codewords. Each + * is represented by an instance of this class.

+ * + * @author bbrown@google.com (Brian Brown) + */ +pub struct DataBlock { + numDataCodewords: u32, + codewords: Vec, +} + +impl DataBlock { + pub fn new(numDataCodewords: u32, codewords: Vec) -> Self { + Self { + numDataCodewords, + codewords, + } + } + + /** + *

When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them. + * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This + * method will separate the data into original blocks.

+ * + * @param rawCodewords bytes as read directly from the Data Matrix Code + * @param version version of the Data Matrix Code + * @return DataBlocks containing original bytes, "de-interleaved" from representation in the + * Data Matrix Code + */ + pub fn getDataBlocks( + rawCodewords: &[u8], + version: &Version, + ) -> Result, Exceptions> { + // Figure out the number and size of data blocks used by this version + let ecBlocks = version.getECBlocks(); + + // First count the total number of data blocks + let mut totalBlocks = 0_usize; + let ecBlockArray = ecBlocks.getECBlocks(); + for ecBlock in ecBlockArray { + totalBlocks += ecBlock.getCount() as usize; + } + + // Now establish DataBlocks of the appropriate size and number of data codewords + let mut result = Vec::with_capacity(totalBlocks); + let numRXingResultBlocks = 0; + for ecBlock in ecBlockArray { + for _i in 0..ecBlock.getCount() { + // for (int i = 0; i < ecBlock.getCount(); i++) { + let numDataCodewords = ecBlock.getDataCodewords() as usize; + let numBlockCodewords = ecBlocks.getECCodewords() as usize + numDataCodewords; + // result[numRXingResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]); + result.push(DataBlock::new( + numDataCodewords as u32, + vec![0; numBlockCodewords], + )); + } + } + + // All blocks have the same amount of data, except that the last n + // (where n may be 0) have 1 less byte. Figure out where these start. + // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144 + let longerBlocksTotalCodewords = result[0].codewords.len(); + //int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1; + + let longerBlocksNumDataCodewords = + longerBlocksTotalCodewords - ecBlocks.getECCodewords() as usize; + let shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1; + // The last elements of result may be 1 element shorter for 144 matrix + // first fill out as many elements as all of them have minus 1 + let mut rawCodewordsOffset = 0; + for i in 0..shorterBlocksNumDataCodewords { + // for (int i = 0; i < shorterBlocksNumDataCodewords; i++) { + for j in 0..numRXingResultBlocks { + // for (int j = 0; j < numRXingResultBlocks; j++) { + result[j].codewords[i] = rawCodewords[rawCodewordsOffset]; + rawCodewordsOffset += 1; + } + } + + // Fill out the last data block in the longer ones + let specialVersion = version.getVersionNumber() == 24; + let numLongerBlocks = if specialVersion { + 8 + } else { + numRXingResultBlocks + }; + for j in 0..numLongerBlocks { + // for (int j = 0; j < numLongerBlocks; j++) { + result[j].codewords[longerBlocksNumDataCodewords - 1] = + rawCodewords[rawCodewordsOffset]; + rawCodewordsOffset += 1; + } + + // Now add in error correction blocks + let max = result[0].codewords.len(); + for i in longerBlocksNumDataCodewords..max { + // for (int i = longerBlocksNumDataCodewords; i < max; i++) { + for j in 0..numRXingResultBlocks { + // for (int j = 0; j < numRXingResultBlocks; j++) { + let jOffset = if specialVersion { + (j + 8) % numRXingResultBlocks + } else { + j + }; + let iOffset = if specialVersion && jOffset > 7 { + i - 1 + } else { + i + }; + result[jOffset].codewords[iOffset] = rawCodewords[rawCodewordsOffset]; + rawCodewordsOffset += 1; + } + } + + if rawCodewordsOffset != rawCodewords.len() { + return Err(Exceptions::IllegalArgumentException("".to_owned())); + } + + Ok(result) + } + + pub fn getNumDataCodewords(&self) -> u32 { + self.numDataCodewords + } + + pub fn getCodewords(&self) -> &[u8] { + &self.codewords + } +} diff --git a/src/datamatrix/decoder/mod.rs b/src/datamatrix/decoder/mod.rs index 2ed4e31..d4c68f7 100644 --- a/src/datamatrix/decoder/mod.rs +++ b/src/datamatrix/decoder/mod.rs @@ -1,4 +1,6 @@ mod version; +mod data_block; -pub use version::*; \ No newline at end of file +pub use version::*; +pub use data_block::*; \ No newline at end of file