private static Result[] decode(BinaryBitmap image, Map<DecodeHintType, ?> hints, boolean multiple) throws NotFoundException, FormatException, ChecksumException { List<Result> results = new ArrayList<>(); PDF417DetectorResult detectorResult = Detector.detect(image, hints, multiple); for (ResultPoint[] points : detectorResult.getPoints()) { DecoderResult decoderResult = PDF417ScanningDecoder.decode(detectorResult.getBits(), points[4], points[5], points[6], points[7], getMinCodewordWidth(points), getMaxCodewordWidth(points)); Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.PDF_417); result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel()); PDF417ResultMetadata pdf417ResultMetadata = (PDF417ResultMetadata) decoderResult.getOther(); if (pdf417ResultMetadata != null) { result.putMetadata(ResultMetadataType.PDF417_EXTRA_METADATA, pdf417ResultMetadata); } results.add(result); } return results.toArray(new Result[results.size()]); }
private static DecoderResult decodeCodewords(int[] codewords, int ecLevel, int[] erasures) throws FormatException, ChecksumException { if (codewords.length == 0) { throw FormatException.getFormatInstance(); } int numECCodewords = 1 << (ecLevel + 1); int correctedErrorsCount = correctErrors(codewords, erasures, numECCodewords); verifyCodewordCount(codewords, numECCodewords); // Decode the codewords DecoderResult decoderResult = DecodedBitStreamParser.decode(codewords, String.valueOf(ecLevel)); decoderResult.setErrorsCorrected(correctedErrorsCount); decoderResult.setErasures(erasures.length); return decoderResult; }
@Override public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, ChecksumException, FormatException { DecoderResult decoderResult; ResultPoint[] points; if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) { BitMatrix bits = extractPureBits(image.getBlackMatrix()); decoderResult = decoder.decode(bits); points = NO_POINTS; } else { DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(); decoderResult = decoder.decode(detectorResult.getBits()); points = detectorResult.getPoints(); } Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.DATA_MATRIX); List<byte[]> byteSegments = decoderResult.getByteSegments(); if (byteSegments != null) { result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments); } String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } return result; }
@Override public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, ChecksumException, FormatException { DecoderResult decoderResult; if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) { BitMatrix bits = extractPureBits(image.getBlackMatrix()); decoderResult = decoder.decode(bits, hints); } else { throw NotFoundException.getNotFoundInstance(); } ResultPoint[] points = NO_POINTS; Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.MAXICODE); String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } return result; }
private static Result[] decode(BinaryBitmap image, Map<DecodeHintType, ?> hints, boolean multiple) throws NotFoundException, FormatException, ChecksumException { List<Result> results = new ArrayList(); PDF417DetectorResult detectorResult = Detector.detect(image, hints, multiple); for (ResultPoint[] points : detectorResult.getPoints()) { DecoderResult decoderResult = PDF417ScanningDecoder.decode(detectorResult.getBits(), points[4], points[5], points[6], points[7], getMinCodewordWidth(points), getMaxCodewordWidth(points)); Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.PDF_417); result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult .getECLevel()); PDF417ResultMetadata pdf417ResultMetadata = (PDF417ResultMetadata) decoderResult .getOther(); if (pdf417ResultMetadata != null) { result.putMetadata(ResultMetadataType.PDF417_EXTRA_METADATA, pdf417ResultMetadata); } results.add(result); } return (Result[]) results.toArray(new Result[results.size()]); }
public Result decode(BinaryBitmap image, Map<DecodeHintType, ?> hints) throws NotFoundException, ChecksumException, FormatException { DecoderResult decoderResult; ResultPoint[] points; if (hints == null || !hints.containsKey(DecodeHintType.PURE_BARCODE)) { DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(); decoderResult = this.decoder.decode(detectorResult.getBits()); points = detectorResult.getPoints(); } else { decoderResult = this.decoder.decode(extractPureBits(image.getBlackMatrix())); points = NO_POINTS; } Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.DATA_MATRIX); List<byte[]> byteSegments = decoderResult.getByteSegments(); if (byteSegments != null) { result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments); } String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } return result; }
public DecoderResult decode(BitMatrix bits) throws FormatException, ChecksumException { BitMatrixParser parser = new BitMatrixParser(bits); DataBlock[] dataBlocks = DataBlock.getDataBlocks(parser.readCodewords(), parser .getVersion()); int dataBlocksCount = dataBlocks.length; int totalBytes = 0; for (DataBlock db : dataBlocks) { totalBytes += db.getNumDataCodewords(); } byte[] resultBytes = new byte[totalBytes]; for (int j = 0; j < dataBlocksCount; j++) { DataBlock dataBlock = dataBlocks[j]; byte[] codewordBytes = dataBlock.getCodewords(); int numDataCodewords = dataBlock.getNumDataCodewords(); correctErrors(codewordBytes, numDataCodewords); for (int i = 0; i < numDataCodewords; i++) { resultBytes[(i * dataBlocksCount) + j] = codewordBytes[i]; } } return DecodedBitStreamParser.decode(resultBytes); }
public DecoderResult decode(BitMatrix bits, Map<DecodeHintType, ?> map) throws FormatException, ChecksumException { byte[] datawords; byte[] codewords = new BitMatrixParser(bits).readCodewords(); correctErrors(codewords, 0, 10, 10, 0); int mode = codewords[0] & 15; switch (mode) { case 2: case 3: case 4: correctErrors(codewords, 20, 84, 40, 1); correctErrors(codewords, 20, 84, 40, 2); datawords = new byte[94]; break; case 5: correctErrors(codewords, 20, 68, 56, 1); correctErrors(codewords, 20, 68, 56, 2); datawords = new byte[78]; break; default: throw FormatException.getFormatInstance(); } System.arraycopy(codewords, 0, datawords, 0, 10); System.arraycopy(codewords, 20, datawords, 10, datawords.length - 10); return DecodedBitStreamParser.decode(datawords, mode); }
@Override public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, FormatException, ChecksumException { DecoderResult decoderResult; ResultPoint[] points; if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) { BitMatrix bits = extractPureBits(image.getBlackMatrix()); decoderResult = decoder.decode(bits); points = NO_POINTS; } else { DetectorResult detectorResult = new Detector(image).detect(); decoderResult = decoder.decode(detectorResult.getBits()); points = detectorResult.getPoints(); } return new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.PDF_417); }
/** * <p>Decodes a PDF417 Code represented as a {@link BitMatrix}. * A 1 or "true" is taken to mean a black module.</p> * * @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, ChecksumException { // 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); }
private static DecoderResult createDecoderResult(DetectionResult detectionResult) throws FormatException, ChecksumException, NotFoundException { BarcodeValue[][] barcodeMatrix = createBarcodeMatrix(detectionResult); adjustCodewordCount(detectionResult, barcodeMatrix); Collection<Integer> erasures = new ArrayList<>(); int[] codewords = new int[detectionResult.getBarcodeRowCount() * detectionResult.getBarcodeColumnCount()]; List<int[]> ambiguousIndexValuesList = new ArrayList<>(); List<Integer> ambiguousIndexesList = new ArrayList<>(); for (int row = 0; row < detectionResult.getBarcodeRowCount(); row++) { for (int column = 0; column < detectionResult.getBarcodeColumnCount(); column++) { int[] values = barcodeMatrix[row][column + 1].getValue(); int codewordIndex = row * detectionResult.getBarcodeColumnCount() + column; if (values.length == 0) { erasures.add(codewordIndex); } else if (values.length == 1) { codewords[codewordIndex] = values[0]; } else { ambiguousIndexesList.add(codewordIndex); ambiguousIndexValuesList.add(values); } } } int[][] ambiguousIndexValues = new int[ambiguousIndexValuesList.size()][]; for (int i = 0; i < ambiguousIndexValues.length; i++) { ambiguousIndexValues[i] = ambiguousIndexValuesList.get(i); } return createDecoderResultFromAmbiguousValues(detectionResult.getBarcodeECLevel(), codewords, PDF417Common.toIntArray(erasures), PDF417Common.toIntArray(ambiguousIndexesList), ambiguousIndexValues); }
/** * This method deals with the fact, that the decoding process doesn't always yield a single most likely value. The * current error correction implementation doesn't deal with erasures very well, so it's better to provide a value * for these ambiguous codewords instead of treating it as an erasure. The problem is that we don't know which of * the ambiguous values to choose. We try decode using the first value, and if that fails, we use another of the * ambiguous values and try to decode again. This usually only happens on very hard to read and decode barcodes, * so decoding the normal barcodes is not affected by this. * * @param erasureArray contains the indexes of erasures * @param ambiguousIndexes array with the indexes that have more than one most likely value * @param ambiguousIndexValues two dimensional array that contains the ambiguous values. The first dimension must * be the same length as the ambiguousIndexes array */ private static DecoderResult createDecoderResultFromAmbiguousValues(int ecLevel, int[] codewords, int[] erasureArray, int[] ambiguousIndexes, int[][] ambiguousIndexValues) throws FormatException, ChecksumException { int[] ambiguousIndexCount = new int[ambiguousIndexes.length]; int tries = 100; while (tries-- > 0) { for (int i = 0; i < ambiguousIndexCount.length; i++) { codewords[ambiguousIndexes[i]] = ambiguousIndexValues[i][ambiguousIndexCount[i]]; } try { return decodeCodewords(codewords, ecLevel, erasureArray); } catch (ChecksumException ignored) { // } if (ambiguousIndexCount.length == 0) { throw ChecksumException.getChecksumInstance(); } for (int i = 0; i < ambiguousIndexCount.length; i++) { if (ambiguousIndexCount[i] < ambiguousIndexValues[i].length - 1) { ambiguousIndexCount[i]++; break; } else { ambiguousIndexCount[i] = 0; if (i == ambiguousIndexCount.length - 1) { throw ChecksumException.getChecksumInstance(); } } } } throw ChecksumException.getChecksumInstance(); }
@Override public final Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException, ChecksumException, FormatException { DecoderResult decoderResult; ResultPoint[] points; if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) { BitMatrix bits = extractPureBits(image.getBlackMatrix()); decoderResult = decoder.decode(bits, hints); points = NO_POINTS; } else { DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(hints); decoderResult = decoder.decode(detectorResult.getBits(), hints); points = detectorResult.getPoints(); } // If the code was mirrored: swap the bottom-left and the top-right points. if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) { ((QRCodeDecoderMetaData) decoderResult.getOther()).applyMirroredCorrection(points); } Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE); List<byte[]> byteSegments = decoderResult.getByteSegments(); if (byteSegments != null) { result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments); } String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } if (decoderResult.hasStructuredAppend()) { result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.getStructuredAppendSequenceNumber()); result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.getStructuredAppendParity()); } return result; }
/** * <p>Convenience method that can decode a QR Code represented as a 2D array of booleans. * "true" is taken to mean a black module.</p> * * @param image booleans representing white/black QR Code modules * @param hints decoding hints that should be used to influence decoding * @return text and bytes encoded within the QR Code * @throws FormatException if the QR Code cannot be decoded * @throws ChecksumException if error correction fails */ public DecoderResult decode(boolean[][] image, Map<DecodeHintType,?> hints) throws ChecksumException, 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[i][j]) { bits.set(j, i); } } } return decode(bits, hints); }
public DecoderResult decode(AztecDetectorResult detectorResult) throws FormatException { ddata = detectorResult; BitMatrix matrix = detectorResult.getBits(); boolean[] rawbits = extractBits(matrix); boolean[] correctedBits = correctBits(rawbits); String result = getEncodedData(correctedBits); return new DecoderResult(null, result, null, null); }
static DecoderResult decode(byte[] bytes) throws FormatException { BitSource bits = new BitSource(bytes); StringBuilder result = new StringBuilder(100); StringBuilder resultTrailer = new StringBuilder(0); List<byte[]> byteSegments = new ArrayList<>(1); Mode mode = Mode.ASCII_ENCODE; do { if (mode == Mode.ASCII_ENCODE) { mode = decodeAsciiSegment(bits, result, resultTrailer); } else { switch (mode) { case C40_ENCODE: decodeC40Segment(bits, result); break; case TEXT_ENCODE: decodeTextSegment(bits, result); break; case ANSIX12_ENCODE: decodeAnsiX12Segment(bits, result); break; case EDIFACT_ENCODE: decodeEdifactSegment(bits, result); break; case BASE256_ENCODE: decodeBase256Segment(bits, result, byteSegments); break; default: throw FormatException.getFormatInstance(); } mode = Mode.ASCII_ENCODE; } } while (mode != Mode.PAD_ENCODE && bits.available() > 0); if (resultTrailer.length() > 0) { result.append(resultTrailer); } return new DecoderResult(bytes, result.toString(), byteSegments.isEmpty() ? null : byteSegments, null); }
/** * <p>Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans. * "true" is taken to mean a black module.</p> * * @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 { 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[i][j]) { bits.set(j, i); } } } return decode(bits); }
/** * <p>Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken * to mean a black module.</p> * * @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); int dataBlocksCount = dataBlocks.length; // Count total number of data bytes int totalBytes = 0; for (DataBlock db : dataBlocks) { totalBytes += db.getNumDataCodewords(); } byte[] resultBytes = new byte[totalBytes]; // 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(); 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 return DecodedBitStreamParser.decode(resultBytes); }
static DecoderResult decode(byte[] bytes, int mode) { StringBuilder result = new StringBuilder(144); switch (mode) { case 2: case 3: String postcode; if (mode == 2) { int pc = getPostCode2(bytes); NumberFormat df = new DecimalFormat("0000000000".substring(0, getPostCode2Length(bytes))); postcode = df.format(pc); } else { postcode = getPostCode3(bytes); } String country = THREE_DIGITS.format(getCountry(bytes)); String service = THREE_DIGITS.format(getServiceClass(bytes)); result.append(getMessage(bytes, 10, 84)); if (result.toString().startsWith("[)>"+RS+"01"+GS)) { result.insert(9, postcode + GS + country + GS + service + GS); } else { result.insert(0, postcode + GS + country + GS + service + GS); } break; case 4: result.append(getMessage(bytes, 1, 93)); break; case 5: result.append(getMessage(bytes, 1, 77)); break; } return new DecoderResult(bytes, result.toString(), null, String.valueOf(mode)); }
public DecoderResult decode(BitMatrix bits, Map<DecodeHintType,?> hints) throws FormatException, ChecksumException { BitMatrixParser parser = new BitMatrixParser(bits); byte[] codewords = parser.readCodewords(); correctErrors(codewords, 0, 10, 10, ALL); int mode = codewords[0] & 0x0F; byte[] datawords; switch (mode) { case 2: case 3: case 4: correctErrors(codewords, 20, 84, 40, EVEN); correctErrors(codewords, 20, 84, 40, ODD); datawords = new byte[94]; break; case 5: correctErrors(codewords, 20, 68, 56, EVEN); correctErrors(codewords, 20, 68, 56, ODD); datawords = new byte[78]; break; default: throw FormatException.getFormatInstance(); } System.arraycopy(codewords, 0, datawords, 0, 10); System.arraycopy(codewords, 20, datawords, 10, datawords.length - 10); return DecodedBitStreamParser.decode(datawords, mode); }
@Override public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException { List<Result> results = new ArrayList<>(); DetectorResult[] detectorResults = new MultiDetector(image.getBlackMatrix()).detectMulti(hints); for (DetectorResult detectorResult : detectorResults) { try { DecoderResult decoderResult = getDecoder().decode(detectorResult.getBits(), hints); ResultPoint[] points = detectorResult.getPoints(); // If the code was mirrored: swap the bottom-left and the top-right points. if (decoderResult.getOther() instanceof QRCodeDecoderMetaData) { ((QRCodeDecoderMetaData) decoderResult.getOther()).applyMirroredCorrection(points); } Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE); List<byte[]> byteSegments = decoderResult.getByteSegments(); if (byteSegments != null) { result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments); } String ecLevel = decoderResult.getECLevel(); if (ecLevel != null) { result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel); } if (decoderResult.hasStructuredAppend()) { result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE, decoderResult.getStructuredAppendSequenceNumber()); result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY, decoderResult.getStructuredAppendParity()); } results.add(result); } catch (ReaderException re) { // ignore and continue } } if (results.isEmpty()) { return EMPTY_RESULT_ARRAY; } else { results = processStructuredAppend(results); return results.toArray(new Result[results.size()]); } }