c++ port of r2516

git-svn-id: https://zxing.googlecode.com/svn/trunk@2610 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
smparkes@smparkes.net 2013-04-01 06:01:06 +00:00
parent 98e5f33f93
commit e6b876ae71
3 changed files with 57 additions and 48 deletions

View file

@ -74,12 +74,13 @@ const int CodaBarReader::PADDING =
CodaBarReader::CodaBarReader() CodaBarReader::CodaBarReader()
: counters(80, 0), counterLength(0) {} : counters(80, 0), counterLength(0) {}
using namespace std; Ref<Result> CodaBarReader::decodeRow(int rowNumber, Ref<BitArray> row) {
Ref<Result> CodaBarReader::decodeRow(int rowNumber, { // Arrays.fill(counters, 0);
Ref<BitArray> row) { int size = counters.size();
counters.resize(0);
counters.resize(size); }
// cerr << "cbr " << rowNumber << " " << *row << endl;
setCounters(row); setCounters(row);
int startOffset = findStartPattern(); int startOffset = findStartPattern();
int nextStart = startOffset; int nextStart = startOffset;

View file

@ -53,6 +53,15 @@ namespace {
int ASTERISK_ENCODING = 0x094; int ASTERISK_ENCODING = 0x094;
const char* ALPHABET_STRING = const char* ALPHABET_STRING =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%"; "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";
std::string alphabet_string (ALPHABET_STRING);
}
void Code39Reader::init(bool usingCheckDigit_, bool extendedMode_) {
usingCheckDigit = usingCheckDigit_;
extendedMode = extendedMode_;
decodeRowResult.reserve(20);
counters.resize(9);
} }
/** /**
@ -60,9 +69,8 @@ namespace {
* the final character as a check digit. It will not decoded "extended * the final character as a check digit. It will not decoded "extended
* Code 39" sequences. * Code 39" sequences.
*/ */
Code39Reader::Code39Reader() : alphabet_string(ALPHABET_STRING), Code39Reader::Code39Reader() {
usingCheckDigit(false), init();
extendedMode(false) {
} }
/** /**
@ -72,27 +80,26 @@ Code39Reader::Code39Reader() : alphabet_string(ALPHABET_STRING),
* @param usingCheckDigit if true, treat the last data character as a check * @param usingCheckDigit if true, treat the last data character as a check
* digit, not data, and verify that the checksum passes. * digit, not data, and verify that the checksum passes.
*/ */
Code39Reader::Code39Reader(bool usingCheckDigit_) : Code39Reader::Code39Reader(bool usingCheckDigit_) {
alphabet_string(ALPHABET_STRING), init(usingCheckDigit_);
usingCheckDigit(usingCheckDigit_),
extendedMode(false) {
} }
Code39Reader::Code39Reader(bool usingCheckDigit_, bool extendedMode_) {
Code39Reader::Code39Reader(bool usingCheckDigit_, bool extendedMode_) : init(usingCheckDigit_, extendedMode_);
alphabet_string(ALPHABET_STRING), }
usingCheckDigit(usingCheckDigit_),
extendedMode(extendedMode_) {
}
Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) { Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
vector<int> counters (9, 0); { // Arrays.fill(counters, 0);
int size = counters.size();
counters.resize(0);
counters.resize(size); }
decodeRowResult.clear();
vector<int> start (findAsteriskPattern(row, counters)); vector<int> start (findAsteriskPattern(row, counters));
// Read off white space // Read off white space
int nextStart = row->getNextSet(start[1]); int nextStart = row->getNextSet(start[1]);
int end = row->getSize(); int end = row->getSize();
std::string result;
char decodedChar; char decodedChar;
int lastStart; int lastStart;
do { do {
@ -102,7 +109,7 @@ Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
throw NotFoundException();; throw NotFoundException();;
} }
decodedChar = patternToChar(pattern); decodedChar = patternToChar(pattern);
result.append(1, decodedChar); decodeRowResult.append(1, decodedChar);
lastStart = nextStart; lastStart = nextStart;
for (int i = 0, end=counters.size(); i < end; i++) { for (int i = 0, end=counters.size(); i < end; i++) {
nextStart += counters[i]; nextStart += counters[i];
@ -111,7 +118,7 @@ Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
nextStart = row->getNextSet(nextStart); nextStart = row->getNextSet(nextStart);
} while (decodedChar != '*'); } while (decodedChar != '*');
result.resize(result.length()-1);// remove asterisk decodeRowResult.resize(decodeRowResult.length()-1);// remove asterisk
// Look for whitespace after pattern: // Look for whitespace after pattern:
int lastPatternSize = 0; int lastPatternSize = 0;
@ -126,27 +133,27 @@ Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
} }
if (usingCheckDigit) { if (usingCheckDigit) {
int max = result.length() - 1; int max = decodeRowResult.length() - 1;
int total = 0; int total = 0;
for (int i = 0; i < max; i++) { for (int i = 0; i < max; i++) {
total += alphabet_string.find_first_of(result[i], 0); total += alphabet_string.find_first_of(decodeRowResult[i], 0);
} }
if (result[max] != ALPHABET[total % 43]) { if (decodeRowResult[max] != ALPHABET[total % 43]) {
throw ChecksumException(); throw ChecksumException();
} }
result.resize(max); decodeRowResult.resize(max);
} }
if (result.length() == 0) { if (decodeRowResult.length() == 0) {
// Almost false positive // Almost false positive
throw NotFoundException(); throw NotFoundException();
} }
Ref<String> resultString; Ref<String> resultString;
if (extendedMode) { if (extendedMode) {
resultString = decodeExtended(result); resultString = decodeExtended(decodeRowResult);
} else { } else {
resultString = Ref<String>(new String(result)); resultString = Ref<String>(new String(decodeRowResult));
} }
float left = (float) (start[1] + start[0]) / 2.0f; float left = (float) (start[1] + start[0]) / 2.0f;
@ -163,8 +170,7 @@ Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
); );
} }
vector<int> Code39Reader::findAsteriskPattern(Ref<BitArray> row, vector<int> Code39Reader::findAsteriskPattern(Ref<BitArray> row, vector<int>& counters){
vector<int>& counters){
int width = row->getSize(); int width = row->getSize();
int rowOffset = row->getNextSet(0); int rowOffset = row->getNextSet(0);

View file

@ -25,9 +25,9 @@
#include <zxing/Result.h> #include <zxing/Result.h>
namespace zxing { namespace zxing {
namespace oned { namespace oned {
class Code39Reader; class Code39Reader;
} }
} }
/** /**
@ -36,26 +36,28 @@ namespace zxing {
* @author Lukasz Warchol * @author Lukasz Warchol
*/ */
class zxing::oned::Code39Reader : public OneDReader { class zxing::oned::Code39Reader : public OneDReader {
private: private:
std::string alphabet_string; bool usingCheckDigit;
bool extendedMode;
std::string decodeRowResult;
std::vector<int> counters;
void init(bool usingCheckDigit = false, bool extendedMode = false);
bool usingCheckDigit; static std::vector<int> findAsteriskPattern(Ref<BitArray> row,
bool extendedMode; std::vector<int>& counters);
static int toNarrowWidePattern(std::vector<int>& counters);
static char patternToChar(int pattern);
static Ref<String> decodeExtended(std::string encoded);
static std::vector<int> findAsteriskPattern(Ref<BitArray> row, void append(char* s, char c);
std::vector<int>& counters);
static int toNarrowWidePattern(std::vector<int>& counters);
static char patternToChar(int pattern);
static Ref<String> decodeExtended(std::string encoded);
void append(char* s, char c);
public: public:
Code39Reader(); Code39Reader();
Code39Reader(bool usingCheckDigit_); Code39Reader(bool usingCheckDigit_);
Code39Reader(bool usingCheckDigit_, bool extendedMode_); Code39Reader(bool usingCheckDigit_, bool extendedMode_);
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row); Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
}; };
#endif #endif