com.google.zxing.datamatrix.decoder.Decoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Core barcode encoding/decoding library
/*
* 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.decoder;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult;
import com.google.zxing.common.reedsolomon.GenericGF;
import com.google.zxing.common.reedsolomon.ReedSolomonDecoder;
import com.google.zxing.common.reedsolomon.ReedSolomonException;
/**
* The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting
* the Data Matrix Code from an image.
*
* @author [email protected] (Brian Brown)
*/
public final class Decoder {
private final ReedSolomonDecoder rsDecoder;
public Decoder() {
rsDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256);
}
/**
* Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans.
* "true" is taken to mean a black module.
*
* @param image booleans representing white/black Data Matrix Code modules
* @return text and bytes encoded within the Data Matrix Code
* @throws FormatException if the Data Matrix Code cannot be decoded
* @throws ChecksumException if error correction fails
*/
public DecoderResult decode(boolean[][] image) throws FormatException, ChecksumException {
return decode(BitMatrix.parse(image));
}
/**
* Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken
* to mean a black module.
*
* @param bits booleans representing white/black Data Matrix Code modules
* @return text and bytes encoded within the Data Matrix Code
* @throws FormatException if the Data Matrix Code cannot be decoded
* @throws ChecksumException if error correction fails
*/
public DecoderResult decode(BitMatrix bits) throws FormatException, ChecksumException {
// Construct a parser and read version, error-correction level
BitMatrixParser parser = new BitMatrixParser(bits);
Version version = parser.getVersion();
// Read codewords
byte[] codewords = parser.readCodewords();
// Separate into data blocks
DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, version);
// Count total number of data bytes
int totalBytes = 0;
for (DataBlock db : dataBlocks) {
totalBytes += db.getNumDataCodewords();
}
byte[] resultBytes = new byte[totalBytes];
int errorsCorrected = 0;
int dataBlocksCount = dataBlocks.length;
// Error-correct and copy data blocks together into a stream of bytes
for (int j = 0; j < dataBlocksCount; j++) {
DataBlock dataBlock = dataBlocks[j];
byte[] codewordBytes = dataBlock.getCodewords();
int numDataCodewords = dataBlock.getNumDataCodewords();
errorsCorrected += correctErrors(codewordBytes, numDataCodewords);
for (int i = 0; i < numDataCodewords; i++) {
// De-interlace data blocks.
resultBytes[i * dataBlocksCount + j] = codewordBytes[i];
}
}
// Decode the contents of that stream of bytes
DecoderResult result = DecodedBitStreamParser.decode(resultBytes);
result.setErrorsCorrected(errorsCorrected);
return result;
}
/**
* Given data and error-correction codewords received, possibly corrupted by errors, attempts to
* correct the errors in-place using Reed-Solomon error correction.
*
* @param codewordBytes data and error correction codewords
* @param numDataCodewords number of codewords that are data bytes
* @return the number of errors corrected
* @throws ChecksumException if error correction fails
*/
private int correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
int numCodewords = codewordBytes.length;
// First read into an array of ints
int[] codewordsInts = new int[numCodewords];
for (int i = 0; i < numCodewords; i++) {
codewordsInts[i] = codewordBytes[i] & 0xFF;
}
int errorsCorrected = 0;
try {
errorsCorrected = rsDecoder.decodeWithECCount(codewordsInts, codewordBytes.length - numDataCodewords);
} catch (ReedSolomonException ignored) {
throw ChecksumException.getChecksumInstance();
}
// Copy back into array of bytes -- only need to worry about the bytes that were data
// We don't care about errors in the error-correction codewords
for (int i = 0; i < numDataCodewords; i++) {
codewordBytes[i] = (byte) codewordsInts[i];
}
return errorsCorrected;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy