mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
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:
parent
15deb0c3d9
commit
96f6428eea
|
@ -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.
|
* Create a greyscale Android Bitmap from the YUV data based on the crop rectangle.
|
||||||
*
|
*
|
||||||
|
|
|
@ -74,4 +74,8 @@ public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSo
|
||||||
// do nothing; we are already forced to cache all pixels
|
// do nothing; we are already forced to cache all pixels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cacheColumnForLuminance(int x) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,11 @@ public interface MonochromeBitmapSource {
|
||||||
*/
|
*/
|
||||||
BitArray getBlackRow(int y, BitArray row, int startX, int getWidth);
|
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
|
* @return height of underlying image
|
||||||
*/
|
*/
|
||||||
|
@ -76,6 +81,11 @@ public interface MonochromeBitmapSource {
|
||||||
*/
|
*/
|
||||||
void cacheRowForLuminance(int y);
|
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
|
* <p>Estimates black point according to the given method, which is optionally parameterized by
|
||||||
* a single int argument. For {@link BlackPointEstimationMethod#ROW_SAMPLING}, this
|
* a single int argument. For {@link BlackPointEstimationMethod#ROW_SAMPLING}, this
|
||||||
|
|
|
@ -76,6 +76,23 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
|
||||||
return row;
|
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 {
|
public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) throws ReaderException {
|
||||||
if (!method.equals(lastMethod) || argument != lastArgument) {
|
if (!method.equals(lastMethod) || argument != lastArgument) {
|
||||||
int width = getWidth();
|
int width = getWidth();
|
||||||
|
@ -131,4 +148,6 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour
|
||||||
|
|
||||||
public abstract void cacheRowForLuminance(int y);
|
public abstract void cacheRowForLuminance(int y);
|
||||||
|
|
||||||
|
public abstract void cacheColumnForLuminance(int x);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.google.zxing.MonochromeBitmapSource;
|
||||||
import com.google.zxing.ReaderException;
|
import com.google.zxing.ReaderException;
|
||||||
import com.google.zxing.ResultPoint;
|
import com.google.zxing.ResultPoint;
|
||||||
import com.google.zxing.BlackPointEstimationMethod;
|
import com.google.zxing.BlackPointEstimationMethod;
|
||||||
|
import com.google.zxing.common.BitArray;
|
||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
import com.google.zxing.common.Collections;
|
import com.google.zxing.common.Collections;
|
||||||
import com.google.zxing.common.Comparator;
|
import com.google.zxing.common.Comparator;
|
||||||
|
@ -262,17 +263,19 @@ public final class Detector {
|
||||||
|
|
||||||
int center = (minDim + maxDim) / 2;
|
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
|
// Scan left/up first
|
||||||
int start = center;
|
int start = center;
|
||||||
while (start >= minDim) {
|
while (start >= minDim) {
|
||||||
if (horizontal ? image.isBlack(start, fixedDimension) : image.isBlack(fixedDimension, start)) {
|
if (rowOrColumn.get(start)) {
|
||||||
start--;
|
start--;
|
||||||
} else {
|
} else {
|
||||||
int whiteRunStart = start;
|
int whiteRunStart = start;
|
||||||
do {
|
do {
|
||||||
start--;
|
start--;
|
||||||
} while (start >= minDim &&
|
} while (start >= minDim && !rowOrColumn.get(start));
|
||||||
!(horizontal ? image.isBlack(start, fixedDimension) : image.isBlack(fixedDimension, start)));
|
|
||||||
int whiteRunSize = whiteRunStart - start;
|
int whiteRunSize = whiteRunStart - start;
|
||||||
if (start < minDim || whiteRunSize > maxWhiteRun) {
|
if (start < minDim || whiteRunSize > maxWhiteRun) {
|
||||||
start = whiteRunStart + 1; // back up
|
start = whiteRunStart + 1; // back up
|
||||||
|
@ -284,14 +287,13 @@ public final class Detector {
|
||||||
// Then try right/down
|
// Then try right/down
|
||||||
int end = center;
|
int end = center;
|
||||||
while (end < maxDim) {
|
while (end < maxDim) {
|
||||||
if (horizontal ? image.isBlack(end, fixedDimension) : image.isBlack(fixedDimension, end)) {
|
if (rowOrColumn.get(end)) {
|
||||||
end++;
|
end++;
|
||||||
} else {
|
} else {
|
||||||
int whiteRunStart = end;
|
int whiteRunStart = end;
|
||||||
do {
|
do {
|
||||||
end++;
|
end++;
|
||||||
} while (end < maxDim &&
|
} while (end < maxDim && !rowOrColumn.get(end));
|
||||||
!(horizontal ? image.isBlack(end, fixedDimension) : image.isBlack(fixedDimension, end)));
|
|
||||||
int whiteRunSize = end - whiteRunStart;
|
int whiteRunSize = end - whiteRunStart;
|
||||||
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
|
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
|
||||||
end = whiteRunStart - 1;
|
end = whiteRunStart - 1;
|
||||||
|
|
|
@ -32,16 +32,20 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
|
||||||
private final int width;
|
private final int width;
|
||||||
// For why this isn't final, see below
|
// For why this isn't final, see below
|
||||||
private int[] rgbRow;
|
private int[] rgbRow;
|
||||||
|
private int[] rgbColumn;
|
||||||
private final int[] pixelHolder;
|
private final int[] pixelHolder;
|
||||||
private int cachedRow;
|
private int cachedRow;
|
||||||
|
private int cachedColumn;
|
||||||
|
|
||||||
public LCDUIImageMonochromeBitmapSource(Image image) {
|
public LCDUIImageMonochromeBitmapSource(Image image) {
|
||||||
this.image = image;
|
this.image = image;
|
||||||
height = image.getHeight();
|
height = image.getHeight();
|
||||||
width = image.getWidth();
|
width = image.getWidth();
|
||||||
rgbRow = new int[width];
|
rgbRow = new int[width];
|
||||||
|
rgbColumn = new int[height];
|
||||||
pixelHolder = new int[1];
|
pixelHolder = new int[1];
|
||||||
cachedRow = -1;
|
cachedRow = -1;
|
||||||
|
cachedColumn = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
|
@ -61,6 +65,8 @@ public final class LCDUIImageMonochromeBitmapSource extends BaseMonochromeBitmap
|
||||||
int pixel;
|
int pixel;
|
||||||
if (cachedRow == y && rgbRow.length == width) {
|
if (cachedRow == y && rgbRow.length == width) {
|
||||||
pixel = rgbRow[x];
|
pixel = rgbRow[x];
|
||||||
|
} else if (cachedColumn == x && rgbColumn.length == height) {
|
||||||
|
pixel = rgbColumn[y];
|
||||||
} else {
|
} else {
|
||||||
image.getRGB(pixelHolder, 0, width, x, y, 1, 1);
|
image.getRGB(pixelHolder, 0, width, x, y, 1, 1);
|
||||||
pixel = pixelHolder[0];
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -43,7 +43,9 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
private int[] rgbRow;
|
private int[] rgbRow;
|
||||||
|
private int[] rgbColumn;
|
||||||
private int cachedRow;
|
private int cachedRow;
|
||||||
|
private int cachedColumn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance that uses the entire given image as a source of pixels to decode.
|
* 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.width = right - left;
|
||||||
this.height = bottom - top;
|
this.height = bottom - top;
|
||||||
rgbRow = new int[width];
|
rgbRow = new int[width];
|
||||||
|
rgbColumn = new int[height];
|
||||||
cachedRow = -1;
|
cachedRow = -1;
|
||||||
|
cachedColumn = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,6 +140,8 @@ public final class BufferedImageMonochromeBitmapSource extends BaseMonochromeBit
|
||||||
int pixel;
|
int pixel;
|
||||||
if (cachedRow == y) {
|
if (cachedRow == y) {
|
||||||
pixel = rgbRow[x];
|
pixel = rgbRow[x];
|
||||||
|
} else if (cachedColumn == x) {
|
||||||
|
pixel = rgbColumn[y];
|
||||||
} else {
|
} else {
|
||||||
pixel = image.getRGB(left + x, top + y);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue