Add ResultMetadataType.ERRORS_CORRECTED and ERASURES_CORRECTED (#1657)

* Add ResultMetadataType.ERRORS_CORRECTED and ERASURES_CORRECTED (2D barcodes)

* Maintain existing constructor on AztecDetectorResult

* Maintain existing ReedSolomonDecoder.decode method
This commit is contained in:
Daniel Gredler 2023-06-25 18:30:21 -04:00 committed by GitHub
parent 57ed027468
commit 282f5ba726
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 179 additions and 53 deletions

View file

@ -55,6 +55,18 @@ public enum ResultMetadataType {
*/
ERROR_CORRECTION_LEVEL,
/**
* The number of errors corrected. If applicable, maps to an {@link Integer} of value
* greater than or equal to zero.
*/
ERRORS_CORRECTED,
/**
* The number of erasures corrected. If applicable, maps to an {@link Integer} of value
* greater than or equal to zero.
*/
ERASURES_CORRECTED,
/**
* For some periodicals, indicates the issue number as an {@link Integer}.
*/
@ -73,12 +85,12 @@ public enum ResultMetadataType {
POSSIBLE_COUNTRY,
/**
* For some products, the extension text
* For some products, the extension text.
*/
UPC_EAN_EXTENSION,
/**
* PDF417-specific metadata
* PDF417-specific metadata.
*/
PDF417_EXTRA_METADATA,

View file

@ -31,16 +31,27 @@ public final class AztecDetectorResult extends DetectorResult {
private final boolean compact;
private final int nbDatablocks;
private final int nbLayers;
private final int errorsCorrected;
public AztecDetectorResult(BitMatrix bits,
ResultPoint[] points,
boolean compact,
int nbDatablocks,
int nbLayers) {
this(bits, points, compact, nbDatablocks, nbLayers, 0);
}
public AztecDetectorResult(BitMatrix bits,
ResultPoint[] points,
boolean compact,
int nbDatablocks,
int nbLayers,
int errorsCorrected) {
super(bits, points);
this.compact = compact;
this.nbDatablocks = nbDatablocks;
this.nbLayers = nbLayers;
this.errorsCorrected = errorsCorrected;
}
public int getNbLayers() {
@ -55,4 +66,7 @@ public final class AztecDetectorResult extends DetectorResult {
return compact;
}
public int getErrorsCorrected() {
return errorsCorrected;
}
}

View file

@ -61,9 +61,11 @@ public final class AztecReader implements Reader {
Detector detector = new Detector(image.getBlackMatrix());
ResultPoint[] points = null;
DecoderResult decoderResult = null;
int errorsCorrected = 0;
try {
AztecDetectorResult detectorResult = detector.detect(false);
points = detectorResult.getPoints();
errorsCorrected = detectorResult.getErrorsCorrected();
decoderResult = new Decoder().decode(detectorResult);
} catch (NotFoundException e) {
notFoundException = e;
@ -74,6 +76,7 @@ public final class AztecReader implements Reader {
try {
AztecDetectorResult detectorResult = detector.detect(true);
points = detectorResult.getPoints();
errorsCorrected = detectorResult.getErrorsCorrected();
decoderResult = new Decoder().decode(detectorResult);
} catch (NotFoundException | FormatException e) {
if (notFoundException != null) {
@ -110,6 +113,8 @@ public final class AztecReader implements Reader {
if (ecLevel != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
}
errorsCorrected += decoderResult.getErrorsCorrected();
result.putMetadata(ResultMetadataType.ERRORS_CORRECTED, errorsCorrected);
result.putMetadata(ResultMetadataType.SYMBOLOGY_IDENTIFIER, "]z" + decoderResult.getSymbologyModifier());
return result;

View file

@ -87,6 +87,7 @@ public final class Decoder {
DecoderResult decoderResult =
new DecoderResult(rawBytes, result, null, String.format("%d%%", correctedBits.ecLevel));
decoderResult.setNumBits(correctedBits.correctBits.length);
decoderResult.setErrorsCorrected(correctedBits.errorsCorrected);
return decoderResult;
}
@ -264,10 +265,12 @@ public final class Decoder {
static final class CorrectedBitsResult {
private final boolean[] correctBits;
private final int errorsCorrected;
private final int ecLevel;
CorrectedBitsResult(boolean[] correctBits, int ecLevel) {
CorrectedBitsResult(boolean[] correctBits, int errorsCorrected, int ecLevel) {
this.correctBits = correctBits;
this.errorsCorrected = errorsCorrected;
this.ecLevel = ecLevel;
}
}
@ -308,9 +311,10 @@ public final class Decoder {
dataWords[i] = readCode(rawbits, offset, codewordSize);
}
int errorsCorrected = 0;
try {
ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(gf);
rsDecoder.decode(dataWords, numCodewords - numDataCodewords);
errorsCorrected = rsDecoder.decodeWithECCount(dataWords, numCodewords - numDataCodewords);
} catch (ReedSolomonException ex) {
throw FormatException.getFormatInstance(ex);
}
@ -343,7 +347,8 @@ public final class Decoder {
}
}
return new CorrectedBitsResult(correctedBits, 100 * (numCodewords - numDataCodewords) / numCodewords);
int ecLevel = 100 * (numCodewords - numDataCodewords) / numCodewords;
return new CorrectedBitsResult(correctedBits, errorsCorrected, ecLevel);
}
/**

View file

@ -82,7 +82,7 @@ public final class Detector {
}
// 3. Get the size of the matrix and other parameters from the bull's eye
extractParameters(bullsEyeCorners);
int errorsCorrected = extractParameters(bullsEyeCorners);
// 4. Sample the grid
BitMatrix bits = sampleGrid(image,
@ -94,16 +94,17 @@ public final class Detector {
// 5. Get the corners of the matrix.
ResultPoint[] corners = getMatrixCornerPoints(bullsEyeCorners);
return new AztecDetectorResult(bits, corners, compact, nbDataBlocks, nbLayers);
return new AztecDetectorResult(bits, corners, compact, nbDataBlocks, nbLayers, errorsCorrected);
}
/**
* Extracts the number of data layers and data blocks from the layer around the bull's eye.
*
* @param bullsEyeCorners the array of bull's eye corners
* @return the number of errors corrected during parameter extraction
* @throws NotFoundException in case of too many errors or invalid parameters
*/
private void extractParameters(ResultPoint[] bullsEyeCorners) throws NotFoundException {
private int extractParameters(ResultPoint[] bullsEyeCorners) throws NotFoundException {
if (!isValid(bullsEyeCorners[0]) || !isValid(bullsEyeCorners[1]) ||
!isValid(bullsEyeCorners[2]) || !isValid(bullsEyeCorners[3])) {
throw NotFoundException.getNotFoundInstance();
@ -140,7 +141,8 @@ public final class Detector {
// Corrects parameter data using RS. Returns just the data portion
// without the error correction.
int correctedData = getCorrectedParameterData(parameterData, compact);
CorrectedParameter correctedParam = getCorrectedParameterData(parameterData, compact);
int correctedData = correctedParam.getData();
if (compact) {
// 8 bits: 2 bits layers and 6 bits data blocks
@ -151,6 +153,8 @@ public final class Detector {
nbLayers = (correctedData >> 11) + 1;
nbDataBlocks = (correctedData & 0x7FF) + 1;
}
return correctedParam.getErrorsCorrected();
}
private static int getRotation(int[] sides, int length) throws NotFoundException {
@ -189,9 +193,11 @@ public final class Detector {
*
* @param parameterData parameter bits
* @param compact true if this is a compact Aztec code
* @return the corrected parameter
* @throws NotFoundException if the array contains too many errors
*/
private static int getCorrectedParameterData(long parameterData, boolean compact) throws NotFoundException {
private static CorrectedParameter getCorrectedParameterData(long parameterData,
boolean compact) throws NotFoundException {
int numCodewords;
int numDataCodewords;
@ -209,18 +215,21 @@ public final class Detector {
parameterWords[i] = (int) parameterData & 0xF;
parameterData >>= 4;
}
int errorsCorrected = 0;
try {
ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM);
rsDecoder.decode(parameterWords, numECCodewords);
errorsCorrected = rsDecoder.decodeWithECCount(parameterWords, numECCodewords);
} catch (ReedSolomonException ignored) {
throw NotFoundException.getNotFoundInstance();
}
// Toss the error correction. Just return the data as an integer
int result = 0;
for (int i = 0; i < numDataCodewords; i++) {
result = (result << 4) + parameterWords[i];
}
return result;
return new CorrectedParameter(result, errorsCorrected);
}
/**
@ -600,4 +609,22 @@ public final class Detector {
return "<" + x + ' ' + y + '>';
}
}
static final class CorrectedParameter {
private final int data;
private final int errorsCorrected;
CorrectedParameter(int data, int errorsCorrected) {
this.data = data;
this.errorsCorrected = errorsCorrected;
}
int getData() {
return data;
}
int getErrorsCorrected() {
return errorsCorrected;
}
}
}

View file

@ -56,6 +56,20 @@ public final class ReedSolomonDecoder {
* @throws ReedSolomonException if decoding fails for any reason
*/
public void decode(int[] received, int twoS) throws ReedSolomonException {
decodeWithECCount(received, twoS);
}
/**
* <p>Decodes given set of received codewords, which include both data and error-correction
* codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
* in the input.</p>
*
* @param received data and error-correction codewords
* @param twoS number of error-correction codewords available
* @return the number of errors corrected
* @throws ReedSolomonException if decoding fails for any reason
*/
public int decodeWithECCount(int[] received, int twoS) throws ReedSolomonException {
GenericGFPoly poly = new GenericGFPoly(field, received);
int[] syndromeCoefficients = new int[twoS];
boolean noError = true;
@ -67,7 +81,7 @@ public final class ReedSolomonDecoder {
}
}
if (noError) {
return;
return 0;
}
GenericGFPoly syndrome = new GenericGFPoly(field, syndromeCoefficients);
GenericGFPoly[] sigmaOmega =
@ -83,6 +97,7 @@ public final class ReedSolomonDecoder {
}
received[position] = GenericGF.addOrSubtract(received[position], errorMagnitudes[i]);
}
return errorLocations.length;
}
private GenericGFPoly[] runEuclideanAlgorithm(GenericGFPoly a, GenericGFPoly b, int R)

View file

@ -83,6 +83,7 @@ public final class DataMatrixReader implements Reader {
if (ecLevel != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
}
result.putMetadata(ResultMetadataType.ERRORS_CORRECTED, decoderResult.getErrorsCorrected());
result.putMetadata(ResultMetadataType.SYMBOLOGY_IDENTIFIER, "]d" + decoderResult.getSymbologyModifier());
return result;
}

View file

@ -78,13 +78,14 @@ public final class Decoder {
}
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();
correctErrors(codewordBytes, numDataCodewords);
errorsCorrected += correctErrors(codewordBytes, numDataCodewords);
for (int i = 0; i < numDataCodewords; i++) {
// De-interlace data blocks.
resultBytes[i * dataBlocksCount + j] = codewordBytes[i];
@ -92,7 +93,9 @@ public final class Decoder {
}
// Decode the contents of that stream of bytes
return DecodedBitStreamParser.decode(resultBytes);
DecoderResult result = DecodedBitStreamParser.decode(resultBytes);
result.setErrorsCorrected(errorsCorrected);
return result;
}
/**
@ -101,17 +104,19 @@ public final class Decoder {
*
* @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 void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
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 {
rsDecoder.decode(codewordsInts, codewordBytes.length - numDataCodewords);
errorsCorrected = rsDecoder.decodeWithECCount(codewordsInts, codewordBytes.length - numDataCodewords);
} catch (ReedSolomonException ignored) {
throw ChecksumException.getChecksumInstance();
}
@ -120,6 +125,7 @@ public final class Decoder {
for (int i = 0; i < numDataCodewords; i++) {
codewordBytes[i] = (byte) codewordsInts[i];
}
return errorsCorrected;
}
}

View file

@ -64,7 +64,7 @@ public final class MaxiCodeReader implements Reader {
BitMatrix bits = extractPureBits(image.getBlackMatrix());
DecoderResult decoderResult = decoder.decode(bits, hints);
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), NO_POINTS, BarcodeFormat.MAXICODE);
result.putMetadata(ResultMetadataType.ERRORS_CORRECTED, decoderResult.getErrorsCorrected());
String ecLevel = decoderResult.getECLevel();
if (ecLevel != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);

View file

@ -54,20 +54,20 @@ public final class Decoder {
BitMatrixParser parser = new BitMatrixParser(bits);
byte[] codewords = parser.readCodewords();
correctErrors(codewords, 0, 10, 10, ALL);
int errorsCorrected = 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);
errorsCorrected += correctErrors(codewords, 20, 84, 40, EVEN);
errorsCorrected += 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);
errorsCorrected += correctErrors(codewords, 20, 68, 56, EVEN);
errorsCorrected += correctErrors(codewords, 20, 68, 56, ODD);
datawords = new byte[78];
break;
default:
@ -77,10 +77,12 @@ public final class Decoder {
System.arraycopy(codewords, 0, datawords, 0, 10);
System.arraycopy(codewords, 20, datawords, 10, datawords.length - 10);
return DecodedBitStreamParser.decode(datawords, mode);
DecoderResult result = DecodedBitStreamParser.decode(datawords, mode);
result.setErrorsCorrected(errorsCorrected);
return result;
}
private void correctErrors(byte[] codewordBytes,
private int correctErrors(byte[] codewordBytes,
int start,
int dataCodewords,
int ecCodewords,
@ -97,8 +99,9 @@ public final class Decoder {
codewordsInts[i / divisor] = codewordBytes[i + start] & 0xFF;
}
}
int errorsCorrected = 0;
try {
rsDecoder.decode(codewordsInts, ecCodewords / divisor);
errorsCorrected = rsDecoder.decodeWithECCount(codewordsInts, ecCodewords / divisor);
} catch (ReedSolomonException ignored) {
throw ChecksumException.getChecksumInstance();
}
@ -109,6 +112,7 @@ public final class Decoder {
codewordBytes[i + start] = (byte) codewordsInts[i / divisor];
}
}
return errorsCorrected;
}
}

View file

@ -90,6 +90,8 @@ public final class PDF417Reader implements Reader, MultipleBarcodeReader {
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());
result.putMetadata(ResultMetadataType.ERRORS_CORRECTED, decoderResult.getErrorsCorrected());
result.putMetadata(ResultMetadataType.ERASURES_CORRECTED, decoderResult.getErasures());
PDF417ResultMetadata pdf417ResultMetadata = (PDF417ResultMetadata) decoderResult.getOther();
if (pdf417ResultMetadata != null) {
result.putMetadata(ResultMetadataType.PDF417_EXTRA_METADATA, pdf417ResultMetadata);

View file

@ -99,6 +99,7 @@ public class QRCodeReader implements Reader {
result.putMetadata(ResultMetadataType.STRUCTURED_APPEND_PARITY,
decoderResult.getStructuredAppendParity());
}
result.putMetadata(ResultMetadataType.ERRORS_CORRECTED, decoderResult.getErrorsCorrected());
result.putMetadata(ResultMetadataType.SYMBOLOGY_IDENTIFIER, "]Q" + decoderResult.getSymbologyModifier());
return result;
}

View file

@ -146,17 +146,20 @@ public final class Decoder {
int resultOffset = 0;
// Error-correct and copy data blocks together into a stream of bytes
int errorsCorrected = 0;
for (DataBlock dataBlock : dataBlocks) {
byte[] codewordBytes = dataBlock.getCodewords();
int numDataCodewords = dataBlock.getNumDataCodewords();
correctErrors(codewordBytes, numDataCodewords);
errorsCorrected += correctErrors(codewordBytes, numDataCodewords);
for (int i = 0; i < numDataCodewords; i++) {
resultBytes[resultOffset++] = codewordBytes[i];
}
}
// Decode the contents of that stream of bytes
return DecodedBitStreamParser.decode(resultBytes, version, ecLevel, hints);
DecoderResult result = DecodedBitStreamParser.decode(resultBytes, version, ecLevel, hints);
result.setErrorsCorrected(errorsCorrected);
return result;
}
/**
@ -165,17 +168,19 @@ public final class Decoder {
*
* @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 void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {
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 {
rsDecoder.decode(codewordsInts, codewordBytes.length - numDataCodewords);
errorsCorrected = rsDecoder.decodeWithECCount(codewordsInts, codewordBytes.length - numDataCodewords);
} catch (ReedSolomonException ignored) {
throw ChecksumException.getChecksumInstance();
}
@ -184,6 +189,7 @@ public final class Decoder {
for (int i = 0; i < numDataCodewords; i++) {
codewordBytes[i] = (byte) codewordsInts[i];
}
return errorsCorrected;
}
}

View file

@ -26,10 +26,10 @@ public final class AztecBlackBox1TestCase extends AbstractBlackBoxTestCase {
public AztecBlackBox1TestCase() {
super("src/test/resources/blackbox/aztec-1", new AztecReader(), BarcodeFormat.AZTEC);
addTest(14, 14, 0.0f);
addTest(14, 14, 90.0f);
addTest(14, 14, 180.0f);
addTest(14, 14, 270.0f);
addTest(15, 15, 0.0f);
addTest(15, 15, 90.0f);
addTest(15, 15, 180.0f);
addTest(15, 15, 270.0f);
}
}

View file

@ -493,7 +493,7 @@ public final class EncoderTest extends Assert {
assertEquals("Unexpected nr. of layers", layers, aztec.getLayers());
BitMatrix matrix = aztec.getMatrix();
AztecDetectorResult r =
new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers());
new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers(), 0);
DecoderResult res = new Decoder().decode(r);
assertEquals(data, res.getText());
// Check error correction by introducing a few minor errors
@ -502,7 +502,7 @@ public final class EncoderTest extends Assert {
matrix.flip(random.nextInt(matrix.getWidth()), matrix.getHeight() - 2 + random.nextInt(2));
matrix.flip(random.nextInt(2), random.nextInt(matrix.getHeight()));
matrix.flip(matrix.getWidth() - 2 + random.nextInt(2), random.nextInt(matrix.getHeight()));
r = new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers());
r = new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers(), 0);
res = new Decoder().decode(r);
assertEquals(data, res.getText());
}
@ -527,7 +527,7 @@ public final class EncoderTest extends Assert {
BitMatrix matrix2 = aztec.getMatrix();
assertEquals(matrix, matrix2);
AztecDetectorResult r =
new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers());
new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers(), 0);
DecoderResult res = new Decoder().decode(r);
assertEquals(data, res.getText());
// Check error correction by introducing up to eccPercent/2 errors
@ -543,7 +543,7 @@ public final class EncoderTest extends Assert {
: matrix.getHeight() - 1 - random.nextInt(aztec.getLayers() * 2);
matrix.flip(x, y);
}
r = new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers());
r = new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers(), 0);
res = new Decoder().decode(r);
assertEquals(data, res.getText());
}

View file

@ -165,6 +165,8 @@ public abstract class AbstractBlackBoxTestCase extends Assert {
try (BufferedReader reader = Files.newBufferedReader(expectedMetadataFile, StandardCharsets.UTF_8)) {
expectedMetadata.load(reader);
}
correctInteger(expectedMetadata, ResultMetadataType.ERRORS_CORRECTED);
correctInteger(expectedMetadata, ResultMetadataType.ERASURES_CORRECTED);
}
for (int x = 0; x < testCount; x++) {
@ -249,6 +251,15 @@ public abstract class AbstractBlackBoxTestCase extends Assert {
}
}
private static void correctInteger(Properties metadata, ResultMetadataType key) {
String skey = key.toString();
if (metadata.containsKey(skey)) {
String sval = metadata.getProperty(skey);
Integer ival = Integer.parseInt(sval);
metadata.put(skey, ival);
}
}
private boolean decode(BinaryBitmap source,
float rotation,
String expectedText,

View file

@ -27,10 +27,10 @@ public final class DataMatrixBlackBox1TestCase extends AbstractBlackBoxTestCase
public DataMatrixBlackBox1TestCase() {
super("src/test/resources/blackbox/datamatrix-1", new MultiFormatReader(), BarcodeFormat.DATA_MATRIX);
addTest(21, 21, 0.0f);
addTest(21, 21, 90.0f);
addTest(21, 21, 180.0f);
addTest(21, 21, 270.0f);
addTest(22, 22, 0.0f);
addTest(22, 22, 90.0f);
addTest(22, 22, 180.0f);
addTest(22, 22, 270.0f);
}
}
}

View file

@ -32,7 +32,7 @@ public final class MaxiCodeBlackBox1TestCase extends AbstractBlackBoxTestCase {
public MaxiCodeBlackBox1TestCase() {
super("src/test/resources/blackbox/maxicode-1", new MultiFormatReader(), BarcodeFormat.MAXICODE);
addHint(DecodeHintType.PURE_BARCODE);
addTest(7, 7, 0.0f);
addTest(8, 8, 0.0f);
}
}

View file

@ -27,7 +27,7 @@ public final class Maxicode1TestCase extends AbstractBlackBoxTestCase {
public Maxicode1TestCase() {
super("src/test/resources/blackbox/maxicode-1", new MultiFormatReader(), BarcodeFormat.MAXICODE);
addTest(7, 7, 0.0f);
addTest(8, 8, 0.0f);
}
}

View file

@ -29,10 +29,10 @@ public final class PDF417BlackBox1TestCase extends AbstractBlackBoxTestCase {
public PDF417BlackBox1TestCase() {
super("src/test/resources/blackbox/pdf417-1", new MultiFormatReader(), BarcodeFormat.PDF_417);
addTest(12, 12, 0.0f);
addTest(12, 12, 90.0f);
addTest(12, 12, 180.0f);
addTest(12, 12, 270.0f);
addTest(13, 13, 0.0f);
addTest(13, 13, 90.0f);
addTest(13, 13, 180.0f);
addTest(13, 13, 270.0f);
}
}

View file

@ -27,10 +27,10 @@ public final class QRCodeBlackBox2TestCase extends AbstractBlackBoxTestCase {
public QRCodeBlackBox2TestCase() {
super("src/test/resources/blackbox/qrcode-2", new MultiFormatReader(), BarcodeFormat.QR_CODE);
addTest(31, 31, 0.0f);
addTest(29, 29, 90.0f);
addTest(30, 30, 180.0f);
addTest(30, 30, 270.0f);
addTest(32, 32, 0.0f);
addTest(30, 30, 90.0f);
addTest(31, 31, 180.0f);
addTest(31, 31, 270.0f);
}
}

View file

@ -0,0 +1 @@
ERRORS_CORRECTED=3

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View file

@ -0,0 +1 @@
hello

View file

@ -0,0 +1 @@
ERRORS_CORRECTED=0

View file

@ -1 +1,2 @@
SYMBOLOGY_IDENTIFIER=]d1
ERRORS_CORRECTED=0

View file

@ -0,0 +1 @@
ERRORS_CORRECTED=2

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1 @@
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(),./\

View file

@ -0,0 +1 @@
ERRORS_CORRECTED=0

View file

@ -0,0 +1 @@
ERRORS_CORRECTED=3

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1 @@
ABCDEFGHIJKLMNOPQRSTUVWXYZ "#$%&'()*+,-./01234:56789

View file

@ -1 +1,3 @@
SYMBOLOGY_IDENTIFIER=]L0
ERRORS_CORRECTED=0
ERASURES_CORRECTED=0

View file

@ -0,0 +1,2 @@
ERRORS_CORRECTED=4
ERASURES_CORRECTED=3

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1 @@
This is PDF417

View file

@ -1 +1,2 @@
SYMBOLOGY_IDENTIFIER=]Q1
ERRORS_CORRECTED=0

View file

@ -0,0 +1 @@
ERRORS_CORRECTED=2

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

View file

@ -0,0 +1 @@
Morden