From 6ed938ceb681243e6fbc7d331e96bddc25a88abb Mon Sep 17 00:00:00 2001 From: srowen Date: Wed, 22 Oct 2008 08:43:56 +0000 Subject: [PATCH] Add column caching to MonochromeBitmapSources and use it to improve Data Matrix speed git-svn-id: http://zxing.googlecode.com/svn/trunk@631 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../android/YUVMonochromeBitmapSource.java | 4 ++++ .../bug/AWTImageMonochromeBitmapSource.java | 4 ++++ .../google/zxing/MonochromeBitmapSource.java | 10 ++++++++++ .../common/BaseMonochromeBitmapSource.java | 19 +++++++++++++++++++ .../zxing/datamatrix/detector/Detector.java | 14 ++++++++------ .../LCDUIImageMonochromeBitmapSource.java | 16 ++++++++++++++++ .../BufferedImageMonochromeBitmapSource.java | 13 +++++++++++++ 7 files changed, 74 insertions(+), 6 deletions(-) diff --git a/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java b/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java index 9c0ff14c..15021b81 100755 --- a/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java +++ b/android/src/com/google/zxing/client/android/YUVMonochromeBitmapSource.java @@ -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. * diff --git a/bug/src/com/google/zxing/client/bug/AWTImageMonochromeBitmapSource.java b/bug/src/com/google/zxing/client/bug/AWTImageMonochromeBitmapSource.java index 6752cb3a..d1db8eb4 100644 --- a/bug/src/com/google/zxing/client/bug/AWTImageMonochromeBitmapSource.java +++ b/bug/src/com/google/zxing/client/bug/AWTImageMonochromeBitmapSource.java @@ -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 + } + } diff --git a/core/src/com/google/zxing/MonochromeBitmapSource.java b/core/src/com/google/zxing/MonochromeBitmapSource.java index 8dda19ec..6d3655ab 100644 --- a/core/src/com/google/zxing/MonochromeBitmapSource.java +++ b/core/src/com/google/zxing/MonochromeBitmapSource.java @@ -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); + /** *

Estimates black point according to the given method, which is optionally parameterized by * a single int argument. For {@link BlackPointEstimationMethod#ROW_SAMPLING}, this diff --git a/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java b/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java index b9de750f..dd6e5f1f 100644 --- a/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java +++ b/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java @@ -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); + } diff --git a/core/src/com/google/zxing/datamatrix/detector/Detector.java b/core/src/com/google/zxing/datamatrix/detector/Detector.java index a7549e3f..28c727e0 100644 --- a/core/src/com/google/zxing/datamatrix/detector/Detector.java +++ b/core/src/com/google/zxing/datamatrix/detector/Detector.java @@ -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; diff --git a/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java b/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java index 04d0ca39..3ee5fe06 100644 --- a/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java +++ b/javame/src/com/google/zxing/client/j2me/LCDUIImageMonochromeBitmapSource.java @@ -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; + } + } + } \ No newline at end of file diff --git a/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java b/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java index 93b0211d..8e27609d 100644 --- a/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java +++ b/javase/src/com/google/zxing/client/j2se/BufferedImageMonochromeBitmapSource.java @@ -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; + } + } + } -- 2.20.1