Add column caching to MonochromeBitmapSources and use it to improve Data Matrix speed
[zxing.git] / core / src / com / google / zxing / datamatrix / detector / Detector.java
index af53b91..28c727e 100644 (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;
@@ -68,20 +69,20 @@ public final class Detector {
     int width = image.getWidth();
     int halfHeight = height >> 1;
     int halfWidth = width >> 1;
-    int iSkip = Math.max(1, height / (MAX_MODULES << 2));
-    int jSkip = Math.max(1, width / (MAX_MODULES << 2));
+    int iSkip = Math.max(1, height / (MAX_MODULES << 3));
+    int jSkip = Math.max(1, width / (MAX_MODULES << 3));
 
     int minI = 0;
     int maxI = height;
     int minJ = 0;
     int maxJ = width;
-    ResultPoint pointA = findCornerFromCenter(halfHeight, -iSkip, minI, maxI, halfWidth,      0, minJ, maxJ, halfWidth >> 2);
+    ResultPoint pointA = findCornerFromCenter(halfHeight, -iSkip, minI, maxI, halfWidth,      0, minJ, maxJ, halfWidth >> 1);
     minI = (int) pointA.getY() - 1;
-    ResultPoint pointB = findCornerFromCenter(halfHeight, 0,      minI, maxI, halfWidth, -jSkip, minJ, maxJ, halfHeight >> 2);
+    ResultPoint pointB = findCornerFromCenter(halfHeight, 0,      minI, maxI, halfWidth, -jSkip, minJ, maxJ, halfHeight >> 1);
     minJ = (int) pointB.getX() - 1;
-    ResultPoint pointC = findCornerFromCenter(halfHeight, 0,      minI, maxI, halfWidth,  jSkip, minJ, maxJ, halfHeight >> 2);
+    ResultPoint pointC = findCornerFromCenter(halfHeight, 0,      minI, maxI, halfWidth,  jSkip, minJ, maxJ, halfHeight >> 1);
     maxJ = (int) pointC.getX() + 1;
-    ResultPoint pointD = findCornerFromCenter(halfHeight,  iSkip, minI, maxI, halfWidth,      0, minJ, maxJ, halfWidth >> 2);
+    ResultPoint pointD = findCornerFromCenter(halfHeight,  iSkip, minI, maxI, halfWidth,      0, minJ, maxJ, halfWidth >> 1);
     maxI = (int) pointD.getY() + 1;
     // Go try to find point A again with better information -- might have been off at first.
     pointA = findCornerFromCenter(halfHeight, -iSkip, minI, maxI, halfWidth,      0, minJ, maxJ, halfWidth >> 2);
@@ -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;