All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.zxing.pdf417.decoder.Decoder Maven / Gradle / Ivy

There is a newer version: 3.5.3
Show newest version
/*
 * Copyright 2009 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.decoder;

import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult;

/**
 * 

The main class which implements PDF417 Code decoding -- as * opposed to locating and extracting the PDF417 Code from an image.

* * @author SITA Lab ([email protected]) */ public final class Decoder { private static final int MAX_ERRORS = 3; private static final int MAX_EC_CODEWORDS = 512; //private final ReedSolomonDecoder rsDecoder; public Decoder() { // TODO MGMG //rsDecoder = new ReedSolomonDecoder(); } /** *

Convenience method that can decode a PDF417 Code represented as a 2D array of booleans. * "true" is taken to mean a black module.

* * @param image booleans representing white/black PDF417 modules * @return text and bytes encoded within the PDF417 Code * @throws NotFoundException if the PDF417 Code cannot be decoded */ public DecoderResult decode(boolean[][] image) throws FormatException { int dimension = image.length; BitMatrix bits = new BitMatrix(dimension); for (int i = 0; i < dimension; i++) { for (int j = 0; j < dimension; j++) { if (image[j][i]) { bits.set(j, i); } } } return decode(bits); } /** *

Decodes a PDF417 Code represented as a {@link BitMatrix}. * A 1 or "true" is taken to mean a black module.

* * @param bits booleans representing white/black PDF417 Code modules * @return text and bytes encoded within the PDF417 Code * @throws FormatException if the PDF417 Code cannot be decoded */ public DecoderResult decode(BitMatrix bits) throws FormatException { // Construct a parser to read the data codewords and error-correction level BitMatrixParser parser = new BitMatrixParser(bits); int[] codewords = parser.readCodewords(); if (codewords.length == 0) { throw FormatException.getFormatInstance(); } int ecLevel = parser.getECLevel(); int numECCodewords = 1 << (ecLevel + 1); int[] erasures = parser.getErasures(); correctErrors(codewords, erasures, numECCodewords); verifyCodewordCount(codewords, numECCodewords); // Decode the codewords return DecodedBitStreamParser.decode(codewords); } /** * Verify that all is OK with the codeword array. * * @param codewords * @return an index to the first data codeword. * @throws FormatException */ private static void verifyCodewordCount(int[] codewords, int numECCodewords) throws FormatException { if (codewords.length < 4) { // Codeword array size should be at least 4 allowing for // Count CW, At least one Data CW, Error Correction CW, Error Correction CW throw FormatException.getFormatInstance(); } // The first codeword, the Symbol Length Descriptor, shall always encode the total number of data // codewords in the symbol, including the Symbol Length Descriptor itself, data codewords and pad // codewords, but excluding the number of error correction codewords. int numberOfCodewords = codewords[0]; if (numberOfCodewords > codewords.length) { throw FormatException.getFormatInstance(); } if (numberOfCodewords == 0) { // Reset to the length of the array - 8 (Allow for at least level 3 Error Correction (8 Error Codewords) if (numECCodewords < codewords.length) { codewords[0] = codewords.length - numECCodewords; } else { throw FormatException.getFormatInstance(); } } } /** *

Given data and error-correction codewords received, possibly corrupted by errors, attempts to * correct the errors in-place using Reed-Solomon error correction.

* * @param codewords data and error correction codewords * @throws ChecksumException if error correction fails */ private static int correctErrors(int[] codewords, int[] erasures, int numECCodewords) throws FormatException { if (erasures.length > numECCodewords / 2 + MAX_ERRORS || numECCodewords < 0 || numECCodewords > MAX_EC_CODEWORDS) { // Too many errors or EC Codewords is corrupted throw FormatException.getFormatInstance(); } // Try to correct the errors // TODO enable error correction int result = 0; // rsDecoder.correctErrors(codewords, numECCodewords); int numErasures = erasures.length; if (result > 0) { numErasures -= result; } if (numErasures > MAX_ERRORS) { // Still too many errors throw FormatException.getFormatInstance(); } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy