From 8f2a89aa54e084988c626aa2e5cf072ca6ed58e5 Mon Sep 17 00:00:00 2001 From: "dswitkin@google.com" Date: Wed, 25 Aug 2010 20:51:14 +0000 Subject: [PATCH] Removed dynamic allocation of new int[2] when searching for guard patterns to improve performance. git-svn-id: http://zxing.googlecode.com/svn/trunk@1563 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- cpp/core/src/zxing/oned/EAN13Reader.cpp | 16 +++-- cpp/core/src/zxing/oned/EAN13Reader.h | 2 +- cpp/core/src/zxing/oned/EAN8Reader.cpp | 16 +++-- cpp/core/src/zxing/oned/EAN8Reader.h | 2 +- cpp/core/src/zxing/oned/UPCAReader.cpp | 10 +-- cpp/core/src/zxing/oned/UPCAReader.h | 5 +- cpp/core/src/zxing/oned/UPCEANReader.cpp | 80 ++++++++++-------------- cpp/core/src/zxing/oned/UPCEANReader.h | 13 ++-- cpp/core/src/zxing/oned/UPCEReader.cpp | 9 +-- cpp/core/src/zxing/oned/UPCEReader.h | 4 +- 10 files changed, 72 insertions(+), 85 deletions(-) diff --git a/cpp/core/src/zxing/oned/EAN13Reader.cpp b/cpp/core/src/zxing/oned/EAN13Reader.cpp index 29a9a807..223c79a2 100644 --- a/cpp/core/src/zxing/oned/EAN13Reader.cpp +++ b/cpp/core/src/zxing/oned/EAN13Reader.cpp @@ -29,13 +29,13 @@ namespace zxing { EAN13Reader::EAN13Reader() { } - int EAN13Reader::decodeMiddle(Ref row, int startRange[], int startRangeLen, + int EAN13Reader::decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString) { const int countersLen = 4; int counters[countersLen] = { 0, 0, 0, 0 }; int end = row->getSize(); - int rowOffset = startRange[1]; + int rowOffset = startGuardEnd; int lgPatternFound = 0; for (int x = 0; x < 6 && rowOffset < end; x++) { @@ -57,15 +57,15 @@ namespace zxing { return -1; } - int* middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), - getMIDDLE_PATTERN_LEN()); - if (middleRange != NULL) { - rowOffset = middleRange[1]; + int middleRangeStart; + int middleRangeEnd; + if (findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), + getMIDDLE_PATTERN_LEN(), &middleRangeStart, &middleRangeEnd)) { + rowOffset = middleRangeEnd; for (int x = 0; x < 6 && rowOffset < end; x++) { int bestMatch = decodeDigit(row, counters, countersLen, rowOffset, UPC_EAN_PATTERNS_L_PATTERNS); if (bestMatch < 0) { - delete [] middleRange; return -1; } resultString.append(1, (char) ('0' + bestMatch)); @@ -73,8 +73,6 @@ namespace zxing { rowOffset += counters[i]; } } - - delete [] middleRange; return rowOffset; } return -1; diff --git a/cpp/core/src/zxing/oned/EAN13Reader.h b/cpp/core/src/zxing/oned/EAN13Reader.h index 39426435..4ba4e0b7 100644 --- a/cpp/core/src/zxing/oned/EAN13Reader.h +++ b/cpp/core/src/zxing/oned/EAN13Reader.h @@ -33,7 +33,7 @@ namespace zxing { public: EAN13Reader(); - int decodeMiddle(Ref row, int startRange[], int startRangeLen, + int decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString); BarcodeFormat getBarcodeFormat(); diff --git a/cpp/core/src/zxing/oned/EAN8Reader.cpp b/cpp/core/src/zxing/oned/EAN8Reader.cpp index fb94f150..05ff5cb1 100644 --- a/cpp/core/src/zxing/oned/EAN8Reader.cpp +++ b/cpp/core/src/zxing/oned/EAN8Reader.cpp @@ -25,13 +25,13 @@ namespace zxing { EAN8Reader::EAN8Reader(){ } - int EAN8Reader::decodeMiddle(Ref row, int startRange[], int startRangeLen, + int EAN8Reader::decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString){ const int countersLen = 4; int counters[countersLen] = { 0, 0, 0, 0 }; int end = row->getSize(); - int rowOffset = startRange[1]; + int rowOffset = startGuardEnd; for (int x = 0; x < 4 && rowOffset < end; x++) { int bestMatch = decodeDigit(row, counters, countersLen, rowOffset, @@ -45,15 +45,15 @@ namespace zxing { } } - int* middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), - getMIDDLE_PATTERN_LEN()); - if (middleRange != NULL) { - rowOffset = middleRange[1]; + int middleRangeStart; + int middleRangeEnd; + if (findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), + getMIDDLE_PATTERN_LEN(), &middleRangeStart, &middleRangeEnd)) { + rowOffset = middleRangeEnd; for (int x = 0; x < 4 && rowOffset < end; x++) { int bestMatch = decodeDigit(row, counters, countersLen, rowOffset, UPC_EAN_PATTERNS_L_PATTERNS); if (bestMatch < 0) { - delete [] middleRange; return -1; } resultString.append(1, (char) ('0' + bestMatch)); @@ -61,8 +61,6 @@ namespace zxing { rowOffset += counters[i]; } } - - delete [] middleRange; return rowOffset; } return -1; diff --git a/cpp/core/src/zxing/oned/EAN8Reader.h b/cpp/core/src/zxing/oned/EAN8Reader.h index 5709a6b9..4db52fba 100644 --- a/cpp/core/src/zxing/oned/EAN8Reader.h +++ b/cpp/core/src/zxing/oned/EAN8Reader.h @@ -30,7 +30,7 @@ namespace zxing { public: EAN8Reader(); - int decodeMiddle(Ref row, int startRange[], int startRangeLen, + int decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString); BarcodeFormat getBarcodeFormat(); diff --git a/cpp/core/src/zxing/oned/UPCAReader.cpp b/cpp/core/src/zxing/oned/UPCAReader.cpp index cc379a7f..1eb2b6f3 100644 --- a/cpp/core/src/zxing/oned/UPCAReader.cpp +++ b/cpp/core/src/zxing/oned/UPCAReader.cpp @@ -29,17 +29,19 @@ namespace zxing { return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row)); } - Ref UPCAReader::decodeRow(int rowNumber, Ref row, int startGuardRange[]) { - return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardRange)); + Ref UPCAReader::decodeRow(int rowNumber, Ref row, int startGuardBegin, + int startGuardEnd) { + return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardBegin, + startGuardEnd)); } Ref UPCAReader::decode(Ref image, DecodeHints hints) { return maybeReturnResult(ean13Reader.decode(image, hints)); } - int UPCAReader::decodeMiddle(Ref row, int startRange[], int startRangeLen, + int UPCAReader::decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString) { - return ean13Reader.decodeMiddle(row, startRange, startRangeLen, resultString); + return ean13Reader.decodeMiddle(row, startGuardBegin, startGuardEnd, resultString); } Ref UPCAReader::maybeReturnResult(Ref result) { diff --git a/cpp/core/src/zxing/oned/UPCAReader.h b/cpp/core/src/zxing/oned/UPCAReader.h index 4a06afdf..7c61cf11 100644 --- a/cpp/core/src/zxing/oned/UPCAReader.h +++ b/cpp/core/src/zxing/oned/UPCAReader.h @@ -33,11 +33,12 @@ namespace zxing { public: UPCAReader(); - int decodeMiddle(Ref row, int startRange[], int startRangeLen, + int decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString); Ref decodeRow(int rowNumber, Ref row); - Ref decodeRow(int rowNumber, Ref row, int startGuardRange[]); + Ref decodeRow(int rowNumber, Ref row, int startGuardBegin, + int startGuardEnd); Ref decode(Ref image, DecodeHints hints); BarcodeFormat getBarcodeFormat(); diff --git a/cpp/core/src/zxing/oned/UPCEANReader.cpp b/cpp/core/src/zxing/oned/UPCEANReader.cpp index 76defafd..9fe36db7 100644 --- a/cpp/core/src/zxing/oned/UPCEANReader.cpp +++ b/cpp/core/src/zxing/oned/UPCEANReader.cpp @@ -95,50 +95,46 @@ namespace zxing { Ref UPCEANReader::decodeRow(int rowNumber, Ref row) { - int* start = findStartGuardPattern(row); - if (start != NULL) { + int rangeStart; + int rangeEnd; + if (findStartGuardPattern(row, &rangeStart, &rangeEnd)) { try { - Ref result = decodeRow(rowNumber, row, start); - delete [] start; - return result; + return decodeRow(rowNumber, row, rangeStart, rangeEnd); } catch (ReaderException const& re) { - delete [] start; } } return Ref(); } - Ref UPCEANReader::decodeRow(int rowNumber, Ref row, int startGuardRange[]) { + Ref UPCEANReader::decodeRow(int rowNumber, Ref row, int startGuardBegin, + int startGuardEnd) { std::string tmpResultString; std::string& tmpResultStringRef = tmpResultString; - int endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ , - tmpResultStringRef); + int endStart = decodeMiddle(row, startGuardBegin, startGuardEnd, tmpResultStringRef); if (endStart < 0) { return Ref(); } - int* endRange = decodeEnd(row, endStart); - if (endRange == NULL) { + + int endGuardBegin; + int endGuardEnd; + if (!decodeEnd(row, endStart, &endGuardBegin, &endGuardEnd)) { return Ref(); } // Make sure there is a quiet zone at least as big as the end pattern after the barcode. // The spec might want more whitespace, but in practice this is the maximum we can count on. - size_t end = endRange[1]; - size_t quietEnd = end + (end - endRange[0]); - if (quietEnd >= row->getSize() || !row->isRange(end, quietEnd, false)) { - delete [] endRange; + size_t quietEnd = endGuardEnd + (endGuardEnd - endGuardBegin); + if (quietEnd >= row->getSize() || !row->isRange(endGuardEnd, quietEnd, false)) { return Ref(); } if (!checkChecksum(tmpResultString)) { - delete [] endRange; return Ref(); } Ref resultString(new String(tmpResultString)); - - float left = (float) (startGuardRange[1] + startGuardRange[0]) / 2.0f; - float right = (float) (endRange[1] + endRange[0]) / 2.0f; + float left = (float) (startGuardBegin + startGuardEnd) / 2.0f; + float right = (float) (endGuardBegin + endGuardEnd) / 2.0f; std::vector< Ref > resultPoints(2); Ref resultPoint1(new OneDResultPoint(left, (float) rowNumber)); @@ -147,38 +143,28 @@ namespace zxing { resultPoints[1] = resultPoint2; ArrayRef resultBytes(1); - Ref res(new Result(resultString, resultBytes, resultPoints, getBarcodeFormat())); - delete [] endRange; - return res; + return Ref(new Result(resultString, resultBytes, resultPoints, getBarcodeFormat())); } - int* UPCEANReader::findStartGuardPattern(Ref row) { - bool foundStart = false; - int* startRange = NULL; + bool UPCEANReader::findStartGuardPattern(Ref row, int* rangeStart, int* rangeEnd) { int nextStart = 0; - while (!foundStart) { - delete [] startRange; - startRange = findGuardPattern(row, nextStart, false, START_END_PATTERN, - sizeof(START_END_PATTERN) / sizeof(int)); - if (startRange == NULL) { - return NULL; - } - int start = startRange[0]; - nextStart = startRange[1]; + while (findGuardPattern(row, nextStart, false, START_END_PATTERN, + sizeof(START_END_PATTERN) / sizeof(int), rangeStart, rangeEnd)) { + int start = *rangeStart; + nextStart = *rangeEnd; // Make sure there is a quiet zone at least as big as the start pattern before the barcode. // If this check would run off the left edge of the image, do not accept this barcode, // as it is very likely to be a false positive. int quietStart = start - (nextStart - start); - if (quietStart >= 0) { - foundStart = row->isRange(quietStart, start, false); + if (quietStart >= 0 && row->isRange(quietStart, start, false)) { + return true; } } - return startRange; + return false; } - // TODO(flyashi): Return a pair for return value to avoid using the heap. - int* UPCEANReader::findGuardPattern(Ref row, int rowOffset, bool whiteFirst, - const int pattern[], int patternLen) { + bool UPCEANReader::findGuardPattern(Ref row, int rowOffset, bool whiteFirst, + const int pattern[], int patternLen, int* start, int* end) { int patternLength = patternLen; int counters[patternLength]; int countersCount = sizeof(counters) / sizeof(int); @@ -205,10 +191,9 @@ namespace zxing { if (counterPosition == patternLength - 1) { if (patternMatchVariance(counters, countersCount, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) { - int* resultValue = new int[2]; - resultValue[0] = patternStart; - resultValue[1] = x; - return resultValue; + *start = patternStart; + *end = x; + return true; } patternStart += counters[0] + counters[1]; for (int y = 2; y < patternLength; y++) { @@ -224,12 +209,13 @@ namespace zxing { isWhite = !isWhite; } } - return NULL; + return false; } - int* UPCEANReader::decodeEnd(Ref row, int endStart) { + bool UPCEANReader::decodeEnd(Ref row, int endStart, int* endGuardBegin, + int* endGuardEnd) { return findGuardPattern(row, endStart, false, START_END_PATTERN, - sizeof(START_END_PATTERN) / sizeof(int)); + sizeof(START_END_PATTERN) / sizeof(int), endGuardBegin, endGuardEnd); } int UPCEANReader::decodeDigit(Ref row, int counters[], int countersLen, int rowOffset, diff --git a/cpp/core/src/zxing/oned/UPCEANReader.h b/cpp/core/src/zxing/oned/UPCEANReader.h index 90766814..2584b26b 100644 --- a/cpp/core/src/zxing/oned/UPCEANReader.h +++ b/cpp/core/src/zxing/oned/UPCEANReader.h @@ -37,14 +37,14 @@ namespace zxing { static const unsigned int MAX_AVG_VARIANCE = (unsigned int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f); static const int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f); - static int* findStartGuardPattern(Ref row); + static bool findStartGuardPattern(Ref row, int* rangeStart, int* rangeEnd); - virtual int* decodeEnd(Ref row, int endStart); + virtual bool decodeEnd(Ref row, int endStart, int* endGuardBegin, int* endGuardEnd); static bool checkStandardUPCEANChecksum(std::string s); protected: - static int* findGuardPattern(Ref row, int rowOffset, bool whiteFirst, - const int pattern[], int patternLen); + static bool findGuardPattern(Ref row, int rowOffset, bool whiteFirst, + const int pattern[], int patternLen, int* start, int* end); virtual const int getMIDDLE_PATTERN_LEN(); virtual const int* getMIDDLE_PATTERN(); @@ -53,13 +53,14 @@ namespace zxing { UPCEANReader(); // Returns < 0 on failure, >= 0 on success. - virtual int decodeMiddle(Ref row, int startRange[], int startRangeLen, + virtual int decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString) = 0; Ref decodeRow(int rowNumber, Ref row); // TODO(dswitkin): Should this be virtual so that UPCAReader can override it? - Ref decodeRow(int rowNumber, Ref row, int startGuardRange[]); + Ref decodeRow(int rowNumber, Ref row, int startGuardBegin, + int startGuardEnd); // Returns < 0 on failure, >= 0 on success. static int decodeDigit(Ref row, int counters[], int countersLen, int rowOffset, diff --git a/cpp/core/src/zxing/oned/UPCEReader.cpp b/cpp/core/src/zxing/oned/UPCEReader.cpp index cd364927..520512ed 100644 --- a/cpp/core/src/zxing/oned/UPCEReader.cpp +++ b/cpp/core/src/zxing/oned/UPCEReader.cpp @@ -42,13 +42,13 @@ namespace zxing { UPCEReader::UPCEReader() { } - int UPCEReader::decodeMiddle(Ref row, int startRange[], int startRangeLen, + int UPCEReader::decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString) { const int countersLen = 4; int counters[countersLen] = { 0, 0, 0, 0 }; int end = row->getSize(); - int rowOffset = startRange[1]; + int rowOffset = startGuardEnd; int lgPatternFound = 0; for (int x = 0; x < 6 && rowOffset < end; x++) { @@ -72,9 +72,10 @@ namespace zxing { return rowOffset; } - int* UPCEReader::decodeEnd(Ref row, int endStart) { + bool UPCEReader::decodeEnd(Ref row, int endStart, int* endGuardBegin, + int* endGuardEnd) { return findGuardPattern(row, endStart, true, MIDDLE_END_PATTERN, - sizeof(MIDDLE_END_PATTERN) / sizeof(int)); + sizeof(MIDDLE_END_PATTERN) / sizeof(int), endGuardBegin, endGuardEnd); } bool UPCEReader::checkChecksum(std::string s){ diff --git a/cpp/core/src/zxing/oned/UPCEReader.h b/cpp/core/src/zxing/oned/UPCEReader.h index 42a4fd06..0f4c61fb 100644 --- a/cpp/core/src/zxing/oned/UPCEReader.h +++ b/cpp/core/src/zxing/oned/UPCEReader.h @@ -30,12 +30,12 @@ namespace zxing { private: static bool determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound); protected: - int* decodeEnd(Ref row, int endStart); + bool decodeEnd(Ref row, int endStart, int* endGuardBegin, int* endGuardEnd); bool checkChecksum(std::string s); public: UPCEReader(); - int decodeMiddle(Ref row, int startRange[], int startRangeLen, + int decodeMiddle(Ref row, int startGuardBegin, int startGuardEnd, std::string& resultString); static std::string convertUPCEtoUPCA(std::string upce); -- 2.20.1