mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Removed as many exceptions as possible from the C++ product readers
to improve performance. There is no change in the number of images which pass the unit tests. git-svn-id: https://zxing.googlecode.com/svn/trunk@1535 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
c194eb915c
commit
e68b2951f4
|
@ -30,7 +30,7 @@ namespace zxing {
|
|||
EAN13Reader::EAN13Reader() { }
|
||||
|
||||
int EAN13Reader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString){
|
||||
std::string& resultString) {
|
||||
const int countersLen = 4;
|
||||
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||
|
||||
|
@ -41,6 +41,9 @@ namespace zxing {
|
|||
for (int x = 0; x < 6 && rowOffset < end; x++) {
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_AND_G_PATTERNS);
|
||||
if (bestMatch < 0) {
|
||||
return -1;
|
||||
}
|
||||
resultString.append(1, (char) ('0' + bestMatch % 10));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
@ -50,39 +53,41 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
determineFirstDigit(resultString, lgPatternFound);
|
||||
if (!determineFirstDigit(resultString, lgPatternFound)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int* middleRange = 0;
|
||||
try {
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),
|
||||
int* middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),
|
||||
getMIDDLE_PATTERN_LEN());
|
||||
if (middleRange != NULL) {
|
||||
rowOffset = middleRange[1];
|
||||
|
||||
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));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
rowOffset += counters[i];
|
||||
}
|
||||
}
|
||||
|
||||
delete [] middleRange;
|
||||
return rowOffset;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] middleRange;
|
||||
throw re;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void EAN13Reader::determineFirstDigit(std::string& resultString, int lgPatternFound) {
|
||||
bool EAN13Reader::determineFirstDigit(std::string& resultString, int lgPatternFound) {
|
||||
for (int d = 0; d < 10; d++) {
|
||||
if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) {
|
||||
resultString.insert(0, 1, (char) ('0' + d));
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
throw ReaderException("determineFirstDigit");
|
||||
return false;
|
||||
}
|
||||
|
||||
BarcodeFormat EAN13Reader::getBarcodeFormat(){
|
||||
|
|
|
@ -26,15 +26,16 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
class EAN13Reader : public UPCEANReader {
|
||||
|
||||
|
||||
private:
|
||||
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||
|
||||
static bool determineFirstDigit(std::string& resultString, int lgPatternFound);
|
||||
|
||||
public:
|
||||
EAN13Reader();
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString); //throws ReaderException
|
||||
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString);
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -36,21 +36,26 @@ namespace zxing {
|
|||
for (int x = 0; x < 4 && rowOffset < end; x++) {
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_PATTERNS);
|
||||
if (bestMatch < 0) {
|
||||
return -1;
|
||||
}
|
||||
resultString.append(1, (char) ('0' + bestMatch));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
}
|
||||
}
|
||||
|
||||
int* middleRange = 0;
|
||||
try {
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),
|
||||
int* middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),
|
||||
getMIDDLE_PATTERN_LEN());
|
||||
if (middleRange != NULL) {
|
||||
rowOffset = middleRange[1];
|
||||
|
||||
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));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
@ -59,10 +64,8 @@ namespace zxing {
|
|||
|
||||
delete [] middleRange;
|
||||
return rowOffset;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] middleRange;
|
||||
throw re;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
BarcodeFormat EAN8Reader::getBarcodeFormat(){
|
||||
|
|
|
@ -26,12 +26,13 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
class EAN8Reader : public UPCEANReader {
|
||||
|
||||
|
||||
public:
|
||||
EAN8Reader();
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString); //throws ReaderException
|
||||
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString);
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -31,13 +31,12 @@ namespace zxing {
|
|||
}
|
||||
|
||||
Ref<Result> OneDReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
|
||||
try {
|
||||
return doDecode(image, hints);
|
||||
} catch (ReaderException re) {
|
||||
if (hints.getTryHarder() && image->isRotateSupported()) {
|
||||
Ref<BinaryBitmap> rotatedImage(image->rotateCounterClockwise());
|
||||
Ref<Result> result(doDecode(rotatedImage, hints));
|
||||
/*
|
||||
Ref<Result> result = doDecode(image, hints);
|
||||
if (result.empty() && hints.getTryHarder() && image->isRotateSupported()) {
|
||||
Ref<BinaryBitmap> rotatedImage(image->rotateCounterClockwise());
|
||||
result = doDecode(rotatedImage, hints);
|
||||
if (!result.empty()) {
|
||||
/*
|
||||
// Record that we found it rotated 90 degrees CCW / 270 degrees CW
|
||||
Hashtable metadata = result.getResultMetadata();
|
||||
int orientation = 270;
|
||||
|
@ -54,11 +53,12 @@ namespace zxing {
|
|||
for (size_t i = 0; i < points.size(); i++) {
|
||||
points[i].reset(new OneDResultPoint(height - points[i]->getY() - 1, points[i]->getX()));
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.empty()) {
|
||||
throw ReaderException("");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Ref<Result> OneDReader::doDecode(Ref<BinaryBitmap> image, DecodeHints hints) {
|
||||
|
@ -127,7 +127,7 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
}
|
||||
throw ReaderException("doDecode() failed");
|
||||
return Ref<Result>();
|
||||
}
|
||||
|
||||
unsigned int OneDReader::patternMatchVariance(int counters[], int countersSize,
|
||||
|
|
|
@ -25,20 +25,21 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
class UPCAReader : public UPCEANReader {
|
||||
|
||||
|
||||
private:
|
||||
EAN13Reader ean13Reader;
|
||||
static Ref<Result> maybeReturnResult(Ref<Result> result); //throws ReaderException
|
||||
|
||||
static Ref<Result> maybeReturnResult(Ref<Result> result);
|
||||
|
||||
public:
|
||||
UPCAReader();
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString); //throws ReaderException
|
||||
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row); //throws ReaderException
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]); //throws ReaderException
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString);
|
||||
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]);
|
||||
Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);
|
||||
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -95,86 +95,85 @@ namespace zxing {
|
|||
|
||||
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
int* start = NULL;
|
||||
try {
|
||||
start = findStartGuardPattern(row);
|
||||
Ref<Result> result = decodeRow(rowNumber, row, start);
|
||||
delete [] start;
|
||||
return result;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] start;
|
||||
return Ref<Result>();
|
||||
int* start = findStartGuardPattern(row);
|
||||
if (start != NULL) {
|
||||
try {
|
||||
Ref<Result> result = decodeRow(rowNumber, row, start);
|
||||
delete [] start;
|
||||
return result;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] start;
|
||||
}
|
||||
}
|
||||
return Ref<Result>();
|
||||
}
|
||||
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]) {
|
||||
int* endRange = NULL;
|
||||
try {
|
||||
std::string tmpResultString;
|
||||
std::string& tmpResultStringRef = tmpResultString;
|
||||
int endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ ,
|
||||
tmpResultStringRef);
|
||||
endRange = decodeEnd(row, endStart);
|
||||
std::string tmpResultString;
|
||||
std::string& tmpResultStringRef = tmpResultString;
|
||||
int endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ ,
|
||||
tmpResultStringRef);
|
||||
if (endStart < 0) {
|
||||
return Ref<Result>();
|
||||
}
|
||||
int* endRange = decodeEnd(row, endStart);
|
||||
if (endRange == NULL) {
|
||||
return Ref<Result>();
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
throw ReaderException("Quiet zone asserrt fail.");
|
||||
}
|
||||
|
||||
if (!checkChecksum(tmpResultString)) {
|
||||
throw ReaderException("Checksum fail.");
|
||||
}
|
||||
|
||||
Ref<String> resultString(new String(tmpResultString));
|
||||
|
||||
float left = (float) (startGuardRange[1] + startGuardRange[0]) / 2.0f;
|
||||
float right = (float) (endRange[1] + endRange[0]) / 2.0f;
|
||||
|
||||
std::vector< Ref<ResultPoint> > resultPoints(2);
|
||||
Ref<OneDResultPoint> resultPoint1(new OneDResultPoint(left, (float) rowNumber));
|
||||
Ref<OneDResultPoint> resultPoint2(new OneDResultPoint(right, (float) rowNumber));
|
||||
resultPoints[0] = resultPoint1;
|
||||
resultPoints[1] = resultPoint2;
|
||||
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, getBarcodeFormat()));
|
||||
// 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;
|
||||
return res;
|
||||
} catch (ReaderException const& re) {
|
||||
return Ref<Result>();
|
||||
}
|
||||
|
||||
if (!checkChecksum(tmpResultString)) {
|
||||
delete [] endRange;
|
||||
throw re;
|
||||
}
|
||||
return Ref<Result>();
|
||||
}
|
||||
|
||||
Ref<String> resultString(new String(tmpResultString));
|
||||
|
||||
float left = (float) (startGuardRange[1] + startGuardRange[0]) / 2.0f;
|
||||
float right = (float) (endRange[1] + endRange[0]) / 2.0f;
|
||||
|
||||
std::vector< Ref<ResultPoint> > resultPoints(2);
|
||||
Ref<OneDResultPoint> resultPoint1(new OneDResultPoint(left, (float) rowNumber));
|
||||
Ref<OneDResultPoint> resultPoint2(new OneDResultPoint(right, (float) rowNumber));
|
||||
resultPoints[0] = resultPoint1;
|
||||
resultPoints[1] = resultPoint2;
|
||||
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, getBarcodeFormat()));
|
||||
delete [] endRange;
|
||||
return res;
|
||||
}
|
||||
|
||||
int* UPCEANReader::findStartGuardPattern(Ref<BitArray> row) {
|
||||
bool foundStart = false;
|
||||
int* startRange = NULL;
|
||||
int nextStart = 0;
|
||||
try {
|
||||
while (!foundStart) {
|
||||
delete [] startRange;
|
||||
startRange = NULL;
|
||||
startRange = findGuardPattern(row, nextStart, false, START_END_PATTERN,
|
||||
sizeof(START_END_PATTERN) / sizeof(int));
|
||||
int start = startRange[0];
|
||||
nextStart = startRange[1];
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
return startRange;
|
||||
} catch (ReaderException const& re) {
|
||||
while (!foundStart) {
|
||||
delete [] startRange;
|
||||
throw re;
|
||||
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];
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
return startRange;
|
||||
}
|
||||
|
||||
// TODO(flyashi): Return a pair<int, int> for return value to avoid using the heap.
|
||||
|
@ -225,7 +224,7 @@ namespace zxing {
|
|||
isWhite = !isWhite;
|
||||
}
|
||||
}
|
||||
throw ReaderException("findGuardPattern");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int* UPCEANReader::decodeEnd(Ref<BitArray> row, int endStart) {
|
||||
|
@ -236,7 +235,7 @@ namespace zxing {
|
|||
int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset,
|
||||
UPC_EAN_PATTERNS patternType) {
|
||||
if (!recordPattern(row, rowOffset, counters, countersLen)) {
|
||||
throw ReaderException("");
|
||||
return -1;
|
||||
}
|
||||
unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
||||
int bestMatch = -1;
|
||||
|
@ -278,14 +277,9 @@ namespace zxing {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (bestMatch >= 0) {
|
||||
return bestMatch;
|
||||
} else {
|
||||
throw ReaderException("UPCEANReader::decodeDigit: No best mach");
|
||||
}
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {@link #checkStandardUPCEANChecksum(String)}
|
||||
*/
|
||||
|
@ -299,7 +293,6 @@ namespace zxing {
|
|||
*
|
||||
* @param s string of digits to check
|
||||
* @return true iff string of digits passes the UPC/EAN checksum algorithm
|
||||
* @throws ReaderException if the string does not contain only digits
|
||||
*/
|
||||
bool UPCEANReader::checkStandardUPCEANChecksum(std::string s) {
|
||||
int length = s.length();
|
||||
|
@ -311,7 +304,7 @@ namespace zxing {
|
|||
for (int i = length - 2; i >= 0; i -= 2) {
|
||||
int digit = (int) s[i] - (int) '0';
|
||||
if (digit < 0 || digit > 9) {
|
||||
throw ReaderException("checkStandardUPCEANChecksum");
|
||||
return false;
|
||||
}
|
||||
sum += digit;
|
||||
}
|
||||
|
@ -319,7 +312,7 @@ namespace zxing {
|
|||
for (int i = length - 1; i >= 0; i -= 2) {
|
||||
int digit = (int) s[i] - (int) '0';
|
||||
if (digit < 0 || digit > 9) {
|
||||
throw ReaderException("checkStandardUPCEANChecksum");
|
||||
return false;
|
||||
}
|
||||
sum += digit;
|
||||
}
|
||||
|
|
|
@ -20,46 +20,53 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <zxing/oned/OneDReader.h>
|
||||
#include <zxing/common/BitArray.h>
|
||||
#include <zxing/Result.h>
|
||||
|
||||
typedef enum UPC_EAN_PATTERNS {
|
||||
UPC_EAN_PATTERNS_L_PATTERNS = 0,
|
||||
UPC_EAN_PATTERNS_L_AND_G_PATTERNS
|
||||
} UPC_EAN_PATTERNS;
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
class UPCEANReader : public OneDReader {
|
||||
|
||||
|
||||
private:
|
||||
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<BitArray> row); //throws ReaderException
|
||||
|
||||
virtual int* decodeEnd(Ref<BitArray> row, int endStart); //throws ReaderException
|
||||
|
||||
static bool checkStandardUPCEANChecksum(std::string s); //throws ReaderException
|
||||
|
||||
static int* findStartGuardPattern(Ref<BitArray> row);
|
||||
|
||||
virtual int* decodeEnd(Ref<BitArray> row, int endStart);
|
||||
|
||||
static bool checkStandardUPCEANChecksum(std::string s);
|
||||
protected:
|
||||
static int* findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst, const int pattern[], int patternLen); //throws ReaderException
|
||||
|
||||
static int* findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst,
|
||||
const int pattern[], int patternLen);
|
||||
|
||||
virtual const int getMIDDLE_PATTERN_LEN();
|
||||
virtual const int* getMIDDLE_PATTERN();
|
||||
|
||||
|
||||
public:
|
||||
UPCEANReader();
|
||||
|
||||
virtual int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString) = 0; //throws ReaderException
|
||||
|
||||
|
||||
// Returns < 0 on failure, >= 0 on success.
|
||||
virtual int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString) = 0;
|
||||
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||
|
||||
// TODO(dswitkin): Should this be virtual so that UPCAReader can override it?
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]);
|
||||
|
||||
static int decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, UPC_EAN_PATTERNS patternType); //throws ReaderException
|
||||
|
||||
virtual bool checkChecksum(std::string s); //throws ReaderException
|
||||
|
||||
|
||||
// Returns < 0 on failure, >= 0 on success.
|
||||
static int decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset,
|
||||
UPC_EAN_PATTERNS patternType);
|
||||
|
||||
virtual bool checkChecksum(std::string s);
|
||||
|
||||
virtual BarcodeFormat getBarcodeFormat() = 0;
|
||||
virtual ~UPCEANReader();
|
||||
};
|
||||
|
|
|
@ -49,12 +49,14 @@ namespace zxing {
|
|||
|
||||
int end = row->getSize();
|
||||
int rowOffset = startRange[1];
|
||||
|
||||
int lgPatternFound = 0;
|
||||
|
||||
for (int x = 0; x < 6 && rowOffset < end; x++) {
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_AND_G_PATTERNS);
|
||||
if (bestMatch < 0) {
|
||||
return -1;
|
||||
}
|
||||
resultString.append(1, (char) ('0' + bestMatch % 10));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
@ -64,8 +66,9 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
determineNumSysAndCheckDigit(resultString, lgPatternFound);
|
||||
|
||||
if (!determineNumSysAndCheckDigit(resultString, lgPatternFound)) {
|
||||
return -1;
|
||||
}
|
||||
return rowOffset;
|
||||
}
|
||||
|
||||
|
@ -79,17 +82,17 @@ namespace zxing {
|
|||
}
|
||||
|
||||
|
||||
void UPCEReader::determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound) {
|
||||
bool UPCEReader::determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound) {
|
||||
for (int numSys = 0; numSys <= 1; numSys++) {
|
||||
for (int d = 0; d < 10; d++) {
|
||||
if (lgPatternFound == NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d]) {
|
||||
resultString.insert(0, 1, (char) ('0' + numSys));
|
||||
resultString.append(1, (char) ('0' + d));
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw ReaderException("determineNumSysAndCheckDigit exception");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,19 +26,19 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
class UPCEReader : public UPCEANReader {
|
||||
|
||||
|
||||
private:
|
||||
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||
static void determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||
static bool determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound);
|
||||
protected:
|
||||
int* decodeEnd(Ref<BitArray> row, int endStart); //throws ReaderException
|
||||
bool checkChecksum(std::string s); //throws ReaderException
|
||||
int* decodeEnd(Ref<BitArray> row, int endStart);
|
||||
bool checkChecksum(std::string s);
|
||||
public:
|
||||
UPCEReader();
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString); //throws ReaderException
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString);
|
||||
static std::string convertUPCEtoUPCA(std::string upce);
|
||||
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue