mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
c++ changes for r2542
git-svn-id: https://zxing.googlecode.com/svn/trunk@2614 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
1b8b0113c7
commit
1d366b108b
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue