diff --git a/core/src/main/java/com/google/zxing/ChecksumException.java b/core/src/main/java/com/google/zxing/ChecksumException.java
index dedb4be99..77bb908d2 100644
--- a/core/src/main/java/com/google/zxing/ChecksumException.java
+++ b/core/src/main/java/com/google/zxing/ChecksumException.java
@@ -30,8 +30,23 @@ public final class ChecksumException extends ReaderException {
// do nothing
}
- public static ChecksumException getChecksumInstance() {
- return instance;
+ private ChecksumException(Throwable cause) {
+ super(cause);
}
+ public static ChecksumException getChecksumInstance() {
+ if (isStackTrace) {
+ return new ChecksumException();
+ } else {
+ return instance;
+ }
+ }
+
+ public static ChecksumException getChecksumInstance(Throwable cause) {
+ if (isStackTrace) {
+ return new ChecksumException(cause);
+ } else {
+ return instance;
+ }
+ }
}
\ No newline at end of file
diff --git a/core/src/main/java/com/google/zxing/FormatException.java b/core/src/main/java/com/google/zxing/FormatException.java
index 6967e93de..b169bbc99 100644
--- a/core/src/main/java/com/google/zxing/FormatException.java
+++ b/core/src/main/java/com/google/zxing/FormatException.java
@@ -28,11 +28,25 @@ public final class FormatException extends ReaderException {
private static final FormatException instance = new FormatException();
private FormatException() {
- // do nothing
+ }
+
+ private FormatException(Throwable cause) {
+ super(cause);
}
public static FormatException getFormatInstance() {
- return instance;
+ if (isStackTrace) {
+ return new FormatException();
+ } else {
+ return instance;
+ }
+ }
+
+ public static FormatException getFormatInstance(Throwable cause) {
+ if (isStackTrace) {
+ return new FormatException(cause);
+ } else {
+ return instance;
+ }
}
-
}
\ No newline at end of file
diff --git a/core/src/main/java/com/google/zxing/ReaderException.java b/core/src/main/java/com/google/zxing/ReaderException.java
index 9bb0dd4b9..871a0d98d 100644
--- a/core/src/main/java/com/google/zxing/ReaderException.java
+++ b/core/src/main/java/com/google/zxing/ReaderException.java
@@ -25,10 +25,17 @@ package com.google.zxing;
*/
public abstract class ReaderException extends Exception {
+ // disable stack traces when not running inside test units
+ protected static final boolean isStackTrace = System.getProperty("surefire.test.class.path") != null;
+
ReaderException() {
// do nothing
}
+ ReaderException(Throwable cause) {
+ super(cause);
+ }
+
// Prevent stack traces from being taken
// srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?
// This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.
diff --git a/core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java b/core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java
index 8fa7f3baa..d0304a9a1 100644
--- a/core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java
+++ b/core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java
@@ -229,8 +229,8 @@ public final class Decoder {
try {
ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(gf);
rsDecoder.decode(dataWords, numECCodewords);
- } catch (ReedSolomonException ignored) {
- throw FormatException.getFormatInstance();
+ } catch (ReedSolomonException ex) {
+ throw FormatException.getFormatInstance(ex);
}
// Now perform the unstuffing operation.
diff --git a/core/src/main/java/com/google/zxing/common/BitMatrix.java b/core/src/main/java/com/google/zxing/common/BitMatrix.java
index 04e30a241..c3004a0d0 100755
--- a/core/src/main/java/com/google/zxing/common/BitMatrix.java
+++ b/core/src/main/java/com/google/zxing/common/BitMatrix.java
@@ -62,6 +62,65 @@ public final class BitMatrix implements Cloneable {
this.bits = bits;
}
+ public static BitMatrix parse(String stringRepresentation, String setString, String unsetString) {
+ int pos = 0;
+ if (stringRepresentation == null) {
+ throw new IllegalArgumentException();
+ }
+
+ boolean[] bits = new boolean[stringRepresentation.length()];
+ int bitsPos = 0;
+ int rowStartPos = 0;
+ int rowLength = -1;
+ int nRows = 0;
+ while (pos < stringRepresentation.length()) {
+ if (stringRepresentation.substring(pos, pos + 1).equals("\n") || stringRepresentation.substring(pos, pos + 1).equals("\r")) {
+ if (bitsPos > rowStartPos) {
+ if(rowLength == -1) {
+ rowLength = bitsPos - rowStartPos;
+ }
+ else if (bitsPos - rowStartPos != rowLength) {
+ throw new IllegalArgumentException("row lengths do not match");
+ }
+ rowStartPos = bitsPos;
+ nRows++;
+ }
+ pos++;
+ }
+ else if (stringRepresentation.substring(pos, pos + setString.length()).equals(setString)) {
+ pos += setString.length();
+ bits[bitsPos] = true;
+ bitsPos++;
+ }
+ else if (stringRepresentation.substring(pos, pos + unsetString.length()).equals(unsetString)) {
+ pos += unsetString.length();
+ bits[bitsPos] = false;
+ bitsPos++;
+ } else {
+ throw new IllegalArgumentException("illegal character encountered: " + stringRepresentation.substring(pos));
+ }
+ }
+
+ // no EOL at end?
+ if (bitsPos > rowStartPos) {
+ if(rowLength == -1) {
+ rowLength = bitsPos - rowStartPos;
+ }
+ else if (bitsPos - rowStartPos != rowLength) {
+ throw new IllegalArgumentException("row lengths do not match");
+ }
+ nRows++;
+ }
+
+ BitMatrix matrix = new BitMatrix(rowLength, nRows);
+ for (int i=0; i
Flips the given bit.
* @@ -96,6 +160,27 @@ public final class BitMatrix implements Cloneable { bits[offset] ^= 1 << (x & 0x1f); } + /** + *XOR for {@link BitMatrix}.
+ * Flip the bit in this {@link BitMatrix} if the corresponding mask bit is set. + * + * @param mask + */ + public void xor(BitMatrix mask) { + if (width != mask.getWidth() || height != mask.getHeight() + || rowSize != mask.getRowSize()) { + throw new IllegalArgumentException("input matrix dimensions do not match"); + } + BitArray rowArray = new BitArray(width/32+1); + for (int y = 0; y < height; y++) { + int offset = y * rowSize; + int[] row = mask.getRow(y, rowArray).getBitArray(); + for (int x = 0; x < rowSize; x++) { + bits[offset + x] ^= row[x]; + } + } + } + /** * Clears all bits (sets to false). */ @@ -295,6 +380,13 @@ public final class BitMatrix implements Cloneable { return height; } + /** + * @return The row size of the matrix + */ + public int getRowSize() { + return rowSize; + } + @Override public boolean equals(Object o) { if (!(o instanceof BitMatrix)) { @@ -317,12 +409,20 @@ public final class BitMatrix implements Cloneable { @Override public String toString() { + return toString("X ", " "); + } + + public String toString(String setString, String unsetString) { + return toString(setString, unsetString, System.lineSeparator()); + } + + public String toString(String setString, String unsetString, String lineSeparator) { StringBuilder result = new StringBuilder(height * (width + 1)); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - result.append(get(x, y) ? "X " : " "); + result.append(get(x, y) ? setString : unsetString); } - result.append('\n'); + result.append(lineSeparator); } return result.toString(); } diff --git a/core/src/test/java/com/google/zxing/aztec/decoder/DecoderTest.java b/core/src/test/java/com/google/zxing/aztec/decoder/DecoderTest.java new file mode 100644 index 000000000..1babafc13 --- /dev/null +++ b/core/src/test/java/com/google/zxing/aztec/decoder/DecoderTest.java @@ -0,0 +1,117 @@ +/* + * Copyright 2014 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.aztec.decoder; + +import com.google.zxing.FormatException; +import com.google.zxing.ResultPoint; +import com.google.zxing.aztec.AztecDetectorResult; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.DecoderResult; +import org.junit.Test; +import static org.junit.Assert.*; + +public class DecoderTest { + + private static final ResultPoint[] NO_POINTS = new ResultPoint[0]; + + /** + * throws + *com.google.zxing.FormatException: com.google.zxing.common.reedsolomon.ReedSolomonException: Error locator degree does not match number of roots + * at com.google.zxing.common.reedsolomon.ReedSolomonDecoder.findErrorLocations(ReedSolomonDecoder.java:158) + * at com.google.zxing.common.reedsolomon.ReedSolomonDecoder.decode(ReedSolomonDecoder.java:77) + * at com.google.zxing.aztec.decoder.Decoder.correctBits(Decoder.java:231) + * at com.google.zxing.aztec.decoder.Decoder.decode(Decoder.java:77) + * at com.google.zxing.aztec.decoder.DecoderTest.testDecodeBug1(DecoderTest.java:66)+ */ + @Test + public void testDecodeTooManyErrors() { + BitMatrix matrix = BitMatrix.parse("" + + "X X . X . . . X X . . . X . . X X X . X . X X X X X . \n" + + "X X . . X X . . . . . X X . . . X X . . . X . X . . X \n" + + "X . . . X X . . X X X . X X . X X X X . X X . . X . . \n" + + ". . . . X . X X . . X X . X X . X . X X X X . X . . X \n" + + "X X X . . X X X X X . . . . . X X . . . X . X . X . X \n" + + "X X . . . . . . . . X . . . X . X X X . X . . X . . . \n" + + "X X . . X . . . . . X X . . . . . X . . . . X . . X X \n" + + ". . . X . X . X . . . . . X X X X X X . . . . . . X X \n" + + "X . . . X . X X X X X X . . X X X . X . X X X X X X . \n" + + "X . . X X X . X X X X X X X X X X X X X . . . X . X X \n" + + ". . . . X X . . . X . . . . . . . X X . . . X X . X . \n" + + ". . . X X X . . X X . X X X X X . X . . X . . . . . . \n" + + "X . . . . X . X . X . X . . . X . X . X X . X X . X X \n" + + "X . X . . X . X . X . X . X . X . X . . . . . X . X X \n" + + "X . X X X . . X . X . X . . . X . X . X X X . . . X X \n" + + "X X X X X X X X . X . X X X X X . X . X . X . X X X . \n" + + ". . . . . . . X . X . . . . . . . X X X X . . . X X X \n" + + "X X . . X . . X . X X X X X X X X X X X X X . . X . X \n" + + "X X X . X X X X . . X X X X . . X . . . . X . . X X X \n" + + ". . . . X . X X X . . . . X X X X . . X X X X . . . . \n" + + ". . X . . X . X . . . X . X X . X X . X . . . X . X . \n" + + "X X . . X . . X X X X X X X . . X . X X X X X X X . . \n" + + "X . X X . . X X . . . . . X . . . . . . X X . X X X . \n" + + "X . . X X . . X X . X . X . . . . X . X . . X . . X . \n" + + "X . X . X . . X . X X X X X X X X . X X X X . . X X . \n" + + "X X X X . . . X . . X X X . X X . . X . . . . X X X . \n" + + "X X . X . X . . . X . X . . . . X X . X . . X X . . . \n", + "X ", ". "); + AztecDetectorResult r = new AztecDetectorResult(matrix, NO_POINTS, true, 16, 4); + try { + DecoderResult res = new Decoder().decode(r); + fail(); + } catch (FormatException ex) { + } + } + + @Test + public void testDecodeTooManyErrors2() { + BitMatrix matrix = BitMatrix.parse("" + + ". X X . . X . X X . . . X . . X X X . . . X X . X X . \n" + + "X X . X X . . X . . . X X . . . X X . X X X . X . X X \n" + + ". . . . X . . . X X X . X X . X X X X . X X . . X . . \n" + + "X . X X . . X . . . X X . X X . X . X X . . . . . X . \n" + + "X X . X . . X . X X . . . . . X X . . . . . X . . . X \n" + + "X . . X . . . . . . X . . . X . X X X X X X X . . . X \n" + + "X . . X X . . X . . X X . . . . . X . . . . . X X X . \n" + + ". . X X X X . X . . . . . X X X X X X . . . . . . X X \n" + + "X . . . X . X X X X X X . . X X X . X . X X X X X X . \n" + + "X . . X X X . X X X X X X X X X X X X X . . . X . X X \n" + + ". . . . X X . . . X . . . . . . . X X . . . X X . X . \n" + + ". . . X X X . . X X . X X X X X . X . . X . . . . . . \n" + + "X . . . . X . X . X . X . . . X . X . X X . X X . X X \n" + + "X . X . . X . X . X . X . X . X . X . . . . . X . X X \n" + + "X . X X X . . X . X . X . . . X . X . X X X . . . X X \n" + + "X X X X X X X X . X . X X X X X . X . X . X . X X X . \n" + + ". . . . . . . X . X . . . . . . . X X X X . . . X X X \n" + + "X X . . X . . X . X X X X X X X X X X X X X . . X . X \n" + + "X X X . X X X X . . X X X X . . X . . . . X . . X X X \n" + + ". . X X X X X . X . . . . X X X X . . X X X . X . X . \n" + + ". . X X . X . X . . . X . X X . X X . . . . X X . . . \n" + + "X . . . X . X . X X X X X X . . X . X X X X X . X . . \n" + + ". X . . . X X X . . . . . X . . . . . X X X X X . X . \n" + + "X . . X . X X X X . X . X . . . . X . X X . X . . X . \n" + + "X . . . X X . X . X X X X X X X X . X X X X . . X X . \n" + + ". X X X X . . X . . X X X . X X . . X . . . . X X X . \n" + + "X X . . . X X . . X . X . . . . X X . X . . X . X . X \n", + "X ", ". "); + AztecDetectorResult r = new AztecDetectorResult(matrix, NO_POINTS, true, 16, 4); + try { + DecoderResult res = new Decoder().decode(r); + fail(); + } catch (FormatException ex) { + } + } + +} diff --git a/core/src/test/java/com/google/zxing/aztec/encoder/EncoderTest.java b/core/src/test/java/com/google/zxing/aztec/encoder/EncoderTest.java index a48c65742..aaf45e2ae 100644 --- a/core/src/test/java/com/google/zxing/aztec/encoder/EncoderTest.java +++ b/core/src/test/java/com/google/zxing/aztec/encoder/EncoderTest.java @@ -37,6 +37,7 @@ import java.util.EnumMap; import java.util.Map; import java.util.Random; import java.util.regex.Pattern; +import org.junit.Before; /** * Aztec 2D generator unit tests. @@ -48,6 +49,12 @@ public final class EncoderTest extends Assert { private static final Pattern DOTX = Pattern.compile("[^.X]"); private static final ResultPoint[] NO_POINTS = new ResultPoint[0]; + private static Random random; + + @Before + public void beforeTest() { + random = new Random(0); + } // real life tests @@ -127,23 +134,24 @@ public final class EncoderTest extends Assert { "X X X X X X X X X X X X X \n"); } - @Ignore("Flaky test for unknown reasons -- disabling for now") @Test public void testAztecWriter() throws Exception { - testWriter("\u20AC 1 sample data.", "ISO-8859-1", 25, true, 2); - testWriter("\u20AC 1 sample data.", "ISO-8859-15", 25, true, 2); - testWriter("\u20AC 1 sample data.", "UTF-8", 25, true, 2); - testWriter("\u20AC 1 sample data.", "UTF-8", 100, true, 3); - testWriter("\u20AC 1 sample data.", "UTF-8", 300, true, 4); - testWriter("\u20AC 1 sample data.", "UTF-8", 500, false, 5); - // Test AztecWriter defaults - String data = "In ut magna vel mauris malesuada"; - AztecWriter writer = new AztecWriter(); - BitMatrix matrix = writer.encode(data, BarcodeFormat.AZTEC, 0, 0); - AztecCode aztec = Encoder.encode(data.getBytes(StandardCharsets.ISO_8859_1), - Encoder.DEFAULT_EC_PERCENT, Encoder.DEFAULT_AZTEC_LAYERS); - BitMatrix expectedMatrix = aztec.getMatrix(); - assertEquals(matrix, expectedMatrix); + for (int i = 0; i < 1000; i++) { + testWriter("\u20AC 1 sample data.", "ISO-8859-1", 25, true, 2); + testWriter("\u20AC 1 sample data.", "ISO-8859-15", 25, true, 2); + testWriter("\u20AC 1 sample data.", "UTF-8", 25, true, 2); + testWriter("\u20AC 1 sample data.", "UTF-8", 100, true, 3); + testWriter("\u20AC 1 sample data.", "UTF-8", 300, true, 4); + testWriter("\u20AC 1 sample data.", "UTF-8", 500, false, 5); + // Test AztecWriter defaults + String data = "In ut magna vel mauris malesuada"; + AztecWriter writer = new AztecWriter(); + BitMatrix matrix = writer.encode(data, BarcodeFormat.AZTEC, 0, 0); + AztecCode aztec = Encoder.encode(data.getBytes(StandardCharsets.ISO_8859_1), + Encoder.DEFAULT_EC_PERCENT, Encoder.DEFAULT_AZTEC_LAYERS); + BitMatrix expectedMatrix = aztec.getMatrix(); + assertEquals(matrix, expectedMatrix); + } } // synthetic tests (encode-decode round-trip) @@ -486,8 +494,8 @@ public final class EncoderTest extends Assert { new AztecDetectorResult(matrix, NO_POINTS, aztec.isCompact(), aztec.getCodeWords(), aztec.getLayers()); DecoderResult res = new Decoder().decode(r); assertEquals(expectedData, res.getText()); - // Check error correction by introducing up to eccPercent errors - int ecWords = aztec.getCodeWords() * eccPercent / 100; + // Check error correction by introducing up to eccPercent/2 errors + int ecWords = aztec.getCodeWords() * eccPercent / 100 / 2; Random random = getPseudoRandom(); for (int i = 0; i < ecWords; i++) { // don't touch the core @@ -505,7 +513,7 @@ public final class EncoderTest extends Assert { } private static Random getPseudoRandom() { - return new SecureRandom(new byte[] {(byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF}); + return random; } private static void testModeMessage(boolean compact, int layers, int words, String expected) { diff --git a/core/src/test/java/com/google/zxing/common/BitMatrixTestCase.java b/core/src/test/java/com/google/zxing/common/BitMatrixTestCase.java index 5fbc36a89..60cd3f93b 100644 --- a/core/src/test/java/com/google/zxing/common/BitMatrixTestCase.java +++ b/core/src/test/java/com/google/zxing/common/BitMatrixTestCase.java @@ -153,6 +153,89 @@ public final class BitMatrixTestCase extends Assert { testRotate180(8, 5); } + @Test + public void testParse() { + BitMatrix emptyMatrix = new BitMatrix(3, 3); + BitMatrix fullMatrix = new BitMatrix(3, 3); + fullMatrix.setRegion(0, 0, 3, 3); + BitMatrix centerMatrix = new BitMatrix(3, 3); + centerMatrix.setRegion(1, 1, 1, 1); + BitMatrix emptyMatrix24 = new BitMatrix(2, 4); + + assertEquals(emptyMatrix, BitMatrix.parse(" \n \n \n", "x", " ")); + assertEquals(emptyMatrix, BitMatrix.parse(" \n \r\r\n \n\r", "x", " ")); + assertEquals(emptyMatrix, BitMatrix.parse(" \n \n ", "x", " ")); + + assertEquals(fullMatrix, BitMatrix.parse("xxx\nxxx\nxxx\n", "x", " ")); + + assertEquals(centerMatrix, BitMatrix.parse(" \n x \n \n", "x", " ")); + assertEquals(centerMatrix, BitMatrix.parse(" \n x \n \n", "x ", " ")); + try { + assertEquals(centerMatrix, BitMatrix.parse(" \n xy\n \n", "x", " ")); + fail(); + } catch (IllegalArgumentException ex) {} + + assertEquals(emptyMatrix24, BitMatrix.parse(" \n \n \n \n", "x", " ")); + + assertEquals(centerMatrix, BitMatrix.parse(centerMatrix.toString("x", ".", "\n"), "x", ".")); + } + + @Test + public void testUnset() { + BitMatrix emptyMatrix = new BitMatrix(3, 3); + BitMatrix matrix = emptyMatrix.clone(); + matrix.set(1, 1); + assertNotEquals(emptyMatrix, matrix); + matrix.unset(1, 1); + assertEquals(emptyMatrix, matrix); + matrix.unset(1, 1); + assertEquals(emptyMatrix, matrix); + } + + @Test + public void testXOR() { + BitMatrix emptyMatrix = new BitMatrix(3, 3); + BitMatrix fullMatrix = new BitMatrix(3, 3); + fullMatrix.setRegion(0, 0, 3, 3); + BitMatrix centerMatrix = new BitMatrix(3, 3); + centerMatrix.setRegion(1, 1, 1, 1); + BitMatrix invertedCenterMatrix = fullMatrix.clone(); + invertedCenterMatrix.unset(1, 1); + BitMatrix badMatrix = new BitMatrix(4, 4); + + testXOR(emptyMatrix, emptyMatrix, emptyMatrix); + testXOR(emptyMatrix, centerMatrix, centerMatrix); + testXOR(emptyMatrix, fullMatrix, fullMatrix); + + testXOR(centerMatrix, emptyMatrix, centerMatrix); + testXOR(centerMatrix, centerMatrix, emptyMatrix); + testXOR(centerMatrix, fullMatrix, invertedCenterMatrix); + + testXOR(invertedCenterMatrix, emptyMatrix, invertedCenterMatrix); + testXOR(invertedCenterMatrix, centerMatrix, fullMatrix); + testXOR(invertedCenterMatrix, fullMatrix, centerMatrix); + + testXOR(fullMatrix, emptyMatrix, fullMatrix); + testXOR(fullMatrix, centerMatrix, invertedCenterMatrix); + testXOR(fullMatrix, fullMatrix, emptyMatrix); + + try { + emptyMatrix.clone().xor(badMatrix); + fail(); + } catch(IllegalArgumentException ex) {} + + try { + badMatrix.clone().xor(emptyMatrix); + fail(); + } catch(IllegalArgumentException ex) {} + } + + private static void testXOR(BitMatrix dataMatrix, BitMatrix flipMatrix, BitMatrix expectedMatrix) { + BitMatrix matrix = dataMatrix.clone(); + matrix.xor(flipMatrix); + assertEquals(expectedMatrix, matrix); + } + private static void testRotate180(int width, int height) { BitMatrix input = getInput(width, height); input.rotate180(); diff --git a/core/src/test/java/com/google/zxing/common/reedsolomon/ReedSolomonTestCase.java b/core/src/test/java/com/google/zxing/common/reedsolomon/ReedSolomonTestCase.java index d397c155a..f86d35efa 100644 --- a/core/src/test/java/com/google/zxing/common/reedsolomon/ReedSolomonTestCase.java +++ b/core/src/test/java/com/google/zxing/common/reedsolomon/ReedSolomonTestCase.java @@ -394,7 +394,7 @@ public final class ReedSolomonTestCase extends Assert { testEncodeDecodeRandom(GenericGF.AZTEC_DATA_12, 3072, 1023); } - private static void corrupt(int[] received, int howMany, Random random, int max) { + public static void corrupt(int[] received, int howMany, Random random, int max) { BitSet corrupted = new BitSet(received.length); for (int j = 0; j < howMany; j++) { int location = random.nextInt(received.length); diff --git a/core/src/test/java/com/google/zxing/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.java b/core/src/test/java/com/google/zxing/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.java index 8ddc8c509..06d7221c4 100644 --- a/core/src/test/java/com/google/zxing/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.java +++ b/core/src/test/java/com/google/zxing/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.java @@ -16,9 +16,9 @@ package com.google.zxing.pdf417.decoder.ec; +import com.google.zxing.common.reedsolomon.ReedSolomonTestCase; import org.junit.Assert; -import java.security.SecureRandom; import java.util.BitSet; import java.util.Random; @@ -28,16 +28,7 @@ import java.util.Random; abstract class AbstractErrorCorrectionTestCase extends Assert { static void corrupt(int[] received, int howMany, Random random) { - BitSet corrupted = new BitSet(received.length); - for (int j = 0; j < howMany; j++) { - int location = random.nextInt(received.length); - if (corrupted.get(location)) { - j--; - } else { - corrupted.set(location); - received[location] = random.nextInt(929); - } - } + ReedSolomonTestCase.corrupt(received, howMany, random, 929); } static int[] erase(int[] received, int howMany, Random random) { @@ -58,7 +49,7 @@ abstract class AbstractErrorCorrectionTestCase extends Assert { } static Random getRandom() { - return new SecureRandom(new byte[] {(byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF}); + return new Random(0); } } \ No newline at end of file diff --git a/core/src/test/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrectionTestCase.java b/core/src/test/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrectionTestCase.java index 9e3f2e22d..3ccf3b9b5 100644 --- a/core/src/test/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrectionTestCase.java +++ b/core/src/test/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrectionTestCase.java @@ -28,12 +28,6 @@ import java.util.Random; */ public final class ErrorCorrectionTestCase extends AbstractErrorCorrectionTestCase { - /** See ISO 15438, Annex Q */ - //private static final int[] PDF417_TEST = - // { 5, 453, 178, 121, 239 }; - //private static final int[] PDF417_TEST_WITH_EC = - // { 5, 453, 178, 121, 239, 452, 327, 657, 619 }; - private static final int[] PDF417_TEST = { 48, 901, 56, 141, 627, 856, 330, 69, 244, 900, 852, 169, 843, 895, 852, 895, 913, 154, 845, 778, 387, 89, 869, 901, 219, 474, 543, 650, 169, 201, 9, 160, 35, 70, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, @@ -45,10 +39,7 @@ public final class ErrorCorrectionTestCase extends AbstractErrorCorrectionTestCa 806, 908, 309, 153, 871, 686, 838, 185, 674, 68, 679, 691, 794, 497, 479, 234, 250, 496, 43, 347, 582, 882, 536, 322, 317, 273, 194, 917, 237, 420, 859, 340, 115, 222, 808, 866, 836, 417, 121, 833, 459, 64, 159}; private static final int ECC_BYTES = PDF417_TEST_WITH_EC.length - PDF417_TEST.length; - // Example is EC level 1 (s=1). The number of erasures (l) and substitutions (f) must obey: - // l + 2f <= 2^(s+1) - 3 - private static final int EC_LEVEL = 5; - private static final int ERROR_LIMIT = (1 << (EC_LEVEL + 1)) - 3; + private static final int ERROR_LIMIT = ECC_BYTES; private static final int MAX_ERRORS = ERROR_LIMIT / 2; private static final int MAX_ERASURES = ERROR_LIMIT; @@ -81,13 +72,11 @@ public final class ErrorCorrectionTestCase extends AbstractErrorCorrectionTestCa } } - @Ignore("Unresolved flakiness with OpenJDK 7 only") @Test public void testTooManyErrors() { int[] received = PDF417_TEST_WITH_EC.clone(); Random random = getRandom(); - // +3 since the algorithm can actually correct 2 more than it should here - corrupt(received, MAX_ERRORS + 3, random); + corrupt(received, MAX_ERRORS + 1, random); try { checkDecode(received); fail("Should not have decoded");