From 7f06b18976a990c1fff47e5e88a041796ff66dbd Mon Sep 17 00:00:00 2001 From: srowen Date: Fri, 10 Jun 2011 08:43:38 +0000 Subject: [PATCH] Rationalize the black-run counting to avoid AIOOBE but also get the right answer still git-svn-id: https://zxing.googlecode.com/svn/trunk@1820 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../zxing/qrcode/detector/Detector.java | 93 +++++++++---------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/core/src/com/google/zxing/qrcode/detector/Detector.java b/core/src/com/google/zxing/qrcode/detector/Detector.java index 724d39d59..070d85a83 100644 --- a/core/src/com/google/zxing/qrcode/detector/Detector.java +++ b/core/src/com/google/zxing/qrcode/detector/Detector.java @@ -256,33 +256,35 @@ public class Detector { */ private float sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY) { - float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY); + float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY); - // Now count other way -- don't run off image though of course - float scale = 1.0f; - int otherToX = fromX - (toX - fromX); - if (otherToX < 0) { - scale = (float) fromX / (float) (fromX - otherToX); - otherToX = 0; - } else if (otherToX > image.getWidth()) { - scale = (float) (image.getWidth() - fromX) / (float) (otherToX - fromX); - otherToX = image.getWidth(); - } - int otherToY = (int) (fromY - (toY - fromY) * scale); + // Now count other way -- don't run off image though of course + float scale = 1.0f; + int otherToX = fromX - (toX - fromX); + if (otherToX < 0) { + scale = (float) fromX / (float) (fromX - otherToX); + otherToX = 0; + } else if (otherToX >= image.getWidth()) { + scale = (float) (image.getWidth() - 1 - fromX) / (float) (otherToX - fromX); + otherToX = image.getWidth() - 1; + } + int otherToY = (int) (fromY - (toY - fromY) * scale); - scale = 1.0f; - if (otherToY < 0) { - scale = (float) fromY / (float) (fromY - otherToY); - otherToY = 0; - } else if (otherToY > image.getHeight()) { - scale = (float) (image.getHeight() - fromY) / (float) (otherToY - fromY); - otherToY = image.getHeight(); - } - otherToX = (int) (fromX + (otherToX - fromX) * scale); + scale = 1.0f; + if (otherToY < 0) { + scale = (float) fromY / (float) (fromY - otherToY); + otherToY = 0; + } else if (otherToY >= image.getHeight()) { + scale = (float) (image.getHeight() - 1 - fromY) / (float) (otherToY - fromY); + otherToY = image.getHeight() - 1; + } + otherToX = (int) (fromX + (otherToX - fromX) * scale); - result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY); - return result; - } + result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY); + + // Middle pixel is double-counted this way; subtract 1 + return result - 1.0f; + } /** *

This method traces a line from a point in the image, in the direction towards another point. @@ -313,32 +315,22 @@ public class Detector { // In black pixels, looking for white, first or second time. int state = 0; - for (int x = fromX, y = fromY; x != toX; x += xstep) { + // Loop up until x == toX, but not beyond + int xLimit = toX + xstep; + for (int x = fromX, y = fromY; x != xLimit; x += xstep) { int realX = steep ? y : x; int realY = steep ? x : y; - // In white pixels, looking for black. - // FIXME(dswitkin): This method seems to assume square images, which can cause these calls to - // BitMatrix.get() to throw ArrayIndexOutOfBoundsException. - if (state == 1) { - if (image.get(realX, realY)) { - state++; - } - } else { - if (!image.get(realX, realY)) { - state++; + // Does current pixel mean we have moved white to black or vice versa? + if (!(state == 1 ^ image.get(realX, realY))) { + if (state == 2) { + int diffX = x - fromX; + int diffY = y - fromY; + return (float) Math.sqrt((double) (diffX * diffX + diffY * diffY)); } + state++; } - // Found black, white, black, and stumbled back onto white, so we're done. - if (state == 3) { - int diffX = x - fromX; - int diffY = y - fromY; - if (xstep < 0) { - diffX++; - } - return (float) Math.sqrt((double) (diffX * diffX + diffY * diffY)); - } error += dy; if (error > 0) { if (y == toY) { @@ -348,9 +340,16 @@ public class Detector { error -= dx; } } - int diffX = toX - fromX; - int diffY = toY - fromY; - return (float) Math.sqrt((double) (diffX * diffX + diffY * diffY)); + // Found black-white-black; give the benefit of the doubt that the next pixel outside the image + // is "white" so this last point at (toX+xStep,toY) is the right ending. This is really a + // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this. + if (state == 2) { + int diffX = toX + xstep - fromX; + int diffY = toY - fromY; + return (float) Math.sqrt((double) (diffX * diffX + diffY * diffY)); + } + // else we didn't find even black-white-black; no estimate is really possible + return Float.NaN; } /**