diff --git a/src/datamatrix/DataMatrixReader.java b/src/datamatrix/DataMatrixReader.java deleted file mode 100644 index 890cf9f..0000000 --- a/src/datamatrix/DataMatrixReader.java +++ /dev/null @@ -1,160 +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.datamatrix; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.BinaryBitmap; -import com.google.zxing.ChecksumException; -import com.google.zxing.DecodeHintType; -import com.google.zxing.FormatException; -import com.google.zxing.NotFoundException; -import com.google.zxing.Reader; -import com.google.zxing.RXingResult; -import com.google.zxing.RXingResultMetadataType; -import com.google.zxing.RXingResultPoint; -import com.google.zxing.common.BitMatrix; -import com.google.zxing.common.DecoderRXingResult; -import com.google.zxing.common.DetectorRXingResult; -import com.google.zxing.datamatrix.decoder.Decoder; -import com.google.zxing.datamatrix.detector.Detector; - -import java.util.List; -import java.util.Map; - -/** - * This implementation can detect and decode Data Matrix codes in an image. - * - * @author bbrown@google.com (Brian Brown) - */ -public final class DataMatrixReader implements Reader { - - private static final RXingResultPoint[] NO_POINTS = new RXingResultPoint[0]; - - private final Decoder decoder = new Decoder(); - - /** - * Locates and decodes a Data Matrix code in an image. - * - * @return a String representing the content encoded by the Data Matrix code - * @throws NotFoundException if a Data Matrix code cannot be found - * @throws FormatException if a Data Matrix code cannot be decoded - * @throws ChecksumException if error correction fails - */ - @Override - public RXingResult decode(BinaryBitmap image) throws NotFoundException, ChecksumException, FormatException { - return decode(image, null); - } - - @Override - public RXingResult decode(BinaryBitmap image, Map hints) - throws NotFoundException, ChecksumException, FormatException { - DecoderRXingResult decoderRXingResult; - RXingResultPoint[] points; - if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) { - BitMatrix bits = extractPureBits(image.getBlackMatrix()); - decoderRXingResult = decoder.decode(bits); - points = NO_POINTS; - } else { - DetectorRXingResult detectorRXingResult = new Detector(image.getBlackMatrix()).detect(); - decoderRXingResult = decoder.decode(detectorRXingResult.getBits()); - points = detectorRXingResult.getPoints(); - } - RXingResult result = new RXingResult(decoderRXingResult.getText(), decoderRXingResult.getRawBytes(), points, - BarcodeFormat.DATA_MATRIX); - List byteSegments = decoderRXingResult.getByteSegments(); - if (byteSegments != null) { - result.putMetadata(RXingResultMetadataType.BYTE_SEGMENTS, byteSegments); - } - String ecLevel = decoderRXingResult.getECLevel(); - if (ecLevel != null) { - result.putMetadata(RXingResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); - } - result.putMetadata(RXingResultMetadataType.SYMBOLOGY_IDENTIFIER, "]d" + decoderRXingResult.getSymbologyModifier()); - return result; - } - - @Override - public void reset() { - // 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. - */ - private static BitMatrix extractPureBits(BitMatrix image) throws NotFoundException { - - int[] leftTopBlack = image.getTopLeftOnBit(); - int[] rightBottomBlack = image.getBottomRightOnBit(); - if (leftTopBlack == null || rightBottomBlack == null) { - throw NotFoundException.getNotFoundInstance(); - } - - int moduleSize = moduleSize(leftTopBlack, image); - - int top = leftTopBlack[1]; - int bottom = rightBottomBlack[1]; - int left = leftTopBlack[0]; - int right = rightBottomBlack[0]; - - int matrixWidth = (right - left + 1) / moduleSize; - int matrixHeight = (bottom - top + 1) / moduleSize; - if (matrixWidth <= 0 || matrixHeight <= 0) { - throw NotFoundException.getNotFoundInstance(); - } - - // 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. - int nudge = moduleSize / 2; - top += nudge; - left += nudge; - - // Now just read off the bits - BitMatrix bits = new BitMatrix(matrixWidth, matrixHeight); - for (int y = 0; y < matrixHeight; y++) { - int iOffset = top + y * moduleSize; - for (int x = 0; x < matrixWidth; x++) { - if (image.get(left + x * moduleSize, iOffset)) { - bits.set(x, y); - } - } - } - return bits; - } - - private static int moduleSize(int[] leftTopBlack, BitMatrix image) throws NotFoundException { - int width = image.getWidth(); - int x = leftTopBlack[0]; - int y = leftTopBlack[1]; - while (x < width && image.get(x, y)) { - x++; - } - if (x == width) { - throw NotFoundException.getNotFoundInstance(); - } - - int moduleSize = x - leftTopBlack[0]; - if (moduleSize == 0) { - throw NotFoundException.getNotFoundInstance(); - } - return moduleSize; - } - -} diff --git a/src/datamatrix/data_matrix_reader.rs b/src/datamatrix/data_matrix_reader.rs new file mode 100644 index 0000000..174885d --- /dev/null +++ b/src/datamatrix/data_matrix_reader.rs @@ -0,0 +1,173 @@ +/* + * 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. + */ + +use std::collections::HashMap; + +use crate::{Reader, Exceptions, common::{BitMatrix, DetectorRXingResult}, RXingResultPoint, DecodeHintType, RXingResult, BarcodeFormat, RXingResultMetadataType, RXingResultMetadataValue}; + +use super::{detector::Detector, decoder::Decoder}; + +use lazy_static::lazy_static; + +lazy_static!{ + static ref decoder : Decoder = Decoder::new(); +} + +/** + * This implementation can detect and decode Data Matrix codes in an image. + * + * @author bbrown@google.com (Brian Brown) + */ +pub struct DataMatrixReader; + + // private static final RXingResultPoint[] NO_POINTS = new RXingResultPoint[0]; + + // private final Decoder decoder = new Decoder(); + + impl Reader for DataMatrixReader { + + /** + * Locates and decodes a Data Matrix code in an image. + * + * @return a String representing the content encoded by the Data Matrix code + * @throws NotFoundException if a Data Matrix code cannot be found + * @throws FormatException if a Data Matrix code cannot be decoded + * @throws ChecksumException if error correction fails + */ + fn decode(&mut self, image: &crate::BinaryBitmap) -> Result { + self.decode_with_hints(image,&HashMap::new()) + } + + /** + * Locates and decodes a Data Matrix code in an image. + * + * @return a String representing the content encoded by the Data Matrix code + * @throws NotFoundException if a Data Matrix code cannot be found + * @throws FormatException if a Data Matrix code cannot be decoded + * @throws ChecksumException if error correction fails + */ + fn decode_with_hints( + &mut self, + image: &crate::BinaryBitmap, + hints: &crate::DecodingHintDictionary, + ) -> Result { + let decoderRXingResult; + let mut points = Vec::new(); + if hints.contains_key(&DecodeHintType::PURE_BARCODE) { + let bits = self.extractPureBits(image.getBlackMatrix())?; + decoderRXingResult = decoder.decode(&bits)?; + points.clear(); + } else { + let detectorRXingResult = Detector::new(image.getBlackMatrix().clone())?.detect()?; + decoderRXingResult = decoder.decode(detectorRXingResult.getBits())?; + points = detectorRXingResult.getPoints().clone(); + } + let mut result = RXingResult::new(decoderRXingResult.getText().clone(), decoderRXingResult.getRawBytes().clone(), points.clone(), + BarcodeFormat::DATA_MATRIX); + let byteSegments = decoderRXingResult.getByteSegments(); + if !byteSegments.is_empty() { + result.putMetadata(RXingResultMetadataType::BYTE_SEGMENTS, RXingResultMetadataValue::ByteSegments(byteSegments.clone())); + } + let ecLevel = decoderRXingResult.getECLevel(); + if !ecLevel.is_empty() { + result.putMetadata(RXingResultMetadataType::ERROR_CORRECTION_LEVEL, RXingResultMetadataValue::ErrorCorrectionLevel(ecLevel.to_string())); + } + result.putMetadata(RXingResultMetadataType::SYMBOLOGY_IDENTIFIER, RXingResultMetadataValue::SymbologyIdentifier(format!("]d{}" , decoderRXingResult.getSymbologyModifier()))); + + Ok(result) + } + + fn reset(&mut self) { + // do nothing + } +} + + + + + impl DataMatrixReader { + + /** + * 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 extractPureBits(&self, image:&BitMatrix) -> Result { + + let Some(leftTopBlack) = image.getTopLeftOnBit() else { + return Err(Exceptions::NotFoundException("".to_owned())) + }; + let Some(rightBottomBlack) = image.getBottomRightOnBit()else { + return Err(Exceptions::NotFoundException("".to_owned())) + }; + + let moduleSize = Self::moduleSize(&leftTopBlack, image)?; + + let mut top = leftTopBlack[1]; + let bottom = rightBottomBlack[1]; + let mut left = leftTopBlack[0]; + let right = rightBottomBlack[0]; + + let matrixWidth = (right - left + 1) / moduleSize; + let matrixHeight = (bottom - top + 1) / moduleSize; + if matrixWidth <= 0 || matrixHeight <= 0 { + return Err(Exceptions::NotFoundException("".to_owned())) + // throw NotFoundException.getNotFoundInstance(); + } + + // 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 = moduleSize / 2; + top += nudge; + left += nudge; + + // Now just read off the bits + let mut bits = BitMatrix::new(matrixWidth, matrixHeight)?; + for y in 0..matrixHeight { + // for (int y = 0; y < matrixHeight; y++) { + let iOffset = top + y * moduleSize; + for x in 0..matrixWidth { + // for (int x = 0; x < matrixWidth; x++) { + if image.get(left + x * moduleSize, iOffset) { + bits.set(x, y); + } + } + } + Ok( bits) + } + + fn moduleSize( leftTopBlack:&[u32], image:&BitMatrix) -> Result { + let width = image.getWidth(); + let mut x = leftTopBlack[0]; + let y = leftTopBlack[1]; + while x < width && image.get(x, y) { + x+=1; + } + if x == width { + return Err(Exceptions::NotFoundException("".to_owned())) + } + + let moduleSize = x - leftTopBlack[0]; + if moduleSize == 0 { + return Err(Exceptions::NotFoundException("".to_owned())) + } + + Ok(moduleSize) + } + +} diff --git a/src/datamatrix/DataMatrixWriter.java b/src/datamatrix/data_matrix_writer.rs similarity index 100% rename from src/datamatrix/DataMatrixWriter.java rename to src/datamatrix/data_matrix_writer.rs diff --git a/src/datamatrix/DataMatrixWriterTestCase.java b/src/datamatrix/data_matrix_writer_test_case.rs similarity index 100% rename from src/datamatrix/DataMatrixWriterTestCase.java rename to src/datamatrix/data_matrix_writer_test_case.rs diff --git a/src/datamatrix/mod.rs b/src/datamatrix/mod.rs index 5413428..61fff3b 100644 --- a/src/datamatrix/mod.rs +++ b/src/datamatrix/mod.rs @@ -1,3 +1,6 @@ pub mod decoder; pub mod detector; pub mod encoder; + +mod data_matrix_reader; +pub use data_matrix_reader::*; \ No newline at end of file