Remove use of BinaryBitmap in QR Code, DM

git-svn-id: https://zxing.googlecode.com/svn/trunk@999 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2009-06-26 19:22:48 +00:00
parent ce1badea71
commit 550511d760
13 changed files with 86 additions and 111 deletions

View file

@ -138,13 +138,13 @@ public final class BitMatrix {
* @return The resulting BitArray - this reference should always be used even when passing
* your own row
*/
BitArray getRow(int y, BitArray row) {
public BitArray getRow(int y, BitArray row) {
if (row == null || row.getSize() < width) {
row = new BitArray(width);
}
int offset = y * rowSize;
for (int x = 0; x < rowSize; x++) {
row.setBulk(x * 32, bits[offset + x]);
row.setBulk(x << 5, bits[offset + x]);
}
return row;
}

View file

@ -17,14 +17,13 @@
package com.google.zxing.common;
import com.google.zxing.ReaderException;
import com.google.zxing.BinaryBitmap;
/**
* @author Sean Owen
*/
public final class DefaultGridSampler extends GridSampler {
public BitMatrix sampleGrid(BinaryBitmap image,
public BitMatrix sampleGrid(BitMatrix image,
int dimension,
float p1ToX, float p1ToY,
float p2ToX, float p2ToY,
@ -50,11 +49,11 @@ public final class DefaultGridSampler extends GridSampler {
}
transform.transformPoints(points);
// Quick check to see if points transformed to something inside the image;
// sufficent to check the endpoints
// sufficient to check the endpoints
checkAndNudgePoints(image, points);
try {
for (int j = 0; j < max; j += 2) {
if (image.isBlack((int) points[j], (int) points[j + 1])) {
if (image.get((int) points[j], (int) points[j + 1])) {
// Black(-ish) pixel
bits.set(j >> 1, i);
}

View file

@ -16,7 +16,6 @@
package com.google.zxing.common;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ReaderException;
/**
@ -82,7 +81,7 @@ public abstract class GridSampler {
* @throws ReaderException if image can't be sampled, for example, if the transformation defined
* by the given points is invalid or results in sampling outside the image boundaries
*/
public abstract BitMatrix sampleGrid(BinaryBitmap image,
public abstract BitMatrix sampleGrid(BitMatrix image,
int dimension,
float p1ToX, float p1ToY,
float p2ToX, float p2ToY,
@ -108,7 +107,7 @@ public abstract class GridSampler {
* @param points actual points in x1,y1,...,xn,yn form
* @throws ReaderException if an endpoint is lies outside the image boundaries
*/
protected static void checkAndNudgePoints(BinaryBitmap image, float[] points)
protected static void checkAndNudgePoints(BitMatrix image, float[] points)
throws ReaderException {
int width = image.getWidth();
int height = image.getHeight();

View file

@ -16,10 +16,10 @@
package com.google.zxing.common.detector;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.BitMatrix;
/**
* <p>A somewhat generic detector that looks for a barcode-like rectangular region within an image.
@ -32,9 +32,9 @@ public final class MonochromeRectangleDetector {
private static final int MAX_MODULES = 32;
private final BinaryBitmap image;
private final BitMatrix image;
public MonochromeRectangleDetector(BinaryBitmap image) {
public MonochromeRectangleDetector(BitMatrix image) {
this.image = image;
}
@ -160,24 +160,20 @@ public final class MonochromeRectangleDetector {
* (e.g. only white was found)
*/
private int[] blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,
boolean horizontal) throws ReaderException {
boolean horizontal) {
int center = (minDim + maxDim) >> 1;
BitArray rowOrColumn = horizontal ?
image.getBlackRow(fixedDimension, null, 0, image.getWidth()) :
image.getBlackColumn(fixedDimension, null, 0, image.getHeight());
// Scan left/up first
int start = center;
while (start >= minDim) {
if (rowOrColumn.get(start)) {
if (horizontal ? image.get(start, fixedDimension) : image.get(fixedDimension, start)) {
start--;
} else {
int whiteRunStart = start;
do {
start--;
} while (start >= minDim && !rowOrColumn.get(start));
} while (start >= minDim && !(horizontal ? image.get(start, fixedDimension) : image.get(fixedDimension, start)));
int whiteRunSize = whiteRunStart - start;
if (start < minDim || whiteRunSize > maxWhiteRun) {
start = whiteRunStart;
@ -190,13 +186,13 @@ public final class MonochromeRectangleDetector {
// Then try right/down
int end = center;
while (end < maxDim) {
if (rowOrColumn.get(end)) {
if (horizontal ? image.get(end, fixedDimension) : image.get(fixedDimension, end)) {
end++;
} else {
int whiteRunStart = end;
do {
end++;
} while (end < maxDim && !rowOrColumn.get(end));
} while (end < maxDim && !(horizontal ? image.get(end, fixedDimension) : image.get(fixedDimension, end)));
int whiteRunSize = end - whiteRunStart;
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
end = whiteRunStart;

View file

@ -24,7 +24,6 @@ import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.ResultMetadataType;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DecoderResult;
import com.google.zxing.common.DetectorResult;
@ -59,11 +58,11 @@ public final class DataMatrixReader implements Reader {
DecoderResult decoderResult;
ResultPoint[] points;
if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {
BitMatrix bits = extractPureBits(image);
BitMatrix bits = extractPureBits(image.getBlackMatrix());
decoderResult = decoder.decode(bits);
points = NO_POINTS;
} else {
DetectorResult detectorResult = new Detector(image).detect();
DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
decoderResult = decoder.decode(detectorResult.getBits());
points = detectorResult.getPoints();
}
@ -80,7 +79,7 @@ public final class DataMatrixReader implements Reader {
* around it. This is a specialized method that works exceptionally fast in this special
* case.
*/
private static BitMatrix extractPureBits(BinaryBitmap image) throws ReaderException {
private static BitMatrix extractPureBits(BitMatrix image) throws ReaderException {
// Now need to determine module size in pixels
int height = image.getHeight();
@ -89,7 +88,7 @@ public final class DataMatrixReader implements Reader {
// First, skip white border by tracking diagonally from the top left down and to the right:
int borderWidth = 0;
while (borderWidth < minDimension && !image.isBlack(borderWidth, borderWidth)) {
while (borderWidth < minDimension && !image.get(borderWidth, borderWidth)) {
borderWidth++;
}
if (borderWidth == minDimension) {
@ -98,7 +97,7 @@ public final class DataMatrixReader implements Reader {
// And then keep tracking across the top-left black module to determine module size
int moduleEnd = borderWidth + 1;
while (moduleEnd < width && image.isBlack(moduleEnd, borderWidth)) {
while (moduleEnd < width && image.get(moduleEnd, borderWidth)) {
moduleEnd++;
}
if (moduleEnd == width) {
@ -109,7 +108,7 @@ public final class DataMatrixReader implements Reader {
// And now find where the bottommost black module on the first column ends
int columnEndOfSymbol = height - 1;
while (columnEndOfSymbol >= 0 && !image.isBlack(borderWidth, columnEndOfSymbol)) {
while (columnEndOfSymbol >= 0 && !image.get(borderWidth, columnEndOfSymbol)) {
columnEndOfSymbol--;
}
if (columnEndOfSymbol < 0) {
@ -138,7 +137,7 @@ public final class DataMatrixReader implements Reader {
for (int i = 0; i < dimension; i++) {
int iOffset = borderWidth + i * moduleSize;
for (int j = 0; j < dimension; j++) {
if (image.isBlack(borderWidth + j * moduleSize, iOffset)) {
if (image.get(borderWidth + j * moduleSize, iOffset)) {
bits.set(j, i);
}
}

View file

@ -16,10 +16,8 @@
package com.google.zxing.datamatrix.detector;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.Collections;
import com.google.zxing.common.Comparator;
@ -46,10 +44,10 @@ public final class Detector {
private static final Integer[] INTEGERS =
{ new Integer(0), new Integer(1), new Integer(2), new Integer(3), new Integer(4) };
private final BinaryBitmap image;
private final BitMatrix image;
private final MonochromeRectangleDetector rectangleDetector;
public Detector(BinaryBitmap image) {
public Detector(BitMatrix image) {
this.image = image;
rectangleDetector = new MonochromeRectangleDetector(image);
}
@ -166,7 +164,7 @@ public final class Detector {
table.put(key, value == null ? INTEGERS[1] : INTEGERS[value.intValue() + 1]);
}
private static BitMatrix sampleGrid(BinaryBitmap image,
private static BitMatrix sampleGrid(BitMatrix image,
ResultPoint topLeft,
ResultPoint bottomLeft,
ResultPoint bottomRight,
@ -228,9 +226,9 @@ public final class Detector {
int ystep = fromY < toY ? 1 : -1;
int xstep = fromX < toX ? 1 : -1;
int transitions = 0;
boolean inBlack = image.isBlack(steep ? fromY : fromX, steep ? fromX : fromY);
boolean inBlack = image.get(steep ? fromY : fromX, steep ? fromX : fromY);
for (int x = fromX, y = fromY; x != toX; x += xstep) {
boolean isBlack = image.isBlack(steep ? y : x, steep ? x : y);
boolean isBlack = image.get(steep ? y : x, steep ? x : y);
if (isBlack != inBlack) {
transitions++;
inBlack = isBlack;

View file

@ -47,7 +47,7 @@ public final class QRCodeMultiReader extends QRCodeReader implements MultipleBar
public Result[] decodeMultiple(BinaryBitmap image, Hashtable hints) throws ReaderException {
Vector results = new Vector();
DetectorResult[] detectorResult = new MultiDetector(image).detectMulti(hints);
DetectorResult[] detectorResult = new MultiDetector(image.getBlackMatrix()).detectMulti(hints);
for (int i = 0; i < detectorResult.length; i++) {
try {
DecoderResult decoderResult = getDecoder().decode(detectorResult[i].getBits());

View file

@ -16,9 +16,9 @@
package com.google.zxing.multi.qrcode.detector;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ReaderException;
import com.google.zxing.common.DetectorResult;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.detector.Detector;
import com.google.zxing.qrcode.detector.FinderPatternInfo;
@ -36,12 +36,12 @@ public final class MultiDetector extends Detector {
private static final DetectorResult[] EMPTY_DETECTOR_RESULTS = new DetectorResult[0];
public MultiDetector(BinaryBitmap image) {
public MultiDetector(BitMatrix image) {
super(image);
}
public DetectorResult[] detectMulti(Hashtable hints) throws ReaderException {
BinaryBitmap image = getImage();
BitMatrix image = getImage();
MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image);
FinderPatternInfo[] info = finder.findMulti(hints);

View file

@ -17,12 +17,11 @@
package com.google.zxing.multi.qrcode.detector;
import com.google.zxing.DecodeHintType;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.Collections;
import com.google.zxing.common.Comparator;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.detector.FinderPattern;
import com.google.zxing.qrcode.detector.FinderPatternFinder;
import com.google.zxing.qrcode.detector.FinderPatternInfo;
@ -87,7 +86,7 @@ final class MultiFinderPatternFinder extends FinderPatternFinder {
*
* @param image image to search
*/
MultiFinderPatternFinder(BinaryBitmap image) {
MultiFinderPatternFinder(BitMatrix image) {
super(image);
}
@ -228,7 +227,7 @@ final class MultiFinderPatternFinder extends FinderPatternFinder {
public FinderPatternInfo[] findMulti(Hashtable hints) throws ReaderException {
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
BinaryBitmap image = getImage();
BitMatrix image = getImage();
int maxI = image.getHeight();
int maxJ = image.getWidth();
// We are looking for black/white/black/white/black modules in
@ -245,10 +244,7 @@ final class MultiFinderPatternFinder extends FinderPatternFinder {
int[] stateCount = new int[5];
for (int i = iSkip - 1; i < maxI; i += iSkip) {
BitArray blackRow = new BitArray(maxJ);
// Get a row of black/white values
blackRow = image.getBlackRow(i, blackRow, 0, maxJ);
stateCount[0] = 0;
stateCount[1] = 0;
stateCount[2] = 0;
@ -256,7 +252,7 @@ final class MultiFinderPatternFinder extends FinderPatternFinder {
stateCount[4] = 0;
int currentState = 0;
for (int j = 0; j < maxJ; j++) {
if (blackRow.get(j)) {
if (image.get(j, i)) {
// Black pixel
if ((currentState & 1) == 1) { // Counting white pixels
currentState++;
@ -270,7 +266,7 @@ final class MultiFinderPatternFinder extends FinderPatternFinder {
if (!confirmed) {
do { // Advance to next black pixel
j++;
} while (j < maxJ && !blackRow.get(j));
} while (j < maxJ && !image.get(j, i));
j--; // back up to that last white pixel
}
// Clear state to start looking again

View file

@ -62,11 +62,11 @@ public class QRCodeReader implements Reader {
DecoderResult decoderResult;
ResultPoint[] points;
if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {
BitMatrix bits = extractPureBits(image);
BitMatrix bits = extractPureBits(image.getBlackMatrix());
decoderResult = decoder.decode(bits);
points = NO_POINTS;
} else {
DetectorResult detectorResult = new Detector(image).detect(hints);
DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(hints);
decoderResult = decoder.decode(detectorResult.getBits());
points = detectorResult.getPoints();
}
@ -84,7 +84,7 @@ public class QRCodeReader implements Reader {
* around it. This is a specialized method that works exceptionally fast in this special
* case.
*/
private static BitMatrix extractPureBits(BinaryBitmap image) throws ReaderException {
private static BitMatrix extractPureBits(BitMatrix image) throws ReaderException {
// Now need to determine module size in pixels
int height = image.getHeight();
@ -93,7 +93,7 @@ public class QRCodeReader implements Reader {
// First, skip white border by tracking diagonally from the top left down and to the right:
int borderWidth = 0;
while (borderWidth < minDimension && !image.isBlack(borderWidth, borderWidth)) {
while (borderWidth < minDimension && !image.get(borderWidth, borderWidth)) {
borderWidth++;
}
if (borderWidth == minDimension) {
@ -102,7 +102,7 @@ public class QRCodeReader implements Reader {
// And then keep tracking across the top-left black module to determine module size
int moduleEnd = borderWidth;
while (moduleEnd < minDimension && image.isBlack(moduleEnd, moduleEnd)) {
while (moduleEnd < minDimension && image.get(moduleEnd, moduleEnd)) {
moduleEnd++;
}
if (moduleEnd == minDimension) {
@ -113,7 +113,7 @@ public class QRCodeReader implements Reader {
// And now find where the rightmost black module on the first row ends
int rowEndOfSymbol = width - 1;
while (rowEndOfSymbol >= 0 && !image.isBlack(rowEndOfSymbol, borderWidth)) {
while (rowEndOfSymbol >= 0 && !image.get(rowEndOfSymbol, borderWidth)) {
rowEndOfSymbol--;
}
if (rowEndOfSymbol < 0) {
@ -142,7 +142,7 @@ public class QRCodeReader implements Reader {
for (int i = 0; i < dimension; i++) {
int iOffset = borderWidth + i * moduleSize;
for (int j = 0; j < dimension; j++) {
if (image.isBlack(borderWidth + j * moduleSize, iOffset)) {
if (image.get(borderWidth + j * moduleSize, iOffset)) {
bits.set(j, i);
}
}

View file

@ -17,8 +17,7 @@
package com.google.zxing.qrcode.detector;
import com.google.zxing.ReaderException;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.BitMatrix;
import java.util.Vector;
@ -38,7 +37,7 @@ import java.util.Vector;
*/
final class AlignmentPatternFinder {
private final BinaryBitmap image;
private final BitMatrix image;
private final Vector possibleCenters;
private final int startX;
private final int startY;
@ -57,7 +56,7 @@ final class AlignmentPatternFinder {
* @param height height of region to search
* @param moduleSize estimated module size so far
*/
AlignmentPatternFinder(BinaryBitmap image,
AlignmentPatternFinder(BitMatrix image,
int startX,
int startY,
int width,
@ -85,14 +84,12 @@ final class AlignmentPatternFinder {
int height = this.height;
int maxJ = startX + width;
int middleI = startY + (height >> 1);
BitArray luminanceRow = new BitArray(width);
// We are looking for black/white/black modules in 1:1:1 ratio;
// this tracks the number of black/white/black modules seen so far
int[] stateCount = new int[3];
for (int iGen = 0; iGen < height; iGen++) {
// Search from middle outwards
int i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
luminanceRow = image.getBlackRow(i, luminanceRow, startX, width);
stateCount[0] = 0;
stateCount[1] = 0;
stateCount[2] = 0;
@ -100,12 +97,12 @@ final class AlignmentPatternFinder {
// Burn off leading white pixels before anything else; if we start in the middle of
// a white run, it doesn't make sense to count its length, since we don't know if the
// white run continued to the left of the start point
while (j < maxJ && !luminanceRow.get(j - startX)) {
while (j < maxJ && !image.get(j, i)) {
j++;
}
int currentState = 0;
while (j < maxJ) {
if (luminanceRow.get(j - startX)) {
if (image.get(j, i)) {
// Black pixel
if (currentState == 1) { // Counting black pixels
stateCount[currentState]++;
@ -187,8 +184,8 @@ final class AlignmentPatternFinder {
* @return vertical center of alignment pattern, or {@link Float#NaN} if not found
*/
private float crossCheckVertical(int startI, int centerJ, int maxCount,
int originalStateCountTotal) throws ReaderException {
BinaryBitmap image = this.image;
int originalStateCountTotal) {
BitMatrix image = this.image;
int maxI = image.getHeight();
int[] stateCount = crossCheckStateCount;
@ -198,7 +195,7 @@ final class AlignmentPatternFinder {
// Start counting up from center
int i = startI;
while (i >= 0 && image.isBlack(centerJ, i) && stateCount[1] <= maxCount) {
while (i >= 0 && image.get(centerJ, i) && stateCount[1] <= maxCount) {
stateCount[1]++;
i--;
}
@ -206,7 +203,7 @@ final class AlignmentPatternFinder {
if (i < 0 || stateCount[1] > maxCount) {
return Float.NaN;
}
while (i >= 0 && !image.isBlack(centerJ, i) && stateCount[0] <= maxCount) {
while (i >= 0 && !image.get(centerJ, i) && stateCount[0] <= maxCount) {
stateCount[0]++;
i--;
}
@ -216,14 +213,14 @@ final class AlignmentPatternFinder {
// Now also count down from center
i = startI + 1;
while (i < maxI && image.isBlack(centerJ, i) && stateCount[1] <= maxCount) {
while (i < maxI && image.get(centerJ, i) && stateCount[1] <= maxCount) {
stateCount[1]++;
i++;
}
if (i == maxI || stateCount[1] > maxCount) {
return Float.NaN;
}
while (i < maxI && !image.isBlack(centerJ, i) && stateCount[2] <= maxCount) {
while (i < maxI && !image.get(centerJ, i) && stateCount[2] <= maxCount) {
stateCount[2]++;
i++;
}
@ -250,8 +247,7 @@ final class AlignmentPatternFinder {
* @param j end of possible alignment pattern in row
* @return {@link AlignmentPattern} if we have found the same pattern twice, or null if not
*/
private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j)
throws ReaderException {
private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) {
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
float centerJ = centerFromEnd(stateCount, j);
float centerI = crossCheckVertical(i, (int) centerJ, 2 * stateCount[1], stateCountTotal);

View file

@ -18,7 +18,6 @@ package com.google.zxing.qrcode.detector;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DetectorResult;
import com.google.zxing.common.GridSampler;
@ -34,13 +33,13 @@ import java.util.Hashtable;
*/
public class Detector {
private final BinaryBitmap image;
private final BitMatrix image;
public Detector(BinaryBitmap image) {
public Detector(BitMatrix image) {
this.image = image;
}
protected BinaryBitmap getImage() {
protected BitMatrix getImage() {
return image;
}
@ -63,7 +62,6 @@ public class Detector {
*/
public DetectorResult detect(Hashtable hints) throws ReaderException {
BinaryBitmap image = this.image;
FinderPatternFinder finder = new FinderPatternFinder(image);
FinderPatternInfo info = finder.find(hints);
@ -124,7 +122,7 @@ public class Detector {
return new DetectorResult(bits, points);
}
private static BitMatrix sampleGrid(BinaryBitmap image,
private static BitMatrix sampleGrid(BitMatrix image,
ResultPoint topLeft,
ResultPoint topRight,
ResultPoint bottomLeft,
@ -209,8 +207,7 @@ public class Detector {
* {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
* width of each, measuring along the axis between their centers.</p>
*/
private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern)
throws ReaderException {
private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern) {
float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int) pattern.getX(),
(int) pattern.getY(),
(int) otherPattern.getX(),
@ -235,8 +232,7 @@ public class Detector {
* a finder pattern by looking for a black-white-black run from the center in the direction
* of another point (another finder pattern center), and in the opposite direction too.</p>
*/
private float sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY)
throws ReaderException {
private float sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY) {
float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
@ -267,8 +263,7 @@ public class Detector {
* <p>This is used when figuring out how wide a finder pattern is, when the finder pattern
* may be skewed or rotated.</p>
*/
private float sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY)
throws ReaderException {
private float sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) {
// Mild variant of Bresenham's algorithm;
// see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
boolean steep = Math.abs(toY - fromY) > Math.abs(toX - fromX);
@ -292,11 +287,11 @@ public class Detector {
int realX = steep ? y : x;
int realY = steep ? x : y;
if (state == 1) { // In white pixels, looking for black
if (image.isBlack(realX, realY)) {
if (image.get(realX, realY)) {
state++;
}
} else {
if (!image.isBlack(realX, realY)) {
if (!image.get(realX, realY)) {
state++;
}
}

View file

@ -16,13 +16,12 @@
package com.google.zxing.qrcode.detector;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.Collections;
import com.google.zxing.common.Comparator;
import com.google.zxing.common.BitMatrix;
import java.util.Hashtable;
import java.util.Vector;
@ -42,7 +41,7 @@ public class FinderPatternFinder {
protected static final int MAX_MODULES = 57; // support up to version 10 for mobile clients
private static final int INTEGER_MATH_SHIFT = 8;
private final BinaryBitmap image;
private final BitMatrix image;
private final Vector possibleCenters;
private boolean hasSkipped;
private final int[] crossCheckStateCount;
@ -52,13 +51,13 @@ public class FinderPatternFinder {
*
* @param image image to search
*/
public FinderPatternFinder(BinaryBitmap image) {
public FinderPatternFinder(BitMatrix image) {
this.image = image;
this.possibleCenters = new Vector();
this.crossCheckStateCount = new int[5];
}
protected BinaryBitmap getImage() {
protected BitMatrix getImage() {
return image;
}
@ -84,10 +83,8 @@ public class FinderPatternFinder {
boolean done = false;
int[] stateCount = new int[5];
BitArray blackRow = new BitArray(maxJ);
for (int i = iSkip - 1; i < maxI && !done; i += iSkip) {
// Get a row of black/white values
blackRow = image.getBlackRow(i, blackRow, 0, maxJ);
stateCount[0] = 0;
stateCount[1] = 0;
stateCount[2] = 0;
@ -95,7 +92,7 @@ public class FinderPatternFinder {
stateCount[4] = 0;
int currentState = 0;
for (int j = 0; j < maxJ; j++) {
if (blackRow.get(j)) {
if (image.get(j, i)) {
// Black pixel
if ((currentState & 1) == 1) { // Counting white pixels
currentState++;
@ -131,7 +128,7 @@ public class FinderPatternFinder {
// Advance to next black pixel
do {
j++;
} while (j < maxJ && !blackRow.get(j));
} while (j < maxJ && !image.get(j, i));
j--; // back up to that last white pixel
}
// Clear state to start looking again
@ -231,22 +228,22 @@ public class FinderPatternFinder {
* @return vertical center of finder pattern, or {@link Float#NaN} if not found
*/
private float crossCheckVertical(int startI, int centerJ, int maxCount,
int originalStateCountTotal) throws ReaderException {
BinaryBitmap image = this.image;
int originalStateCountTotal) {
BitMatrix image = this.image;
int maxI = image.getHeight();
int[] stateCount = getCrossCheckStateCount();
// Start counting up from center
int i = startI;
while (i >= 0 && image.isBlack(centerJ, i)) {
while (i >= 0 && image.get(centerJ, i)) {
stateCount[2]++;
i--;
}
if (i < 0) {
return Float.NaN;
}
while (i >= 0 && !image.isBlack(centerJ, i) && stateCount[1] <= maxCount) {
while (i >= 0 && !image.get(centerJ, i) && stateCount[1] <= maxCount) {
stateCount[1]++;
i--;
}
@ -254,7 +251,7 @@ public class FinderPatternFinder {
if (i < 0 || stateCount[1] > maxCount) {
return Float.NaN;
}
while (i >= 0 && image.isBlack(centerJ, i) && stateCount[0] <= maxCount) {
while (i >= 0 && image.get(centerJ, i) && stateCount[0] <= maxCount) {
stateCount[0]++;
i--;
}
@ -264,21 +261,21 @@ public class FinderPatternFinder {
// Now also count down from center
i = startI + 1;
while (i < maxI && image.isBlack(centerJ, i)) {
while (i < maxI && image.get(centerJ, i)) {
stateCount[2]++;
i++;
}
if (i == maxI) {
return Float.NaN;
}
while (i < maxI && !image.isBlack(centerJ, i) && stateCount[3] < maxCount) {
while (i < maxI && !image.get(centerJ, i) && stateCount[3] < maxCount) {
stateCount[3]++;
i++;
}
if (i == maxI || stateCount[3] >= maxCount) {
return Float.NaN;
}
while (i < maxI && image.isBlack(centerJ, i) && stateCount[4] < maxCount) {
while (i < maxI && image.get(centerJ, i) && stateCount[4] < maxCount) {
stateCount[4]++;
i++;
}
@ -303,28 +300,28 @@ public class FinderPatternFinder {
* check a vertical cross check and locate the real center of the alignment pattern.</p>
*/
private float crossCheckHorizontal(int startJ, int centerI, int maxCount,
int originalStateCountTotal) throws ReaderException {
BinaryBitmap image = this.image;
int originalStateCountTotal) {
BitMatrix image = this.image;
int maxJ = image.getWidth();
int[] stateCount = getCrossCheckStateCount();
int j = startJ;
while (j >= 0 && image.isBlack(j, centerI)) {
while (j >= 0 && image.get(j, centerI)) {
stateCount[2]++;
j--;
}
if (j < 0) {
return Float.NaN;
}
while (j >= 0 && !image.isBlack(j, centerI) && stateCount[1] <= maxCount) {
while (j >= 0 && !image.get(j, centerI) && stateCount[1] <= maxCount) {
stateCount[1]++;
j--;
}
if (j < 0 || stateCount[1] > maxCount) {
return Float.NaN;
}
while (j >= 0 && image.isBlack(j, centerI) && stateCount[0] <= maxCount) {
while (j >= 0 && image.get(j, centerI) && stateCount[0] <= maxCount) {
stateCount[0]++;
j--;
}
@ -333,21 +330,21 @@ public class FinderPatternFinder {
}
j = startJ + 1;
while (j < maxJ && image.isBlack(j, centerI)) {
while (j < maxJ && image.get(j, centerI)) {
stateCount[2]++;
j++;
}
if (j == maxJ) {
return Float.NaN;
}
while (j < maxJ && !image.isBlack(j, centerI) && stateCount[3] < maxCount) {
while (j < maxJ && !image.get(j, centerI) && stateCount[3] < maxCount) {
stateCount[3]++;
j++;
}
if (j == maxJ || stateCount[3] >= maxCount) {
return Float.NaN;
}
while (j < maxJ && image.isBlack(j, centerI) && stateCount[4] < maxCount) {
while (j < maxJ && image.get(j, centerI) && stateCount[4] < maxCount) {
stateCount[4]++;
j++;
}