mirror of
https://github.com/zxing/zxing.git
synced 2024-11-10 04:54:04 -08:00
Issue 1825. PDF417Reader can't modify the image. When it doesn't, it actually reduces the number of images that pass unfortunately.
git-svn-id: https://zxing.googlecode.com/svn/trunk@3001 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
10c2f71671
commit
6463455d26
|
@ -136,4 +136,13 @@ public final class BinaryBitmap {
|
|||
return new BinaryBitmap(binarizer.createBinarizer(newSource));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return getBlackMatrix().toString();
|
||||
} catch (NotFoundException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
|
||||
package com.google.zxing.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
public final class BitArray {
|
||||
public final class BitArray implements Cloneable {
|
||||
|
||||
private int[] bits;
|
||||
private int size;
|
||||
|
@ -334,6 +336,20 @@ public final class BitArray {
|
|||
return new int[(size + 31) / 32];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof BitArray)) {
|
||||
return false;
|
||||
}
|
||||
BitArray other = (BitArray) o;
|
||||
return size == other.size && Arrays.equals(bits, other.bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * size + Arrays.hashCode(bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder(size);
|
||||
|
@ -346,4 +362,9 @@ public final class BitArray {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BitArray clone() {
|
||||
return new BitArray(bits.clone(), size);
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package com.google.zxing.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* <p>Represents a 2D matrix of bits. In function arguments below, and throughout the common
|
||||
* module, x is the column position, and y is the row position. The ordering is always x, y.
|
||||
|
@ -31,7 +33,7 @@ package com.google.zxing.common;
|
|||
* @author Sean Owen
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class BitMatrix {
|
||||
public final class BitMatrix implements Cloneable {
|
||||
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
@ -53,6 +55,13 @@ public final class BitMatrix {
|
|||
bits = new int[rowSize * height];
|
||||
}
|
||||
|
||||
private BitMatrix(int width, int height, int rowSize, int[] bits) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.rowSize = rowSize;
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets the requested bit, where true means black.</p>
|
||||
*
|
||||
|
@ -136,6 +145,8 @@ public final class BitMatrix {
|
|||
public BitArray getRow(int y, BitArray row) {
|
||||
if (row == null || row.getSize() < width) {
|
||||
row = new BitArray(width);
|
||||
} else {
|
||||
row.clear();
|
||||
}
|
||||
int offset = y * rowSize;
|
||||
for (int x = 0; x < rowSize; x++) {
|
||||
|
@ -152,10 +163,28 @@ public final class BitMatrix {
|
|||
System.arraycopy(row.getBitArray(), 0, bits, y * rowSize, rowSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies this {@code BitMatrix} to represent the same but rotated 180 degrees
|
||||
*/
|
||||
public void rotate180() {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
BitArray topRow = new BitArray(width);
|
||||
BitArray bottomRow = new BitArray(width);
|
||||
for (int i = 0; i < (height+1) / 2; i++) {
|
||||
topRow = getRow(i, topRow);
|
||||
bottomRow = getRow(height - 1 - i, bottomRow);
|
||||
topRow.reverse();
|
||||
bottomRow.reverse();
|
||||
setRow(i, bottomRow);
|
||||
setRow(height - 1 - i, topRow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is useful in detecting the enclosing rectangle of a 'pure' barcode.
|
||||
*
|
||||
* @return {left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
|
||||
* @return {@code left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
|
||||
*/
|
||||
public int[] getEnclosingRectangle() {
|
||||
int left = width;
|
||||
|
@ -208,7 +237,7 @@ public final class BitMatrix {
|
|||
/**
|
||||
* This is useful in detecting a corner of a 'pure' barcode.
|
||||
*
|
||||
* @return {x,y} coordinate of top-left-most 1 bit, or null if it is all white
|
||||
* @return {@code x,y} coordinate of top-left-most 1 bit, or null if it is all white
|
||||
*/
|
||||
public int[] getTopLeftOnBit() {
|
||||
int bitsOffset = 0;
|
||||
|
@ -272,16 +301,8 @@ public final class BitMatrix {
|
|||
return false;
|
||||
}
|
||||
BitMatrix other = (BitMatrix) o;
|
||||
if (width != other.width || height != other.height ||
|
||||
rowSize != other.rowSize || bits.length != other.bits.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < bits.length; i++) {
|
||||
if (bits[i] != other.bits[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return width == other.width && height == other.height && rowSize == other.rowSize &&
|
||||
Arrays.equals(bits, other.bits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -290,9 +311,7 @@ public final class BitMatrix {
|
|||
hash = 31 * hash + width;
|
||||
hash = 31 * hash + height;
|
||||
hash = 31 * hash + rowSize;
|
||||
for (int bit : bits) {
|
||||
hash = 31 * hash + bit;
|
||||
}
|
||||
hash = 31 * hash + Arrays.hashCode(bits);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -308,4 +327,9 @@ public final class BitMatrix {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BitMatrix clone() {
|
||||
return new BitMatrix(width, height, rowSize, bits.clone());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import com.google.zxing.BinaryBitmap;
|
|||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -82,7 +81,8 @@ public final class Detector {
|
|||
|
||||
List<ResultPoint[]> barcodeCoordinates = detect(multiple, bitMatrix);
|
||||
if (barcodeCoordinates.isEmpty()) {
|
||||
rotate180(bitMatrix);
|
||||
bitMatrix = bitMatrix.clone();
|
||||
bitMatrix.rotate180();
|
||||
barcodeCoordinates = detect(multiple, bitMatrix);
|
||||
}
|
||||
return new PDF417DetectorResult(bitMatrix, barcodeCoordinates);
|
||||
|
@ -141,39 +141,6 @@ public final class Detector {
|
|||
return barcodeCoordinates;
|
||||
}
|
||||
|
||||
// The following could go to the BitMatrix class (maybe in a more efficient version using the BitMatrix internal
|
||||
// data structures)
|
||||
/**
|
||||
* Rotates a bit matrix by 180 degrees.
|
||||
* @param bitMatrix bit matrix to rotate
|
||||
*/
|
||||
static void rotate180(BitMatrix bitMatrix) {
|
||||
int width = bitMatrix.getWidth();
|
||||
int height = bitMatrix.getHeight();
|
||||
BitArray firstRowBitArray = new BitArray(width);
|
||||
BitArray secondRowBitArray = new BitArray(width);
|
||||
BitArray tmpBitArray = new BitArray(width);
|
||||
for (int y = 0; y < height + 1 >> 1; y++) {
|
||||
firstRowBitArray = bitMatrix.getRow(y, firstRowBitArray);
|
||||
bitMatrix.setRow(y, mirror(bitMatrix.getRow(height - 1 - y, secondRowBitArray), tmpBitArray));
|
||||
bitMatrix.setRow(height - 1 - y, mirror(firstRowBitArray, tmpBitArray));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the bits from the input to the result BitArray in reverse order
|
||||
*/
|
||||
static BitArray mirror(BitArray input, BitArray result) {
|
||||
result.clear();
|
||||
int size = input.getSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (input.get(i)) {
|
||||
result.set(size - 1 - i);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate the vertices and the codewords area of a black blob using the Start
|
||||
* and Stop patterns as locators.
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.junit.Test;
|
|||
*/
|
||||
public final class BitMatrixTestCase extends Assert {
|
||||
|
||||
private static final int[] BIT_MATRIX_POINTS = { 1, 2, 2, 0, 3, 1 };
|
||||
|
||||
@Test
|
||||
public void testGetSet() {
|
||||
BitMatrix matrix = new BitMatrix(33);
|
||||
|
@ -127,4 +129,56 @@ public final class BitMatrixTestCase extends Assert {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRotate180Simple() {
|
||||
BitMatrix matrix = new BitMatrix(3, 3);
|
||||
matrix.set(0, 0);
|
||||
matrix.set(0, 1);
|
||||
matrix.set(1, 2);
|
||||
matrix.set(2, 1);
|
||||
|
||||
matrix.rotate180();
|
||||
|
||||
assertTrue(matrix.get(2, 2));
|
||||
assertTrue(matrix.get(2, 1));
|
||||
assertTrue(matrix.get(1, 0));
|
||||
assertTrue(matrix.get(0, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRotate180() {
|
||||
testRotate180(7, 4);
|
||||
testRotate180(7, 5);
|
||||
testRotate180(8, 4);
|
||||
testRotate180(8, 5);
|
||||
}
|
||||
|
||||
private static void testRotate180(int width, int height) {
|
||||
BitMatrix input = getInput(width, height);
|
||||
input.rotate180();
|
||||
BitMatrix expected = getExpected(width, height);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
assertEquals("(" + x + ',' + y + ')', expected.get(x, y), input.get(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BitMatrix getExpected(int width, int height) {
|
||||
BitMatrix result = new BitMatrix(width, height);
|
||||
for (int i = 0; i < BIT_MATRIX_POINTS.length; i += 2) {
|
||||
result.set(width - 1 - BIT_MATRIX_POINTS[i], height - 1 - BIT_MATRIX_POINTS[i + 1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BitMatrix getInput(int width, int height) {
|
||||
BitMatrix result = new BitMatrix(width, height);
|
||||
for (int i = 0; i < BIT_MATRIX_POINTS.length; i += 2) {
|
||||
result.set(BIT_MATRIX_POINTS[i], BIT_MATRIX_POINTS[i + 1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ public final class DataMatrixBlackBox2TestCase extends AbstractBlackBoxTestCase
|
|||
|
||||
public DataMatrixBlackBox2TestCase() {
|
||||
super("src/test/resources/blackbox/datamatrix-2", new MultiFormatReader(), BarcodeFormat.DATA_MATRIX);
|
||||
addTest(8, 15, 0, 1, 0.0f);
|
||||
addTest(14, 16, 0, 1, 90.0f);
|
||||
addTest(14, 15, 0, 1, 180.0f);
|
||||
addTest(13, 16, 0, 1, 270.0f);
|
||||
addTest(8, 8, 0, 1, 0.0f);
|
||||
addTest(14, 14, 0, 1, 90.0f);
|
||||
addTest(14, 14, 0, 1, 180.0f);
|
||||
addTest(13, 13, 0, 1, 270.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 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.detector;
|
||||
|
||||
import com.google.zxing.common.BitArray;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public final class DetectorTest extends Assert {
|
||||
|
||||
private static final int[] BIT_SET_INDEX = { 1, 2, 3, 5 };
|
||||
private static final int[] BIT_MATRIX_POINTS = { 1, 2, 2, 0, 3, 1 };
|
||||
|
||||
@Test
|
||||
public void testMirror() {
|
||||
testMirror(7);
|
||||
testMirror(8);
|
||||
}
|
||||
|
||||
private static void testMirror(int size) {
|
||||
BitArray result = new BitArray(size);
|
||||
Detector.mirror(getInput(size), result);
|
||||
assertEquals(getExpected(size).toString(), result.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRotate180() {
|
||||
testRotate180(7, 4);
|
||||
testRotate180(7, 5);
|
||||
testRotate180(8, 4);
|
||||
testRotate180(8, 5);
|
||||
}
|
||||
|
||||
private static void testRotate180(int width, int height) {
|
||||
BitMatrix input = getInput(width, height);
|
||||
Detector.rotate180(input);
|
||||
BitMatrix expected = getExpected(width, height);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
assertEquals("(" + x + ',' + y + ')', expected.get(x, y), input.get(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BitMatrix getExpected(int width, int height) {
|
||||
BitMatrix result = new BitMatrix(width, height);
|
||||
for (int i = 0; i < BIT_MATRIX_POINTS.length; i += 2) {
|
||||
result.set(width - 1 - BIT_MATRIX_POINTS[i], height - 1 - BIT_MATRIX_POINTS[i + 1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BitMatrix getInput(int width, int height) {
|
||||
BitMatrix result = new BitMatrix(width, height);
|
||||
for (int i = 0; i < BIT_MATRIX_POINTS.length; i += 2) {
|
||||
result.set(BIT_MATRIX_POINTS[i], BIT_MATRIX_POINTS[i + 1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BitArray getExpected(int size) {
|
||||
BitArray expected = new BitArray(size);
|
||||
for (int index : BIT_SET_INDEX) {
|
||||
expected.set(size - 1 - index);
|
||||
}
|
||||
return expected;
|
||||
}
|
||||
|
||||
private static BitArray getInput(int size) {
|
||||
BitArray input = new BitArray(size);
|
||||
for (int index : BIT_SET_INDEX) {
|
||||
input.set(index);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
|
@ -28,9 +28,9 @@ public final class QRCodeBlackBox1TestCase extends AbstractBlackBoxTestCase {
|
|||
public QRCodeBlackBox1TestCase() {
|
||||
super("src/test/resources/blackbox/qrcode-1", new MultiFormatReader(), BarcodeFormat.QR_CODE);
|
||||
addTest(17, 17, 0.0f);
|
||||
addTest(14, 15, 90.0f);
|
||||
addTest(14, 14, 90.0f);
|
||||
addTest(17, 17, 180.0f);
|
||||
addTest(14, 15, 270.0f);
|
||||
addTest(14, 14, 270.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(30, 31, 0.0f);
|
||||
addTest(29, 30, 90.0f);
|
||||
addTest(30, 30, 0.0f);
|
||||
addTest(29, 29, 90.0f);
|
||||
addTest(30, 30, 180.0f);
|
||||
addTest(29, 30, 270.0f);
|
||||
addTest(29, 29, 270.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ public final class QRCodeBlackBox3TestCase extends AbstractBlackBoxTestCase {
|
|||
public QRCodeBlackBox3TestCase() {
|
||||
super("src/test/resources/blackbox/qrcode-3", new MultiFormatReader(), BarcodeFormat.QR_CODE);
|
||||
addTest(38, 38, 0.0f);
|
||||
addTest(38, 39, 90.0f);
|
||||
addTest(36, 38, 180.0f);
|
||||
addTest(38, 38, 90.0f);
|
||||
addTest(36, 36, 180.0f);
|
||||
addTest(39, 39, 270.0f);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ public final class QRCodeBlackBox4TestCase extends AbstractBlackBoxTestCase {
|
|||
super("src/test/resources/blackbox/qrcode-4", new MultiFormatReader(), BarcodeFormat.QR_CODE);
|
||||
addTest(36, 36, 0.0f);
|
||||
addTest(35, 35, 90.0f);
|
||||
addTest(35, 36, 180.0f);
|
||||
addTest(35, 36, 270.0f);
|
||||
addTest(35, 35, 180.0f);
|
||||
addTest(35, 35, 270.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public final class QRCodeBlackBox5TestCase extends AbstractBlackBoxTestCase {
|
|||
addTest(19, 19, 0.0f);
|
||||
addTest(19, 19, 90.0f);
|
||||
addTest(19, 19, 180.0f);
|
||||
addTest(18, 19, 270.0f);
|
||||
addTest(18, 18, 270.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ public final class QRCodeBlackBox6TestCase extends AbstractBlackBoxTestCase {
|
|||
public QRCodeBlackBox6TestCase() {
|
||||
super("src/test/resources/blackbox/qrcode-6", new MultiFormatReader(), BarcodeFormat.QR_CODE);
|
||||
addTest(15, 15, 0.0f);
|
||||
addTest(14, 15, 90.0f);
|
||||
addTest(12, 15, 180.0f);
|
||||
addTest(14, 15, 270.0f);
|
||||
addTest(14, 14, 90.0f);
|
||||
addTest(12, 13, 180.0f);
|
||||
addTest(14, 14, 270.0f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue