c++ changes for r2542

git-svn-id: https://zxing.googlecode.com/svn/trunk@2614 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
smparkes@smparkes.net 2013-04-01 06:01:26 +00:00
parent 1b8b0113c7
commit 1d366b108b
6 changed files with 105 additions and 259 deletions

View file

@ -23,11 +23,6 @@
#include <vector>
#ifdef DEBUG_COUNTING
#include <iostream>
#include <typeinfo>
#endif
#include <zxing/common/Counted.h>
namespace zxing {
@ -58,23 +53,11 @@ public:
virtual ~Array() {
}
Array<T>& operator=(const Array<T> &other) {
#ifdef DEBUG_COUNTING
cout << "assigning values from Array " << &other << " to this Array " << this << ", ";
#endif
values_ = other.values_;
#ifdef DEBUG_COUNTING
cout << "new size = " << values_.size() << "\n";
#endif
return *this;
}
Array<T>& operator=(const std::vector<T> &array) {
#ifdef DEBUG_COUNTING
cout << "assigning values from Array " << &array << " to this Array " << this << ", ";
#endif
values_ = array;
#ifdef DEBUG_COUNTING
cout << "new size = " << values_.size() << "\n";
#endif
return *this;
}
T operator[](int i) const {
@ -103,53 +86,31 @@ public:
Array<T> *array_;
ArrayRef() :
array_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating empty ArrayRef " << this << "\n";
#endif
}
explicit ArrayRef(int n) :
array_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating ArrayRef " << this << "with size " << n << "\n";
#endif
reset(new Array<T> (n));
}
ArrayRef(T *ts, int n) :
array_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating ArrayRef " << this << "with " << n << " elements at " << (void *)ts << "\n";
#endif
reset(new Array<T> (ts, n));
}
ArrayRef(Array<T> *a) :
array_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating ArrayRef " << this << " from pointer:\n";
#endif
reset(a);
}
ArrayRef(const ArrayRef &other) :
Counted(), array_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";
#endif
reset(other.array_);
}
template<class Y>
ArrayRef(const ArrayRef<Y> &other) :
array_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";
#endif
reset(static_cast<const Array<T> *>(other.array_));
}
~ArrayRef() {
#ifdef DEBUG_COUNTING
cout << "destroying ArrayRef " << this << " with " << (array_ ? typeid(*array_).name() : "NULL") << " "
<< array_ << "\n";
#endif
if (array_) {
array_->release();
}
@ -167,10 +128,6 @@ public:
}
void reset(Array<T> *a) {
#ifdef DEBUG_COUNTING
cout << "resetting ArrayRef " << this << " from " << (array_ ? typeid(*array_).name() : "NULL") << " "
<< array_ << " to " << (a ? typeid(*a).name() : "NULL") << " " << a << "\n";
#endif
if (a) {
a->retain();
}

View file

@ -18,14 +18,8 @@
* limitations under the License.
*/
//#define DEBUG_COUNTING
#include <iostream>
#ifdef DEBUG_COUNTING
#include <typeinfo>
#endif
namespace zxing {
/* base class for reference-counted objects */
@ -35,43 +29,19 @@ private:
public:
Counted() :
count_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating " << typeid(*this).name() << " " << this <<
" @ " << count_ << "\n";
#endif
}
virtual ~Counted() {
}
Counted *retain() {
#ifdef DEBUG_COUNTING
cout << "retaining " << typeid(*this).name() << " " << this <<
" @ " << count_;
#endif
count_++;
#ifdef DEBUG_COUNTING
cout << "->" << count_ << "\n";
#endif
return this;
}
void release() {
#ifdef DEBUG_COUNTING
cout << "releasing " << typeid(*this).name() << " " << this <<
" @ " << count_;
#endif
if (count_ == 0 || count_ == 54321) {
#ifdef DEBUG_COUNTING
cout << "\nOverreleasing already-deleted object " << this << "!!!\n";
#endif
throw 4711;
}
count_--;
#ifdef DEBUG_COUNTING
cout << "->" << count_ << "\n";
#endif
if (count_ == 0) {
#ifdef DEBUG_COUNTING
cout << "deleting " << typeid(*this).name() << " " << this << "\n";
#endif
count_ = 0xDEADF001;
delete this;
}
@ -91,44 +61,26 @@ public:
T *object_;
explicit Ref(T *o = 0) :
object_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating Ref " << this << " from pointer" << o << "\n";
#endif
reset(o);
}
Ref(const Ref &other) :
object_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating Ref " << this << " from Ref " << &other << "\n";
#endif
reset(other.object_);
}
template<class Y>
Ref(const Ref<Y> &other) :
object_(0) {
#ifdef DEBUG_COUNTING
cout << "instantiating Ref " << this << " from reference\n";
#endif
reset(other.object_);
}
~Ref() {
#ifdef DEBUG_COUNTING
cout << "destroying Ref " << this << " with " <<
(object_ ? typeid(*object_).name() : "NULL") << " " << object_ << "\n";
#endif
if (object_) {
object_->release();
}
}
void reset(T *o) {
#ifdef DEBUG_COUNTING
cout << "resetting Ref " << this << " from " <<
(object_ ? typeid(*object_).name() : "NULL") << " " << object_ <<
" to " << (o ? typeid(*o).name() : "NULL") << " " << o << "\n";
#endif
if (o) {
o->retain();
}

View file

@ -34,45 +34,15 @@ DataMatrixReader::DataMatrixReader() :
Ref<Result> DataMatrixReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
(void)hints;
#ifdef DEBUG
cout << "decoding image " << image.object_ << ":\n" << flush;
#endif
Detector detector(image->getBlackMatrix());
#ifdef DEBUG
cout << "(1) created detector " << &detector << "\n" << flush;
#endif
Ref<DetectorResult> detectorResult(detector.detect());
#ifdef DEBUG
cout << "(2) detected, have detectorResult " << detectorResult.object_ << "\n" << flush;
#endif
ArrayRef< Ref<ResultPoint> > points(detectorResult->getPoints());
#ifdef DEBUG
cout << "(3) extracted points " << &points << "\n" << flush;
cout << "found " << points.size() << " points:\n";
for (size_t i = 0; i < points.size(); i++) {
cout << " " << points[i]->getX() << "," << points[i]->getY() << "\n";
}
cout << "bits:\n";
cout << *(detectorResult->getBits()) << "\n";
#endif
Ref<DecoderResult> decoderResult(decoder_.decode(detectorResult->getBits()));
#ifdef DEBUG
cout << "(4) decoded, have decoderResult " << decoderResult.object_ << "\n" << flush;
#endif
Ref<Result> result(
new Result(decoderResult->getText(), decoderResult->getRawBytes(), points, BarcodeFormat::DATA_MATRIX));
#ifdef DEBUG
cout << "(5) created result " << result.object_ << ", returning\n" << flush;
#endif
return result;
}

View file

@ -33,45 +33,12 @@ namespace zxing {
}
//TODO: see if any of the other files in the qrcode tree need tryHarder
Ref<Result> QRCodeReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
#ifdef DEBUG
cout << "decoding image " << image.object_ << ":\n" << flush;
#endif
Detector detector(image->getBlackMatrix());
#ifdef DEBUG
cout << "(1) created detector " << &detector << "\n" << flush;
#endif
Ref<DetectorResult> detectorResult(detector.detect(hints));
#ifdef DEBUG
cout << "(2) detected, have detectorResult " << detectorResult.object_ << "\n" << flush;
#endif
ArrayRef< Ref<ResultPoint> > points (detectorResult->getPoints());
#ifdef DEBUG
cout << "(3) extracted points " << &points << "\n" << flush;
cout << "found " << points.size() << " points:\n";
for (size_t i = 0; i < points.size(); i++) {
cout << " " << points[i]->getX() << "," << points[i]->getY() << "\n";
}
cout << "bits:\n";
cout << *(detectorResult->getBits()) << "\n";
#endif
Ref<DecoderResult> decoderResult(decoder_.decode(detectorResult->getBits()));
#ifdef DEBUG
cout << "(4) decoded, have decoderResult " << decoderResult.object_ << "\n" << flush;
#endif
Ref<Result> result(
new Result(decoderResult->getText(), decoderResult->getRawBytes(), points, BarcodeFormat::QR_CODE));
#ifdef DEBUG
cout << "(5) created result " << result.object_ << ", returning\n" << flush;
#endif
return result;
}

View file

@ -196,12 +196,6 @@ Ref<BitMatrix> Version::buildFunctionPattern() {
functionPattern->setRegion(0, dimension - 11, 6, 3);
}
//#ifdef DEBUG
// cout << "version " << versionNumber_ << " built function pattern:\n";
// cout << *functionPattern;
//#endif
return functionPattern;
}

View file

@ -44,11 +44,11 @@ using namespace zxing::qrcode;
using namespace zxing::common;
const char DecodedBitStreamParser::ALPHANUMERIC_CHARS[] =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'
};
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'
};
namespace {int GB2312_SUBSET = 1;}
@ -103,44 +103,44 @@ void DecodedBitStreamParser::append(std::string &result,
void DecodedBitStreamParser::decodeHanziSegment(Ref<BitSource> bits_,
string& result,
int count) {
BitSource& bits (*bits_);
// Don't crash trying to read more bits than we have available.
if (count * 13 > bits.available()) {
throw FormatException();
}
// Each character will require 2 bytes. Read the characters as 2-byte pairs
// and decode as GB2312 afterwards
size_t nBytes = 2 * count;
char* buffer = new char[nBytes];
int offset = 0;
while (count > 0) {
// Each 13 bits encodes a 2-byte character
int twoBytes = bits.readBits(13);
int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
if (assembledTwoBytes < 0x003BF) {
// In the 0xA1A1 to 0xAAFE range
assembledTwoBytes += 0x0A1A1;
} else {
// In the 0xB0A1 to 0xFAFE range
assembledTwoBytes += 0x0A6A1;
}
buffer[offset] = (char) ((assembledTwoBytes >> 8) & 0xFF);
buffer[offset + 1] = (char) (assembledTwoBytes & 0xFF);
offset += 2;
count--;
}
try {
append(result, buffer, nBytes, StringUtils::GB2312);
} catch (ReaderException const& re) {
delete [] buffer;
throw FormatException();
}
delete [] buffer;
BitSource& bits (*bits_);
// Don't crash trying to read more bits than we have available.
if (count * 13 > bits.available()) {
throw FormatException();
}
// Each character will require 2 bytes. Read the characters as 2-byte pairs
// and decode as GB2312 afterwards
size_t nBytes = 2 * count;
char* buffer = new char[nBytes];
int offset = 0;
while (count > 0) {
// Each 13 bits encodes a 2-byte character
int twoBytes = bits.readBits(13);
int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
if (assembledTwoBytes < 0x003BF) {
// In the 0xA1A1 to 0xAAFE range
assembledTwoBytes += 0x0A1A1;
} else {
// In the 0xB0A1 to 0xFAFE range
assembledTwoBytes += 0x0A6A1;
}
buffer[offset] = (char) ((assembledTwoBytes >> 8) & 0xFF);
buffer[offset + 1] = (char) (assembledTwoBytes & 0xFF);
offset += 2;
count--;
}
try {
append(result, buffer, nBytes, StringUtils::GB2312);
} catch (ReaderException const& re) {
delete [] buffer;
throw FormatException();
}
delete [] buffer;
}
void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, std::string &result, int count) {
// Each character will require 2 bytes. Read the characters as 2-byte pairs
// and decode as Shift_JIS afterwards
@ -342,70 +342,76 @@ DecodedBitStreamParser::decode(ArrayRef<char> bytes,
Ref<BitSource> bits_ (new BitSource(bytes));
BitSource& bits (*bits_);
string result;
CharacterSetECI* currentCharacterSetECI = 0;
bool fc1InEffect = false;
result.reserve(50);
ArrayRef< ArrayRef<char> > byteSegments (0);
Mode* mode = 0;
do {
// While still another segment to read...
if (bits.available() < 4) {
// OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
mode = &Mode::TERMINATOR;
} else {
try {
mode = &Mode::forBits(bits.readBits(4)); // mode is encoded by 4 bits
} catch (IllegalArgumentException const& iae) {
throw iae;
// throw FormatException.getFormatInstance();
}
}
if (mode != &Mode::TERMINATOR) {
if ((mode == &Mode::FNC1_FIRST_POSITION) || (mode == &Mode::FNC1_SECOND_POSITION)) {
// We do little with FNC1 except alter the parsed result a bit according to the spec
fc1InEffect = true;
} else if (mode == &Mode::STRUCTURED_APPEND) {
if (bits.available() < 16) {
throw FormatException();
}
// not really supported; all we do is ignore it
// Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
bits.readBits(16);
} else if (mode == &Mode::ECI) {
// Count doesn't apply to ECI
int value = parseECIValue(bits);
currentCharacterSetECI = CharacterSetECI::getCharacterSetECIByValue(value);
if (currentCharacterSetECI == 0) {
throw FormatException();
}
try {
CharacterSetECI* currentCharacterSetECI = 0;
bool fc1InEffect = false;
Mode* mode = 0;
do {
// While still another segment to read...
if (bits.available() < 4) {
// OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
mode = &Mode::TERMINATOR;
} else {
// First handle Hanzi mode which does not start with character count
if (mode == &Mode::HANZI) {
//chinese mode contains a sub set indicator right after mode indicator
int subset = bits.readBits(4);
int countHanzi = bits.readBits(mode->getCharacterCountBits(version));
if (subset == GB2312_SUBSET) {
decodeHanziSegment(bits_, result, countHanzi);
}
} else {
// "Normal" QR code modes:
// How many characters will follow, encoded in this mode?
int count = bits.readBits(mode->getCharacterCountBits(version));
if (mode == &Mode::NUMERIC) {
decodeNumericSegment(bits_, result, count);
} else if (mode == &Mode::ALPHANUMERIC) {
decodeAlphanumericSegment(bits_, result, count, fc1InEffect);
} else if (mode == &Mode::BYTE) {
decodeByteSegment(bits_, result, count, currentCharacterSetECI, byteSegments, hints);
} else if (mode == &Mode::KANJI) {
decodeKanjiSegment(bits_, result, count);
} else {
try {
mode = &Mode::forBits(bits.readBits(4)); // mode is encoded by 4 bits
} catch (IllegalArgumentException const& iae) {
throw iae;
// throw FormatException.getFormatInstance();
}
}
if (mode != &Mode::TERMINATOR) {
if ((mode == &Mode::FNC1_FIRST_POSITION) || (mode == &Mode::FNC1_SECOND_POSITION)) {
// We do little with FNC1 except alter the parsed result a bit according to the spec
fc1InEffect = true;
} else if (mode == &Mode::STRUCTURED_APPEND) {
if (bits.available() < 16) {
throw FormatException();
}
// not really supported; all we do is ignore it
// Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
bits.readBits(16);
} else if (mode == &Mode::ECI) {
// Count doesn't apply to ECI
int value = parseECIValue(bits);
currentCharacterSetECI = CharacterSetECI::getCharacterSetECIByValue(value);
if (currentCharacterSetECI == 0) {
throw FormatException();
}
} else {
// First handle Hanzi mode which does not start with character count
if (mode == &Mode::HANZI) {
//chinese mode contains a sub set indicator right after mode indicator
int subset = bits.readBits(4);
int countHanzi = bits.readBits(mode->getCharacterCountBits(version));
if (subset == GB2312_SUBSET) {
decodeHanziSegment(bits_, result, countHanzi);
}
} else {
// "Normal" QR code modes:
// How many characters will follow, encoded in this mode?
int count = bits.readBits(mode->getCharacterCountBits(version));
if (mode == &Mode::NUMERIC) {
decodeNumericSegment(bits_, result, count);
} else if (mode == &Mode::ALPHANUMERIC) {
decodeAlphanumericSegment(bits_, result, count, fc1InEffect);
} else if (mode == &Mode::BYTE) {
decodeByteSegment(bits_, result, count, currentCharacterSetECI, byteSegments, hints);
} else if (mode == &Mode::KANJI) {
decodeKanjiSegment(bits_, result, count);
} else {
throw FormatException();
}
}
}
}
}
} while (mode != &Mode::TERMINATOR);
} while (mode != &Mode::TERMINATOR);
} catch (IllegalArgumentException const& iae) {
// from readBits() calls
throw FormatException();
}
return Ref<DecoderResult>(new DecoderResult(bytes, Ref<String>(new String(result)), byteSegments, (string)ecLevel));
}