Add column caching to MonochromeBitmapSources and use it to improve Data Matrix speed

git-svn-id: https://zxing.googlecode.com/svn/trunk@631 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-10-22 08:43:56 +00:00
parent 15deb0c3d9
commit 96f6428eea
7 changed files with 74 additions and 6 deletions

View file

@ -72,6 +72,10 @@ final class YUVMonochromeBitmapSource extends BaseMonochromeBitmapSource {
}
public void cacheColumnForLuminance(int x) {
}
/**
* Create a greyscale Android Bitmap from the YUV data based on the crop rectangle.
*

View file

@ -74,4 +74,8 @@ public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSo
// do nothing; we are already forced to cache all pixels
}
public void cacheColumnForLuminance(int x) {
// do nothing
}
}

View file

@ -48,6 +48,11 @@ public interface MonochromeBitmapSource {
*/
BitArray getBlackRow(int y, BitArray row, int startX, int getWidth);
/**
* Entirely analogous to {@link #getBlackRow(int, BitArray, int, int)} but gets a column.
*/
BitArray getBlackColumn(int x, BitArray column, int startY, int getHeight);
/**
* @return height of underlying image
*/
@ -76,6 +81,11 @@ public interface MonochromeBitmapSource {
*/
void cacheRowForLuminance(int y);
/**
* Entirely analogous to {@link #cacheRowForLuminance(int)} but caches a column.
*/
void cacheColumnForLuminance(int x);
/**
* <p>Estimates black point according to the given method, which is optionally parameterized by
* a single int argument. For {@link BlackPointEstimationMethod#ROW_SAMPLING}, this

View file

@ -76,6 +76,23 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
return row;
}
public BitArray getBlackColumn(int x, BitArray column, int startY, int getHeight) {
if (column == null || column.getSize() < getHeight) {
column = new BitArray(getHeight);
} else {
column.clear();
}
cacheColumnForLuminance(x);
// We don't handle "row sampling" specially here
for (int y = 0; y < getHeight; y++) {
if (getLuminance(x, startY + y) < blackPoint) {
column.set(y);
}
}
return column;
}
public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) throws ReaderException {
if (!method.equals(lastMethod) || argument != lastArgument) {
int width = getWidth();
@ -131,4 +148,6 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
public abstract void cacheRowForLuminance(int y);
public abstract void cacheColumnForLuminance(int x);
}

View file

@ -20,6 +20,7 @@ import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.BlackPointEstimationMethod;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.Collections;
import com.google.zxing.common.Comparator;
@ -262,17 +263,19 @@ public final class Detector {
int center = (minDim + maxDim) / 2;
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 (horizontal ? image.isBlack(start, fixedDimension) : image.isBlack(fixedDimension, start)) {
if (rowOrColumn.get(start)) {
start--;
} else {
int whiteRunStart = start;
do {
start--;
} while (start >= minDim &&
!(horizontal ? image.isBlack(start, fixedDimension) : image.isBlack(fixedDimension, start)));
} while (start >= minDim && !rowOrColumn.get(start));
int whiteRunSize = whiteRunStart - start;
if (start < minDim || whiteRunSize > maxWhiteRun) {
start = whiteRunStart + 1; // back up
@ -284,14 +287,13 @@ public final class Detector {
// Then try right/down
int end = center;
while (end < maxDim) {
if (horizontal ? image.isBlack(end, fixedDimension) : image.isBlack(fixedDimension, end)) {
if (rowOrColumn.get(end)) {
end++;
} else {
int whiteRunStart = end;
do {
end++;
} while (end < maxDim &&
!(horizontal ? image.isBlack(end, fixedDimension) : image.isBlack(fixedDimension, end)));
} while (end < maxDim && !rowOrColumn.get(end));
int whiteRunSize = end - whiteRunStart;
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
end = whiteRunStart - 1;

View file

@ -32,16 +32,20 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
private final int width;
// For why this isn't final, see below
private int[] rgbRow;
private int[] rgbColumn;
private final int[] pixelHolder;
private int cachedRow;
private int cachedColumn;
public LCDUIImageMonochromeBitmapSource(Image image) {
this.image = image;
height = image.getHeight();
width = image.getWidth();
rgbRow = new int[width];
rgbColumn = new int[height];
pixelHolder = new int[1];
cachedRow = -1;
cachedColumn = -1;
}
public int getHeight() {
@ -61,6 +65,8 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
int pixel;
if (cachedRow == y && rgbRow.length == width) {
pixel = rgbRow[x];
} else if (cachedColumn == x && rgbColumn.length == height) {
pixel = rgbColumn[y];
} else {
image.getRGB(pixelHolder, 0, width, x, y, 1, 1);
pixel = pixelHolder[0];
@ -94,4 +100,14 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
}
}
public void cacheColumnForLuminance(int x) {
if (x != cachedColumn) {
if (rgbColumn.length != height) {
rgbColumn = new int[height];
}
image.getRGB(rgbColumn, 0, 1, x, 0, 1, height);
cachedColumn = x;
}
}
}

View file

@ -43,7 +43,9 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
private final int width;
private final int height;
private int[] rgbRow;
private int[] rgbColumn;
private int cachedRow;
private int cachedColumn;
/**
* Creates an instance that uses the entire given image as a source of pixels to decode.
@ -78,7 +80,9 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
this.width = right - left;
this.height = bottom - top;
rgbRow = new int[width];
rgbColumn = new int[height];
cachedRow = -1;
cachedColumn = -1;
}
/**
@ -136,6 +140,8 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
int pixel;
if (cachedRow == y) {
pixel = rgbRow[x];
} else if (cachedColumn == x) {
pixel = rgbColumn[y];
} else {
pixel = image.getRGB(left + x, top + y);
}
@ -153,4 +159,11 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
}
}
public void cacheColumnForLuminance(int x) {
if (x != cachedColumn) {
image.getRGB(left + x, top, 1, height, rgbColumn, 0, 1);
cachedColumn = x;
}
}
}