mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Updated the zxing folder with the latest SVN version, changed the CameraImageWrapper to comply with the new library version and changed the PRO file (added a MACRO)
git-svn-id: https://zxing.googlecode.com/svn/trunk@1341 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
2407314d99
commit
3ca1966aa2
|
@ -8,48 +8,64 @@ CameraImageWrapper::CameraImageWrapper() : LuminanceSource()
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraImageWrapper::CameraImageWrapper(CameraImageWrapper& otherInstance) : LuminanceSource()
|
CameraImageWrapper::CameraImageWrapper(CameraImageWrapper& otherInstance) : LuminanceSource()
|
||||||
{
|
{
|
||||||
image = otherInstance.getOriginalImage().copy();
|
image = otherInstance.getOriginalImage().copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraImageWrapper::~CameraImageWrapper()
|
CameraImageWrapper::~CameraImageWrapper()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int CameraImageWrapper::getWidth()
|
int CameraImageWrapper::getWidth() const
|
||||||
{
|
{
|
||||||
return image.width();
|
return image.width();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CameraImageWrapper::getHeight()
|
int CameraImageWrapper::getHeight() const
|
||||||
{
|
{
|
||||||
return image.height();
|
return image.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char CameraImageWrapper::getPixel(int x, int y)
|
unsigned char CameraImageWrapper::getPixel(int x, int y) const
|
||||||
{
|
{
|
||||||
QRgb pixel = image.pixel(x,y);
|
QRgb pixel = image.pixel(x,y);
|
||||||
|
|
||||||
return qGray(pixel);//((qRed(pixel) + qGreen(pixel) + qBlue(pixel)) / 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraImageWrapper::setImage(QString fileName, char* format)
|
return qGray(pixel);//((qRed(pixel) + qGreen(pixel) + qBlue(pixel)) / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* CameraImageWrapper::copyMatrix() const
|
||||||
|
{
|
||||||
|
unsigned char* newMatrix = (unsigned char*)malloc(image.width()*image.height()*sizeof(unsigned char));
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
for(int i=0; i<image.width(); i++)
|
||||||
|
{
|
||||||
|
for(int j=0; j<image.height(); j++)
|
||||||
|
{
|
||||||
|
newMatrix[cnt++] = getPixel(i,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraImageWrapper::setImage(QString fileName)
|
||||||
{
|
{
|
||||||
image.load(fileName);
|
image.load(fileName);
|
||||||
|
|
||||||
if(image.width() > QApplication::desktop()->width())
|
if(image.width() > QApplication::desktop()->width())
|
||||||
image = image.scaled(QApplication::desktop()->width(), image.height(), Qt::IgnoreAspectRatio);
|
image = image.scaled(QApplication::desktop()->width(), image.height(), Qt::IgnoreAspectRatio);
|
||||||
|
|
||||||
if(image.height() > QApplication::desktop()->height())
|
if(image.height() > QApplication::desktop()->height())
|
||||||
image = image.scaled(image.width(), QApplication::desktop()->height(), Qt::IgnoreAspectRatio);
|
image = image.scaled(image.width(), QApplication::desktop()->height(), Qt::IgnoreAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraImageWrapper::setImage(QImage newImage)
|
void CameraImageWrapper::setImage(QImage newImage)
|
||||||
{
|
{
|
||||||
image = newImage.copy();
|
image = newImage.copy();
|
||||||
|
|
||||||
if(image.width() > 640)
|
if(image.width() > 640)
|
||||||
image = image.scaled(640, image.height(), Qt::KeepAspectRatio);
|
image = image.scaled(640, image.height(), Qt::KeepAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage CameraImageWrapper::grayScaleImage(QImage::Format f)
|
QImage CameraImageWrapper::grayScaleImage(QImage::Format f)
|
||||||
|
@ -63,15 +79,15 @@ QImage CameraImageWrapper::grayScaleImage(QImage::Format f)
|
||||||
tmp.setPixel(i,j, qRgb(pix ,pix,pix));
|
tmp.setPixel(i,j, qRgb(pix ,pix,pix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
||||||
//return image.convertToFormat(f);
|
//return image.convertToFormat(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage CameraImageWrapper::getOriginalImage()
|
QImage CameraImageWrapper::getOriginalImage()
|
||||||
{
|
{
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,13 @@ public:
|
||||||
CameraImageWrapper(CameraImageWrapper& otherInstance);
|
CameraImageWrapper(CameraImageWrapper& otherInstance);
|
||||||
~CameraImageWrapper();
|
~CameraImageWrapper();
|
||||||
|
|
||||||
int getWidth();
|
int getWidth() const;
|
||||||
int getHeight();
|
int getHeight() const;
|
||||||
|
|
||||||
unsigned char getPixel(int x, int y);
|
unsigned char getPixel(int x, int y) const;
|
||||||
|
unsigned char* copyMatrix() const;
|
||||||
|
|
||||||
void setImage(QString fileName, char* format);
|
void setImage(QString fileName);
|
||||||
void setImage(QImage newImage);
|
void setImage(QImage newImage);
|
||||||
QImage grayScaleImage(QImage::Format f);
|
QImage grayScaleImage(QImage::Format f);
|
||||||
QImage getOriginalImage();
|
QImage getOriginalImage();
|
||||||
|
|
|
@ -156,4 +156,6 @@ symbian {
|
||||||
DEPLOYMENT += customrules
|
DEPLOYMENT += customrules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINES += ZXING_ICONV_CONST
|
||||||
|
|
||||||
ICON = QQrDecoder.svg
|
ICON = QQrDecoder.svg
|
||||||
|
|
Binary file not shown.
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
|
||||||
Binarizer::Binarizer(Ref<LuminanceSource> source) : source_(source) {
|
Binarizer::Binarizer(Ref<LuminanceSource> source) : source_(source), array_(NULL), matrix_(NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Binarizer::~Binarizer() {
|
Binarizer::~Binarizer() {
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
|
||||||
BinaryBitmap::BinaryBitmap(Ref<Binarizer> binarizer) : bits_(NULL), binarizer_(binarizer) {
|
BinaryBitmap::BinaryBitmap(Ref<Binarizer> binarizer) : bits_(NULL), array_bits_(NULL), binarizer_(binarizer) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ Exception::Exception(const char *msg) :
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Exception::what() const throw() {
|
const char* Exception::what() const throw() {
|
||||||
return message;
|
return message.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
Exception::~Exception() throw() {
|
Exception::~Exception() throw() {
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace zxing {
|
||||||
|
|
||||||
class Exception : public std::exception {
|
class Exception : public std::exception {
|
||||||
private:
|
private:
|
||||||
const char * message;
|
std::string message;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Exception(const char *msg);
|
Exception(const char *msg);
|
||||||
|
|
|
@ -28,7 +28,7 @@ LuminanceSource::LuminanceSource() {
|
||||||
LuminanceSource::~LuminanceSource() {
|
LuminanceSource::~LuminanceSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* LuminanceSource::copyMatrix() {
|
unsigned char* LuminanceSource::copyMatrix() const {
|
||||||
int width = getWidth();
|
int width = getWidth();
|
||||||
int height = getHeight();
|
int height = getHeight();
|
||||||
unsigned char* matrix = new unsigned char[width*height];
|
unsigned char* matrix = new unsigned char[width*height];
|
||||||
|
|
|
@ -30,11 +30,11 @@ public:
|
||||||
LuminanceSource();
|
LuminanceSource();
|
||||||
virtual ~LuminanceSource();
|
virtual ~LuminanceSource();
|
||||||
|
|
||||||
virtual int getWidth() = 0;
|
virtual int getWidth() const = 0;
|
||||||
virtual int getHeight() = 0;
|
virtual int getHeight() const = 0;
|
||||||
|
|
||||||
virtual unsigned char getPixel(int x, int y) = 0;
|
virtual unsigned char getPixel(int x, int y) const = 0;
|
||||||
virtual unsigned char* copyMatrix();
|
virtual unsigned char* copyMatrix() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,19 +27,17 @@
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
MultiFormatReader::MultiFormatReader(){
|
MultiFormatReader::MultiFormatReader() : readers() {
|
||||||
readers = new std::vector<Reader*>();
|
readers.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader()));
|
||||||
|
//readers.push_back(Ref<Reader>(new zxing::datamatrix::DataMatrixReader()));
|
||||||
readers->push_back(new zxing::qrcode::QRCodeReader());
|
readers.push_back(Ref<Reader>(new zxing::oned::MultiFormatUPCEANReader()));
|
||||||
// readers->push_back(new zxing::datamatrix::DataMatrixReader());
|
readers.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader()));
|
||||||
readers->push_back(new zxing::oned::MultiFormatUPCEANReader());
|
|
||||||
readers->push_back(new zxing::oned::MultiFormatOneDReader());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image){
|
Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image){
|
||||||
int size = readers->size();
|
int size = readers.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
Reader* reader = (*readers)[i];
|
Ref<Reader> reader = readers[i];
|
||||||
try {
|
try {
|
||||||
return reader->decode(image);
|
return reader->decode(image);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException re) {
|
||||||
|
@ -48,7 +46,4 @@ namespace zxing {
|
||||||
}
|
}
|
||||||
throw ReaderException("No code detected");
|
throw ReaderException("No code detected");
|
||||||
}
|
}
|
||||||
MultiFormatReader::~MultiFormatReader(){
|
|
||||||
delete readers;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,11 @@ namespace zxing {
|
||||||
class MultiFormatReader : public Reader {
|
class MultiFormatReader : public Reader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Reader*>* readers;
|
std::vector<Ref<Reader> >readers;
|
||||||
public:
|
public:
|
||||||
MultiFormatReader();
|
MultiFormatReader();
|
||||||
|
|
||||||
Ref<Result> decode(Ref<BinaryBitmap> image);
|
Ref<Result> decode(Ref<BinaryBitmap> image);
|
||||||
|
|
||||||
~MultiFormatReader();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,16 +21,17 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <zxing/BinaryBitmap.h>
|
#include <zxing/BinaryBitmap.h>
|
||||||
#include <zxing/Result.h>
|
#include <zxing/Result.h>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
|
||||||
class Reader {
|
class Reader : public Counted {
|
||||||
public:
|
protected:
|
||||||
virtual Ref<Result> decode(Ref<BinaryBitmap> image) = 0;
|
Reader() {}
|
||||||
virtual ~Reader();
|
public:
|
||||||
|
virtual Ref<Result> decode(Ref<BinaryBitmap> image) = 0;
|
||||||
|
virtual ~Reader();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,11 @@ ArrayRef<unsigned char> Result::getRawBytes() {
|
||||||
return rawBytes_;
|
return rawBytes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Ref<ResultPoint> > Result::getResultPoints() {
|
const std::vector<Ref<ResultPoint> >& Result::getResultPoints() const {
|
||||||
return resultPoints_;
|
return resultPoints_;
|
||||||
}
|
}
|
||||||
|
|
||||||
BarcodeFormat Result::getBarcodeFormat() {
|
BarcodeFormat Result::getBarcodeFormat() const {
|
||||||
return format_;
|
return format_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,8 @@ public:
|
||||||
~Result();
|
~Result();
|
||||||
Ref<String> getText();
|
Ref<String> getText();
|
||||||
ArrayRef<unsigned char> getRawBytes();
|
ArrayRef<unsigned char> getRawBytes();
|
||||||
std::vector<Ref<ResultPoint> > getResultPoints();
|
const std::vector<Ref<ResultPoint> >& getResultPoints() const;
|
||||||
BarcodeFormat getBarcodeFormat();
|
BarcodeFormat getBarcodeFormat() const;
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream &out, Result& result);
|
friend std::ostream& operator<<(std::ostream &out, Result& result);
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,9 +26,11 @@
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
|
||||||
class ResultPoint : public Counted {
|
class ResultPoint : public Counted {
|
||||||
|
protected:
|
||||||
|
ResultPoint() {}
|
||||||
public:
|
public:
|
||||||
virtual float getX() = 0;
|
virtual float getX() const = 0;
|
||||||
virtual float getY() = 0;
|
virtual float getY() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <valarray>
|
#include <vector>
|
||||||
#include <cstdarg>
|
|
||||||
|
|
||||||
#ifdef DEBUG_COUNTING
|
#ifdef DEBUG_COUNTING
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -37,17 +36,17 @@ namespace zxing {
|
||||||
template<typename T> class Array : public Counted {
|
template<typename T> class Array : public Counted {
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
std::valarray<T> values_;
|
std::vector<T> values_;
|
||||||
Array(size_t n) :
|
Array(size_t n) :
|
||||||
Counted(), values_(T(), n) {
|
Counted(), values_(n, T()) {
|
||||||
}
|
}
|
||||||
Array(T *ts, size_t n) :
|
Array(T *ts, size_t n) :
|
||||||
Counted(), values_(ts, n) {
|
Counted(), values_(ts, ts+n) {
|
||||||
}
|
}
|
||||||
Array(T v, size_t n) :
|
Array(T v, size_t n) :
|
||||||
Counted(), values_(v, n) {
|
Counted(), values_(n, v) {
|
||||||
}
|
}
|
||||||
Array(std::valarray<T> &v) :
|
Array(std::vector<T> &v) :
|
||||||
Counted(), values_(v) {
|
Counted(), values_(v) {
|
||||||
}
|
}
|
||||||
Array(Array<T> &other) :
|
Array(Array<T> &other) :
|
||||||
|
@ -68,7 +67,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Array<T>& operator=(const std::valarray<T> &array) {
|
Array<T>& operator=(const std::vector<T> &array) {
|
||||||
#ifdef DEBUG_COUNTING
|
#ifdef DEBUG_COUNTING
|
||||||
cout << "assigning values from Array " << &array << " to this Array " << this << ", ";
|
cout << "assigning values from Array " << &array << " to this Array " << this << ", ";
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,10 +86,10 @@ public:
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return values_.size();
|
return values_.size();
|
||||||
}
|
}
|
||||||
std::valarray<T> values() const {
|
std::vector<T> values() const {
|
||||||
return values_;
|
return values_;
|
||||||
}
|
}
|
||||||
std::valarray<T>& values() {
|
std::vector<T>& values() {
|
||||||
return values_;
|
return values_;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <zxing/common/BitArray.h>
|
#include <zxing/common/BitArray.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -43,12 +44,9 @@ size_t BitArray::wordsForBits(size_t bits) {
|
||||||
}
|
}
|
||||||
return arraySize;
|
return arraySize;
|
||||||
}
|
}
|
||||||
BitArray::BitArray() {
|
|
||||||
cout << "hey! don't use this BitArrayConstructor!\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
BitArray::BitArray(size_t size) :
|
BitArray::BitArray(size_t size) :
|
||||||
size_(size), bits_((const unsigned int)0, wordsForBits(size)) {
|
size_(size), bits_(wordsForBits(size), (const unsigned int)0) {
|
||||||
}
|
}
|
||||||
BitArray::~BitArray() {
|
BitArray::~BitArray() {
|
||||||
}
|
}
|
||||||
|
@ -105,7 +103,7 @@ bool BitArray::isRange(size_t start, size_t end, bool value) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
valarray<unsigned int>& BitArray::getBitArray() {
|
vector<unsigned int>& BitArray::getBitArray() {
|
||||||
return bits_;
|
return bits_;
|
||||||
}
|
}
|
||||||
void BitArray::reverse() {
|
void BitArray::reverse() {
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
|
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
#include <zxing/common/IllegalArgumentException.h>
|
#include <zxing/common/IllegalArgumentException.h>
|
||||||
#include <valarray>
|
#include <vector>
|
||||||
#include <limits>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
@ -32,7 +31,7 @@ namespace zxing {
|
||||||
class BitArray : public Counted {
|
class BitArray : public Counted {
|
||||||
private:
|
private:
|
||||||
size_t size_;
|
size_t size_;
|
||||||
std::valarray<unsigned int> bits_;
|
std::vector<unsigned int> bits_;
|
||||||
static const unsigned int bitsPerWord_;
|
static const unsigned int bitsPerWord_;
|
||||||
static const unsigned int logBits_;
|
static const unsigned int logBits_;
|
||||||
static const unsigned int bitsMask_;
|
static const unsigned int bitsMask_;
|
||||||
|
@ -48,7 +47,7 @@ public:
|
||||||
void setBulk(size_t i, unsigned int newBits);
|
void setBulk(size_t i, unsigned int newBits);
|
||||||
void clear();
|
void clear();
|
||||||
bool isRange(size_t start, size_t end, bool value);
|
bool isRange(size_t start, size_t end, bool value);
|
||||||
std::valarray<unsigned int>& getBitArray();
|
std::vector<unsigned int>& getBitArray();
|
||||||
void reverse();
|
void reverse();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -40,7 +39,7 @@ unsigned int logDigits(unsigned digits) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const unsigned int bitsPerWord = std::numeric_limits<unsigned int>::digits;
|
const unsigned int bitsPerWord = numeric_limits<unsigned int>::digits;
|
||||||
const unsigned int logBits = logDigits(bitsPerWord);
|
const unsigned int logBits = logDigits(bitsPerWord);
|
||||||
const unsigned int bitsMask = (1 << logBits) - 1;
|
const unsigned int bitsMask = (1 << logBits) - 1;
|
||||||
|
|
||||||
|
@ -54,7 +53,7 @@ static size_t wordsForSize(size_t width, size_t height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BitMatrix::BitMatrix(size_t dimension) :
|
BitMatrix::BitMatrix(size_t dimension) :
|
||||||
width_(dimension), height_(dimension), bits_(NULL) {
|
width_(dimension), height_(dimension), words_(0), bits_(NULL) {
|
||||||
|
|
||||||
words_ = wordsForSize(width_, height_);
|
words_ = wordsForSize(width_, height_);
|
||||||
bits_ = new unsigned int[words_];
|
bits_ = new unsigned int[words_];
|
||||||
|
@ -62,7 +61,7 @@ BitMatrix::BitMatrix(size_t dimension) :
|
||||||
}
|
}
|
||||||
|
|
||||||
BitMatrix::BitMatrix(size_t width, size_t height) :
|
BitMatrix::BitMatrix(size_t width, size_t height) :
|
||||||
width_(width), height_(height), bits_(NULL) {
|
width_(width), height_(height), words_(0), bits_(NULL) {
|
||||||
|
|
||||||
words_ = wordsForSize(width_, height_);
|
words_ = wordsForSize(width_, height_);
|
||||||
bits_ = new unsigned int[words_];
|
bits_ = new unsigned int[words_];
|
||||||
|
@ -90,7 +89,7 @@ void BitMatrix::flip(size_t x, size_t y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitMatrix::clear() {
|
void BitMatrix::clear() {
|
||||||
std::memset(bits_, 0, sizeof(unsigned int) * words_);
|
std::fill(bits_, bits_+words_, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitMatrix::setRegion(size_t left, size_t top, size_t width, size_t height) {
|
void BitMatrix::setRegion(size_t left, size_t top, size_t width, size_t height) {
|
||||||
|
@ -126,11 +125,11 @@ size_t BitMatrix::getDimension() const {
|
||||||
return width_;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int* BitMatrix::getBits() {
|
unsigned int* BitMatrix::getBits() const {
|
||||||
return bits_;
|
return bits_;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& operator<<(ostream &out, BitMatrix &bm) {
|
ostream& operator<<(ostream &out, const BitMatrix &bm) {
|
||||||
for (size_t y = 0; y < bm.height_; y++) {
|
for (size_t y = 0; y < bm.height_; y++) {
|
||||||
for (size_t x = 0; x < bm.width_; x++) {
|
for (size_t x = 0; x < bm.width_; x++) {
|
||||||
out << (bm.get(x, y) ? "X " : " ");
|
out << (bm.get(x, y) ? "X " : " ");
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
#include <valarray>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
@ -50,10 +49,14 @@ public:
|
||||||
size_t getWidth() const;
|
size_t getWidth() const;
|
||||||
size_t getHeight() const;
|
size_t getHeight() const;
|
||||||
|
|
||||||
unsigned int* getBits();
|
unsigned int* getBits() const;
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream &out, BitMatrix &bm);
|
friend std::ostream& operator<<(std::ostream &out, const BitMatrix &bm);
|
||||||
const char *description();
|
const char *description();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BitMatrix(const BitMatrix&);
|
||||||
|
BitMatrix& operator =(const BitMatrix&);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,8 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_COUNTING
|
#ifdef DEBUG_COUNTING
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
using namespace std;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
@ -174,10 +172,10 @@ public:
|
||||||
T& operator*() {
|
T& operator*() {
|
||||||
return *object_;
|
return *object_;
|
||||||
}
|
}
|
||||||
T* operator->() {
|
T* operator->() const {
|
||||||
return object_;
|
return object_;
|
||||||
}
|
}
|
||||||
operator T*() {
|
operator T*() const {
|
||||||
return object_;
|
return object_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <zxing/common/EdgeDetector.h>
|
#include <zxing/common/EdgeDetector.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace zxing {
|
||||||
|
|
||||||
|
|
||||||
Ref<BitArray> GlobalHistogramBinarizer::estimateBlackRow(int y, Ref<BitArray> row){
|
Ref<BitArray> GlobalHistogramBinarizer::estimateBlackRow(int y, Ref<BitArray> row){
|
||||||
valarray<int> histogram(0, LUMINANCE_BUCKETS);
|
vector<int> histogram(LUMINANCE_BUCKETS, 0);
|
||||||
LuminanceSource& source = *getSource();
|
LuminanceSource& source = *getSource();
|
||||||
int width = source.getWidth();
|
int width = source.getWidth();
|
||||||
if (row == NULL || row->getSize() < width) {
|
if (row == NULL || row->getSize() < width) {
|
||||||
|
@ -80,7 +80,7 @@ namespace zxing {
|
||||||
LuminanceSource& source = *getSource();
|
LuminanceSource& source = *getSource();
|
||||||
int width = source.getWidth();
|
int width = source.getWidth();
|
||||||
int height = source.getHeight();
|
int height = source.getHeight();
|
||||||
valarray<int> histogram(0, LUMINANCE_BUCKETS);
|
vector<int> histogram(LUMINANCE_BUCKETS, 0);
|
||||||
|
|
||||||
|
|
||||||
// Quickly calculates the histogram by sampling four rows from the image. This proved to be
|
// Quickly calculates the histogram by sampling four rows from the image. This proved to be
|
||||||
|
@ -109,7 +109,7 @@ namespace zxing {
|
||||||
return matrix_ref;
|
return matrix_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GlobalHistogramBinarizer::estimate(valarray<int> &histogram) {
|
int GlobalHistogramBinarizer::estimate(vector<int> &histogram) {
|
||||||
int numBuckets = histogram.size();
|
int numBuckets = histogram.size();
|
||||||
int maxBucketCount = 0;
|
int maxBucketCount = 0;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#ifndef GLOBALHISTOGRAMBINARIZER_H_
|
#ifndef GLOBALHISTOGRAMBINARIZER_H_
|
||||||
#define GLOBALHISTOGRAMBINARIZER_H_
|
#define GLOBALHISTOGRAMBINARIZER_H_
|
||||||
|
|
||||||
#include <valarray>
|
#include <vector>
|
||||||
#include <zxing/Binarizer.h>
|
#include <zxing/Binarizer.h>
|
||||||
#include <zxing/common/BitArray.h>
|
#include <zxing/common/BitArray.h>
|
||||||
#include <zxing/common/BitMatrix.h>
|
#include <zxing/common/BitMatrix.h>
|
||||||
|
@ -36,7 +36,7 @@ namespace zxing {
|
||||||
|
|
||||||
virtual Ref<BitArray> estimateBlackRow(int y, Ref<BitArray> row);
|
virtual Ref<BitArray> estimateBlackRow(int y, Ref<BitArray> row);
|
||||||
virtual Ref<BitMatrix> estimateBlackMatrix();
|
virtual Ref<BitMatrix> estimateBlackMatrix();
|
||||||
static int estimate(std::valarray<int> &histogram);
|
static int estimate(std::vector<int> &histogram);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ GridSampler::GridSampler() {
|
||||||
|
|
||||||
Ref<BitMatrix> GridSampler::sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform) {
|
Ref<BitMatrix> GridSampler::sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform) {
|
||||||
Ref<BitMatrix> bits(new BitMatrix(dimension));
|
Ref<BitMatrix> bits(new BitMatrix(dimension));
|
||||||
valarray<float> points((const float)0.0f, dimension << 1);
|
vector<float> points(dimension << 1, (const float)0.0f);
|
||||||
for (int y = 0; y < dimension; y++) {
|
for (int y = 0; y < dimension; y++) {
|
||||||
int max = points.size();
|
int max = points.size();
|
||||||
float yValue = (float)y + 0.5f;
|
float yValue = (float)y + 0.5f;
|
||||||
|
@ -63,7 +63,7 @@ Ref<BitMatrix> GridSampler::sampleGrid(Ref<BitMatrix> image, int dimension, floa
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GridSampler::checkAndNudgePoints(Ref<BitMatrix> image, valarray<float> &points) {
|
void GridSampler::checkAndNudgePoints(Ref<BitMatrix> image, vector<float> &points) {
|
||||||
int width = image->getWidth();
|
int width = image->getWidth();
|
||||||
int height = image->getHeight();
|
int height = image->getHeight();
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, float p1ToX, float p1ToY, float p2ToX, float p2ToY,
|
Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, float p1ToX, float p1ToY, float p2ToX, float p2ToY,
|
||||||
float p3ToX, float p3ToY, float p4ToX, float p4ToY, float p1FromX, float p1FromY, float p2FromX,
|
float p3ToX, float p3ToY, float p4ToX, float p4ToY, float p1FromX, float p1FromY, float p2FromX,
|
||||||
float p2FromY, float p3FromX, float p3FromY, float p4FromX, float p4FromY);
|
float p2FromY, float p3FromX, float p3FromY, float p4FromX, float p4FromY);
|
||||||
static void checkAndNudgePoints(Ref<BitMatrix> image, std::valarray<float> &points);
|
static void checkAndNudgePoints(Ref<BitMatrix> image, std::vector<float> &points);
|
||||||
static GridSampler &getInstance();
|
static GridSampler &getInstance();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,18 +23,13 @@
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
PerspectiveTransform::PerspectiveTransform(float a11, float a21, float a31, float a12, float a22, float a32, float a13,
|
PerspectiveTransform::PerspectiveTransform(float inA11, float inA21,
|
||||||
float a23, float a33) {
|
float inA31, float inA12,
|
||||||
this->a11 = a11;
|
float inA22, float inA32,
|
||||||
this->a12 = a12;
|
float inA13, float inA23,
|
||||||
this->a13 = a13;
|
float inA33) :
|
||||||
this->a21 = a21;
|
a11(inA11), a21(inA21), a31(inA31), a12(inA12), a22(inA22), a32(inA32),
|
||||||
this->a22 = a22;
|
a13(inA13), a23(inA23), a33(inA33) {}
|
||||||
this->a23 = a23;
|
|
||||||
this->a31 = a31;
|
|
||||||
this->a32 = a32;
|
|
||||||
this->a33 = a33;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<PerspectiveTransform> PerspectiveTransform::quadrilateralToQuadrilateral(float x0, float y0, float x1, float y1,
|
Ref<PerspectiveTransform> PerspectiveTransform::quadrilateralToQuadrilateral(float x0, float y0, float x1, float y1,
|
||||||
float x2, float y2, float x3, float y3, float x0p, float y0p, float x1p, float y1p, float x2p, float y2p,
|
float x2, float y2, float x3, float y3, float x0p, float y0p, float x1p, float y1p, float x2p, float y2p,
|
||||||
|
@ -91,17 +86,8 @@ Ref<PerspectiveTransform> PerspectiveTransform::times(Ref<PerspectiveTransform>
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerspectiveTransform::transformPoints(valarray<float> &points) {
|
void PerspectiveTransform::transformPoints(vector<float> &points) {
|
||||||
int max = points.size();
|
int max = points.size();
|
||||||
float a11 = this->a11;
|
|
||||||
float a12 = this->a12;
|
|
||||||
float a13 = this->a13;
|
|
||||||
float a21 = this->a21;
|
|
||||||
float a22 = this->a22;
|
|
||||||
float a23 = this->a23;
|
|
||||||
float a31 = this->a31;
|
|
||||||
float a32 = this->a32;
|
|
||||||
float a33 = this->a33;
|
|
||||||
for (int i = 0; i < max; i += 2) {
|
for (int i = 0; i < max; i += 2) {
|
||||||
float x = points[i];
|
float x = points[i];
|
||||||
float y = points[i + 1];
|
float y = points[i + 1];
|
||||||
|
@ -111,7 +97,7 @@ void PerspectiveTransform::transformPoints(valarray<float> &points) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& operator<<(ostream& out, PerspectiveTransform &pt) {
|
ostream& operator<<(ostream& out, const PerspectiveTransform &pt) {
|
||||||
out << pt.a11 << ", " << pt.a12 << ", " << pt.a13 << ", \n";
|
out << pt.a11 << ", " << pt.a12 << ", " << pt.a13 << ", \n";
|
||||||
out << pt.a21 << ", " << pt.a22 << ", " << pt.a23 << ", \n";
|
out << pt.a21 << ", " << pt.a22 << ", " << pt.a23 << ", \n";
|
||||||
out << pt.a31 << ", " << pt.a32 << ", " << pt.a33 << "\n";
|
out << pt.a31 << ", " << pt.a32 << ", " << pt.a33 << "\n";
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
#include <valarray>
|
#include <vector>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
class PerspectiveTransform : public Counted {
|
class PerspectiveTransform : public Counted {
|
||||||
|
@ -41,9 +41,9 @@ public:
|
||||||
float x3, float y3);
|
float x3, float y3);
|
||||||
Ref<PerspectiveTransform> buildAdjoint();
|
Ref<PerspectiveTransform> buildAdjoint();
|
||||||
Ref<PerspectiveTransform> times(Ref<PerspectiveTransform> other);
|
Ref<PerspectiveTransform> times(Ref<PerspectiveTransform> other);
|
||||||
void transformPoints(std::valarray<float> &points);
|
void transformPoints(std::vector<float> &points);
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& out, PerspectiveTransform &pt);
|
friend std::ostream& operator<<(std::ostream& out, const PerspectiveTransform &pt);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZXING_POINT_H_
|
#ifndef ZXING_POINT_H_
|
||||||
#define ZXING_POINT_H_
|
#define ZXING_POINT_H_
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
class PointI {
|
class PointI {
|
||||||
public:
|
public:
|
||||||
int x;
|
int x;
|
||||||
|
@ -30,6 +30,7 @@ public:
|
||||||
|
|
||||||
class Point {
|
class Point {
|
||||||
public:
|
public:
|
||||||
|
Point() : x(0.0f), y(0.0f) {};
|
||||||
Point(float x_, float y_) : x(x_), y(y_) {};
|
Point(float x_, float y_) : x(x_), y(y_) {};
|
||||||
|
|
||||||
float x;
|
float x;
|
||||||
|
@ -42,6 +43,6 @@ public:
|
||||||
|
|
||||||
Point start;
|
Point start;
|
||||||
Point end;
|
Point end;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // POINT_H_
|
#endif // POINT_H_
|
||||||
|
|
|
@ -26,7 +26,7 @@ using namespace std;
|
||||||
String::String(const std::string &text) :
|
String::String(const std::string &text) :
|
||||||
text_(text) {
|
text_(text) {
|
||||||
}
|
}
|
||||||
std::string& String::getText() {
|
const std::string& String::getText() const {
|
||||||
return text_;
|
return text_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ private:
|
||||||
std::string text_;
|
std::string text_;
|
||||||
public:
|
public:
|
||||||
String(const std::string &text);
|
String(const std::string &text);
|
||||||
std::string &getText();
|
const std::string &getText() const;
|
||||||
friend std::ostream &operator<<(std::ostream &out, const String &s);
|
friend std::ostream &operator<<(std::ostream &out, const String &s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <valarray>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <zxing/common/reedsolomon/GF256.h>
|
#include <zxing/common/reedsolomon/GF256.h>
|
||||||
|
@ -42,7 +41,7 @@ static inline Ref<GF256Poly> refPoly(GF256 &field, int value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
GF256::GF256(int primitive) :
|
GF256::GF256(int primitive) :
|
||||||
exp_((const int)0, 256), log_((const int)0, 256), zero_(refPoly(*this, 0)), one_(refPoly(*this, 1)) {
|
exp_(256, (const int)0), log_(256, (const int)0), zero_(refPoly(*this, 0)), one_(refPoly(*this, 1)) {
|
||||||
int x = 1;
|
int x = 1;
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
exp_[i] = x;
|
exp_[i] = x;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <valarray>
|
#include <vector>
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
@ -42,8 +42,8 @@ class GF256 {
|
||||||
* @author christian.brunschen@gmail.com (Christian Brunschen)
|
* @author christian.brunschen@gmail.com (Christian Brunschen)
|
||||||
*/
|
*/
|
||||||
private:
|
private:
|
||||||
std::valarray<int> exp_;
|
std::vector<int> exp_;
|
||||||
std::valarray<int> log_;
|
std::vector<int> log_;
|
||||||
Ref<GF256Poly> zero_;
|
Ref<GF256Poly> zero_;
|
||||||
Ref<GF256Poly> one_;
|
Ref<GF256Poly> one_;
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,9 @@
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
|
|
||||||
const int CODE_PATTERNS_LENGHT = 107;
|
const int CODE_PATTERNS_LENGTH = 107;
|
||||||
const int countersLenght = 6;
|
const int countersLength = 6;
|
||||||
static const int CODE_PATTERNS[CODE_PATTERNS_LENGHT][countersLenght] = {
|
static const int CODE_PATTERNS[CODE_PATTERNS_LENGTH][countersLength] = {
|
||||||
{2, 1, 2, 2, 2, 2}, /* 0 */
|
{2, 1, 2, 2, 2, 2}, /* 0 */
|
||||||
{2, 2, 2, 1, 2, 2},
|
{2, 2, 2, 1, 2, 2},
|
||||||
{2, 2, 2, 2, 2, 1},
|
{2, 2, 2, 2, 2, 1},
|
||||||
|
@ -155,7 +155,7 @@ namespace zxing {
|
||||||
}
|
}
|
||||||
|
|
||||||
int counterPosition = 0;
|
int counterPosition = 0;
|
||||||
int counters[countersLenght] = {0,0,0,0,0,0};
|
int counters[countersLength] = {0,0,0,0,0,0};
|
||||||
int patternStart = rowOffset;
|
int patternStart = rowOffset;
|
||||||
bool isWhite = false;
|
bool isWhite = false;
|
||||||
int patternLength = sizeof(counters) / sizeof(int);
|
int patternLength = sizeof(counters) / sizeof(int);
|
||||||
|
@ -206,13 +206,13 @@ namespace zxing {
|
||||||
recordPattern(row, rowOffset, counters, countersCount);
|
recordPattern(row, rowOffset, counters, countersCount);
|
||||||
int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
||||||
int bestMatch = -1;
|
int bestMatch = -1;
|
||||||
for (int d = 0; d < CODE_PATTERNS_LENGHT; d++) {
|
for (int d = 0; d < CODE_PATTERNS_LENGTH; d++) {
|
||||||
int pattern[countersLenght];
|
int pattern[countersLength];
|
||||||
|
|
||||||
for(int ind = 0; ind< countersLenght; ind++){
|
for(int ind = 0; ind< countersLength; ind++){
|
||||||
pattern[ind] = CODE_PATTERNS[d][ind];
|
pattern[ind] = CODE_PATTERNS[d][ind];
|
||||||
}
|
}
|
||||||
// memcpy(pattern, CODE_PATTERNS[d], countersLenght);
|
// memcpy(pattern, CODE_PATTERNS[d], countersLength);
|
||||||
int variance = patternMatchVariance(counters, countersCount, pattern, MAX_INDIVIDUAL_VARIANCE);
|
int variance = patternMatchVariance(counters, countersCount, pattern, MAX_INDIVIDUAL_VARIANCE);
|
||||||
if (variance < bestVariance) {
|
if (variance < bestVariance) {
|
||||||
bestVariance = variance;
|
bestVariance = variance;
|
||||||
|
@ -243,6 +243,7 @@ namespace zxing {
|
||||||
codeSet = CODE_CODE_C;
|
codeSet = CODE_CODE_C;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
delete [] startPatternInfo;
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +255,7 @@ namespace zxing {
|
||||||
|
|
||||||
int lastStart = startPatternInfo[0];
|
int lastStart = startPatternInfo[0];
|
||||||
int nextStart = startPatternInfo[1];
|
int nextStart = startPatternInfo[1];
|
||||||
int counters[countersLenght] = {0,0,0,0,0,0};
|
int counters[countersLength] = {0,0,0,0,0,0};
|
||||||
|
|
||||||
int lastCode = 0;
|
int lastCode = 0;
|
||||||
int code = 0;
|
int code = 0;
|
||||||
|
@ -271,7 +272,12 @@ namespace zxing {
|
||||||
lastCode = code;
|
lastCode = code;
|
||||||
|
|
||||||
// Decode another code from image
|
// Decode another code from image
|
||||||
|
try {
|
||||||
code = decodeCode(row, counters, sizeof(counters)/sizeof(int), nextStart);
|
code = decodeCode(row, counters, sizeof(counters)/sizeof(int), nextStart);
|
||||||
|
} catch (ReaderException re) {
|
||||||
|
delete [] startPatternInfo;
|
||||||
|
throw re;
|
||||||
|
}
|
||||||
|
|
||||||
// Remember whether the last code was printable or not (excluding CODE_STOP)
|
// Remember whether the last code was printable or not (excluding CODE_STOP)
|
||||||
if (code != CODE_STOP) {
|
if (code != CODE_STOP) {
|
||||||
|
@ -286,8 +292,8 @@ namespace zxing {
|
||||||
|
|
||||||
// Advance to where the next code will to start
|
// Advance to where the next code will to start
|
||||||
lastStart = nextStart;
|
lastStart = nextStart;
|
||||||
int _countersLenght = sizeof(counters) / sizeof(int);
|
int _countersLength = sizeof(counters) / sizeof(int);
|
||||||
for (int i = 0; i < _countersLenght; i++) {
|
for (int i = 0; i < _countersLength; i++) {
|
||||||
nextStart += counters[i];
|
nextStart += counters[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,6 +302,7 @@ namespace zxing {
|
||||||
case CODE_START_A:
|
case CODE_START_A:
|
||||||
case CODE_START_B:
|
case CODE_START_B:
|
||||||
case CODE_START_C:
|
case CODE_START_C:
|
||||||
|
delete [] startPatternInfo;
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,6 +425,7 @@ namespace zxing {
|
||||||
nextStart++;
|
nextStart++;
|
||||||
}
|
}
|
||||||
if (!row->isRange(nextStart, fminl(width, nextStart + (nextStart - lastStart) / 2), false)) {
|
if (!row->isRange(nextStart, fminl(width, nextStart + (nextStart - lastStart) / 2), false)) {
|
||||||
|
delete [] startPatternInfo;
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,6 +433,7 @@ namespace zxing {
|
||||||
checksumTotal -= multiplier * lastCode;
|
checksumTotal -= multiplier * lastCode;
|
||||||
// lastCode is the checksum then:
|
// lastCode is the checksum then:
|
||||||
if (checksumTotal % 103 != lastCode) {
|
if (checksumTotal % 103 != lastCode) {
|
||||||
|
delete [] startPatternInfo;
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +453,7 @@ namespace zxing {
|
||||||
// String resultString(tmpResultString);
|
// String resultString(tmpResultString);
|
||||||
|
|
||||||
if (tmpResultString.length() == 0) {
|
if (tmpResultString.length() == 0) {
|
||||||
|
delete [] startPatternInfo;
|
||||||
// Almost surely a false positive
|
// Almost surely a false positive
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,17 +46,16 @@ namespace zxing {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ASTERISK_ENCODING = 0x094;
|
static int ASTERISK_ENCODING = 0x094;
|
||||||
|
static const char* ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a reader that assumes all encoded data is data, and does not treat the final
|
* Creates a reader that assumes all encoded data is data, and does not treat the final
|
||||||
* character as a check digit. It will not decoded "extended Code 39" sequences.
|
* character as a check digit. It will not decoded "extended Code 39" sequences.
|
||||||
*/
|
*/
|
||||||
Code39Reader::Code39Reader(){
|
Code39Reader::Code39Reader() : alphabet_string(ALPHABET_STRING),
|
||||||
ALPHABET_STRING = new std::string("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%");
|
usingCheckDigit(false),
|
||||||
usingCheckDigit = false;
|
extendedMode(false) {
|
||||||
extendedMode = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,10 +65,9 @@ namespace zxing {
|
||||||
* @param usingCheckDigit if true, treat the last data character as a check digit, not
|
* @param usingCheckDigit if true, treat the last data character as a check digit, not
|
||||||
* data, and verify that the checksum passes.
|
* data, and verify that the checksum passes.
|
||||||
*/
|
*/
|
||||||
Code39Reader::Code39Reader(bool usingCheckDigit_){
|
Code39Reader::Code39Reader(bool usingCheckDigit_) : alphabet_string(ALPHABET_STRING),
|
||||||
ALPHABET_STRING = new std::string("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%");
|
usingCheckDigit(usingCheckDigit_),
|
||||||
usingCheckDigit = usingCheckDigit_;
|
extendedMode(false) {
|
||||||
extendedMode = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,9 +92,15 @@ namespace zxing {
|
||||||
char decodedChar;
|
char decodedChar;
|
||||||
int lastStart;
|
int lastStart;
|
||||||
do {
|
do {
|
||||||
|
try {
|
||||||
recordPattern(row, nextStart, counters, countersLen);
|
recordPattern(row, nextStart, counters, countersLen);
|
||||||
|
} catch (ReaderException re) {
|
||||||
|
delete [] start;
|
||||||
|
throw re;
|
||||||
|
}
|
||||||
int pattern = toNarrowWidePattern(counters, countersLen);
|
int pattern = toNarrowWidePattern(counters, countersLen);
|
||||||
if (pattern < 0) {
|
if (pattern < 0) {
|
||||||
|
delete [] start;
|
||||||
throw ReaderException("pattern < 0");
|
throw ReaderException("pattern < 0");
|
||||||
}
|
}
|
||||||
decodedChar = patternToChar(pattern);
|
decodedChar = patternToChar(pattern);
|
||||||
|
@ -117,10 +121,14 @@ namespace zxing {
|
||||||
for (int i = 0; i < countersLen; i++) {
|
for (int i = 0; i < countersLen; i++) {
|
||||||
lastPatternSize += counters[i];
|
lastPatternSize += counters[i];
|
||||||
}
|
}
|
||||||
|
// IS begin
|
||||||
|
delete [] counters;
|
||||||
|
// IS end
|
||||||
int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
|
int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
|
||||||
// If 50% of last pattern size, following last pattern, is not whitespace, fail
|
// If 50% of last pattern size, following last pattern, is not whitespace, fail
|
||||||
// (but if it's whitespace to the very end of the image, that's OK)
|
// (but if it's whitespace to the very end of the image, that's OK)
|
||||||
if (nextStart != end && whiteSpaceAfterEnd / 2 < lastPatternSize) {
|
if (nextStart != end && whiteSpaceAfterEnd / 2 < lastPatternSize) {
|
||||||
|
delete [] start;
|
||||||
throw ReaderException("too short end white space");
|
throw ReaderException("too short end white space");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,9 +136,9 @@ namespace zxing {
|
||||||
int max = tmpResultString.length() - 1;
|
int max = tmpResultString.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(tmpResultString[i], 0);
|
total += alphabet_string.find_first_of(tmpResultString[i], 0);
|
||||||
}
|
}
|
||||||
if (total % 43 != ALPHABET_STRING->find_first_of(tmpResultString[max], 0)) {
|
if (total % 43 != alphabet_string.find_first_of(tmpResultString[max], 0)) {
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
tmpResultString.erase(max, 1);
|
tmpResultString.erase(max, 1);
|
||||||
|
@ -146,6 +154,7 @@ namespace zxing {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmpResultString.length() == 0) {
|
if (tmpResultString.length() == 0) {
|
||||||
|
delete [] start;
|
||||||
// Almost surely a false positive
|
// Almost surely a false positive
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
|
@ -216,6 +225,9 @@ namespace zxing {
|
||||||
isWhite = !isWhite;
|
isWhite = !isWhite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// IS begin
|
||||||
|
delete [] counters;
|
||||||
|
// IS end
|
||||||
throw ReaderException("");
|
throw ReaderException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,11 +342,5 @@ namespace zxing {
|
||||||
Ref<String> decoded(new String(tmpDecoded));
|
Ref<String> decoded(new String(tmpDecoded));
|
||||||
return decoded;
|
return decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Code39Reader::~Code39Reader(){
|
|
||||||
delete ALPHABET_STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace zxing {
|
||||||
class Code39Reader : public OneDReader {
|
class Code39Reader : public OneDReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string* ALPHABET_STRING;
|
std::string alphabet_string;
|
||||||
|
|
||||||
bool usingCheckDigit;
|
bool usingCheckDigit;
|
||||||
bool extendedMode;
|
bool extendedMode;
|
||||||
|
@ -49,9 +49,7 @@ namespace zxing {
|
||||||
Code39Reader(bool usingCheckDigit_);
|
Code39Reader(bool usingCheckDigit_);
|
||||||
|
|
||||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||||
|
};
|
||||||
~Code39Reader();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,20 +27,11 @@ namespace zxing {
|
||||||
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(){
|
EAN13Reader::EAN13Reader() { }
|
||||||
decodeMiddleCounters = new int[4];
|
|
||||||
for (int i=0; i<4; i++) {
|
|
||||||
decodeMiddleCounters[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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){
|
||||||
int countersLen = 4;
|
const int countersLen = 4;
|
||||||
int* counters = decodeMiddleCounters;
|
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||||
counters[0] = 0;
|
|
||||||
counters[1] = 0;
|
|
||||||
counters[2] = 0;
|
|
||||||
counters[3] = 0;
|
|
||||||
|
|
||||||
|
|
||||||
int end = row->getSize();
|
int end = row->getSize();
|
||||||
|
@ -88,8 +79,5 @@ namespace zxing {
|
||||||
BarcodeFormat EAN13Reader::getBarcodeFormat(){
|
BarcodeFormat EAN13Reader::getBarcodeFormat(){
|
||||||
return BarcodeFormat_EAN_13;
|
return BarcodeFormat_EAN_13;
|
||||||
}
|
}
|
||||||
EAN13Reader::~EAN13Reader(){
|
|
||||||
delete [] decodeMiddleCounters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace zxing {
|
||||||
class EAN13Reader : public UPCEANReader {
|
class EAN13Reader : public UPCEANReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int* decodeMiddleCounters;
|
|
||||||
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -35,7 +34,6 @@ namespace zxing {
|
||||||
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); //throws ReaderException
|
||||||
|
|
||||||
BarcodeFormat getBarcodeFormat();
|
BarcodeFormat getBarcodeFormat();
|
||||||
~EAN13Reader();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,21 +24,11 @@
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
|
|
||||||
EAN8Reader::EAN8Reader(){
|
EAN8Reader::EAN8Reader(){ }
|
||||||
decodeMiddleCounters = new int[4];
|
|
||||||
for (int i=0; i<4; i++) {
|
|
||||||
decodeMiddleCounters[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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){
|
||||||
int countersLen = 4;
|
const int countersLen = 4;
|
||||||
int* counters = decodeMiddleCounters;
|
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||||
counters[0] = 0;
|
|
||||||
counters[1] = 0;
|
|
||||||
counters[2] = 0;
|
|
||||||
counters[3] = 0;
|
|
||||||
|
|
||||||
|
|
||||||
int end = row->getSize();
|
int end = row->getSize();
|
||||||
int rowOffset = startRange[1];
|
int rowOffset = startRange[1];
|
||||||
|
@ -68,8 +58,5 @@ namespace zxing {
|
||||||
BarcodeFormat EAN8Reader::getBarcodeFormat(){
|
BarcodeFormat EAN8Reader::getBarcodeFormat(){
|
||||||
return BarcodeFormat_EAN_8;
|
return BarcodeFormat_EAN_8;
|
||||||
}
|
}
|
||||||
EAN8Reader::~EAN8Reader(){
|
|
||||||
delete [] decodeMiddleCounters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,16 +25,12 @@ namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
class EAN8Reader : public UPCEANReader {
|
class EAN8Reader : public UPCEANReader {
|
||||||
|
|
||||||
private:
|
|
||||||
int* decodeMiddleCounters;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EAN8Reader();
|
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); //throws ReaderException
|
||||||
|
|
||||||
BarcodeFormat getBarcodeFormat();
|
BarcodeFormat getBarcodeFormat();
|
||||||
~EAN8Reader();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,18 +62,29 @@ namespace zxing {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ITFReader::ITFReader(){
|
ITFReader::ITFReader() : narrowLineWidth(-1) {
|
||||||
narrowLineWidth = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||||
// Find out where the Middle section (payload) starts & ends
|
// Find out where the Middle section (payload) starts & ends
|
||||||
int* startRange = decodeStart(row);
|
int* startRange = decodeStart(row);
|
||||||
int* endRange = decodeEnd(row);
|
int* endRange;
|
||||||
|
try {
|
||||||
|
endRange = decodeEnd(row);
|
||||||
|
} catch (Exception e) {
|
||||||
|
delete [] startRange;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
std::string tmpResult;
|
std::string tmpResult;
|
||||||
|
try {
|
||||||
decodeMiddle(row, startRange[1], endRange[0], tmpResult);
|
decodeMiddle(row, startRange[1], endRange[0], tmpResult);
|
||||||
|
} catch (zxing::ReaderException re) {
|
||||||
|
delete [] startRange;
|
||||||
|
delete [] endRange;
|
||||||
|
throw re;
|
||||||
|
}
|
||||||
|
|
||||||
// To avoid false positives with 2D barcodes (and other patterns), make
|
// To avoid false positives with 2D barcodes (and other patterns), make
|
||||||
// an assumption that the decoded string must be 6, 10 or 14 digits.
|
// an assumption that the decoded string must be 6, 10 or 14 digits.
|
||||||
|
@ -83,7 +94,9 @@ namespace zxing {
|
||||||
lengthOK = true;
|
lengthOK = true;
|
||||||
}
|
}
|
||||||
if (!lengthOK) {
|
if (!lengthOK) {
|
||||||
throw ReaderException("not enought characters count");
|
delete [] startRange;
|
||||||
|
delete [] endRange;
|
||||||
|
throw ReaderException("not enough characters count");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<String> resultString(new String(tmpResult));
|
Ref<String> resultString(new String(tmpResult));
|
||||||
|
@ -116,13 +129,13 @@ namespace zxing {
|
||||||
// Therefore, need to scan 10 lines and then
|
// Therefore, need to scan 10 lines and then
|
||||||
// split these into two arrays
|
// split these into two arrays
|
||||||
int counterDigitPairLen = 10;
|
int counterDigitPairLen = 10;
|
||||||
int* counterDigitPair = new int[counterDigitPairLen];
|
int counterDigitPair[counterDigitPairLen];
|
||||||
for (int i=0; i<counterDigitPairLen; i++) {
|
for (int i=0; i<counterDigitPairLen; i++) {
|
||||||
counterDigitPair[i] = 0;
|
counterDigitPair[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int* counterBlack = new int[5];
|
int counterBlack[5];
|
||||||
int* counterWhite = new int[5];
|
int counterWhite[5];
|
||||||
for (int i=0; i<5; i++) {
|
for (int i=0; i<5; i++) {
|
||||||
counterBlack[i] = 0;
|
counterBlack[i] = 0;
|
||||||
counterWhite[i] = 0;
|
counterWhite[i] = 0;
|
||||||
|
@ -147,9 +160,6 @@ namespace zxing {
|
||||||
payloadStart += counterDigitPair[i];
|
payloadStart += counterDigitPair[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] counterDigitPair;
|
|
||||||
delete [] counterBlack;
|
|
||||||
delete [] counterWhite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,7 +288,7 @@ namespace zxing {
|
||||||
// TODO: This is very similar to implementation in UPCEANReader. Consider if they can be
|
// TODO: This is very similar to implementation in UPCEANReader. Consider if they can be
|
||||||
// merged to a single method.
|
// merged to a single method.
|
||||||
int patternLength = patternLen;
|
int patternLength = patternLen;
|
||||||
int* counters = new int[patternLength];
|
int counters[patternLength];
|
||||||
for (int i=0; i<patternLength; i++) {
|
for (int i=0; i<patternLength; i++) {
|
||||||
counters[i] = 0;
|
counters[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -329,8 +339,7 @@ namespace zxing {
|
||||||
int bestMatch = -1;
|
int bestMatch = -1;
|
||||||
int max = PATTERNS_LEN;
|
int max = PATTERNS_LEN;
|
||||||
for (int i = 0; i < max; i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
//int pattern[countersLen];
|
int pattern[countersLen];
|
||||||
int* pattern = new int(countersLen);
|
|
||||||
for(int ind = 0; ind<countersLen; ind++){
|
for(int ind = 0; ind<countersLen; ind++){
|
||||||
pattern[ind] = PATTERNS[i][ind];
|
pattern[ind] = PATTERNS[i][ind];
|
||||||
}
|
}
|
||||||
|
@ -339,7 +348,6 @@ namespace zxing {
|
||||||
bestVariance = variance;
|
bestVariance = variance;
|
||||||
bestMatch = i;
|
bestMatch = i;
|
||||||
}
|
}
|
||||||
delete pattern;
|
|
||||||
}
|
}
|
||||||
if (bestMatch >= 0) {
|
if (bestMatch >= 0) {
|
||||||
return bestMatch;
|
return bestMatch;
|
||||||
|
|
|
@ -28,18 +28,17 @@
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
MultiFormatOneDReader::MultiFormatOneDReader(){
|
MultiFormatOneDReader::MultiFormatOneDReader() : readers() {
|
||||||
readers = new std::vector<OneDReader*>();
|
readers.push_back(Ref<OneDReader>(new MultiFormatUPCEANReader()));
|
||||||
readers->push_back(new MultiFormatUPCEANReader());
|
readers.push_back(Ref<OneDReader>(new Code39Reader()));
|
||||||
readers->push_back(new Code39Reader());
|
readers.push_back(Ref<OneDReader>(new Code128Reader()));
|
||||||
readers->push_back(new Code128Reader());
|
readers.push_back(Ref<OneDReader>(new ITFReader()));
|
||||||
readers->push_back(new ITFReader());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||||
int size = readers->size();
|
int size = readers.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
OneDReader* reader = (*readers)[i];
|
OneDReader* reader = readers[i];
|
||||||
try {
|
try {
|
||||||
return reader->decodeRow(rowNumber, row);
|
return reader->decodeRow(rowNumber, row);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException re) {
|
||||||
|
@ -48,8 +47,5 @@ namespace zxing {
|
||||||
}
|
}
|
||||||
throw ReaderException("No code detected");
|
throw ReaderException("No code detected");
|
||||||
}
|
}
|
||||||
MultiFormatOneDReader::~MultiFormatOneDReader(){
|
|
||||||
delete readers;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,11 @@ namespace zxing {
|
||||||
class MultiFormatOneDReader : public OneDReader {
|
class MultiFormatOneDReader : public OneDReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<OneDReader*>* readers;
|
std::vector<Ref<OneDReader> > readers;
|
||||||
public:
|
public:
|
||||||
MultiFormatOneDReader();
|
MultiFormatOneDReader();
|
||||||
|
|
||||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||||
|
|
||||||
~MultiFormatOneDReader();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,19 +30,18 @@
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
|
|
||||||
MultiFormatUPCEANReader::MultiFormatUPCEANReader(){
|
MultiFormatUPCEANReader::MultiFormatUPCEANReader() : readers() {
|
||||||
readers = new std::vector<OneDReader*>();
|
readers.push_back(Ref<OneDReader>(new EAN13Reader()));
|
||||||
readers->push_back(new EAN13Reader());
|
|
||||||
// UPC-A is covered by EAN-13
|
// UPC-A is covered by EAN-13
|
||||||
readers->push_back(new EAN8Reader());
|
readers.push_back(Ref<OneDReader>(new EAN8Reader()));
|
||||||
readers->push_back(new UPCEReader());
|
readers.push_back(Ref<OneDReader>(new UPCEReader()));
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// Compute this location once and reuse it on multiple implementations
|
||||||
int size = readers->size();
|
int size = readers.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
OneDReader* reader = (*readers)[i];
|
Ref<OneDReader> reader = readers[i];
|
||||||
Ref<Result> result;
|
Ref<Result> result;
|
||||||
try {
|
try {
|
||||||
result = reader->decodeRow(rowNumber, row);//decodeRow(rowNumber, row, startGuardPattern);
|
result = reader->decodeRow(rowNumber, row);//decodeRow(rowNumber, row, startGuardPattern);
|
||||||
|
@ -60,7 +59,7 @@ namespace zxing {
|
||||||
// UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A
|
// UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A
|
||||||
// result if appropriate.
|
// result if appropriate.
|
||||||
if (result->getBarcodeFormat() == BarcodeFormat_EAN_13) {
|
if (result->getBarcodeFormat() == BarcodeFormat_EAN_13) {
|
||||||
std::string& text = (result->getText())->getText();
|
const std::string& text = (result->getText())->getText();
|
||||||
if (text[0] == '0') {
|
if (text[0] == '0') {
|
||||||
Ref<String> resultString(new String(text.substr(1)));
|
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));
|
||||||
|
@ -71,9 +70,5 @@ namespace zxing {
|
||||||
}
|
}
|
||||||
throw ReaderException("No EAN code detected");
|
throw ReaderException("No EAN code detected");
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiFormatUPCEANReader::~MultiFormatUPCEANReader(){
|
|
||||||
delete readers;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,13 +29,11 @@ namespace zxing {
|
||||||
class MultiFormatUPCEANReader : public OneDReader {
|
class MultiFormatUPCEANReader : public OneDReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<OneDReader*>* readers;
|
std::vector<Ref<OneDReader> > readers;
|
||||||
public:
|
public:
|
||||||
MultiFormatUPCEANReader();
|
MultiFormatUPCEANReader();
|
||||||
|
|
||||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||||
|
};
|
||||||
~MultiFormatUPCEANReader();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,17 +23,15 @@
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
OneDResultPoint::OneDResultPoint(float posX, float posY) : posX_(posX), posY_(posY){
|
OneDResultPoint::OneDResultPoint(float posX, float posY) : posX_(posX), posY_(posY){
|
||||||
}
|
}
|
||||||
|
|
||||||
float OneDResultPoint::getX() {
|
float OneDResultPoint::getX() const {
|
||||||
return posX_;
|
return posX_;
|
||||||
}
|
}
|
||||||
|
|
||||||
float OneDResultPoint::getY() {
|
float OneDResultPoint::getY() const {
|
||||||
return posY_;
|
return posY_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ namespace zxing {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OneDResultPoint(float posX, float posY);
|
OneDResultPoint(float posX, float posY);
|
||||||
float getX();
|
float getX() const;
|
||||||
float getY();
|
float getY() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,31 +19,29 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "UPCAReader.h"
|
#include "UPCAReader.h"
|
||||||
#include <zxing/oned/EAN13Reader.h>
|
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
UPCAReader::UPCAReader(){
|
UPCAReader::UPCAReader() : ean13Reader() {
|
||||||
ean13Reader = new 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));
|
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));
|
return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardRange));
|
||||||
}
|
}
|
||||||
Ref<Result> UPCAReader::decode(Ref<BinaryBitmap> image){
|
Ref<Result> UPCAReader::decode(Ref<BinaryBitmap> image){
|
||||||
return maybeReturnResult(ean13Reader->decode(image));
|
return maybeReturnResult(ean13Reader.decode(image));
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
return ean13Reader.decodeMiddle(row, startRange, startRangeLen, resultString);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Result> UPCAReader::maybeReturnResult(Ref<Result> result){
|
Ref<Result> UPCAReader::maybeReturnResult(Ref<Result> result){
|
||||||
std::string& text = (result->getText())->getText();
|
const std::string& text = (result->getText())->getText();
|
||||||
if (text[0] == '0') {
|
if (text[0] == '0') {
|
||||||
Ref<String> resultString(new String(text.substr(1)));
|
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));
|
||||||
|
@ -57,8 +55,5 @@ namespace zxing {
|
||||||
BarcodeFormat UPCAReader::getBarcodeFormat(){
|
BarcodeFormat UPCAReader::getBarcodeFormat(){
|
||||||
return BarcodeFormat_UPC_A;
|
return BarcodeFormat_UPC_A;
|
||||||
}
|
}
|
||||||
UPCAReader::~UPCAReader(){
|
|
||||||
delete ean13Reader;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,15 +18,14 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zxing/oned/UPCEANReader.h>
|
#include <zxing/oned/EAN13Reader.h>
|
||||||
#include <zxing/Result.h>
|
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace oned {
|
namespace oned {
|
||||||
class UPCAReader : public UPCEANReader {
|
class UPCAReader : public UPCEANReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UPCEANReader* ean13Reader;
|
EAN13Reader ean13Reader;
|
||||||
static Ref<Result> maybeReturnResult(Ref<Result> result); //throws ReaderException
|
static Ref<Result> maybeReturnResult(Ref<Result> result); //throws ReaderException
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -39,7 +38,6 @@ namespace zxing {
|
||||||
Ref<Result> decode(Ref<BinaryBitmap> image);
|
Ref<Result> decode(Ref<BinaryBitmap> image);
|
||||||
|
|
||||||
BarcodeFormat getBarcodeFormat();
|
BarcodeFormat getBarcodeFormat();
|
||||||
~UPCAReader();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,16 @@ namespace zxing {
|
||||||
|
|
||||||
std::string tmpResultString;
|
std::string tmpResultString;
|
||||||
std::string& tmpResultStringRef = tmpResultString;
|
std::string& tmpResultStringRef = tmpResultString;
|
||||||
int endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ , tmpResultStringRef);
|
int endStart;
|
||||||
|
try {
|
||||||
|
endStart = decodeMiddle(row, startGuardRange, 2 /*reference findGuardPattern*/ , tmpResultStringRef);
|
||||||
|
} catch (ReaderException re) {
|
||||||
|
if (startGuardRange!=NULL) {
|
||||||
|
delete [] startGuardRange;
|
||||||
|
startGuardRange = NULL;
|
||||||
|
}
|
||||||
|
throw re;
|
||||||
|
}
|
||||||
|
|
||||||
int* endRange = decodeEnd(row, endStart);
|
int* endRange = decodeEnd(row, endStart);
|
||||||
|
|
||||||
|
@ -114,6 +123,14 @@ namespace zxing {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (!checkChecksum(tmpResultString)) {
|
if (!checkChecksum(tmpResultString)) {
|
||||||
|
if (startGuardRange!=NULL) {
|
||||||
|
delete [] startGuardRange;
|
||||||
|
startGuardRange = NULL;
|
||||||
|
}
|
||||||
|
if (endRange!=NULL) {
|
||||||
|
delete [] endRange;
|
||||||
|
endRange = NULL;
|
||||||
|
}
|
||||||
throw ReaderException("Checksum fail.");
|
throw ReaderException("Checksum fail.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +176,9 @@ namespace zxing {
|
||||||
if (quietStart >= 0) {
|
if (quietStart >= 0) {
|
||||||
foundStart = row->isRange(quietStart, start, false);
|
foundStart = row->isRange(quietStart, start, false);
|
||||||
}
|
}
|
||||||
|
if (!foundStart) {
|
||||||
|
delete [] startRange;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return startRange;
|
return startRange;
|
||||||
}
|
}
|
||||||
|
@ -166,8 +186,7 @@ namespace zxing {
|
||||||
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 patternLength = patternLen;
|
||||||
|
|
||||||
//int counters[patternLength];
|
int counters[patternLength];
|
||||||
int* counters = new int(patternLength);
|
|
||||||
int countersCount = sizeof(counters)/sizeof(int);
|
int countersCount = sizeof(counters)/sizeof(int);
|
||||||
for (int i=0; i<countersCount ; i++) {
|
for (int i=0; i<countersCount ; i++) {
|
||||||
counters[i]=0;
|
counters[i]=0;
|
||||||
|
@ -210,7 +229,6 @@ namespace zxing {
|
||||||
isWhite = !isWhite;
|
isWhite = !isWhite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete counters;
|
|
||||||
throw ReaderException("findGuardPattern");
|
throw ReaderException("findGuardPattern");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,18 +237,17 @@ namespace zxing {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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, int** patterns/*[][]*/, int paterns1Len, int paterns2Len)
|
||||||
int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, UPC_EAN_PATTERNS paternType){
|
int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, UPC_EAN_PATTERNS patternType){
|
||||||
recordPattern(row, rowOffset, counters, countersLen);
|
recordPattern(row, rowOffset, counters, countersLen);
|
||||||
int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
||||||
int bestMatch = -1;
|
int bestMatch = -1;
|
||||||
|
|
||||||
int max = 0;
|
int max = 0;
|
||||||
switch (paternType) {
|
switch (patternType) {
|
||||||
case UPC_EAN_PATTERNS_L_PATTERNS:
|
case UPC_EAN_PATTERNS_L_PATTERNS:
|
||||||
max = L_PATTERNS_LEN;
|
max = L_PATTERNS_LEN;
|
||||||
for (int i = 0; i < max; i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
//int pattern[countersLen];
|
int pattern[countersLen];
|
||||||
int* pattern = new int(countersLen);
|
|
||||||
for(int j = 0; j< countersLen; j++){
|
for(int j = 0; j< countersLen; j++){
|
||||||
pattern[j] = L_PATTERNS[i][j];
|
pattern[j] = L_PATTERNS[i][j];
|
||||||
}
|
}
|
||||||
|
@ -240,14 +257,12 @@ namespace zxing {
|
||||||
bestVariance = variance;
|
bestVariance = variance;
|
||||||
bestMatch = i;
|
bestMatch = i;
|
||||||
}
|
}
|
||||||
delete pattern;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UPC_EAN_PATTERNS_L_AND_G_PATTERNS:
|
case UPC_EAN_PATTERNS_L_AND_G_PATTERNS:
|
||||||
max = L_AND_G_PATTERNS_LEN;
|
max = L_AND_G_PATTERNS_LEN;
|
||||||
for (int i = 0; i < max; i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
//int pattern[countersLen];
|
int pattern[countersLen];
|
||||||
int* pattern = new int(countersLen);
|
|
||||||
for(int j = 0; j< countersLen; j++){
|
for(int j = 0; j< countersLen; j++){
|
||||||
pattern[j] = L_AND_G_PATTERNS[i][j];
|
pattern[j] = L_AND_G_PATTERNS[i][j];
|
||||||
}
|
}
|
||||||
|
@ -257,7 +272,6 @@ namespace zxing {
|
||||||
bestVariance = variance;
|
bestVariance = variance;
|
||||||
bestMatch = i;
|
bestMatch = i;
|
||||||
}
|
}
|
||||||
delete pattern;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace zxing {
|
||||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int startGuardRange[]);
|
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 paternType); //throws ReaderException
|
static int decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, UPC_EAN_PATTERNS patternType); //throws ReaderException
|
||||||
|
|
||||||
bool checkChecksum(std::string s); //throws ReaderException
|
bool checkChecksum(std::string s); //throws ReaderException
|
||||||
|
|
||||||
|
@ -63,3 +63,4 @@ namespace zxing {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,21 +40,11 @@ namespace zxing {
|
||||||
{0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}
|
{0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}
|
||||||
};
|
};
|
||||||
|
|
||||||
UPCEReader::UPCEReader(){
|
UPCEReader::UPCEReader(){}
|
||||||
decodeMiddleCounters = new int[4];
|
|
||||||
for (int i=0; i<4; i++) {
|
|
||||||
decodeMiddleCounters[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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){
|
||||||
int countersLen = 4;
|
const int countersLen = 4;
|
||||||
int* counters = decodeMiddleCounters;
|
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||||
counters[0] = 0;
|
|
||||||
counters[1] = 0;
|
|
||||||
counters[2] = 0;
|
|
||||||
counters[3] = 0;
|
|
||||||
|
|
||||||
|
|
||||||
int end = row->getSize();
|
int end = row->getSize();
|
||||||
int rowOffset = startRange[1];
|
int rowOffset = startRange[1];
|
||||||
|
@ -143,8 +133,5 @@ namespace zxing {
|
||||||
BarcodeFormat UPCEReader::getBarcodeFormat(){
|
BarcodeFormat UPCEReader::getBarcodeFormat(){
|
||||||
return BarcodeFormat_UPC_E;
|
return BarcodeFormat_UPC_E;
|
||||||
}
|
}
|
||||||
UPCEReader::~UPCEReader(){
|
|
||||||
delete [] decodeMiddleCounters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace zxing {
|
||||||
class UPCEReader : public UPCEANReader {
|
class UPCEReader : public UPCEANReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int* decodeMiddleCounters;
|
|
||||||
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||||
static void determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
static void determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||||
protected:
|
protected:
|
||||||
|
@ -39,7 +38,6 @@ namespace zxing {
|
||||||
static std::string& convertUPCEtoUPCA(std::string upce);
|
static std::string& convertUPCEtoUPCA(std::string upce);
|
||||||
|
|
||||||
BarcodeFormat getBarcodeFormat();
|
BarcodeFormat getBarcodeFormat();
|
||||||
~UPCEReader();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
|
|
||||||
ErrorCorrectionLevel::ErrorCorrectionLevel(int ordinal) :
|
ErrorCorrectionLevel::ErrorCorrectionLevel(int inOrdinal) :
|
||||||
ordinal_(ordinal) {
|
ordinal_(inOrdinal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ErrorCorrectionLevel::ordinal() {
|
int ErrorCorrectionLevel::ordinal() {
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace qrcode {
|
||||||
class ErrorCorrectionLevel {
|
class ErrorCorrectionLevel {
|
||||||
private:
|
private:
|
||||||
int ordinal_;
|
int ordinal_;
|
||||||
ErrorCorrectionLevel(int ordinal);
|
ErrorCorrectionLevel(int inOrdinal);
|
||||||
static ErrorCorrectionLevel *FOR_BITS[];
|
static ErrorCorrectionLevel *FOR_BITS[];
|
||||||
static int N_LEVELS;
|
static int N_LEVELS;
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -33,28 +33,28 @@ namespace zxing {
|
||||||
|
|
||||||
Ref<Result> QRCodeReader::decode(Ref<BinaryBitmap> image) {
|
Ref<Result> QRCodeReader::decode(Ref<BinaryBitmap> image) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "decoding image " << image.object_ << ":\n" ;
|
cout << "decoding image " << image.object_ << ":\n" << flush;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Detector detector(image->getBlackMatrix());
|
Detector detector(image->getBlackMatrix());
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "(1) created detector " << &detector << "\n" ;
|
cout << "(1) created detector " << &detector << "\n" << flush;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Ref<DetectorResult> detectorResult(detector.detect());
|
Ref<DetectorResult> detectorResult(detector.detect());
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "(2) detected, have detectorResult " << detectorResult.object_ << "\n" ;
|
cout << "(2) detected, have detectorResult " << detectorResult.object_ << "\n" << flush;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<Ref<ResultPoint> > points(detectorResult->getPoints());
|
std::vector<Ref<ResultPoint> > points(detectorResult->getPoints());
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "(3) extracted points " << &points << "\n";
|
cout << "(3) extracted points " << &points << "\n" << flush;
|
||||||
cout << "found " << points.size() << " points:\n";
|
cout << "found " << points->size() << " points:\n";
|
||||||
for (size_t i = 0; i < points.size(); i++) {
|
for (size_t i = 0; i < points->size(); i++) {
|
||||||
cout << " " << points[i]->getX() << "," << points[i]->getY() << "\n";
|
cout << " " << points[i]->getX() << "," << points[i]->getY() << "\n";
|
||||||
}
|
}
|
||||||
cout << "bits:\n";
|
cout << "bits:\n";
|
||||||
|
@ -63,15 +63,13 @@ namespace zxing {
|
||||||
|
|
||||||
Ref<DecoderResult> decoderResult(decoder_.decode(detectorResult->getBits()));
|
Ref<DecoderResult> decoderResult(decoder_.decode(detectorResult->getBits()));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "(4) decoded, have decoderResult " << decoderResult.object_ << "\n" ;
|
cout << "(4) decoded, have decoderResult " << decoderResult.object_ << "\n" << flush;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Ref<Result> result(
|
Ref<Result> result(
|
||||||
new Result(decoderResult->getText(), decoderResult->getRawBytes(), points, BarcodeFormat_QR_CODE));
|
new Result(decoderResult->getText(), decoderResult->getRawBytes(), points, BarcodeFormat_QR_CODE));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cout << "(5) created result " << result.object_ << ", returning\n" ;
|
cout << "(5) created result " << result.object_ << ", returning\n" << flush;
|
||||||
|
|
||||||
cout << "(6) text: " << result->getText()->getText() << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
|
|
||||||
#include <zxing/qrcode/Version.h>
|
#include <zxing/qrcode/Version.h>
|
||||||
#include <zxing/qrcode/FormatInformation.h>
|
#include <zxing/qrcode/FormatInformation.h>
|
||||||
#include <cstdarg>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
|
@ -41,13 +41,11 @@ int ECB::getDataCodewords() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks) :
|
ECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks) :
|
||||||
ecCodewords_(ecCodewords) {
|
ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks) {
|
||||||
ecBlocks_.push_back(ecBlocks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2) :
|
ECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2) :
|
||||||
ecCodewords_(ecCodewords) {
|
ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks1) {
|
||||||
ecBlocks_.push_back(ecBlocks1);
|
|
||||||
ecBlocks_.push_back(ecBlocks2);
|
ecBlocks_.push_back(ecBlocks2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +76,7 @@ int Version::getVersionNumber() {
|
||||||
return versionNumber_;
|
return versionNumber_;
|
||||||
}
|
}
|
||||||
|
|
||||||
valarray<int> &Version::getAlignmentPatternCenters() {
|
vector<int> &Version::getAlignmentPatternCenters() {
|
||||||
return alignmentPatternCenters_;
|
return alignmentPatternCenters_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,16 +100,16 @@ Version *Version::getProvisionalVersionForDimension(int dimension) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Version *Version::getVersionForNumber(int versionNumber) {
|
Version *Version::getVersionForNumber(int versionNumber) {
|
||||||
if (versionNumber < 1 || versionNumber > 40) {
|
if (versionNumber < 1 || versionNumber > N_VERSIONS) {
|
||||||
throw ReaderException("versionNumber must be between 1 and 40");
|
throw ReaderException("versionNumber must be between 1 and 40");
|
||||||
}
|
}
|
||||||
|
|
||||||
return VERSIONS[versionNumber - 1];
|
return VERSIONS[versionNumber - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Version::Version(int versionNumber, valarray<int> *alignmentPatternCenters, ECBlocks *ecBlocks1, ECBlocks *ecBlocks2,
|
Version::Version(int versionNumber, vector<int> *alignmentPatternCenters, ECBlocks *ecBlocks1, ECBlocks *ecBlocks2,
|
||||||
ECBlocks *ecBlocks3, ECBlocks *ecBlocks4) :
|
ECBlocks *ecBlocks3, ECBlocks *ecBlocks4) :
|
||||||
versionNumber_(versionNumber), alignmentPatternCenters_(*alignmentPatternCenters), ecBlocks_(4) {
|
versionNumber_(versionNumber), alignmentPatternCenters_(*alignmentPatternCenters), ecBlocks_(4), totalCodewords_(0) {
|
||||||
ecBlocks_[0] = ecBlocks1;
|
ecBlocks_[0] = ecBlocks1;
|
||||||
ecBlocks_[1] = ecBlocks2;
|
ecBlocks_[1] = ecBlocks2;
|
||||||
ecBlocks_[2] = ecBlocks3;
|
ecBlocks_[2] = ecBlocks3;
|
||||||
|
@ -207,10 +205,10 @@ Ref<BitMatrix> Version::buildFunctionPattern() {
|
||||||
return functionPattern;
|
return functionPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
static valarray<int> *intArray(size_t n...) {
|
static vector<int> *intArray(size_t n...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, n);
|
va_start(ap, n);
|
||||||
valarray<int> *result = new valarray<int>(n);
|
vector<int> *result = new vector<int>(n);
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
(*result)[i] = va_arg(ap, int);
|
(*result)[i] = va_arg(ap, int);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <zxing/common/BitMatrix.h>
|
#include <zxing/common/BitMatrix.h>
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <valarray>
|
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
|
@ -58,10 +57,10 @@ class Version : public Counted {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int versionNumber_;
|
int versionNumber_;
|
||||||
std::valarray<int> &alignmentPatternCenters_;
|
std::vector<int> &alignmentPatternCenters_;
|
||||||
std::vector<ECBlocks*> ecBlocks_;
|
std::vector<ECBlocks*> ecBlocks_;
|
||||||
int totalCodewords_;
|
int totalCodewords_;
|
||||||
Version(int versionNumber, std::valarray<int> *alignmentPatternCenters, ECBlocks *ecBlocks1, ECBlocks *ecBlocks2,
|
Version(int versionNumber, std::vector<int> *alignmentPatternCenters, ECBlocks *ecBlocks1, ECBlocks *ecBlocks2,
|
||||||
ECBlocks *ecBlocks3, ECBlocks *ecBlocks4);
|
ECBlocks *ecBlocks3, ECBlocks *ecBlocks4);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -71,7 +70,7 @@ public:
|
||||||
|
|
||||||
~Version();
|
~Version();
|
||||||
int getVersionNumber();
|
int getVersionNumber();
|
||||||
std::valarray<int> &getAlignmentPatternCenters();
|
std::vector<int> &getAlignmentPatternCenters();
|
||||||
int getTotalCodewords();
|
int getTotalCodewords();
|
||||||
int getDimensionForVersion();
|
int getDimensionForVersion();
|
||||||
ECBlocks &getECBlocksForLevel(ErrorCorrectionLevel &ecLevel);
|
ECBlocks &getECBlocksForLevel(ErrorCorrectionLevel &ecLevel);
|
||||||
|
|
|
@ -158,8 +158,8 @@ ArrayRef<unsigned char> BitMatrixParser::readCodewords() {
|
||||||
x--;
|
x--;
|
||||||
}
|
}
|
||||||
// Read alternatingly from bottom to top then top to bottom
|
// Read alternatingly from bottom to top then top to bottom
|
||||||
for (int count = 0; count < dimension; count++) {
|
for (int counter = 0; counter < dimension; counter++) {
|
||||||
int y = readingUp ? dimension - 1 - count : count;
|
int y = readingUp ? dimension - 1 - counter : counter;
|
||||||
for (int col = 0; col < 2; col++) {
|
for (int col = 0; col < 2; col++) {
|
||||||
// Ignore bits covered by the function pattern
|
// Ignore bits covered by the function pattern
|
||||||
if (!functionPattern->get(x - col, y)) {
|
if (!functionPattern->get(x - col, y)) {
|
||||||
|
|
|
@ -44,6 +44,11 @@ public:
|
||||||
Ref<FormatInformation> readFormatInformation();
|
Ref<FormatInformation> readFormatInformation();
|
||||||
Version *readVersion();
|
Version *readVersion();
|
||||||
ArrayRef<unsigned char> readCodewords();
|
ArrayRef<unsigned char> readCodewords();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BitMatrixParser(const BitMatrixParser&);
|
||||||
|
BitMatrixParser& operator =(const BitMatrixParser&);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <valarray>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
#include <zxing/common/Array.h>
|
#include <zxing/common/Array.h>
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
|
|
||||||
#include <zxing/qrcode/decoder/DecodedBitStreamParser.h>
|
#include <zxing/qrcode/decoder/DecodedBitStreamParser.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#ifndef NO_ICONV
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Required for compatibility. TODO: test on Symbian
|
// Required for compatibility. TODO: test on Symbian
|
||||||
#ifdef ZXING_ICONV_CONST
|
#ifdef ZXING_ICONV_CONST
|
||||||
|
@ -50,7 +52,8 @@ const char *DecodedBitStreamParser::UTF8 = "UTF-8";
|
||||||
const char *DecodedBitStreamParser::SHIFT_JIS = "SHIFT_JIS";
|
const char *DecodedBitStreamParser::SHIFT_JIS = "SHIFT_JIS";
|
||||||
const char *DecodedBitStreamParser::EUC_JP = "EUC-JP";
|
const char *DecodedBitStreamParser::EUC_JP = "EUC-JP";
|
||||||
|
|
||||||
void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, size_t nIn, const char *src) {
|
void DecodedBitStreamParser::append(std::string &result, const unsigned char *bufIn, size_t nIn, const char *src) {
|
||||||
|
#ifndef NO_ICONV
|
||||||
if (nIn == 0) {
|
if (nIn == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +68,7 @@ void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, si
|
||||||
size_t nTo = maxOut;
|
size_t nTo = maxOut;
|
||||||
|
|
||||||
while (nFrom > 0) {
|
while (nFrom > 0) {
|
||||||
size_t oneway = iconv(cd, (const char**)&fromPtr, &nFrom, &toPtr, &nTo);
|
size_t oneway = iconv(cd, &fromPtr, &nFrom, &toPtr, &nTo);
|
||||||
if (oneway == (size_t)(-1)) {
|
if (oneway == (size_t)(-1)) {
|
||||||
iconv_close(cd);
|
iconv_close(cd);
|
||||||
delete[] bufOut;
|
delete[] bufOut;
|
||||||
|
@ -76,12 +79,14 @@ void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, si
|
||||||
|
|
||||||
int nResult = maxOut - nTo;
|
int nResult = maxOut - nTo;
|
||||||
bufOut[nResult] = '\0';
|
bufOut[nResult] = '\0';
|
||||||
|
result.append((const char *)bufOut);
|
||||||
ost << bufOut;
|
|
||||||
delete[] bufOut;
|
delete[] bufOut;
|
||||||
|
#else
|
||||||
|
result.append((const char *)bufIn, nIn);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, ostringstream &result, int count) {
|
void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, std::string &result, int count) {
|
||||||
// Each character will require 2 bytes. Read the characters as 2-byte pairs
|
// Each character will require 2 bytes. Read the characters as 2-byte pairs
|
||||||
// and decode as Shift_JIS afterwards
|
// and decode as Shift_JIS afterwards
|
||||||
size_t nBytes = 2 * count;
|
size_t nBytes = 2 * count;
|
||||||
|
@ -109,7 +114,7 @@ void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, ostringstre
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits, ostringstream &result, int count) {
|
void DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits, std::string &result, int count) {
|
||||||
int nBytes = count;
|
int nBytes = count;
|
||||||
unsigned char* readBytes = new unsigned char[nBytes];
|
unsigned char* readBytes = new unsigned char[nBytes];
|
||||||
if (count << 3 > bits->available()) {
|
if (count << 3 > bits->available()) {
|
||||||
|
@ -131,7 +136,7 @@ void DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits, ostringstrea
|
||||||
delete[] readBytes;
|
delete[] readBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, ostringstream &result, int count) {
|
void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, std::string &result, int count) {
|
||||||
int nBytes = count;
|
int nBytes = count;
|
||||||
unsigned char* bytes = new unsigned char[nBytes];
|
unsigned char* bytes = new unsigned char[nBytes];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -176,7 +181,7 @@ void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, ostringst
|
||||||
delete[] bytes;
|
delete[] bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodedBitStreamParser::decodeAlphanumericSegment(Ref<BitSource> bits, ostringstream &result, int count) {
|
void DecodedBitStreamParser::decodeAlphanumericSegment(Ref<BitSource> bits, std::string &result, int count) {
|
||||||
int nBytes = count;
|
int nBytes = count;
|
||||||
unsigned char* bytes = new unsigned char[nBytes];
|
unsigned char* bytes = new unsigned char[nBytes];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -248,7 +253,7 @@ DecodedBitStreamParser::guessEncoding(unsigned char *bytes, int length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
string DecodedBitStreamParser::decode(ArrayRef<unsigned char> bytes, Version *version) {
|
string DecodedBitStreamParser::decode(ArrayRef<unsigned char> bytes, Version *version) {
|
||||||
ostringstream result;
|
string result;
|
||||||
Ref<BitSource> bits(new BitSource(bytes));
|
Ref<BitSource> bits(new BitSource(bytes));
|
||||||
Mode *mode = &Mode::TERMINATOR;
|
Mode *mode = &Mode::TERMINATOR;
|
||||||
do {
|
do {
|
||||||
|
@ -275,7 +280,7 @@ string DecodedBitStreamParser::decode(ArrayRef<unsigned char> bytes, Version *ve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (mode != &Mode::TERMINATOR);
|
} while (mode != &Mode::TERMINATOR);
|
||||||
return result.str();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,12 @@ private:
|
||||||
static const char *SHIFT_JIS;
|
static const char *SHIFT_JIS;
|
||||||
static const char *EUC_JP;
|
static const char *EUC_JP;
|
||||||
|
|
||||||
static void decodeKanjiSegment(Ref<BitSource> bits, std::ostringstream &result, int count);
|
static void decodeKanjiSegment(Ref<BitSource> bits, std::string &result, int count);
|
||||||
static void decodeByteSegment(Ref<BitSource> bits, std::ostringstream &result, int count);
|
static void decodeByteSegment(Ref<BitSource> bits, std::string &result, int count);
|
||||||
static void decodeAlphanumericSegment(Ref<BitSource> bits, std::ostringstream &result, int count);
|
static void decodeAlphanumericSegment(Ref<BitSource> bits, std::string &result, int count);
|
||||||
static void decodeNumericSegment(Ref<BitSource> bits, std::ostringstream &result, int count);
|
static void decodeNumericSegment(Ref<BitSource> bits, std::string &result, int count);
|
||||||
static const char *guessEncoding(unsigned char *bytes, int length);
|
static const char *guessEncoding(unsigned char *bytes, int length);
|
||||||
static void append(std::ostream &ost, const unsigned char *bufIn, size_t nIn, const char *src);
|
static void append(std::string &ost, const unsigned char *bufIn, size_t nIn, const char *src);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::string decode(ArrayRef<unsigned char> bytes, Version *version);
|
static std::string decode(ArrayRef<unsigned char> bytes, Version *version);
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <zxing/common/Array.h>
|
#include <zxing/common/Array.h>
|
||||||
#include <zxing/common/DecoderResult.h>
|
#include <zxing/common/DecoderResult.h>
|
||||||
#include <zxing/common/BitMatrix.h>
|
#include <zxing/common/BitMatrix.h>
|
||||||
#include <valarray>
|
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
|
|
|
@ -29,15 +29,15 @@ AlignmentPattern::AlignmentPattern(float posX, float posY, float estimatedModule
|
||||||
posX_(posX), posY_(posY), estimatedModuleSize_(estimatedModuleSize) {
|
posX_(posX), posY_(posY), estimatedModuleSize_(estimatedModuleSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float AlignmentPattern::getX() {
|
float AlignmentPattern::getX() const {
|
||||||
return posX_;
|
return posX_;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AlignmentPattern::getY() {
|
float AlignmentPattern::getY() const {
|
||||||
return posY_;
|
return posY_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AlignmentPattern::aboutEquals(float moduleSize, float i, float j) {
|
bool AlignmentPattern::aboutEquals(float moduleSize, float i, float j) const {
|
||||||
return abs(i - posY_) <= moduleSize && abs(j - posX_) <= moduleSize && (abs(moduleSize - estimatedModuleSize_)
|
return abs(i - posY_) <= moduleSize && abs(j - posX_) <= moduleSize && (abs(moduleSize - estimatedModuleSize_)
|
||||||
<= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);
|
<= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ namespace zxing {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AlignmentPattern(float posX, float posY, float estimatedModuleSize);
|
AlignmentPattern(float posX, float posY, float estimatedModuleSize);
|
||||||
float getX();
|
float getX() const;
|
||||||
float getY();
|
float getY() const;
|
||||||
bool aboutEquals(float moduleSize, float i, float j);
|
bool aboutEquals(float moduleSize, float i, float j) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,17 +23,18 @@
|
||||||
#include <zxing/common/BitArray.h>
|
#include <zxing/common/BitArray.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
float AlignmentPatternFinder::centerFromEnd(valarray<int> &stateCount, int end) {
|
float AlignmentPatternFinder::centerFromEnd(vector<int> &stateCount, int end) {
|
||||||
return (float)(end - stateCount[2]) - stateCount[1] / 2.0f;
|
return (float)(end - stateCount[2]) - stateCount[1] / 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AlignmentPatternFinder::foundPatternCross(valarray<int> &stateCount) {
|
bool AlignmentPatternFinder::foundPatternCross(vector<int> &stateCount) {
|
||||||
float maxVariance = moduleSize_ / 2.0f;
|
float maxVariance = moduleSize_ / 2.0f;
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
if (abs(moduleSize_ - stateCount[i]) >= maxVariance) {
|
if (abs(moduleSize_ - stateCount[i]) >= maxVariance) {
|
||||||
|
@ -46,7 +47,7 @@ bool AlignmentPatternFinder::foundPatternCross(valarray<int> &stateCount) {
|
||||||
float AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount,
|
float AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount,
|
||||||
int originalStateCountTotal) {
|
int originalStateCountTotal) {
|
||||||
int maxI = image_->getHeight();
|
int maxI = image_->getHeight();
|
||||||
valarray<int> stateCount(0, 3);
|
vector<int> stateCount(3, 0);
|
||||||
|
|
||||||
|
|
||||||
// Start counting up from center
|
// Start counting up from center
|
||||||
|
@ -92,7 +93,7 @@ float AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ,
|
||||||
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : NAN;
|
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<AlignmentPattern> AlignmentPatternFinder::handlePossibleCenter(valarray<int> &stateCount, size_t i, size_t j) {
|
Ref<AlignmentPattern> AlignmentPatternFinder::handlePossibleCenter(vector<int> &stateCount, size_t i, size_t j) {
|
||||||
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
|
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
|
||||||
float centerJ = centerFromEnd(stateCount, j);
|
float centerJ = centerFromEnd(stateCount, j);
|
||||||
float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal);
|
float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal);
|
||||||
|
@ -136,7 +137,7 @@ Ref<AlignmentPattern> AlignmentPatternFinder::find() {
|
||||||
// Ref<BitArray> luminanceRow(new BitArray(width_));
|
// Ref<BitArray> luminanceRow(new BitArray(width_));
|
||||||
// We are looking for black/white/black modules in 1:1:1 ratio;
|
// We are looking for black/white/black modules in 1:1:1 ratio;
|
||||||
// this tracks the number of black/white/black modules seen so far
|
// this tracks the number of black/white/black modules seen so far
|
||||||
valarray<int> stateCount(0, 3);
|
vector<int> stateCount(3, 0);
|
||||||
for (size_t iGen = 0; iGen < height_; iGen++) {
|
for (size_t iGen = 0; iGen < height_; iGen++) {
|
||||||
// Search from middle outwards
|
// Search from middle outwards
|
||||||
size_t i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
|
size_t i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
|
||||||
|
|
|
@ -43,18 +43,23 @@ private:
|
||||||
size_t height_;
|
size_t height_;
|
||||||
float moduleSize_;
|
float moduleSize_;
|
||||||
|
|
||||||
static float centerFromEnd(std::valarray<int> &stateCount, int end);
|
static float centerFromEnd(std::vector<int> &stateCount, int end);
|
||||||
bool foundPatternCross(std::valarray<int> &stateCount);
|
bool foundPatternCross(std::vector<int> &stateCount);
|
||||||
|
|
||||||
float crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal);
|
float crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal);
|
||||||
|
|
||||||
Ref<AlignmentPattern> handlePossibleCenter(std::valarray<int> &stateCount, size_t i, size_t j);
|
Ref<AlignmentPattern> handlePossibleCenter(std::vector<int> &stateCount, size_t i, size_t j);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AlignmentPatternFinder(Ref<BitMatrix> image, size_t startX, size_t startY, size_t width, size_t height,
|
AlignmentPatternFinder(Ref<BitMatrix> image, size_t startX, size_t startY, size_t width, size_t height,
|
||||||
float moduleSize);
|
float moduleSize);
|
||||||
~AlignmentPatternFinder();
|
~AlignmentPatternFinder();
|
||||||
Ref<AlignmentPattern> find();
|
Ref<AlignmentPattern> find();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AlignmentPatternFinder(const AlignmentPatternFinder&);
|
||||||
|
AlignmentPatternFinder& operator =(const AlignmentPatternFinder&);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <zxing/common/GridSampler.h>
|
#include <zxing/common/GridSampler.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
|
@ -34,231 +35,231 @@ namespace qrcode {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Detector::Detector(Ref<BitMatrix> image) :
|
Detector::Detector(Ref<BitMatrix> image) :
|
||||||
image_(image) {
|
image_(image) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BitMatrix> Detector::getImage() {
|
Ref<BitMatrix> Detector::getImage() {
|
||||||
return image_;
|
return image_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<DetectorResult> Detector::detect() {
|
Ref<DetectorResult> Detector::detect() {
|
||||||
FinderPatternFinder finder(image_);
|
FinderPatternFinder finder(image_);
|
||||||
Ref<FinderPatternInfo> info(finder.find());
|
Ref<FinderPatternInfo> info(finder.find());
|
||||||
|
|
||||||
Ref<FinderPattern> topLeft(info->getTopLeft());
|
Ref<FinderPattern> topLeft(info->getTopLeft());
|
||||||
Ref<FinderPattern> topRight(info->getTopRight());
|
Ref<FinderPattern> topRight(info->getTopRight());
|
||||||
Ref<FinderPattern> bottomLeft(info->getBottomLeft());
|
Ref<FinderPattern> bottomLeft(info->getBottomLeft());
|
||||||
|
|
||||||
float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);
|
float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);
|
||||||
int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
|
int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
|
||||||
Version *provisionalVersion = Version::getProvisionalVersionForDimension(dimension);
|
Version *provisionalVersion = Version::getProvisionalVersionForDimension(dimension);
|
||||||
int modulesBetweenFPCenters = provisionalVersion->getDimensionForVersion() - 7;
|
int modulesBetweenFPCenters = provisionalVersion->getDimensionForVersion() - 7;
|
||||||
|
|
||||||
Ref<AlignmentPattern> alignmentPattern;
|
Ref<AlignmentPattern> alignmentPattern;
|
||||||
// Anything above version 1 has an alignment pattern
|
// Anything above version 1 has an alignment pattern
|
||||||
if (provisionalVersion->getAlignmentPatternCenters().size() > 0) {
|
if (provisionalVersion->getAlignmentPatternCenters().size() > 0) {
|
||||||
|
|
||||||
|
|
||||||
// Guess where a "bottom right" finder pattern would have been
|
// Guess where a "bottom right" finder pattern would have been
|
||||||
float bottomRightX = topRight->getX() - topLeft->getX() + bottomLeft->getX();
|
float bottomRightX = topRight->getX() - topLeft->getX() + bottomLeft->getX();
|
||||||
float bottomRightY = topRight->getY() - topLeft->getY() + bottomLeft->getY();
|
float bottomRightY = topRight->getY() - topLeft->getY() + bottomLeft->getY();
|
||||||
|
|
||||||
|
|
||||||
// Estimate that alignment pattern is closer by 3 modules
|
// Estimate that alignment pattern is closer by 3 modules
|
||||||
// from "bottom right" to known top left location
|
// from "bottom right" to known top left location
|
||||||
float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
|
float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
|
||||||
int estAlignmentX = (int)(topLeft->getX() + correctionToTopLeft * (bottomRightX - topLeft->getX()));
|
int estAlignmentX = (int)(topLeft->getX() + correctionToTopLeft * (bottomRightX - topLeft->getX()));
|
||||||
int estAlignmentY = (int)(topLeft->getY() + correctionToTopLeft * (bottomRightY - topLeft->getY()));
|
int estAlignmentY = (int)(topLeft->getY() + correctionToTopLeft * (bottomRightY - topLeft->getY()));
|
||||||
|
|
||||||
|
|
||||||
// Kind of arbitrary -- expand search radius before giving up
|
// Kind of arbitrary -- expand search radius before giving up
|
||||||
for (int i = 4; i <= 16; i <<= 1) {
|
for (int i = 4; i <= 16; i <<= 1) {
|
||||||
try {
|
try {
|
||||||
alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
|
alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
|
||||||
break;
|
break;
|
||||||
} catch (zxing::ReaderException re) {
|
} catch (zxing::ReaderException re) {
|
||||||
// try next round
|
// try next round
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (alignmentPattern == 0) {
|
if (alignmentPattern == 0) {
|
||||||
// Try anyway
|
// Try anyway
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PerspectiveTransform> transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);
|
}
|
||||||
Ref<BitMatrix> bits(sampleGrid(image_, dimension, transform));
|
|
||||||
std::vector<Ref<ResultPoint> > points(alignmentPattern == 0 ? 3 : 4);
|
|
||||||
points[0].reset(bottomLeft);
|
|
||||||
points[1].reset(topLeft);
|
|
||||||
points[2].reset(topRight);
|
|
||||||
if (alignmentPattern != 0) {
|
|
||||||
points[3].reset(alignmentPattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<DetectorResult> result(new DetectorResult(bits, points, transform));
|
Ref<PerspectiveTransform> transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);
|
||||||
return result;
|
Ref<BitMatrix> bits(sampleGrid(image_, dimension, transform));
|
||||||
|
std::vector<Ref<ResultPoint> > points(alignmentPattern == 0 ? 3 : 4);
|
||||||
|
points[0].reset(bottomLeft);
|
||||||
|
points[1].reset(topLeft);
|
||||||
|
points[2].reset(topRight);
|
||||||
|
if (alignmentPattern != 0) {
|
||||||
|
points[3].reset(alignmentPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<DetectorResult> result(new DetectorResult(bits, points, transform));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PerspectiveTransform> Detector::createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <
|
Ref<PerspectiveTransform> Detector::createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <
|
||||||
ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension) {
|
ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension) {
|
||||||
|
|
||||||
float dimMinusThree = (float)dimension - 3.5f;
|
float dimMinusThree = (float)dimension - 3.5f;
|
||||||
float bottomRightX;
|
float bottomRightX;
|
||||||
float bottomRightY;
|
float bottomRightY;
|
||||||
float sourceBottomRightX;
|
float sourceBottomRightX;
|
||||||
float sourceBottomRightY;
|
float sourceBottomRightY;
|
||||||
if (alignmentPattern != 0) {
|
if (alignmentPattern != 0) {
|
||||||
bottomRightX = alignmentPattern->getX();
|
bottomRightX = alignmentPattern->getX();
|
||||||
bottomRightY = alignmentPattern->getY();
|
bottomRightY = alignmentPattern->getY();
|
||||||
sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
|
sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
|
||||||
} else {
|
} else {
|
||||||
// Don't have an alignment pattern, just make up the bottom-right point
|
// Don't have an alignment pattern, just make up the bottom-right point
|
||||||
bottomRightX = (topRight->getX() - topLeft->getX()) + bottomLeft->getX();
|
bottomRightX = (topRight->getX() - topLeft->getX()) + bottomLeft->getX();
|
||||||
bottomRightY = (topRight->getY() - topLeft->getY()) + bottomLeft->getY();
|
bottomRightY = (topRight->getY() - topLeft->getY()) + bottomLeft->getY();
|
||||||
sourceBottomRightX = sourceBottomRightY = dimMinusThree;
|
sourceBottomRightX = sourceBottomRightY = dimMinusThree;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX,
|
Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX,
|
||||||
sourceBottomRightY, 3.5f, dimMinusThree, topLeft->getX(), topLeft->getY(), topRight->getX(),
|
sourceBottomRightY, 3.5f, dimMinusThree, topLeft->getX(), topLeft->getY(), topRight->getX(),
|
||||||
topRight->getY(), bottomRightX, bottomRightY, bottomLeft->getX(), bottomLeft->getY()));
|
topRight->getY(), bottomRightX, bottomRightY, bottomLeft->getX(), bottomLeft->getY()));
|
||||||
|
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BitMatrix> Detector::sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform) {
|
Ref<BitMatrix> Detector::sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform) {
|
||||||
GridSampler &sampler = GridSampler::getInstance();
|
GridSampler &sampler = GridSampler::getInstance();
|
||||||
return sampler.sampleGrid(image, dimension, transform);
|
return sampler.sampleGrid(image, dimension, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Detector::computeDimension(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft,
|
int Detector::computeDimension(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft,
|
||||||
float moduleSize) {
|
float moduleSize) {
|
||||||
int tltrCentersDimension = lround(FinderPatternFinder::distance(topLeft, topRight) / moduleSize);
|
int tltrCentersDimension = int(FinderPatternFinder::distance(topLeft, topRight) / moduleSize + 0.5f);
|
||||||
int tlblCentersDimension = lround(FinderPatternFinder::distance(topLeft, bottomLeft) / moduleSize);
|
int tlblCentersDimension = int(FinderPatternFinder::distance(topLeft, bottomLeft) / moduleSize + 0.5f);
|
||||||
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
|
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
|
||||||
switch (dimension & 0x03) { // mod 4
|
switch (dimension & 0x03) { // mod 4
|
||||||
case 0:
|
case 0:
|
||||||
dimension++;
|
dimension++;
|
||||||
break;
|
break;
|
||||||
// 1? do nothing
|
// 1? do nothing
|
||||||
case 2:
|
case 2:
|
||||||
dimension--;
|
dimension--;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
ostringstream s;
|
ostringstream s;
|
||||||
s << "Bad dimension: " << dimension;
|
s << "Bad dimension: " << dimension;
|
||||||
throw zxing::ReaderException(s.str().c_str());
|
throw zxing::ReaderException(s.str().c_str());
|
||||||
}
|
}
|
||||||
return dimension;
|
return dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Detector::calculateModuleSize(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft) {
|
float Detector::calculateModuleSize(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft) {
|
||||||
// Take the average
|
// Take the average
|
||||||
return (calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
|
return (calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Detector::calculateModuleSizeOneWay(Ref<ResultPoint> pattern, Ref<ResultPoint> otherPattern) {
|
float Detector::calculateModuleSizeOneWay(Ref<ResultPoint> pattern, Ref<ResultPoint> otherPattern) {
|
||||||
float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int)pattern->getX(), (int)pattern->getY(),
|
float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int)pattern->getX(), (int)pattern->getY(),
|
||||||
(int)otherPattern->getX(), (int)otherPattern->getY());
|
(int)otherPattern->getX(), (int)otherPattern->getY());
|
||||||
float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int)otherPattern->getX(), (int)otherPattern->getY(),
|
float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int)otherPattern->getX(), (int)otherPattern->getY(),
|
||||||
(int)pattern->getX(), (int)pattern->getY());
|
(int)pattern->getX(), (int)pattern->getY());
|
||||||
if (isnan(moduleSizeEst1)) {
|
if (isnan(moduleSizeEst1)) {
|
||||||
return moduleSizeEst2;
|
return moduleSizeEst2;
|
||||||
}
|
}
|
||||||
if (isnan(moduleSizeEst2)) {
|
if (isnan(moduleSizeEst2)) {
|
||||||
return moduleSizeEst1;
|
return moduleSizeEst1;
|
||||||
}
|
}
|
||||||
// Average them, and divide by 7 since we've counted the width of 3 black modules,
|
// Average them, and divide by 7 since we've counted the width of 3 black modules,
|
||||||
// and 1 white and 1 black module on either side. Ergo, divide sum by 14.
|
// and 1 white and 1 black module on either side. Ergo, divide sum by 14.
|
||||||
return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
|
return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Detector::sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY) {
|
float Detector::sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY) {
|
||||||
|
|
||||||
float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
|
float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
|
||||||
|
|
||||||
|
|
||||||
// Now count other way -- don't run off image though of course
|
// Now count other way -- don't run off image though of course
|
||||||
int otherToX = fromX - (toX - fromX);
|
int otherToX = fromX - (toX - fromX);
|
||||||
if (otherToX < 0) {
|
if (otherToX < 0) {
|
||||||
// "to" should the be the first value not included, so, the first value off
|
// "to" should the be the first value not included, so, the first value off
|
||||||
// the edge is -1
|
// the edge is -1
|
||||||
otherToX = -1;
|
otherToX = -1;
|
||||||
} else if (otherToX >= (int)image_->getWidth()) {
|
} else if (otherToX >= (int)image_->getWidth()) {
|
||||||
otherToX = image_->getWidth();
|
otherToX = image_->getWidth();
|
||||||
}
|
}
|
||||||
int otherToY = fromY - (toY - fromY);
|
int otherToY = fromY - (toY - fromY);
|
||||||
if (otherToY < 0) {
|
if (otherToY < 0) {
|
||||||
otherToY = -1;
|
otherToY = -1;
|
||||||
} else if (otherToY >= (int)image_->getHeight()) {
|
} else if (otherToY >= (int)image_->getHeight()) {
|
||||||
otherToY = image_->getHeight();
|
otherToY = image_->getHeight();
|
||||||
}
|
}
|
||||||
result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
|
result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
|
||||||
return result - 1.0f; // -1 because we counted the middle pixel twice
|
return result - 1.0f; // -1 because we counted the middle pixel twice
|
||||||
}
|
}
|
||||||
|
|
||||||
float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) {
|
float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) {
|
||||||
// Mild variant of Bresenham's algorithm;
|
// Mild variant of Bresenham's algorithm;
|
||||||
// see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
// see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
||||||
bool steep = abs(toY - fromY) > abs(toX - fromX);
|
bool steep = abs(toY - fromY) > abs(toX - fromX);
|
||||||
if (steep) {
|
if (steep) {
|
||||||
int temp = fromX;
|
int temp = fromX;
|
||||||
fromX = fromY;
|
fromX = fromY;
|
||||||
fromY = temp;
|
fromY = temp;
|
||||||
temp = toX;
|
temp = toX;
|
||||||
toX = toY;
|
toX = toY;
|
||||||
toY = temp;
|
toY = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dx = abs(toX - fromX);
|
||||||
|
int dy = abs(toY - fromY);
|
||||||
|
int error = -dx >> 1;
|
||||||
|
int ystep = fromY < toY ? 1 : -1;
|
||||||
|
int xstep = fromX < toX ? 1 : -1;
|
||||||
|
int state = 0; // In black pixels, looking for white, first or second time
|
||||||
|
for (int x = fromX, y = fromY; x != toX; x += xstep) {
|
||||||
|
|
||||||
|
int realX = steep ? y : x;
|
||||||
|
int realY = steep ? x : y;
|
||||||
|
if (state == 1) { // In white pixels, looking for black
|
||||||
|
if (image_->get(realX, realY)) {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!image_->get(realX, realY)) {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int dx = abs(toX - fromX);
|
if (state == 3) { // Found black, white, black, and stumbled back onto white; done
|
||||||
int dy = abs(toY - fromY);
|
int diffX = x - fromX;
|
||||||
int error = -dx >> 1;
|
int diffY = y - fromY;
|
||||||
int ystep = fromY < toY ? 1 : -1;
|
return (float)sqrt((double)(diffX * diffX + diffY * diffY));
|
||||||
int xstep = fromX < toX ? 1 : -1;
|
|
||||||
int state = 0; // In black pixels, looking for white, first or second time
|
|
||||||
for (int x = fromX, y = fromY; x != toX; x += xstep) {
|
|
||||||
|
|
||||||
int realX = steep ? y : x;
|
|
||||||
int realY = steep ? x : y;
|
|
||||||
if (state == 1) { // In white pixels, looking for black
|
|
||||||
if (image_->get(realX, realY)) {
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!image_->get(realX, realY)) {
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 3) { // Found black, white, black, and stumbled back onto white; done
|
|
||||||
int diffX = x - fromX;
|
|
||||||
int diffY = y - fromY;
|
|
||||||
return (float)sqrt((double)(diffX * diffX + diffY * diffY));
|
|
||||||
}
|
|
||||||
error += dy;
|
|
||||||
if (error > 0) {
|
|
||||||
y += ystep;
|
|
||||||
error -= dx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int diffX = toX - fromX;
|
error += dy;
|
||||||
int diffY = toY - fromY;
|
if (error > 0) {
|
||||||
return (float)sqrt((double)(diffX * diffX + diffY * diffY));
|
y += ystep;
|
||||||
|
error -= dx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int diffX = toX - fromX;
|
||||||
|
int diffY = toY - fromY;
|
||||||
|
return (float)sqrt((double)(diffX * diffX + diffY * diffY));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<AlignmentPattern> Detector::findAlignmentInRegion(float overallEstModuleSize, int estAlignmentX, int estAlignmentY,
|
Ref<AlignmentPattern> Detector::findAlignmentInRegion(float overallEstModuleSize, int estAlignmentX, int estAlignmentY,
|
||||||
float allowanceFactor) {
|
float allowanceFactor) {
|
||||||
// Look for an alignment pattern (3 modules in size) around where it
|
// Look for an alignment pattern (3 modules in size) around where it
|
||||||
// should be
|
// should be
|
||||||
int allowance = (int)(allowanceFactor * overallEstModuleSize);
|
int allowance = (int)(allowanceFactor * overallEstModuleSize);
|
||||||
int alignmentAreaLeftX = max(0, estAlignmentX - allowance);
|
int alignmentAreaLeftX = max(0, estAlignmentX - allowance);
|
||||||
int alignmentAreaRightX = min((int)(image_->getWidth() - 1), estAlignmentX + allowance);
|
int alignmentAreaRightX = min((int)(image_->getWidth() - 1), estAlignmentX + allowance);
|
||||||
int alignmentAreaTopY = max(0, estAlignmentY - allowance);
|
int alignmentAreaTopY = max(0, estAlignmentY - allowance);
|
||||||
int alignmentAreaBottomY = min((int)(image_->getHeight() - 1), estAlignmentY + allowance);
|
int alignmentAreaBottomY = min((int)(image_->getHeight() - 1), estAlignmentY + allowance);
|
||||||
|
|
||||||
AlignmentPatternFinder alignmentFinder(image_, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX
|
AlignmentPatternFinder alignmentFinder(image_, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX
|
||||||
- alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize);
|
- alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize);
|
||||||
return alignmentFinder.find();
|
return alignmentFinder.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,19 +29,19 @@ namespace zxing {
|
||||||
posX_(posX), posY_(posY), estimatedModuleSize_(estimatedModuleSize), counter_(1) {
|
posX_(posX), posY_(posY), estimatedModuleSize_(estimatedModuleSize), counter_(1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float FinderPattern::getX() {
|
float FinderPattern::getX() const {
|
||||||
return posX_;
|
return posX_;
|
||||||
}
|
}
|
||||||
|
|
||||||
float FinderPattern::getY() {
|
float FinderPattern::getY() const {
|
||||||
return posY_;
|
return posY_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FinderPattern::getCount() {
|
int FinderPattern::getCount() const {
|
||||||
return counter_;
|
return counter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
float FinderPattern::getEstimatedModuleSize() {
|
float FinderPattern::getEstimatedModuleSize() const {
|
||||||
return estimatedModuleSize_;
|
return estimatedModuleSize_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace zxing {
|
||||||
counter_++;
|
counter_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FinderPattern::aboutEquals(float moduleSize, float i, float j) {
|
bool FinderPattern::aboutEquals(float moduleSize, float i, float j) const {
|
||||||
return abs(i - posY_) <= moduleSize && abs(j - posX_) <= moduleSize && (abs(moduleSize - estimatedModuleSize_)
|
return abs(i - posY_) <= moduleSize && abs(j - posX_) <= moduleSize && (abs(moduleSize - estimatedModuleSize_)
|
||||||
<= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);
|
<= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,12 @@ namespace zxing {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FinderPattern(float posX, float posY, float estimatedModuleSize);
|
FinderPattern(float posX, float posY, float estimatedModuleSize);
|
||||||
float getX();
|
float getX() const;
|
||||||
float getY();
|
float getY() const;
|
||||||
int getCount();
|
int getCount() const;
|
||||||
float getEstimatedModuleSize();
|
float getEstimatedModuleSize() const;
|
||||||
void incrementCount();
|
void incrementCount();
|
||||||
bool aboutEquals(float moduleSize, float i, float j);
|
bool aboutEquals(float moduleSize, float i, float j) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
namespace qrcode {
|
namespace qrcode {
|
||||||
|
@ -32,6 +34,8 @@ class ClosestToAverageComparator {
|
||||||
private:
|
private:
|
||||||
float averageModuleSize_;
|
float averageModuleSize_;
|
||||||
public:
|
public:
|
||||||
|
ClosestToAverageComparator() : averageModuleSize_(0.0f) { }
|
||||||
|
|
||||||
ClosestToAverageComparator(float averageModuleSize) :
|
ClosestToAverageComparator(float averageModuleSize) :
|
||||||
averageModuleSize_(averageModuleSize) {
|
averageModuleSize_(averageModuleSize) {
|
||||||
}
|
}
|
||||||
|
@ -393,7 +397,7 @@ Ref<FinderPatternInfo> FinderPatternFinder::find() {
|
||||||
// We are looking for black/white/black/white/black modules in
|
// We are looking for black/white/black/white/black modules in
|
||||||
// 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
|
// 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
|
||||||
|
|
||||||
// As this is used often, we use an integer array instead of valarray
|
// As this is used often, we use an integer array instead of vector
|
||||||
int stateCount[5];
|
int stateCount[5];
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <zxing/qrcode/detector/QREdgeDetector.h>
|
#include <zxing/qrcode/detector/QREdgeDetector.h>
|
||||||
#include <zxing/common/EdgeDetector.h>
|
#include <zxing/common/EdgeDetector.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue