mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Began removing the excessive use of exceptions in the 1D readers by drawing
a line in the sand: no one may throw an exception from decodeRow(). Next up is to throw fewer exceptions internally. git-svn-id: https://zxing.googlecode.com/svn/trunk@1527 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
073a3033fc
commit
56ad5f5554
|
@ -193,6 +193,10 @@ public:
|
|||
return x == 0 ? object_ != 0 : true;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return object_ == 0;
|
||||
}
|
||||
|
||||
template<class Y>
|
||||
friend std::ostream& operator<<(std::ostream &out, Ref<Y>& ref);
|
||||
};
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* Code128Reader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-15.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -170,7 +169,8 @@ namespace zxing {
|
|||
unsigned int bestVariance = MAX_AVG_VARIANCE;
|
||||
int bestMatch = -1;
|
||||
for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) {
|
||||
unsigned int variance = patternMatchVariance(counters, sizeof(counters)/sizeof(int), CODE_PATTERNS[startCode], MAX_INDIVIDUAL_VARIANCE);
|
||||
unsigned int variance = patternMatchVariance(counters, sizeof(counters) / sizeof(int),
|
||||
CODE_PATTERNS[startCode], MAX_INDIVIDUAL_VARIANCE);
|
||||
if (variance < bestVariance) {
|
||||
bestVariance = variance;
|
||||
bestMatch = startCode;
|
||||
|
@ -178,7 +178,8 @@ namespace zxing {
|
|||
}
|
||||
if (bestMatch >= 0) {
|
||||
// Look for whitespace before start pattern, >= 50% of width of start pattern
|
||||
if (row->isRange(fmaxl(0, patternStart - (i - patternStart) / 2), patternStart, false)) {
|
||||
if (row->isRange(fmaxl(0, patternStart - (i - patternStart) / 2), patternStart,
|
||||
false)) {
|
||||
int* resultValue = new int[3];
|
||||
resultValue[0] = patternStart;
|
||||
resultValue[1] = i;
|
||||
|
@ -203,7 +204,8 @@ namespace zxing {
|
|||
throw ReaderException("");
|
||||
}
|
||||
|
||||
int Code128Reader::decodeCode(Ref<BitArray> row, int counters[], int countersCount, int rowOffset){
|
||||
int Code128Reader::decodeCode(Ref<BitArray> row, int counters[], int countersCount,
|
||||
int rowOffset){
|
||||
recordPattern(row, rowOffset, counters, countersCount);
|
||||
unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
||||
int bestMatch = -1;
|
||||
|
@ -214,7 +216,8 @@ namespace zxing {
|
|||
pattern[ind] = CODE_PATTERNS[d][ind];
|
||||
}
|
||||
// memcpy(pattern, CODE_PATTERNS[d], countersLength);
|
||||
unsigned int variance = patternMatchVariance(counters, countersCount, pattern, MAX_INDIVIDUAL_VARIANCE);
|
||||
unsigned int variance = patternMatchVariance(counters, countersCount, pattern,
|
||||
MAX_INDIVIDUAL_VARIANCE);
|
||||
if (variance < bestVariance) {
|
||||
bestVariance = variance;
|
||||
bestMatch = d;
|
||||
|
@ -228,9 +231,10 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<Result> Code128Reader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
|
||||
int* startPatternInfo = findStartPattern(row);
|
||||
Ref<Result> Code128Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
int* startPatternInfo = NULL;
|
||||
try {
|
||||
startPatternInfo = findStartPattern(row);
|
||||
int startCode = startPatternInfo[2];
|
||||
int codeSet;
|
||||
switch (startCode) {
|
||||
|
@ -244,7 +248,6 @@ namespace zxing {
|
|||
codeSet = CODE_CODE_C;
|
||||
break;
|
||||
default:
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -265,7 +268,6 @@ namespace zxing {
|
|||
bool lastCharacterWasPrintable = true;
|
||||
|
||||
while (!done) {
|
||||
|
||||
bool unshift = isNextShifted;
|
||||
isNextShifted = false;
|
||||
|
||||
|
@ -276,7 +278,6 @@ namespace zxing {
|
|||
try {
|
||||
code = decodeCode(row, counters, sizeof(counters)/sizeof(int), nextStart);
|
||||
} catch (ReaderException re) {
|
||||
delete [] startPatternInfo;
|
||||
throw re;
|
||||
}
|
||||
|
||||
|
@ -303,7 +304,6 @@ namespace zxing {
|
|||
case CODE_START_A:
|
||||
case CODE_START_B:
|
||||
case CODE_START_C:
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -315,8 +315,8 @@ namespace zxing {
|
|||
} else if (code < 96) {
|
||||
tmpResultString.append(1, (char) (code - 64));
|
||||
} else {
|
||||
// Don't let CODE_STOP, which always appears, affect whether whether we think the last
|
||||
// code was printable or not.
|
||||
// Don't let CODE_STOP, which always appears, affect whether whether we think the
|
||||
// last code was printable or not.
|
||||
if (code != CODE_STOP) {
|
||||
lastCharacterWasPrintable = false;
|
||||
}
|
||||
|
@ -426,7 +426,6 @@ namespace zxing {
|
|||
nextStart++;
|
||||
}
|
||||
if (!row->isRange(nextStart, fminl(width, nextStart + (nextStart - lastStart) / 2), false)) {
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -434,7 +433,6 @@ namespace zxing {
|
|||
checksumTotal -= multiplier * lastCode;
|
||||
// lastCode is the checksum then:
|
||||
if (checksumTotal % 103 != lastCode) {
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -454,10 +452,7 @@ namespace zxing {
|
|||
}
|
||||
|
||||
Ref<String> resultString(new String(tmpResultString));
|
||||
// String resultString(tmpResultString);
|
||||
|
||||
if (tmpResultString.length() == 0) {
|
||||
delete [] startPatternInfo;
|
||||
// Almost surely a false positive
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
@ -471,13 +466,14 @@ namespace zxing {
|
|||
resultPoints[0] = resultPoint1;
|
||||
resultPoints[1] = resultPoint2;
|
||||
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
|
||||
delete [] startPatternInfo;
|
||||
startPatternInfo = NULL;
|
||||
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, BarcodeFormat_CODE_128));
|
||||
return res;
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
return Ref<Result>(new Result(resultString, resultBytes, resultPoints,
|
||||
BarcodeFormat_CODE_128));
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] startPatternInfo;
|
||||
return Ref<Result>();
|
||||
}
|
||||
}
|
||||
|
||||
void Code128Reader::append(char* s, char c){
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* Code39Reader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-26.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -81,7 +80,7 @@ namespace oned {
|
|||
extendedMode(extendedMode_) {
|
||||
}
|
||||
|
||||
Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
int* start = NULL;
|
||||
try {
|
||||
start = findAsteriskPattern(row);
|
||||
|
@ -175,7 +174,7 @@ namespace oned {
|
|||
return res;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] start;
|
||||
throw re;
|
||||
return Ref<Result>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* EAN13Reader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-22.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -24,23 +23,24 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
static const int FIRST_DIGIT_ENCODINGS[10] = {0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A};
|
||||
|
||||
static const int FIRST_DIGIT_ENCODINGS[10] = {
|
||||
0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A
|
||||
};
|
||||
|
||||
EAN13Reader::EAN13Reader() { }
|
||||
|
||||
int EAN13Reader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString){
|
||||
int EAN13Reader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString){
|
||||
const int countersLen = 4;
|
||||
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||
|
||||
|
||||
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);
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_AND_G_PATTERNS);
|
||||
resultString.append(1, (char) ('0' + bestMatch % 10));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
@ -54,11 +54,13 @@ namespace zxing {
|
|||
|
||||
int* middleRange = 0;
|
||||
try {
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), getMIDDLE_PATTERN_LEN());
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),
|
||||
getMIDDLE_PATTERN_LEN());
|
||||
rowOffset = middleRange[1];
|
||||
|
||||
for (int x = 0; x < 6 && rowOffset < end; x++) {
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset, UPC_EAN_PATTERNS_L_PATTERNS);
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_PATTERNS);
|
||||
resultString.append(1, (char) ('0' + bestMatch));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
@ -73,7 +75,7 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
void EAN13Reader::determineFirstDigit(std::string& resultString, int lgPatternFound){
|
||||
void 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));
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* EAN8Reader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-25.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -26,7 +25,8 @@ namespace zxing {
|
|||
|
||||
EAN8Reader::EAN8Reader(){ }
|
||||
|
||||
int EAN8Reader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString){
|
||||
int EAN8Reader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString){
|
||||
const int countersLen = 4;
|
||||
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||
|
||||
|
@ -34,7 +34,8 @@ namespace zxing {
|
|||
int rowOffset = startRange[1];
|
||||
|
||||
for (int x = 0; x < 4 && rowOffset < end; x++) {
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset, UPC_EAN_PATTERNS_L_PATTERNS);
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_PATTERNS);
|
||||
resultString.append(1, (char) ('0' + bestMatch));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
@ -43,11 +44,13 @@ namespace zxing {
|
|||
|
||||
int* middleRange = 0;
|
||||
try {
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(), getMIDDLE_PATTERN_LEN());
|
||||
middleRange = findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),
|
||||
getMIDDLE_PATTERN_LEN());
|
||||
rowOffset = middleRange[1];
|
||||
|
||||
for (int x = 0; x < 4 && rowOffset < end; x++) {
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset, UPC_EAN_PATTERNS_L_PATTERNS);
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_PATTERNS);
|
||||
resultString.append(1, (char) ('0' + bestMatch));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* ITFReader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-26.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -66,7 +65,7 @@ namespace zxing {
|
|||
}
|
||||
|
||||
|
||||
Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
int* startRange = 0;
|
||||
int* endRange = 0;
|
||||
try {
|
||||
|
@ -96,16 +95,14 @@ namespace zxing {
|
|||
resultPoints[0] = resultPoint1;
|
||||
resultPoints[1] = resultPoint2;
|
||||
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
|
||||
Ref<Result> res(new Result(resultString, resultBytes, resultPoints, BarcodeFormat_ITF));
|
||||
delete [] startRange;
|
||||
delete [] endRange;
|
||||
return res;
|
||||
ArrayRef<unsigned char> resultBytes(1);
|
||||
return Ref<Result>(new Result(resultString, resultBytes, resultPoints, BarcodeFormat_ITF));
|
||||
} catch (ReaderException re) {
|
||||
delete [] startRange;
|
||||
delete [] endRange;
|
||||
throw re;
|
||||
return Ref<Result>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,7 +112,8 @@ namespace zxing {
|
|||
* @param resultString {@link StringBuffer} to append decoded chars to
|
||||
* @throws ReaderException if decoding could not complete successfully
|
||||
*/
|
||||
void ITFReader::decodeMiddle(Ref<BitArray> row, int payloadStart, int payloadEnd, std::string& resultString){
|
||||
void ITFReader::decodeMiddle(Ref<BitArray> row, int payloadStart, int payloadEnd,
|
||||
std::string& resultString) {
|
||||
// Digits are interleaved in pairs - 5 black lines for one digit, and the
|
||||
// 5
|
||||
// interleaved white lines for the second digit.
|
||||
|
@ -163,9 +161,8 @@ namespace zxing {
|
|||
* 'start block'
|
||||
* @throws ReaderException
|
||||
*/
|
||||
int* ITFReader::decodeStart(Ref<BitArray> row){
|
||||
int* ITFReader::decodeStart(Ref<BitArray> row) {
|
||||
int endStart = skipWhiteSpace(row);
|
||||
/// static int* findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst, const int pattern[], int patternLen);
|
||||
int* startPattern = 0;
|
||||
try {
|
||||
startPattern = findGuardPattern(row, endStart, START_PATTERN, START_PATTERN_LEN);
|
||||
|
@ -174,9 +171,7 @@ namespace zxing {
|
|||
// getting the width of the start pattern and dividing by 4 because its
|
||||
// made up of 4 narrow lines.
|
||||
narrowLineWidth = (startPattern[1] - startPattern[0]) >> 2;
|
||||
|
||||
validateQuietZone(row, startPattern[0]);
|
||||
|
||||
return startPattern;
|
||||
} catch (ReaderException re) {
|
||||
delete [] startPattern;
|
||||
|
@ -193,7 +188,7 @@ namespace zxing {
|
|||
* @throws ReaderException
|
||||
*/
|
||||
|
||||
int* ITFReader::decodeEnd(Ref<BitArray> row){
|
||||
int* ITFReader::decodeEnd(Ref<BitArray> row) {
|
||||
// For convenience, reverse the row and then
|
||||
// search from 'the start' for the end block
|
||||
row->reverse();
|
||||
|
@ -238,7 +233,7 @@ namespace zxing {
|
|||
* @param startPattern index into row of the start or end pattern.
|
||||
* @throws ReaderException if the quiet zone cannot be found, a ReaderException is thrown.
|
||||
*/
|
||||
void ITFReader::validateQuietZone(Ref<BitArray> row, int startPattern){
|
||||
void ITFReader::validateQuietZone(Ref<BitArray> row, int startPattern) {
|
||||
//#pragma mark needs some corrections
|
||||
// int quietCount = narrowLineWidth * 10; // expect to find this many pixels of quiet zone
|
||||
//
|
||||
|
@ -261,7 +256,7 @@ namespace zxing {
|
|||
* @return index of the first black line.
|
||||
* @throws ReaderException Throws exception if no black lines are found in the row
|
||||
*/
|
||||
int ITFReader::skipWhiteSpace(Ref<BitArray> row){
|
||||
int ITFReader::skipWhiteSpace(Ref<BitArray> row) {
|
||||
int width = row->getSize();
|
||||
int endStart = 0;
|
||||
while (endStart < width) {
|
||||
|
@ -285,8 +280,8 @@ namespace zxing {
|
|||
* ints
|
||||
* @throws ReaderException if pattern is not found
|
||||
*/
|
||||
|
||||
int* ITFReader::findGuardPattern(Ref<BitArray> row, int rowOffset, const int pattern[], int patternLen){
|
||||
int* ITFReader::findGuardPattern(Ref<BitArray> row, int rowOffset, const int pattern[],
|
||||
int patternLen) {
|
||||
// TODO: This is very similar to implementation in UPCEANReader. Consider if they can be
|
||||
// merged to a single method.
|
||||
int patternLength = patternLen;
|
||||
|
@ -305,7 +300,8 @@ namespace zxing {
|
|||
counters[counterPosition]++;
|
||||
} else {
|
||||
if (counterPosition == patternLength - 1) {
|
||||
if (patternMatchVariance(counters, patternLength, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
|
||||
if (patternMatchVariance(counters, patternLength, pattern,
|
||||
MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
|
||||
int* resultValue = new int[2];
|
||||
resultValue[0] = patternStart;
|
||||
resultValue[1] = x;
|
||||
|
@ -345,7 +341,8 @@ namespace zxing {
|
|||
for(int ind = 0; ind<countersLen; ind++){
|
||||
pattern[ind] = PATTERNS[i][ind];
|
||||
}
|
||||
unsigned int variance = patternMatchVariance(counters, countersLen, pattern, MAX_INDIVIDUAL_VARIANCE);
|
||||
unsigned int variance = patternMatchVariance(counters, countersLen, pattern,
|
||||
MAX_INDIVIDUAL_VARIANCE);
|
||||
if (variance < bestVariance) {
|
||||
bestVariance = variance;
|
||||
bestMatch = i;
|
||||
|
@ -358,7 +355,6 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ITFReader::~ITFReader(){
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* MultiFormatOneDReader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-25.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -52,17 +51,16 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
int size = readers.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
OneDReader* reader = readers[i];
|
||||
try {
|
||||
return reader->decodeRow(rowNumber, row);
|
||||
} catch (ReaderException re) {
|
||||
// continue
|
||||
Ref<Result> result = reader->decodeRow(rowNumber, row);
|
||||
if (!result.empty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
throw ReaderException("No code detected");
|
||||
return Ref<Result>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* MultiFormatUPCEANReader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-25.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -51,17 +50,16 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
// Compute this location once and reuse it on multiple implementations
|
||||
int size = readers.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Ref<OneDReader> reader = readers[i];
|
||||
Ref<Result> result;
|
||||
try {
|
||||
result = reader->decodeRow(rowNumber, row);//decodeRow(rowNumber, row, startGuardPattern);
|
||||
} catch (ReaderException re) {
|
||||
Ref<Result> result = reader->decodeRow(rowNumber, row);
|
||||
if (result.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Special case: a 12-digit code encoded in UPC-A is identical to a "0"
|
||||
// followed by those 12 digits encoded as EAN-13. Each will recognize such a code,
|
||||
// UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0".
|
||||
|
@ -76,13 +74,14 @@ namespace zxing {
|
|||
const std::string& text = (result->getText())->getText();
|
||||
if (text[0] == '0') {
|
||||
Ref<String> resultString(new String(text.substr(1)));
|
||||
Ref<Result> res(new Result(resultString, result->getRawBytes(), result->getResultPoints(), BarcodeFormat_UPC_A));
|
||||
Ref<Result> res(new Result(resultString, result->getRawBytes(),
|
||||
result->getResultPoints(), BarcodeFormat_UPC_A));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
throw ReaderException("No EAN code detected");
|
||||
return Ref<Result>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* OneDReader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-15.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -32,12 +31,10 @@ namespace zxing {
|
|||
}
|
||||
|
||||
Ref<Result> OneDReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
|
||||
|
||||
try {
|
||||
return doDecode(image, hints);
|
||||
}catch (ReaderException re) {
|
||||
} catch (ReaderException re) {
|
||||
if (hints.getTryHarder() && image->isRotateSupported()) {
|
||||
|
||||
Ref<BinaryBitmap> rotatedImage(image->rotateCounterClockwise());
|
||||
Ref<Result> result(doDecode(rotatedImage, hints));
|
||||
/*
|
||||
|
@ -64,7 +61,7 @@ namespace zxing {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<Result> OneDReader::doDecode(Ref<BinaryBitmap> image, DecodeHints hints){
|
||||
Ref<Result> OneDReader::doDecode(Ref<BinaryBitmap> image, DecodeHints hints) {
|
||||
int width = image->getWidth();
|
||||
int height = image->getHeight();
|
||||
Ref<BitArray> row(new BitArray(width));
|
||||
|
@ -79,7 +76,6 @@ namespace zxing {
|
|||
}
|
||||
|
||||
for (int x = 0; x < maxLines; x++) {
|
||||
|
||||
// Scanning from the middle out. Determine which row we're looking at next:
|
||||
int rowStepsAboveOrBelow = (x + 1) >> 1;
|
||||
bool isAbove = (x & 0x01) == 0; // i.e. is x even?
|
||||
|
@ -92,9 +88,9 @@ namespace zxing {
|
|||
// Estimate black point for this row and load it:
|
||||
try {
|
||||
row = image->getBlackRow(rowNumber, row);
|
||||
}catch (ReaderException re) {
|
||||
} catch (ReaderException re) {
|
||||
continue;
|
||||
}catch (IllegalArgumentException re) {
|
||||
} catch (IllegalArgumentException re) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -104,11 +100,11 @@ namespace zxing {
|
|||
if (attempt == 1) { // trying again?
|
||||
row->reverse(); // reverse the row and continue
|
||||
}
|
||||
try {
|
||||
|
||||
// Look for a barcode
|
||||
Ref<Result> result = decodeRow(rowNumber, row);
|
||||
// We found our barcode
|
||||
if (attempt == 1) {
|
||||
if (!result.empty()) {
|
||||
// // But it was upside down, so note that
|
||||
// result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180));
|
||||
// // And remember to flip the result points horizontally.
|
||||
|
@ -124,10 +120,7 @@ namespace zxing {
|
|||
|
||||
result.reset(new Result(result->getText(),result->getRawBytes(),points,result->getBarcodeFormat()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} catch (ReaderException re) {
|
||||
// continue -- just couldn't decode this row
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,13 @@ namespace zxing {
|
|||
|
||||
OneDReader();
|
||||
virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);
|
||||
|
||||
// Implementations must not throw any exceptions. If a barcode is not found on this row,
|
||||
// a empty ref should be returned e.g. return Ref<Result>();
|
||||
virtual Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row) = 0;
|
||||
|
||||
static unsigned int patternMatchVariance(int counters[], int countersSize, const int pattern[], int maxIndividualVariance);
|
||||
static unsigned int patternMatchVariance(int counters[], int countersSize,
|
||||
const int pattern[], int maxIndividualVariance);
|
||||
static void recordPattern(Ref<BitArray> row, int start, int counters[], int countersCount);
|
||||
virtual ~OneDReader();
|
||||
};
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* OneDResultPoint.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-20.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -23,7 +22,7 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
OneDResultPoint::OneDResultPoint(float posX, float posY) : posX_(posX), posY_(posY){
|
||||
OneDResultPoint::OneDResultPoint(float posX, float posY) : posX_(posX), posY_(posY) {
|
||||
}
|
||||
|
||||
float OneDResultPoint::getX() const {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* UPCAReader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-25.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -26,32 +25,37 @@ namespace zxing {
|
|||
UPCAReader::UPCAReader() : ean13Reader() {
|
||||
}
|
||||
|
||||
Ref<Result> UPCAReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
Ref<Result> UPCAReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||
return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row));
|
||||
}
|
||||
Ref<Result> UPCAReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]){
|
||||
|
||||
Ref<Result> UPCAReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]) {
|
||||
return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardRange));
|
||||
}
|
||||
Ref<Result> UPCAReader::decode(Ref<BinaryBitmap> image, DecodeHints hints){
|
||||
|
||||
Ref<Result> UPCAReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
|
||||
return maybeReturnResult(ean13Reader.decode(image, hints));
|
||||
}
|
||||
|
||||
int UPCAReader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString){
|
||||
int UPCAReader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString) {
|
||||
return ean13Reader.decodeMiddle(row, startRange, startRangeLen, resultString);
|
||||
}
|
||||
|
||||
Ref<Result> UPCAReader::maybeReturnResult(Ref<Result> result){
|
||||
Ref<Result> UPCAReader::maybeReturnResult(Ref<Result> result) {
|
||||
if (result.empty()) {
|
||||
return result;
|
||||
}
|
||||
const std::string& text = (result->getText())->getText();
|
||||
if (text[0] == '0') {
|
||||
Ref<String> resultString(new String(text.substr(1)));
|
||||
Ref<Result> res(new Result(resultString, result->getRawBytes(), result->getResultPoints(), BarcodeFormat_UPC_A));
|
||||
Ref<Result> res(new Result(resultString, result->getRawBytes(), result->getResultPoints(),
|
||||
BarcodeFormat_UPC_A));
|
||||
return res;
|
||||
} else {
|
||||
throw ReaderException("Not UPC-A barcode.");
|
||||
}
|
||||
return Ref<Result>();
|
||||
}
|
||||
|
||||
|
||||
BarcodeFormat UPCAReader::getBarcodeFormat(){
|
||||
return BarcodeFormat_UPC_A;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* UPCEANReader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-21.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -21,6 +20,7 @@
|
|||
#include "UPCEANReader.h"
|
||||
#include <zxing/oned/OneDResultPoint.h>
|
||||
#include <zxing/ReaderException.h>
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
|
@ -82,14 +82,15 @@ namespace zxing {
|
|||
};
|
||||
|
||||
|
||||
const int UPCEANReader::getMIDDLE_PATTERN_LEN(){
|
||||
const int UPCEANReader::getMIDDLE_PATTERN_LEN() {
|
||||
return MIDDLE_PATTERN_LEN;
|
||||
}
|
||||
const int* UPCEANReader::getMIDDLE_PATTERN(){
|
||||
|
||||
const int* UPCEANReader::getMIDDLE_PATTERN() {
|
||||
return MIDDLE_PATTERN;
|
||||
}
|
||||
|
||||
UPCEANReader::UPCEANReader(){
|
||||
UPCEANReader::UPCEANReader() {
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,22 +103,21 @@ namespace zxing {
|
|||
return result;
|
||||
} catch (ReaderException const& re) {
|
||||
delete [] start;
|
||||
throw re;
|
||||
return Ref<Result>();
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]){
|
||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]) {
|
||||
int* endRange = NULL;
|
||||
try {
|
||||
std::string tmpResultString;
|
||||
std::string& tmpResultStringRef = tmpResultString;
|
||||
int endStart;
|
||||
endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ , tmpResultStringRef);
|
||||
|
||||
int endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ ,
|
||||
tmpResultStringRef);
|
||||
endRange = decodeEnd(row, endStart);
|
||||
|
||||
// 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.
|
||||
// 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)) {
|
||||
|
@ -148,19 +148,18 @@ namespace zxing {
|
|||
delete [] endRange;
|
||||
throw re;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int* UPCEANReader::findStartGuardPattern(Ref<BitArray> row){
|
||||
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));
|
||||
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.
|
||||
|
@ -179,7 +178,8 @@ namespace zxing {
|
|||
}
|
||||
|
||||
// TODO(flyashi): Return a pair<int, int> for return value to avoid using the heap.
|
||||
int* UPCEANReader::findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst, const int pattern[], int patternLen){
|
||||
int* UPCEANReader::findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst,
|
||||
const int pattern[], int patternLen) {
|
||||
int patternLength = patternLen;
|
||||
int counters[patternLength];
|
||||
int countersCount = sizeof(counters) / sizeof(int);
|
||||
|
@ -204,7 +204,8 @@ namespace zxing {
|
|||
counters[counterPosition]++;
|
||||
} else {
|
||||
if (counterPosition == patternLength - 1) {
|
||||
if (patternMatchVariance(counters, countersCount, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
|
||||
if (patternMatchVariance(counters, countersCount, pattern,
|
||||
MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
|
||||
int* resultValue = new int[2];
|
||||
resultValue[0] = patternStart;
|
||||
resultValue[1] = x;
|
||||
|
@ -227,12 +228,14 @@ namespace zxing {
|
|||
throw ReaderException("findGuardPattern");
|
||||
}
|
||||
|
||||
int* UPCEANReader::decodeEnd(Ref<BitArray> row, int endStart){
|
||||
return findGuardPattern(row, endStart, false, START_END_PATTERN, sizeof(START_END_PATTERN)/sizeof(int));
|
||||
int* UPCEANReader::decodeEnd(Ref<BitArray> row, int endStart) {
|
||||
return findGuardPattern(row, endStart, false, START_END_PATTERN,
|
||||
sizeof(START_END_PATTERN) / sizeof(int));
|
||||
}
|
||||
|
||||
// int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, int** patterns/*[][]*/, int paterns1Len, int paterns2Len)
|
||||
int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, UPC_EAN_PATTERNS patternType){
|
||||
int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset,
|
||||
UPC_EAN_PATTERNS patternType) {
|
||||
recordPattern(row, rowOffset, counters, countersLen);
|
||||
unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
||||
int bestMatch = -1;
|
||||
|
@ -247,7 +250,8 @@ namespace zxing {
|
|||
pattern[j] = L_PATTERNS[i][j];
|
||||
}
|
||||
|
||||
unsigned int variance = patternMatchVariance(counters, countersLen, pattern, MAX_INDIVIDUAL_VARIANCE);
|
||||
unsigned int variance = patternMatchVariance(counters, countersLen, pattern,
|
||||
MAX_INDIVIDUAL_VARIANCE);
|
||||
if (variance < bestVariance) {
|
||||
bestVariance = variance;
|
||||
bestMatch = i;
|
||||
|
@ -262,7 +266,8 @@ namespace zxing {
|
|||
pattern[j] = L_AND_G_PATTERNS[i][j];
|
||||
}
|
||||
|
||||
unsigned int variance = patternMatchVariance(counters, countersLen, pattern, MAX_INDIVIDUAL_VARIANCE);
|
||||
unsigned int variance = patternMatchVariance(counters, countersLen, pattern,
|
||||
MAX_INDIVIDUAL_VARIANCE);
|
||||
if (variance < bestVariance) {
|
||||
bestVariance = variance;
|
||||
bestMatch = i;
|
||||
|
@ -283,7 +288,7 @@ namespace zxing {
|
|||
/**
|
||||
* @return {@link #checkStandardUPCEANChecksum(String)}
|
||||
*/
|
||||
bool UPCEANReader::checkChecksum(std::string s){
|
||||
bool UPCEANReader::checkChecksum(std::string s) {
|
||||
return checkStandardUPCEANChecksum(s);
|
||||
}
|
||||
|
||||
|
@ -295,7 +300,7 @@ namespace zxing {
|
|||
* @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){
|
||||
bool UPCEANReader::checkStandardUPCEANChecksum(std::string s) {
|
||||
int length = s.length();
|
||||
if (length == 0) {
|
||||
return false;
|
||||
|
@ -319,7 +324,8 @@ namespace zxing {
|
|||
}
|
||||
return sum % 10 == 0;
|
||||
}
|
||||
UPCEANReader::~UPCEANReader(){
|
||||
|
||||
UPCEANReader::~UPCEANReader() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* UPCEReader.cpp
|
||||
* ZXing
|
||||
*
|
||||
* Created by Lukasz Warchol on 10-01-26.
|
||||
* Copyright 2010 ZXing authors All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -40,9 +39,11 @@ namespace zxing {
|
|||
{0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}
|
||||
};
|
||||
|
||||
UPCEReader::UPCEReader(){}
|
||||
UPCEReader::UPCEReader() {
|
||||
}
|
||||
|
||||
int UPCEReader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString){
|
||||
int UPCEReader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen,
|
||||
std::string& resultString) {
|
||||
const int countersLen = 4;
|
||||
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||
|
||||
|
@ -52,7 +53,8 @@ namespace zxing {
|
|||
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);
|
||||
int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,
|
||||
UPC_EAN_PATTERNS_L_AND_G_PATTERNS);
|
||||
resultString.append(1, (char) ('0' + bestMatch % 10));
|
||||
for (int i = 0; i < countersLen; i++) {
|
||||
rowOffset += counters[i];
|
||||
|
@ -67,8 +69,9 @@ namespace zxing {
|
|||
return rowOffset;
|
||||
}
|
||||
|
||||
int* UPCEReader::decodeEnd(Ref<BitArray> row, int endStart){
|
||||
return findGuardPattern(row, endStart, true, MIDDLE_END_PATTERN, sizeof(MIDDLE_END_PATTERN)/sizeof(int));
|
||||
int* UPCEReader::decodeEnd(Ref<BitArray> row, int endStart) {
|
||||
return findGuardPattern(row, endStart, true, MIDDLE_END_PATTERN,
|
||||
sizeof(MIDDLE_END_PATTERN) / sizeof(int));
|
||||
}
|
||||
|
||||
bool UPCEReader::checkChecksum(std::string s){
|
||||
|
@ -76,7 +79,7 @@ namespace zxing {
|
|||
}
|
||||
|
||||
|
||||
void UPCEReader::determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound){
|
||||
void 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]) {
|
||||
|
@ -129,7 +132,7 @@ namespace zxing {
|
|||
}
|
||||
|
||||
|
||||
BarcodeFormat UPCEReader::getBarcodeFormat(){
|
||||
BarcodeFormat UPCEReader::getBarcodeFormat() {
|
||||
return BarcodeFormat_UPC_E;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue