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;
* <p>Encapsulates logic that can detect a Data Matrix Code in an image, even if the Data Matrix Code
* is rotated or skewed, or partially obscured.</p>
*
- * @author srowen@google.com (Sean Owen)
+ * @author Sean Owen
*/
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);
}
}
+ if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null) {
+ throw ReaderException.getInstance();
+ }
+
// Bottom left is correct but top left and bottom right might be switched
- ResultPoint[] corners = new ResultPoint[] { maybeTopLeft, bottomLeft, maybeBottomRight };
+ ResultPoint[] corners = { maybeTopLeft, bottomLeft, maybeBottomRight };
// Use the dot product trick to sort them out
GenericResultPoint.orderBestPatterns(corners);
}
if (range == null) {
if (lastRange == null) {
- throw new ReaderException("Center of image not within barcode");
+ throw ReaderException.getInstance();
}
// lastRange was found
if (dj == 0) {
}
lastRange = range;
}
- throw new ReaderException("Couldn't find an end to barcode");
+ throw ReaderException.getInstance();
}
/**
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
}
}
}
+ start++;
// 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;
}
}
}
+ end--;
if (end > start) {
return new int[] { start, end };