X-Git-Url: http://git.rot13.org/?p=zxing.git;a=blobdiff_plain;f=cpp%2Fcore%2Fsrc%2Fzxing%2Fqrcode%2Fdetector%2FDetector.cpp;h=bba077f9da552c18f4e089d5be6aedf3cdd9d439;hp=9b4618895db11fe97b483a058b7b4e505160a443;hb=d59aa5593ed5a911b1141be85d1888088c21e859;hpb=269eca430e865769973f91653e23c0f1dec386a7 diff --git a/cpp/core/src/zxing/qrcode/detector/Detector.cpp b/cpp/core/src/zxing/qrcode/detector/Detector.cpp index 9b461889..bba077f9 100644 --- a/cpp/core/src/zxing/qrcode/detector/Detector.cpp +++ b/cpp/core/src/zxing/qrcode/detector/Detector.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -42,9 +43,10 @@ Ref Detector::getImage() { return image_; } -Ref Detector::detect() { - FinderPatternFinder finder(image_); - Ref info(finder.find()); +Ref Detector::detect(DecodeHints const& hints) { + callback_ = hints.getResultPointCallback(); + FinderPatternFinder finder(image_, hints.getResultPointCallback()); + Ref info(finder.find(hints)); Ref topLeft(info->getTopLeft()); Ref topRight(info->getTopRight()); @@ -176,32 +178,38 @@ float Detector::calculateModuleSizeOneWay(Ref pattern, Ref= (int)image_->getWidth()) { - otherToX = image_->getWidth(); - } - int otherToY = fromY - (toY - fromY); - if (otherToY < 0) { - otherToY = -1; - } else if (otherToY >= (int)image_->getHeight()) { - otherToY = image_->getHeight(); - } - result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY); - return result - 1.0f; // -1 because we counted the middle pixel twice + 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 > (int)image_->getWidth()) { + scale = (float) (image_->getWidth() - fromX) / (float) (otherToX - fromX); + otherToX = image_->getWidth(); + } + int otherToY = (int) (fromY - (toY - fromY) * scale); + + scale = 1.0f; + if (otherToY < 0) { + scale = (float) fromY / (float) (fromY - otherToY); + otherToY = 0; + } else if (otherToY > (int)image_->getHeight()) { + scale = (float) (image_->getHeight() - fromY) / (float) (otherToY - fromY); + otherToY = image_->getHeight(); + } + otherToX = (int) (fromX + (otherToX - fromX) * scale); + + result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY); + return result; } float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) { // Mild variant of Bresenham's algorithm; // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm - bool steep = labs(toY - fromY) > labs(toX - fromX); + bool steep = abs(toY - fromY) > abs(toX - fromX); if (steep) { int temp = fromX; fromX = fromY; @@ -211,8 +219,8 @@ float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) toY = temp; } - int dx = labs(toX - fromX); - int dy = labs(toY - fromY); + int dx = abs(toX - fromX); + int dy = abs(toY - fromY); int error = -dx >> 1; int ystep = fromY < toY ? 1 : -1; int xstep = fromX < toX ? 1 : -1; @@ -234,6 +242,9 @@ float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) if (state == 3) { // Found black, white, black, and stumbled back onto white; done int diffX = x - fromX; int diffY = y - fromY; + if (xstep < 0) { + diffX++; + } return (float)sqrt((double)(diffX * diffX + diffY * diffY)); } error += dy; @@ -254,11 +265,14 @@ Ref Detector::findAlignmentInRegion(float overallEstModuleSize int allowance = (int)(allowanceFactor * overallEstModuleSize); int alignmentAreaLeftX = max(0, estAlignmentX - allowance); int alignmentAreaRightX = min((int)(image_->getWidth() - 1), estAlignmentX + allowance); + if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) { + throw zxing::ReaderException("region too small to hold alignment pattern"); + } int alignmentAreaTopY = max(0, estAlignmentY - allowance); int alignmentAreaBottomY = min((int)(image_->getHeight() - 1), estAlignmentY + allowance); AlignmentPatternFinder alignmentFinder(image_, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX - - alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize); + - alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize, callback_); return alignmentFinder.find(); }