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()
|
||||
{
|
||||
{
|
||||
image = otherInstance.getOriginalImage().copy();
|
||||
}
|
||||
}
|
||||
|
||||
CameraImageWrapper::~CameraImageWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
int CameraImageWrapper::getWidth()
|
||||
{
|
||||
return image.width();
|
||||
}
|
||||
int CameraImageWrapper::getWidth() const
|
||||
{
|
||||
return image.width();
|
||||
}
|
||||
|
||||
int CameraImageWrapper::getHeight()
|
||||
{
|
||||
return image.height();
|
||||
}
|
||||
int CameraImageWrapper::getHeight() const
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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())
|
||||
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)
|
||||
{
|
||||
image = newImage.copy();
|
||||
|
||||
|
||||
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)
|
||||
|
@ -63,15 +79,15 @@ QImage CameraImageWrapper::grayScaleImage(QImage::Format f)
|
|||
tmp.setPixel(i,j, qRgb(pix ,pix,pix));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return tmp;
|
||||
|
||||
//return image.convertToFormat(f);
|
||||
|
||||
//return image.convertToFormat(f);
|
||||
}
|
||||
|
||||
QImage CameraImageWrapper::getOriginalImage()
|
||||
{
|
||||
return image;
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,12 +14,13 @@ public:
|
|||
CameraImageWrapper(CameraImageWrapper& otherInstance);
|
||||
~CameraImageWrapper();
|
||||
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
int getWidth() const;
|
||||
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);
|
||||
QImage grayScaleImage(QImage::Format f);
|
||||
QImage getOriginalImage();
|
||||
|
|
|
@ -156,4 +156,6 @@ symbian {
|
|||
DEPLOYMENT += customrules
|
||||
}
|
||||
|
||||
DEFINES += ZXING_ICONV_CONST
|
||||
|
||||
ICON = QQrDecoder.svg
|
||||
|
|
Binary file not shown.
|
@ -23,7 +23,7 @@
|
|||
|
||||
namespace zxing {
|
||||
|
||||
Binarizer::Binarizer(Ref<LuminanceSource> source) : source_(source) {
|
||||
Binarizer::Binarizer(Ref<LuminanceSource> source) : source_(source), array_(NULL), matrix_(NULL) {
|
||||
}
|
||||
|
||||
Binarizer::~Binarizer() {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
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() {
|
||||
return message;
|
||||
return message.c_str();
|
||||
}
|
||||
|
||||
Exception::~Exception() throw() {
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace zxing {
|
|||
|
||||
class Exception : public std::exception {
|
||||
private:
|
||||
const char * message;
|
||||
std::string message;
|
||||
|
||||
public:
|
||||
Exception(const char *msg);
|
||||
|
|
|
@ -28,7 +28,7 @@ LuminanceSource::LuminanceSource() {
|
|||
LuminanceSource::~LuminanceSource() {
|
||||
}
|
||||
|
||||
unsigned char* LuminanceSource::copyMatrix() {
|
||||
unsigned char* LuminanceSource::copyMatrix() const {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
unsigned char* matrix = new unsigned char[width*height];
|
||||
|
|
|
@ -30,11 +30,11 @@ public:
|
|||
LuminanceSource();
|
||||
virtual ~LuminanceSource();
|
||||
|
||||
virtual int getWidth() = 0;
|
||||
virtual int getHeight() = 0;
|
||||
virtual int getWidth() const = 0;
|
||||
virtual int getHeight() const = 0;
|
||||
|
||||
virtual unsigned char getPixel(int x, int y) = 0;
|
||||
virtual unsigned char* copyMatrix();
|
||||
virtual unsigned char getPixel(int x, int y) const = 0;
|
||||
virtual unsigned char* copyMatrix() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -27,19 +27,17 @@
|
|||
#include <zxing/ReaderException.h>
|
||||
|
||||
namespace zxing {
|
||||
MultiFormatReader::MultiFormatReader(){
|
||||
readers = new std::vector<Reader*>();
|
||||
|
||||
readers->push_back(new zxing::qrcode::QRCodeReader());
|
||||
// readers->push_back(new zxing::datamatrix::DataMatrixReader());
|
||||
readers->push_back(new zxing::oned::MultiFormatUPCEANReader());
|
||||
readers->push_back(new zxing::oned::MultiFormatOneDReader());
|
||||
MultiFormatReader::MultiFormatReader() : readers() {
|
||||
readers.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader()));
|
||||
//readers.push_back(Ref<Reader>(new zxing::datamatrix::DataMatrixReader()));
|
||||
readers.push_back(Ref<Reader>(new zxing::oned::MultiFormatUPCEANReader()));
|
||||
readers.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader()));
|
||||
}
|
||||
|
||||
Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image){
|
||||
int size = readers->size();
|
||||
int size = readers.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Reader* reader = (*readers)[i];
|
||||
Ref<Reader> reader = readers[i];
|
||||
try {
|
||||
return reader->decode(image);
|
||||
} catch (ReaderException re) {
|
||||
|
@ -48,7 +46,4 @@ namespace zxing {
|
|||
}
|
||||
throw ReaderException("No code detected");
|
||||
}
|
||||
MultiFormatReader::~MultiFormatReader(){
|
||||
delete readers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,11 @@ namespace zxing {
|
|||
class MultiFormatReader : public Reader {
|
||||
|
||||
private:
|
||||
std::vector<Reader*>* readers;
|
||||
std::vector<Ref<Reader> >readers;
|
||||
public:
|
||||
MultiFormatReader();
|
||||
|
||||
Ref<Result> decode(Ref<BinaryBitmap> image);
|
||||
|
||||
~MultiFormatReader();
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,16 +21,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <zxing/BinaryBitmap.h>
|
||||
#include <zxing/Result.h>
|
||||
|
||||
namespace zxing {
|
||||
|
||||
class Reader {
|
||||
public:
|
||||
virtual Ref<Result> decode(Ref<BinaryBitmap> image) = 0;
|
||||
virtual ~Reader();
|
||||
class Reader : public Counted {
|
||||
protected:
|
||||
Reader() {}
|
||||
public:
|
||||
virtual Ref<Result> decode(Ref<BinaryBitmap> image) = 0;
|
||||
virtual ~Reader();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -39,11 +39,11 @@ ArrayRef<unsigned char> Result::getRawBytes() {
|
|||
return rawBytes_;
|
||||
}
|
||||
|
||||
std::vector<Ref<ResultPoint> > Result::getResultPoints() {
|
||||
const std::vector<Ref<ResultPoint> >& Result::getResultPoints() const {
|
||||
return resultPoints_;
|
||||
}
|
||||
|
||||
BarcodeFormat Result::getBarcodeFormat() {
|
||||
BarcodeFormat Result::getBarcodeFormat() const {
|
||||
return format_;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,8 @@ public:
|
|||
~Result();
|
||||
Ref<String> getText();
|
||||
ArrayRef<unsigned char> getRawBytes();
|
||||
std::vector<Ref<ResultPoint> > getResultPoints();
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
const std::vector<Ref<ResultPoint> >& getResultPoints() const;
|
||||
BarcodeFormat getBarcodeFormat() const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &out, Result& result);
|
||||
};
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
namespace zxing {
|
||||
|
||||
class ResultPoint : public Counted {
|
||||
protected:
|
||||
ResultPoint() {}
|
||||
public:
|
||||
virtual float getX() = 0;
|
||||
virtual float getY() = 0;
|
||||
virtual float getX() const = 0;
|
||||
virtual float getY() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <valarray>
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
|
||||
#ifdef DEBUG_COUNTING
|
||||
#include <iostream>
|
||||
|
@ -37,17 +36,17 @@ namespace zxing {
|
|||
template<typename T> class Array : public Counted {
|
||||
protected:
|
||||
public:
|
||||
std::valarray<T> values_;
|
||||
std::vector<T> values_;
|
||||
Array(size_t n) :
|
||||
Counted(), values_(T(), n) {
|
||||
Counted(), values_(n, T()) {
|
||||
}
|
||||
Array(T *ts, size_t n) :
|
||||
Counted(), values_(ts, n) {
|
||||
Counted(), values_(ts, ts+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) {
|
||||
}
|
||||
Array(Array<T> &other) :
|
||||
|
@ -68,7 +67,7 @@ public:
|
|||
#endif
|
||||
return *this;
|
||||
}
|
||||
Array<T>& operator=(const std::valarray<T> &array) {
|
||||
Array<T>& operator=(const std::vector<T> &array) {
|
||||
#ifdef DEBUG_COUNTING
|
||||
cout << "assigning values from Array " << &array << " to this Array " << this << ", ";
|
||||
#endif
|
||||
|
@ -87,10 +86,10 @@ public:
|
|||
size_t size() const {
|
||||
return values_.size();
|
||||
}
|
||||
std::valarray<T> values() const {
|
||||
std::vector<T> values() const {
|
||||
return values_;
|
||||
}
|
||||
std::valarray<T>& values() {
|
||||
std::vector<T>& values() {
|
||||
return values_;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <zxing/common/BitArray.h>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -43,12 +44,9 @@ size_t BitArray::wordsForBits(size_t bits) {
|
|||
}
|
||||
return arraySize;
|
||||
}
|
||||
BitArray::BitArray() {
|
||||
cout << "hey! don't use this BitArrayConstructor!\n";
|
||||
}
|
||||
|
||||
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() {
|
||||
}
|
||||
|
@ -105,7 +103,7 @@ bool BitArray::isRange(size_t start, size_t end, bool value) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
valarray<unsigned int>& BitArray::getBitArray() {
|
||||
vector<unsigned int>& BitArray::getBitArray() {
|
||||
return bits_;
|
||||
}
|
||||
void BitArray::reverse() {
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
|
||||
#include <zxing/common/Counted.h>
|
||||
#include <zxing/common/IllegalArgumentException.h>
|
||||
#include <valarray>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
namespace zxing {
|
||||
|
@ -32,7 +31,7 @@ namespace zxing {
|
|||
class BitArray : public Counted {
|
||||
private:
|
||||
size_t size_;
|
||||
std::valarray<unsigned int> bits_;
|
||||
std::vector<unsigned int> bits_;
|
||||
static const unsigned int bitsPerWord_;
|
||||
static const unsigned int logBits_;
|
||||
static const unsigned int bitsMask_;
|
||||
|
@ -48,7 +47,7 @@ public:
|
|||
void setBulk(size_t i, unsigned int newBits);
|
||||
void clear();
|
||||
bool isRange(size_t start, size_t end, bool value);
|
||||
std::valarray<unsigned int>& getBitArray();
|
||||
std::vector<unsigned int>& getBitArray();
|
||||
void reverse();
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
namespace zxing {
|
||||
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 bitsMask = (1 << logBits) - 1;
|
||||
|
||||
|
@ -54,7 +53,7 @@ static size_t wordsForSize(size_t width, size_t height) {
|
|||
}
|
||||
|
||||
BitMatrix::BitMatrix(size_t dimension) :
|
||||
width_(dimension), height_(dimension), bits_(NULL) {
|
||||
width_(dimension), height_(dimension), words_(0), bits_(NULL) {
|
||||
|
||||
words_ = wordsForSize(width_, height_);
|
||||
bits_ = new unsigned int[words_];
|
||||
|
@ -62,7 +61,7 @@ BitMatrix::BitMatrix(size_t dimension) :
|
|||
}
|
||||
|
||||
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_);
|
||||
bits_ = new unsigned int[words_];
|
||||
|
@ -90,7 +89,7 @@ void BitMatrix::flip(size_t x, size_t y) {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -126,11 +125,11 @@ size_t BitMatrix::getDimension() const {
|
|||
return width_;
|
||||
}
|
||||
|
||||
unsigned int* BitMatrix::getBits() {
|
||||
unsigned int* BitMatrix::getBits() const {
|
||||
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 x = 0; x < bm.width_; x++) {
|
||||
out << (bm.get(x, y) ? "X " : " ");
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
*/
|
||||
|
||||
#include <zxing/common/Counted.h>
|
||||
#include <valarray>
|
||||
#include <limits>
|
||||
|
||||
namespace zxing {
|
||||
|
@ -50,10 +49,14 @@ public:
|
|||
size_t getWidth() 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();
|
||||
|
||||
private:
|
||||
BitMatrix(const BitMatrix&);
|
||||
BitMatrix& operator =(const BitMatrix&);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -26,10 +26,8 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#ifdef DEBUG_COUNTING
|
||||
#include <typeinfo>
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
namespace zxing {
|
||||
|
@ -174,10 +172,10 @@ public:
|
|||
T& operator*() {
|
||||
return *object_;
|
||||
}
|
||||
T* operator->() {
|
||||
T* operator->() const {
|
||||
return object_;
|
||||
}
|
||||
operator T*() {
|
||||
operator T*() const {
|
||||
return object_;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <zxing/common/EdgeDetector.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace zxing {
|
|||
|
||||
|
||||
Ref<BitArray> GlobalHistogramBinarizer::estimateBlackRow(int y, Ref<BitArray> row){
|
||||
valarray<int> histogram(0, LUMINANCE_BUCKETS);
|
||||
vector<int> histogram(LUMINANCE_BUCKETS, 0);
|
||||
LuminanceSource& source = *getSource();
|
||||
int width = source.getWidth();
|
||||
if (row == NULL || row->getSize() < width) {
|
||||
|
@ -80,7 +80,7 @@ namespace zxing {
|
|||
LuminanceSource& source = *getSource();
|
||||
int width = source.getWidth();
|
||||
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
|
||||
|
@ -109,7 +109,7 @@ namespace zxing {
|
|||
return matrix_ref;
|
||||
}
|
||||
|
||||
int GlobalHistogramBinarizer::estimate(valarray<int> &histogram) {
|
||||
int GlobalHistogramBinarizer::estimate(vector<int> &histogram) {
|
||||
int numBuckets = histogram.size();
|
||||
int maxBucketCount = 0;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef GLOBALHISTOGRAMBINARIZER_H_
|
||||
#define GLOBALHISTOGRAMBINARIZER_H_
|
||||
|
||||
#include <valarray>
|
||||
#include <vector>
|
||||
#include <zxing/Binarizer.h>
|
||||
#include <zxing/common/BitArray.h>
|
||||
#include <zxing/common/BitMatrix.h>
|
||||
|
@ -36,7 +36,7 @@ namespace zxing {
|
|||
|
||||
virtual Ref<BitArray> estimateBlackRow(int y, Ref<BitArray> row);
|
||||
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> 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++) {
|
||||
int max = points.size();
|
||||
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 height = image->getHeight();
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
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 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();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,18 +23,13 @@
|
|||
namespace zxing {
|
||||
using namespace std;
|
||||
|
||||
PerspectiveTransform::PerspectiveTransform(float a11, float a21, float a31, float a12, float a22, float a32, float a13,
|
||||
float a23, float a33) {
|
||||
this->a11 = a11;
|
||||
this->a12 = a12;
|
||||
this->a13 = a13;
|
||||
this->a21 = a21;
|
||||
this->a22 = a22;
|
||||
this->a23 = a23;
|
||||
this->a31 = a31;
|
||||
this->a32 = a32;
|
||||
this->a33 = a33;
|
||||
}
|
||||
PerspectiveTransform::PerspectiveTransform(float inA11, float inA21,
|
||||
float inA31, float inA12,
|
||||
float inA22, float inA32,
|
||||
float inA13, float inA23,
|
||||
float inA33) :
|
||||
a11(inA11), a21(inA21), a31(inA31), a12(inA12), a22(inA22), a32(inA32),
|
||||
a13(inA13), a23(inA23), a33(inA33) {}
|
||||
|
||||
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,
|
||||
|
@ -91,17 +86,8 @@ Ref<PerspectiveTransform> PerspectiveTransform::times(Ref<PerspectiveTransform>
|
|||
return result;
|
||||
}
|
||||
|
||||
void PerspectiveTransform::transformPoints(valarray<float> &points) {
|
||||
void PerspectiveTransform::transformPoints(vector<float> &points) {
|
||||
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) {
|
||||
float x = points[i];
|
||||
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.a21 << ", " << pt.a22 << ", " << pt.a23 << ", \n";
|
||||
out << pt.a31 << ", " << pt.a32 << ", " << pt.a33 << "\n";
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
|
||||
#include <zxing/common/Counted.h>
|
||||
#include <valarray>
|
||||
#include <vector>
|
||||
|
||||
namespace zxing {
|
||||
class PerspectiveTransform : public Counted {
|
||||
|
@ -41,9 +41,9 @@ public:
|
|||
float x3, float y3);
|
||||
Ref<PerspectiveTransform> buildAdjoint();
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef ZXING_POINT_H_
|
||||
#define ZXING_POINT_H_
|
||||
#ifndef ZXING_POINT_H_
|
||||
#define ZXING_POINT_H_
|
||||
|
||||
namespace zxing {
|
||||
namespace zxing {
|
||||
class PointI {
|
||||
public:
|
||||
int x;
|
||||
|
@ -30,6 +30,7 @@ public:
|
|||
|
||||
class Point {
|
||||
public:
|
||||
Point() : x(0.0f), y(0.0f) {};
|
||||
Point(float x_, float y_) : x(x_), y(y_) {};
|
||||
|
||||
float x;
|
||||
|
@ -42,6 +43,6 @@ public:
|
|||
|
||||
Point start;
|
||||
Point end;
|
||||
};
|
||||
}
|
||||
#endif // POINT_H_
|
||||
};
|
||||
}
|
||||
#endif // POINT_H_
|
||||
|
|
|
@ -26,7 +26,7 @@ using namespace std;
|
|||
String::String(const std::string &text) :
|
||||
text_(text) {
|
||||
}
|
||||
std::string& String::getText() {
|
||||
const std::string& String::getText() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ private:
|
|||
std::string text_;
|
||||
public:
|
||||
String(const std::string &text);
|
||||
std::string &getText();
|
||||
const std::string &getText() const;
|
||||
friend std::ostream &operator<<(std::ostream &out, const String &s);
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <valarray>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <zxing/common/reedsolomon/GF256.h>
|
||||
|
@ -42,7 +41,7 @@ static inline Ref<GF256Poly> refPoly(GF256 &field, int value) {
|
|||
}
|
||||
|
||||
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;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
exp_[i] = x;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <valarray>
|
||||
#include <vector>
|
||||
#include <zxing/common/Counted.h>
|
||||
|
||||
namespace zxing {
|
||||
|
@ -42,8 +42,8 @@ class GF256 {
|
|||
* @author christian.brunschen@gmail.com (Christian Brunschen)
|
||||
*/
|
||||
private:
|
||||
std::valarray<int> exp_;
|
||||
std::valarray<int> log_;
|
||||
std::vector<int> exp_;
|
||||
std::vector<int> log_;
|
||||
Ref<GF256Poly> zero_;
|
||||
Ref<GF256Poly> one_;
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
const int CODE_PATTERNS_LENGHT = 107;
|
||||
const int countersLenght = 6;
|
||||
static const int CODE_PATTERNS[CODE_PATTERNS_LENGHT][countersLenght] = {
|
||||
const int CODE_PATTERNS_LENGTH = 107;
|
||||
const int countersLength = 6;
|
||||
static const int CODE_PATTERNS[CODE_PATTERNS_LENGTH][countersLength] = {
|
||||
{2, 1, 2, 2, 2, 2}, /* 0 */
|
||||
{2, 2, 2, 1, 2, 2},
|
||||
{2, 2, 2, 2, 2, 1},
|
||||
|
@ -155,7 +155,7 @@ namespace zxing {
|
|||
}
|
||||
|
||||
int counterPosition = 0;
|
||||
int counters[countersLenght] = {0,0,0,0,0,0};
|
||||
int counters[countersLength] = {0,0,0,0,0,0};
|
||||
int patternStart = rowOffset;
|
||||
bool isWhite = false;
|
||||
int patternLength = sizeof(counters) / sizeof(int);
|
||||
|
@ -206,13 +206,13 @@ namespace zxing {
|
|||
recordPattern(row, rowOffset, counters, countersCount);
|
||||
int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
||||
int bestMatch = -1;
|
||||
for (int d = 0; d < CODE_PATTERNS_LENGHT; d++) {
|
||||
int pattern[countersLenght];
|
||||
for (int d = 0; d < CODE_PATTERNS_LENGTH; d++) {
|
||||
int pattern[countersLength];
|
||||
|
||||
for(int ind = 0; ind< countersLenght; ind++){
|
||||
for(int ind = 0; ind< countersLength; 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);
|
||||
if (variance < bestVariance) {
|
||||
bestVariance = variance;
|
||||
|
@ -243,6 +243,7 @@ namespace zxing {
|
|||
codeSet = CODE_CODE_C;
|
||||
break;
|
||||
default:
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -254,7 +255,7 @@ namespace zxing {
|
|||
|
||||
int lastStart = startPatternInfo[0];
|
||||
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 code = 0;
|
||||
|
@ -271,7 +272,12 @@ namespace zxing {
|
|||
lastCode = code;
|
||||
|
||||
// Decode another code from image
|
||||
try {
|
||||
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)
|
||||
if (code != CODE_STOP) {
|
||||
|
@ -286,8 +292,8 @@ namespace zxing {
|
|||
|
||||
// Advance to where the next code will to start
|
||||
lastStart = nextStart;
|
||||
int _countersLenght = sizeof(counters) / sizeof(int);
|
||||
for (int i = 0; i < _countersLenght; i++) {
|
||||
int _countersLength = sizeof(counters) / sizeof(int);
|
||||
for (int i = 0; i < _countersLength; i++) {
|
||||
nextStart += counters[i];
|
||||
}
|
||||
|
||||
|
@ -296,6 +302,7 @@ namespace zxing {
|
|||
case CODE_START_A:
|
||||
case CODE_START_B:
|
||||
case CODE_START_C:
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -418,6 +425,7 @@ namespace zxing {
|
|||
nextStart++;
|
||||
}
|
||||
if (!row->isRange(nextStart, fminl(width, nextStart + (nextStart - lastStart) / 2), false)) {
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -425,6 +433,7 @@ namespace zxing {
|
|||
checksumTotal -= multiplier * lastCode;
|
||||
// lastCode is the checksum then:
|
||||
if (checksumTotal % 103 != lastCode) {
|
||||
delete [] startPatternInfo;
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -444,6 +453,7 @@ namespace zxing {
|
|||
// String resultString(tmpResultString);
|
||||
|
||||
if (tmpResultString.length() == 0) {
|
||||
delete [] startPatternInfo;
|
||||
// Almost surely a false positive
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
|
|
@ -46,17 +46,16 @@ namespace zxing {
|
|||
};
|
||||
|
||||
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
|
||||
* character as a check digit. It will not decoded "extended Code 39" sequences.
|
||||
*/
|
||||
Code39Reader::Code39Reader(){
|
||||
ALPHABET_STRING = new std::string("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%");
|
||||
usingCheckDigit = false;
|
||||
extendedMode = false;
|
||||
Code39Reader::Code39Reader() : alphabet_string(ALPHABET_STRING),
|
||||
usingCheckDigit(false),
|
||||
extendedMode(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,10 +65,9 @@ namespace zxing {
|
|||
* @param usingCheckDigit if true, treat the last data character as a check digit, not
|
||||
* data, and verify that the checksum passes.
|
||||
*/
|
||||
Code39Reader::Code39Reader(bool usingCheckDigit_){
|
||||
ALPHABET_STRING = new std::string("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%");
|
||||
usingCheckDigit = usingCheckDigit_;
|
||||
extendedMode = false;
|
||||
Code39Reader::Code39Reader(bool usingCheckDigit_) : alphabet_string(ALPHABET_STRING),
|
||||
usingCheckDigit(usingCheckDigit_),
|
||||
extendedMode(false) {
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,9 +92,15 @@ namespace zxing {
|
|||
char decodedChar;
|
||||
int lastStart;
|
||||
do {
|
||||
try {
|
||||
recordPattern(row, nextStart, counters, countersLen);
|
||||
} catch (ReaderException re) {
|
||||
delete [] start;
|
||||
throw re;
|
||||
}
|
||||
int pattern = toNarrowWidePattern(counters, countersLen);
|
||||
if (pattern < 0) {
|
||||
delete [] start;
|
||||
throw ReaderException("pattern < 0");
|
||||
}
|
||||
decodedChar = patternToChar(pattern);
|
||||
|
@ -117,10 +121,14 @@ namespace zxing {
|
|||
for (int i = 0; i < countersLen; i++) {
|
||||
lastPatternSize += counters[i];
|
||||
}
|
||||
// IS begin
|
||||
delete [] counters;
|
||||
// IS end
|
||||
int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
|
||||
// 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)
|
||||
if (nextStart != end && whiteSpaceAfterEnd / 2 < lastPatternSize) {
|
||||
delete [] start;
|
||||
throw ReaderException("too short end white space");
|
||||
}
|
||||
|
||||
|
@ -128,9 +136,9 @@ namespace zxing {
|
|||
int max = tmpResultString.length() - 1;
|
||||
int total = 0;
|
||||
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("");
|
||||
}
|
||||
tmpResultString.erase(max, 1);
|
||||
|
@ -146,6 +154,7 @@ namespace zxing {
|
|||
}
|
||||
|
||||
if (tmpResultString.length() == 0) {
|
||||
delete [] start;
|
||||
// Almost surely a false positive
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
@ -216,6 +225,9 @@ namespace zxing {
|
|||
isWhite = !isWhite;
|
||||
}
|
||||
}
|
||||
// IS begin
|
||||
delete [] counters;
|
||||
// IS end
|
||||
throw ReaderException("");
|
||||
}
|
||||
|
||||
|
@ -330,11 +342,5 @@ namespace zxing {
|
|||
Ref<String> decoded(new String(tmpDecoded));
|
||||
return decoded;
|
||||
}
|
||||
|
||||
|
||||
Code39Reader::~Code39Reader(){
|
||||
delete ALPHABET_STRING;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace zxing {
|
|||
class Code39Reader : public OneDReader {
|
||||
|
||||
private:
|
||||
std::string* ALPHABET_STRING;
|
||||
std::string alphabet_string;
|
||||
|
||||
bool usingCheckDigit;
|
||||
bool extendedMode;
|
||||
|
@ -49,9 +49,7 @@ namespace zxing {
|
|||
Code39Reader(bool usingCheckDigit_);
|
||||
|
||||
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};
|
||||
|
||||
|
||||
EAN13Reader::EAN13Reader(){
|
||||
decodeMiddleCounters = new int[4];
|
||||
for (int i=0; i<4; i++) {
|
||||
decodeMiddleCounters[i] = 0;
|
||||
}
|
||||
}
|
||||
EAN13Reader::EAN13Reader() { }
|
||||
|
||||
int EAN13Reader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString){
|
||||
int countersLen = 4;
|
||||
int* counters = decodeMiddleCounters;
|
||||
counters[0] = 0;
|
||||
counters[1] = 0;
|
||||
counters[2] = 0;
|
||||
counters[3] = 0;
|
||||
const int countersLen = 4;
|
||||
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||
|
||||
|
||||
int end = row->getSize();
|
||||
|
@ -88,8 +79,5 @@ namespace zxing {
|
|||
BarcodeFormat EAN13Reader::getBarcodeFormat(){
|
||||
return BarcodeFormat_EAN_13;
|
||||
}
|
||||
EAN13Reader::~EAN13Reader(){
|
||||
delete [] decodeMiddleCounters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace zxing {
|
|||
class EAN13Reader : public UPCEANReader {
|
||||
|
||||
private:
|
||||
int* decodeMiddleCounters;
|
||||
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||
|
||||
public:
|
||||
|
@ -35,7 +34,6 @@ namespace zxing {
|
|||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString); //throws ReaderException
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
~EAN13Reader();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,21 +24,11 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
EAN8Reader::EAN8Reader(){
|
||||
decodeMiddleCounters = new int[4];
|
||||
for (int i=0; i<4; i++) {
|
||||
decodeMiddleCounters[i] = 0;
|
||||
}
|
||||
}
|
||||
EAN8Reader::EAN8Reader(){ }
|
||||
|
||||
int EAN8Reader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString){
|
||||
int countersLen = 4;
|
||||
int* counters = decodeMiddleCounters;
|
||||
counters[0] = 0;
|
||||
counters[1] = 0;
|
||||
counters[2] = 0;
|
||||
counters[3] = 0;
|
||||
|
||||
const int countersLen = 4;
|
||||
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||
|
||||
int end = row->getSize();
|
||||
int rowOffset = startRange[1];
|
||||
|
@ -68,8 +58,5 @@ namespace zxing {
|
|||
BarcodeFormat EAN8Reader::getBarcodeFormat(){
|
||||
return BarcodeFormat_EAN_8;
|
||||
}
|
||||
EAN8Reader::~EAN8Reader(){
|
||||
delete [] decodeMiddleCounters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,16 +25,12 @@ namespace zxing {
|
|||
namespace oned {
|
||||
class EAN8Reader : public UPCEANReader {
|
||||
|
||||
private:
|
||||
int* decodeMiddleCounters;
|
||||
|
||||
public:
|
||||
EAN8Reader();
|
||||
|
||||
int decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString); //throws ReaderException
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
~EAN8Reader();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,18 +62,29 @@ namespace zxing {
|
|||
};
|
||||
|
||||
|
||||
ITFReader::ITFReader(){
|
||||
narrowLineWidth = -1;
|
||||
ITFReader::ITFReader() : narrowLineWidth(-1) {
|
||||
}
|
||||
|
||||
|
||||
Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
// Find out where the Middle section (payload) starts & ends
|
||||
int* startRange = decodeStart(row);
|
||||
int* endRange = decodeEnd(row);
|
||||
int* endRange;
|
||||
try {
|
||||
endRange = decodeEnd(row);
|
||||
} catch (Exception e) {
|
||||
delete [] startRange;
|
||||
throw e;
|
||||
}
|
||||
|
||||
std::string tmpResult;
|
||||
try {
|
||||
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
|
||||
// an assumption that the decoded string must be 6, 10 or 14 digits.
|
||||
|
@ -83,7 +94,9 @@ namespace zxing {
|
|||
lengthOK = true;
|
||||
}
|
||||
if (!lengthOK) {
|
||||
throw ReaderException("not enought characters count");
|
||||
delete [] startRange;
|
||||
delete [] endRange;
|
||||
throw ReaderException("not enough characters count");
|
||||
}
|
||||
|
||||
Ref<String> resultString(new String(tmpResult));
|
||||
|
@ -116,13 +129,13 @@ namespace zxing {
|
|||
// Therefore, need to scan 10 lines and then
|
||||
// split these into two arrays
|
||||
int counterDigitPairLen = 10;
|
||||
int* counterDigitPair = new int[counterDigitPairLen];
|
||||
int counterDigitPair[counterDigitPairLen];
|
||||
for (int i=0; i<counterDigitPairLen; i++) {
|
||||
counterDigitPair[i] = 0;
|
||||
}
|
||||
|
||||
int* counterBlack = new int[5];
|
||||
int* counterWhite = new int[5];
|
||||
int counterBlack[5];
|
||||
int counterWhite[5];
|
||||
for (int i=0; i<5; i++) {
|
||||
counterBlack[i] = 0;
|
||||
counterWhite[i] = 0;
|
||||
|
@ -147,9 +160,6 @@ namespace zxing {
|
|||
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
|
||||
// merged to a single method.
|
||||
int patternLength = patternLen;
|
||||
int* counters = new int[patternLength];
|
||||
int counters[patternLength];
|
||||
for (int i=0; i<patternLength; i++) {
|
||||
counters[i] = 0;
|
||||
}
|
||||
|
@ -329,8 +339,7 @@ namespace zxing {
|
|||
int bestMatch = -1;
|
||||
int max = PATTERNS_LEN;
|
||||
for (int i = 0; i < max; i++) {
|
||||
//int pattern[countersLen];
|
||||
int* pattern = new int(countersLen);
|
||||
int pattern[countersLen];
|
||||
for(int ind = 0; ind<countersLen; ind++){
|
||||
pattern[ind] = PATTERNS[i][ind];
|
||||
}
|
||||
|
@ -339,7 +348,6 @@ namespace zxing {
|
|||
bestVariance = variance;
|
||||
bestMatch = i;
|
||||
}
|
||||
delete pattern;
|
||||
}
|
||||
if (bestMatch >= 0) {
|
||||
return bestMatch;
|
||||
|
|
|
@ -28,18 +28,17 @@
|
|||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
MultiFormatOneDReader::MultiFormatOneDReader(){
|
||||
readers = new std::vector<OneDReader*>();
|
||||
readers->push_back(new MultiFormatUPCEANReader());
|
||||
readers->push_back(new Code39Reader());
|
||||
readers->push_back(new Code128Reader());
|
||||
readers->push_back(new ITFReader());
|
||||
MultiFormatOneDReader::MultiFormatOneDReader() : readers() {
|
||||
readers.push_back(Ref<OneDReader>(new MultiFormatUPCEANReader()));
|
||||
readers.push_back(Ref<OneDReader>(new Code39Reader()));
|
||||
readers.push_back(Ref<OneDReader>(new Code128Reader()));
|
||||
readers.push_back(Ref<OneDReader>(new ITFReader()));
|
||||
}
|
||||
|
||||
Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
int size = readers->size();
|
||||
int size = readers.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
OneDReader* reader = (*readers)[i];
|
||||
OneDReader* reader = readers[i];
|
||||
try {
|
||||
return reader->decodeRow(rowNumber, row);
|
||||
} catch (ReaderException re) {
|
||||
|
@ -48,8 +47,5 @@ namespace zxing {
|
|||
}
|
||||
throw ReaderException("No code detected");
|
||||
}
|
||||
MultiFormatOneDReader::~MultiFormatOneDReader(){
|
||||
delete readers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,11 @@ namespace zxing {
|
|||
class MultiFormatOneDReader : public OneDReader {
|
||||
|
||||
private:
|
||||
std::vector<OneDReader*>* readers;
|
||||
std::vector<Ref<OneDReader> > readers;
|
||||
public:
|
||||
MultiFormatOneDReader();
|
||||
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||
|
||||
~MultiFormatOneDReader();
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,19 +30,18 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
MultiFormatUPCEANReader::MultiFormatUPCEANReader(){
|
||||
readers = new std::vector<OneDReader*>();
|
||||
readers->push_back(new EAN13Reader());
|
||||
MultiFormatUPCEANReader::MultiFormatUPCEANReader() : readers() {
|
||||
readers.push_back(Ref<OneDReader>(new EAN13Reader()));
|
||||
// UPC-A is covered by EAN-13
|
||||
readers->push_back(new EAN8Reader());
|
||||
readers->push_back(new UPCEReader());
|
||||
readers.push_back(Ref<OneDReader>(new EAN8Reader()));
|
||||
readers.push_back(Ref<OneDReader>(new UPCEReader()));
|
||||
}
|
||||
|
||||
Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row){
|
||||
// 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++) {
|
||||
OneDReader* reader = (*readers)[i];
|
||||
Ref<OneDReader> reader = readers[i];
|
||||
Ref<Result> result;
|
||||
try {
|
||||
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
|
||||
// result if appropriate.
|
||||
if (result->getBarcodeFormat() == BarcodeFormat_EAN_13) {
|
||||
std::string& text = (result->getText())->getText();
|
||||
const std::string& text = (result->getText())->getText();
|
||||
if (text[0] == '0') {
|
||||
Ref<String> resultString(new String(text.substr(1)));
|
||||
Ref<Result> res(new Result(resultString, result->getRawBytes(), result->getResultPoints(), BarcodeFormat_UPC_A));
|
||||
|
@ -71,9 +70,5 @@ namespace zxing {
|
|||
}
|
||||
throw ReaderException("No EAN code detected");
|
||||
}
|
||||
|
||||
MultiFormatUPCEANReader::~MultiFormatUPCEANReader(){
|
||||
delete readers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,11 @@ namespace zxing {
|
|||
class MultiFormatUPCEANReader : public OneDReader {
|
||||
|
||||
private:
|
||||
std::vector<OneDReader*>* readers;
|
||||
std::vector<Ref<OneDReader> > readers;
|
||||
public:
|
||||
MultiFormatUPCEANReader();
|
||||
|
||||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||
|
||||
~MultiFormatUPCEANReader();
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,17 +23,15 @@
|
|||
namespace zxing {
|
||||
namespace oned {
|
||||
|
||||
using namespace std;
|
||||
|
||||
OneDResultPoint::OneDResultPoint(float posX, float posY) : posX_(posX), posY_(posY){
|
||||
}
|
||||
|
||||
float OneDResultPoint::getX() {
|
||||
float OneDResultPoint::getX() const {
|
||||
return posX_;
|
||||
}
|
||||
|
||||
float OneDResultPoint::getY() {
|
||||
float OneDResultPoint::getY() const {
|
||||
return posY_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ namespace zxing {
|
|||
|
||||
public:
|
||||
OneDResultPoint(float posX, float posY);
|
||||
float getX();
|
||||
float getY();
|
||||
float getX() const;
|
||||
float getY() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,31 +19,29 @@
|
|||
*/
|
||||
|
||||
#include "UPCAReader.h"
|
||||
#include <zxing/oned/EAN13Reader.h>
|
||||
#include <zxing/ReaderException.h>
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
UPCAReader::UPCAReader(){
|
||||
ean13Reader = new EAN13Reader();
|
||||
UPCAReader::UPCAReader() : ean13Reader() {
|
||||
}
|
||||
|
||||
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[]){
|
||||
return maybeReturnResult(ean13Reader->decodeRow(rowNumber, row, startGuardRange));
|
||||
return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardRange));
|
||||
}
|
||||
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){
|
||||
return ean13Reader->decodeMiddle(row, startRange, startRangeLen, resultString);
|
||||
return ean13Reader.decodeMiddle(row, startRange, startRangeLen, resultString);
|
||||
}
|
||||
|
||||
Ref<Result> UPCAReader::maybeReturnResult(Ref<Result> result){
|
||||
std::string& text = (result->getText())->getText();
|
||||
const std::string& text = (result->getText())->getText();
|
||||
if (text[0] == '0') {
|
||||
Ref<String> resultString(new String(text.substr(1)));
|
||||
Ref<Result> res(new Result(resultString, result->getRawBytes(), result->getResultPoints(), BarcodeFormat_UPC_A));
|
||||
|
@ -57,8 +55,5 @@ namespace zxing {
|
|||
BarcodeFormat UPCAReader::getBarcodeFormat(){
|
||||
return BarcodeFormat_UPC_A;
|
||||
}
|
||||
UPCAReader::~UPCAReader(){
|
||||
delete ean13Reader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <zxing/oned/UPCEANReader.h>
|
||||
#include <zxing/Result.h>
|
||||
#include <zxing/oned/EAN13Reader.h>
|
||||
|
||||
namespace zxing {
|
||||
namespace oned {
|
||||
class UPCAReader : public UPCEANReader {
|
||||
|
||||
private:
|
||||
UPCEANReader* ean13Reader;
|
||||
EAN13Reader ean13Reader;
|
||||
static Ref<Result> maybeReturnResult(Ref<Result> result); //throws ReaderException
|
||||
|
||||
public:
|
||||
|
@ -39,7 +38,6 @@ namespace zxing {
|
|||
Ref<Result> decode(Ref<BinaryBitmap> image);
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
~UPCAReader();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,16 @@ namespace zxing {
|
|||
|
||||
std::string 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);
|
||||
|
||||
|
@ -114,6 +123,14 @@ namespace zxing {
|
|||
// }
|
||||
|
||||
if (!checkChecksum(tmpResultString)) {
|
||||
if (startGuardRange!=NULL) {
|
||||
delete [] startGuardRange;
|
||||
startGuardRange = NULL;
|
||||
}
|
||||
if (endRange!=NULL) {
|
||||
delete [] endRange;
|
||||
endRange = NULL;
|
||||
}
|
||||
throw ReaderException("Checksum fail.");
|
||||
}
|
||||
|
||||
|
@ -159,6 +176,9 @@ namespace zxing {
|
|||
if (quietStart >= 0) {
|
||||
foundStart = row->isRange(quietStart, start, false);
|
||||
}
|
||||
if (!foundStart) {
|
||||
delete [] 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 patternLength = patternLen;
|
||||
|
||||
//int counters[patternLength];
|
||||
int* counters = new int(patternLength);
|
||||
int counters[patternLength];
|
||||
int countersCount = sizeof(counters)/sizeof(int);
|
||||
for (int i=0; i<countersCount ; i++) {
|
||||
counters[i]=0;
|
||||
|
@ -210,7 +229,6 @@ namespace zxing {
|
|||
isWhite = !isWhite;
|
||||
}
|
||||
}
|
||||
delete counters;
|
||||
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, 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);
|
||||
int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
|
||||
int bestMatch = -1;
|
||||
|
||||
int max = 0;
|
||||
switch (paternType) {
|
||||
switch (patternType) {
|
||||
case UPC_EAN_PATTERNS_L_PATTERNS:
|
||||
max = L_PATTERNS_LEN;
|
||||
for (int i = 0; i < max; i++) {
|
||||
//int pattern[countersLen];
|
||||
int* pattern = new int(countersLen);
|
||||
int pattern[countersLen];
|
||||
for(int j = 0; j< countersLen; j++){
|
||||
pattern[j] = L_PATTERNS[i][j];
|
||||
}
|
||||
|
@ -240,14 +257,12 @@ namespace zxing {
|
|||
bestVariance = variance;
|
||||
bestMatch = i;
|
||||
}
|
||||
delete pattern;
|
||||
}
|
||||
break;
|
||||
case UPC_EAN_PATTERNS_L_AND_G_PATTERNS:
|
||||
max = L_AND_G_PATTERNS_LEN;
|
||||
for (int i = 0; i < max; i++) {
|
||||
//int pattern[countersLen];
|
||||
int* pattern = new int(countersLen);
|
||||
int pattern[countersLen];
|
||||
for(int j = 0; j< countersLen; j++){
|
||||
pattern[j] = L_AND_G_PATTERNS[i][j];
|
||||
}
|
||||
|
@ -257,7 +272,6 @@ namespace zxing {
|
|||
bestVariance = variance;
|
||||
bestMatch = i;
|
||||
}
|
||||
delete pattern;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace zxing {
|
|||
Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);
|
||||
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
|
||||
|
||||
|
@ -63,3 +63,4 @@ namespace zxing {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,21 +40,11 @@ namespace zxing {
|
|||
{0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}
|
||||
};
|
||||
|
||||
UPCEReader::UPCEReader(){
|
||||
decodeMiddleCounters = new int[4];
|
||||
for (int i=0; i<4; i++) {
|
||||
decodeMiddleCounters[i] = 0;
|
||||
}
|
||||
}
|
||||
UPCEReader::UPCEReader(){}
|
||||
|
||||
int UPCEReader::decodeMiddle(Ref<BitArray> row, int startRange[], int startRangeLen, std::string& resultString){
|
||||
int countersLen = 4;
|
||||
int* counters = decodeMiddleCounters;
|
||||
counters[0] = 0;
|
||||
counters[1] = 0;
|
||||
counters[2] = 0;
|
||||
counters[3] = 0;
|
||||
|
||||
const int countersLen = 4;
|
||||
int counters[countersLen] = { 0, 0, 0, 0 };
|
||||
|
||||
int end = row->getSize();
|
||||
int rowOffset = startRange[1];
|
||||
|
@ -143,8 +133,5 @@ namespace zxing {
|
|||
BarcodeFormat UPCEReader::getBarcodeFormat(){
|
||||
return BarcodeFormat_UPC_E;
|
||||
}
|
||||
UPCEReader::~UPCEReader(){
|
||||
delete [] decodeMiddleCounters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace zxing {
|
|||
class UPCEReader : public UPCEANReader {
|
||||
|
||||
private:
|
||||
int* decodeMiddleCounters;
|
||||
static void determineFirstDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||
static void determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound); //throws ReaderException
|
||||
protected:
|
||||
|
@ -39,7 +38,6 @@ namespace zxing {
|
|||
static std::string& convertUPCEtoUPCA(std::string upce);
|
||||
|
||||
BarcodeFormat getBarcodeFormat();
|
||||
~UPCEReader();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
namespace zxing {
|
||||
namespace qrcode {
|
||||
|
||||
ErrorCorrectionLevel::ErrorCorrectionLevel(int ordinal) :
|
||||
ordinal_(ordinal) {
|
||||
ErrorCorrectionLevel::ErrorCorrectionLevel(int inOrdinal) :
|
||||
ordinal_(inOrdinal) {
|
||||
}
|
||||
|
||||
int ErrorCorrectionLevel::ordinal() {
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace qrcode {
|
|||
class ErrorCorrectionLevel {
|
||||
private:
|
||||
int ordinal_;
|
||||
ErrorCorrectionLevel(int ordinal);
|
||||
ErrorCorrectionLevel(int inOrdinal);
|
||||
static ErrorCorrectionLevel *FOR_BITS[];
|
||||
static int N_LEVELS;
|
||||
public:
|
||||
|
|
|
@ -33,28 +33,28 @@ namespace zxing {
|
|||
|
||||
Ref<Result> QRCodeReader::decode(Ref<BinaryBitmap> image) {
|
||||
#ifdef DEBUG
|
||||
cout << "decoding image " << image.object_ << ":\n" ;
|
||||
cout << "decoding image " << image.object_ << ":\n" << flush;
|
||||
#endif
|
||||
|
||||
Detector detector(image->getBlackMatrix());
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
cout << "(1) created detector " << &detector << "\n" ;
|
||||
cout << "(1) created detector " << &detector << "\n" << flush;
|
||||
#endif
|
||||
|
||||
Ref<DetectorResult> detectorResult(detector.detect());
|
||||
#ifdef DEBUG
|
||||
cout << "(2) detected, have detectorResult " << detectorResult.object_ << "\n" ;
|
||||
cout << "(2) detected, have detectorResult " << detectorResult.object_ << "\n" << flush;
|
||||
#endif
|
||||
|
||||
std::vector<Ref<ResultPoint> > points(detectorResult->getPoints());
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
cout << "(3) extracted points " << &points << "\n";
|
||||
cout << "found " << points.size() << " points:\n";
|
||||
for (size_t i = 0; i < points.size(); i++) {
|
||||
cout << "(3) extracted points " << &points << "\n" << flush;
|
||||
cout << "found " << points->size() << " points:\n";
|
||||
for (size_t i = 0; i < points->size(); i++) {
|
||||
cout << " " << points[i]->getX() << "," << points[i]->getY() << "\n";
|
||||
}
|
||||
cout << "bits:\n";
|
||||
|
@ -63,15 +63,13 @@ namespace zxing {
|
|||
|
||||
Ref<DecoderResult> decoderResult(decoder_.decode(detectorResult->getBits()));
|
||||
#ifdef DEBUG
|
||||
cout << "(4) decoded, have decoderResult " << decoderResult.object_ << "\n" ;
|
||||
cout << "(4) decoded, have decoderResult " << decoderResult.object_ << "\n" << flush;
|
||||
#endif
|
||||
|
||||
Ref<Result> result(
|
||||
new Result(decoderResult->getText(), decoderResult->getRawBytes(), points, BarcodeFormat_QR_CODE));
|
||||
#ifdef DEBUG
|
||||
cout << "(5) created result " << result.object_ << ", returning\n" ;
|
||||
|
||||
cout << "(6) text: " << result->getText()->getText() << std::endl;
|
||||
cout << "(5) created result " << result.object_ << ", returning\n" << flush;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include <zxing/qrcode/Version.h>
|
||||
#include <zxing/qrcode/FormatInformation.h>
|
||||
#include <cstdarg>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace zxing {
|
||||
namespace qrcode {
|
||||
|
@ -41,13 +41,11 @@ int ECB::getDataCodewords() {
|
|||
}
|
||||
|
||||
ECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks) :
|
||||
ecCodewords_(ecCodewords) {
|
||||
ecBlocks_.push_back(ecBlocks);
|
||||
ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks) {
|
||||
}
|
||||
|
||||
ECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2) :
|
||||
ecCodewords_(ecCodewords) {
|
||||
ecBlocks_.push_back(ecBlocks1);
|
||||
ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks1) {
|
||||
ecBlocks_.push_back(ecBlocks2);
|
||||
}
|
||||
|
||||
|
@ -78,7 +76,7 @@ int Version::getVersionNumber() {
|
|||
return versionNumber_;
|
||||
}
|
||||
|
||||
valarray<int> &Version::getAlignmentPatternCenters() {
|
||||
vector<int> &Version::getAlignmentPatternCenters() {
|
||||
return alignmentPatternCenters_;
|
||||
}
|
||||
|
||||
|
@ -102,16 +100,16 @@ Version *Version::getProvisionalVersionForDimension(int dimension) {
|
|||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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) :
|
||||
versionNumber_(versionNumber), alignmentPatternCenters_(*alignmentPatternCenters), ecBlocks_(4) {
|
||||
versionNumber_(versionNumber), alignmentPatternCenters_(*alignmentPatternCenters), ecBlocks_(4), totalCodewords_(0) {
|
||||
ecBlocks_[0] = ecBlocks1;
|
||||
ecBlocks_[1] = ecBlocks2;
|
||||
ecBlocks_[2] = ecBlocks3;
|
||||
|
@ -207,10 +205,10 @@ Ref<BitMatrix> Version::buildFunctionPattern() {
|
|||
return functionPattern;
|
||||
}
|
||||
|
||||
static valarray<int> *intArray(size_t n...) {
|
||||
static vector<int> *intArray(size_t n...) {
|
||||
va_list ap;
|
||||
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++) {
|
||||
(*result)[i] = va_arg(ap, int);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <zxing/common/BitMatrix.h>
|
||||
#include <zxing/common/Counted.h>
|
||||
#include <vector>
|
||||
#include <valarray>
|
||||
|
||||
namespace zxing {
|
||||
namespace qrcode {
|
||||
|
@ -58,10 +57,10 @@ class Version : public Counted {
|
|||
|
||||
private:
|
||||
int versionNumber_;
|
||||
std::valarray<int> &alignmentPatternCenters_;
|
||||
std::vector<int> &alignmentPatternCenters_;
|
||||
std::vector<ECBlocks*> ecBlocks_;
|
||||
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);
|
||||
|
||||
public:
|
||||
|
@ -71,7 +70,7 @@ public:
|
|||
|
||||
~Version();
|
||||
int getVersionNumber();
|
||||
std::valarray<int> &getAlignmentPatternCenters();
|
||||
std::vector<int> &getAlignmentPatternCenters();
|
||||
int getTotalCodewords();
|
||||
int getDimensionForVersion();
|
||||
ECBlocks &getECBlocksForLevel(ErrorCorrectionLevel &ecLevel);
|
||||
|
|
|
@ -158,8 +158,8 @@ ArrayRef<unsigned char> BitMatrixParser::readCodewords() {
|
|||
x--;
|
||||
}
|
||||
// Read alternatingly from bottom to top then top to bottom
|
||||
for (int count = 0; count < dimension; count++) {
|
||||
int y = readingUp ? dimension - 1 - count : count;
|
||||
for (int counter = 0; counter < dimension; counter++) {
|
||||
int y = readingUp ? dimension - 1 - counter : counter;
|
||||
for (int col = 0; col < 2; col++) {
|
||||
// Ignore bits covered by the function pattern
|
||||
if (!functionPattern->get(x - col, y)) {
|
||||
|
|
|
@ -44,6 +44,11 @@ public:
|
|||
Ref<FormatInformation> readFormatInformation();
|
||||
Version *readVersion();
|
||||
ArrayRef<unsigned char> readCodewords();
|
||||
|
||||
private:
|
||||
BitMatrixParser(const BitMatrixParser&);
|
||||
BitMatrixParser& operator =(const BitMatrixParser&);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <valarray>
|
||||
#include <vector>
|
||||
#include <zxing/common/Counted.h>
|
||||
#include <zxing/common/Array.h>
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
#include <zxing/qrcode/decoder/DecodedBitStreamParser.h>
|
||||
#include <iostream>
|
||||
#ifndef NO_ICONV
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
// Required for compatibility. TODO: test on Symbian
|
||||
#ifdef ZXING_ICONV_CONST
|
||||
|
@ -50,7 +52,8 @@ const char *DecodedBitStreamParser::UTF8 = "UTF-8";
|
|||
const char *DecodedBitStreamParser::SHIFT_JIS = "SHIFT_JIS";
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -65,7 +68,7 @@ void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, si
|
|||
size_t nTo = maxOut;
|
||||
|
||||
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)) {
|
||||
iconv_close(cd);
|
||||
delete[] bufOut;
|
||||
|
@ -76,12 +79,14 @@ void DecodedBitStreamParser::append(ostream &ost, const unsigned char *bufIn, si
|
|||
|
||||
int nResult = maxOut - nTo;
|
||||
bufOut[nResult] = '\0';
|
||||
|
||||
ost << bufOut;
|
||||
result.append((const char *)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
|
||||
// and decode as Shift_JIS afterwards
|
||||
size_t nBytes = 2 * count;
|
||||
|
@ -109,7 +114,7 @@ void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, ostringstre
|
|||
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;
|
||||
unsigned char* readBytes = new unsigned char[nBytes];
|
||||
if (count << 3 > bits->available()) {
|
||||
|
@ -131,7 +136,7 @@ void DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits, ostringstrea
|
|||
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;
|
||||
unsigned char* bytes = new unsigned char[nBytes];
|
||||
int i = 0;
|
||||
|
@ -176,7 +181,7 @@ void DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, ostringst
|
|||
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;
|
||||
unsigned char* bytes = new unsigned char[nBytes];
|
||||
int i = 0;
|
||||
|
@ -248,7 +253,7 @@ DecodedBitStreamParser::guessEncoding(unsigned char *bytes, int length) {
|
|||
}
|
||||
|
||||
string DecodedBitStreamParser::decode(ArrayRef<unsigned char> bytes, Version *version) {
|
||||
ostringstream result;
|
||||
string result;
|
||||
Ref<BitSource> bits(new BitSource(bytes));
|
||||
Mode *mode = &Mode::TERMINATOR;
|
||||
do {
|
||||
|
@ -275,7 +280,7 @@ string DecodedBitStreamParser::decode(ArrayRef<unsigned char> bytes, Version *ve
|
|||
}
|
||||
}
|
||||
} while (mode != &Mode::TERMINATOR);
|
||||
return result.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@ private:
|
|||
static const char *SHIFT_JIS;
|
||||
static const char *EUC_JP;
|
||||
|
||||
static void decodeKanjiSegment(Ref<BitSource> bits, std::ostringstream &result, int count);
|
||||
static void decodeByteSegment(Ref<BitSource> bits, std::ostringstream &result, int count);
|
||||
static void decodeAlphanumericSegment(Ref<BitSource> bits, std::ostringstream &result, int count);
|
||||
static void decodeNumericSegment(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::string &result, int count);
|
||||
static void decodeAlphanumericSegment(Ref<BitSource> bits, std::string &result, int count);
|
||||
static void decodeNumericSegment(Ref<BitSource> bits, std::string &result, int count);
|
||||
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:
|
||||
static std::string decode(ArrayRef<unsigned char> bytes, Version *version);
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <zxing/common/Array.h>
|
||||
#include <zxing/common/DecoderResult.h>
|
||||
#include <zxing/common/BitMatrix.h>
|
||||
#include <valarray>
|
||||
|
||||
namespace zxing {
|
||||
namespace qrcode {
|
||||
|
|
|
@ -29,15 +29,15 @@ AlignmentPattern::AlignmentPattern(float posX, float posY, float estimatedModule
|
|||
posX_(posX), posY_(posY), estimatedModuleSize_(estimatedModuleSize) {
|
||||
}
|
||||
|
||||
float AlignmentPattern::getX() {
|
||||
float AlignmentPattern::getX() const {
|
||||
return posX_;
|
||||
}
|
||||
|
||||
float AlignmentPattern::getY() {
|
||||
float AlignmentPattern::getY() const {
|
||||
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_)
|
||||
<= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);
|
||||
}
|
||||
|
|
|
@ -35,9 +35,9 @@ namespace zxing {
|
|||
|
||||
public:
|
||||
AlignmentPattern(float posX, float posY, float estimatedModuleSize);
|
||||
float getX();
|
||||
float getY();
|
||||
bool aboutEquals(float moduleSize, float i, float j);
|
||||
float getX() const;
|
||||
float getY() const;
|
||||
bool aboutEquals(float moduleSize, float i, float j) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,17 +23,18 @@
|
|||
#include <zxing/common/BitArray.h>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace zxing {
|
||||
namespace qrcode {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool AlignmentPatternFinder::foundPatternCross(valarray<int> &stateCount) {
|
||||
bool AlignmentPatternFinder::foundPatternCross(vector<int> &stateCount) {
|
||||
float maxVariance = moduleSize_ / 2.0f;
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
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,
|
||||
int originalStateCountTotal) {
|
||||
int maxI = image_->getHeight();
|
||||
valarray<int> stateCount(0, 3);
|
||||
vector<int> stateCount(3, 0);
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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];
|
||||
float centerJ = centerFromEnd(stateCount, j);
|
||||
float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal);
|
||||
|
@ -136,7 +137,7 @@ Ref<AlignmentPattern> AlignmentPatternFinder::find() {
|
|||
// Ref<BitArray> luminanceRow(new BitArray(width_));
|
||||
// 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
|
||||
valarray<int> stateCount(0, 3);
|
||||
vector<int> stateCount(3, 0);
|
||||
for (size_t iGen = 0; iGen < height_; iGen++) {
|
||||
// Search from middle outwards
|
||||
size_t i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
|
||||
|
|
|
@ -43,18 +43,23 @@ private:
|
|||
size_t height_;
|
||||
float moduleSize_;
|
||||
|
||||
static float centerFromEnd(std::valarray<int> &stateCount, int end);
|
||||
bool foundPatternCross(std::valarray<int> &stateCount);
|
||||
static float centerFromEnd(std::vector<int> &stateCount, int end);
|
||||
bool foundPatternCross(std::vector<int> &stateCount);
|
||||
|
||||
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:
|
||||
AlignmentPatternFinder(Ref<BitMatrix> image, size_t startX, size_t startY, size_t width, size_t height,
|
||||
float moduleSize);
|
||||
~AlignmentPatternFinder();
|
||||
Ref<AlignmentPattern> find();
|
||||
|
||||
private:
|
||||
AlignmentPatternFinder(const AlignmentPatternFinder&);
|
||||
AlignmentPatternFinder& operator =(const AlignmentPatternFinder&);
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <zxing/common/GridSampler.h>
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace zxing {
|
||||
namespace qrcode {
|
||||
|
@ -34,231 +35,231 @@ namespace qrcode {
|
|||
using namespace std;
|
||||
|
||||
Detector::Detector(Ref<BitMatrix> image) :
|
||||
image_(image) {
|
||||
image_(image) {
|
||||
}
|
||||
|
||||
Ref<BitMatrix> Detector::getImage() {
|
||||
return image_;
|
||||
return image_;
|
||||
}
|
||||
|
||||
Ref<DetectorResult> Detector::detect() {
|
||||
FinderPatternFinder finder(image_);
|
||||
Ref<FinderPatternInfo> info(finder.find());
|
||||
FinderPatternFinder finder(image_);
|
||||
Ref<FinderPatternInfo> info(finder.find());
|
||||
|
||||
Ref<FinderPattern> topLeft(info->getTopLeft());
|
||||
Ref<FinderPattern> topRight(info->getTopRight());
|
||||
Ref<FinderPattern> bottomLeft(info->getBottomLeft());
|
||||
Ref<FinderPattern> topLeft(info->getTopLeft());
|
||||
Ref<FinderPattern> topRight(info->getTopRight());
|
||||
Ref<FinderPattern> bottomLeft(info->getBottomLeft());
|
||||
|
||||
float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);
|
||||
int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
|
||||
Version *provisionalVersion = Version::getProvisionalVersionForDimension(dimension);
|
||||
int modulesBetweenFPCenters = provisionalVersion->getDimensionForVersion() - 7;
|
||||
float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);
|
||||
int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);
|
||||
Version *provisionalVersion = Version::getProvisionalVersionForDimension(dimension);
|
||||
int modulesBetweenFPCenters = provisionalVersion->getDimensionForVersion() - 7;
|
||||
|
||||
Ref<AlignmentPattern> alignmentPattern;
|
||||
// Anything above version 1 has an alignment pattern
|
||||
if (provisionalVersion->getAlignmentPatternCenters().size() > 0) {
|
||||
Ref<AlignmentPattern> alignmentPattern;
|
||||
// Anything above version 1 has an alignment pattern
|
||||
if (provisionalVersion->getAlignmentPatternCenters().size() > 0) {
|
||||
|
||||
|
||||
// Guess where a "bottom right" finder pattern would have been
|
||||
float bottomRightX = topRight->getX() - topLeft->getX() + bottomLeft->getX();
|
||||
float bottomRightY = topRight->getY() - topLeft->getY() + bottomLeft->getY();
|
||||
// Guess where a "bottom right" finder pattern would have been
|
||||
float bottomRightX = topRight->getX() - topLeft->getX() + bottomLeft->getX();
|
||||
float bottomRightY = topRight->getY() - topLeft->getY() + bottomLeft->getY();
|
||||
|
||||
|
||||
// Estimate that alignment pattern is closer by 3 modules
|
||||
// from "bottom right" to known top left location
|
||||
float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
|
||||
int estAlignmentX = (int)(topLeft->getX() + correctionToTopLeft * (bottomRightX - topLeft->getX()));
|
||||
int estAlignmentY = (int)(topLeft->getY() + correctionToTopLeft * (bottomRightY - topLeft->getY()));
|
||||
// Estimate that alignment pattern is closer by 3 modules
|
||||
// from "bottom right" to known top left location
|
||||
float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
|
||||
int estAlignmentX = (int)(topLeft->getX() + correctionToTopLeft * (bottomRightX - topLeft->getX()));
|
||||
int estAlignmentY = (int)(topLeft->getY() + correctionToTopLeft * (bottomRightY - topLeft->getY()));
|
||||
|
||||
|
||||
// Kind of arbitrary -- expand search radius before giving up
|
||||
for (int i = 4; i <= 16; i <<= 1) {
|
||||
try {
|
||||
alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
|
||||
break;
|
||||
} catch (zxing::ReaderException re) {
|
||||
// try next round
|
||||
}
|
||||
}
|
||||
if (alignmentPattern == 0) {
|
||||
// Try anyway
|
||||
}
|
||||
|
||||
// Kind of arbitrary -- expand search radius before giving up
|
||||
for (int i = 4; i <= 16; i <<= 1) {
|
||||
try {
|
||||
alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
|
||||
break;
|
||||
} catch (zxing::ReaderException re) {
|
||||
// try next round
|
||||
}
|
||||
}
|
||||
if (alignmentPattern == 0) {
|
||||
// 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));
|
||||
return result;
|
||||
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));
|
||||
return result;
|
||||
}
|
||||
|
||||
Ref<PerspectiveTransform> Detector::createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <
|
||||
ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension) {
|
||||
|
||||
float dimMinusThree = (float)dimension - 3.5f;
|
||||
float bottomRightX;
|
||||
float bottomRightY;
|
||||
float sourceBottomRightX;
|
||||
float sourceBottomRightY;
|
||||
if (alignmentPattern != 0) {
|
||||
bottomRightX = alignmentPattern->getX();
|
||||
bottomRightY = alignmentPattern->getY();
|
||||
sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
|
||||
} else {
|
||||
// Don't have an alignment pattern, just make up the bottom-right point
|
||||
bottomRightX = (topRight->getX() - topLeft->getX()) + bottomLeft->getX();
|
||||
bottomRightY = (topRight->getY() - topLeft->getY()) + bottomLeft->getY();
|
||||
sourceBottomRightX = sourceBottomRightY = dimMinusThree;
|
||||
}
|
||||
float dimMinusThree = (float)dimension - 3.5f;
|
||||
float bottomRightX;
|
||||
float bottomRightY;
|
||||
float sourceBottomRightX;
|
||||
float sourceBottomRightY;
|
||||
if (alignmentPattern != 0) {
|
||||
bottomRightX = alignmentPattern->getX();
|
||||
bottomRightY = alignmentPattern->getY();
|
||||
sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
|
||||
} else {
|
||||
// Don't have an alignment pattern, just make up the bottom-right point
|
||||
bottomRightX = (topRight->getX() - topLeft->getX()) + bottomLeft->getX();
|
||||
bottomRightY = (topRight->getY() - topLeft->getY()) + bottomLeft->getY();
|
||||
sourceBottomRightX = sourceBottomRightY = dimMinusThree;
|
||||
}
|
||||
|
||||
Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX,
|
||||
sourceBottomRightY, 3.5f, dimMinusThree, topLeft->getX(), topLeft->getY(), topRight->getX(),
|
||||
topRight->getY(), bottomRightX, bottomRightY, bottomLeft->getX(), bottomLeft->getY()));
|
||||
Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX,
|
||||
sourceBottomRightY, 3.5f, dimMinusThree, topLeft->getX(), topLeft->getY(), topRight->getX(),
|
||||
topRight->getY(), bottomRightX, bottomRightY, bottomLeft->getX(), bottomLeft->getY()));
|
||||
|
||||
return transform;
|
||||
return transform;
|
||||
}
|
||||
|
||||
Ref<BitMatrix> Detector::sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform) {
|
||||
GridSampler &sampler = GridSampler::getInstance();
|
||||
return sampler.sampleGrid(image, dimension, transform);
|
||||
GridSampler &sampler = GridSampler::getInstance();
|
||||
return sampler.sampleGrid(image, dimension, transform);
|
||||
}
|
||||
|
||||
int Detector::computeDimension(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft,
|
||||
float moduleSize) {
|
||||
int tltrCentersDimension = lround(FinderPatternFinder::distance(topLeft, topRight) / moduleSize);
|
||||
int tlblCentersDimension = lround(FinderPatternFinder::distance(topLeft, bottomLeft) / moduleSize);
|
||||
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
|
||||
switch (dimension & 0x03) { // mod 4
|
||||
case 0:
|
||||
dimension++;
|
||||
break;
|
||||
// 1? do nothing
|
||||
case 2:
|
||||
dimension--;
|
||||
break;
|
||||
case 3:
|
||||
ostringstream s;
|
||||
s << "Bad dimension: " << dimension;
|
||||
throw zxing::ReaderException(s.str().c_str());
|
||||
}
|
||||
return dimension;
|
||||
float moduleSize) {
|
||||
int tltrCentersDimension = int(FinderPatternFinder::distance(topLeft, topRight) / moduleSize + 0.5f);
|
||||
int tlblCentersDimension = int(FinderPatternFinder::distance(topLeft, bottomLeft) / moduleSize + 0.5f);
|
||||
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
|
||||
switch (dimension & 0x03) { // mod 4
|
||||
case 0:
|
||||
dimension++;
|
||||
break;
|
||||
// 1? do nothing
|
||||
case 2:
|
||||
dimension--;
|
||||
break;
|
||||
case 3:
|
||||
ostringstream s;
|
||||
s << "Bad dimension: " << dimension;
|
||||
throw zxing::ReaderException(s.str().c_str());
|
||||
}
|
||||
return dimension;
|
||||
}
|
||||
|
||||
float Detector::calculateModuleSize(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft) {
|
||||
// Take the average
|
||||
return (calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
|
||||
// Take the average
|
||||
return (calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
|
||||
}
|
||||
|
||||
float Detector::calculateModuleSizeOneWay(Ref<ResultPoint> pattern, Ref<ResultPoint> otherPattern) {
|
||||
float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int)pattern->getX(), (int)pattern->getY(),
|
||||
(int)otherPattern->getX(), (int)otherPattern->getY());
|
||||
float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int)otherPattern->getX(), (int)otherPattern->getY(),
|
||||
(int)pattern->getX(), (int)pattern->getY());
|
||||
if (isnan(moduleSizeEst1)) {
|
||||
return moduleSizeEst2;
|
||||
}
|
||||
if (isnan(moduleSizeEst2)) {
|
||||
return moduleSizeEst1;
|
||||
}
|
||||
// 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.
|
||||
return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
|
||||
float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int)pattern->getX(), (int)pattern->getY(),
|
||||
(int)otherPattern->getX(), (int)otherPattern->getY());
|
||||
float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int)otherPattern->getX(), (int)otherPattern->getY(),
|
||||
(int)pattern->getX(), (int)pattern->getY());
|
||||
if (isnan(moduleSizeEst1)) {
|
||||
return moduleSizeEst2;
|
||||
}
|
||||
if (isnan(moduleSizeEst2)) {
|
||||
return moduleSizeEst1;
|
||||
}
|
||||
// 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.
|
||||
return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
|
||||
}
|
||||
|
||||
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
|
||||
int otherToX = fromX - (toX - fromX);
|
||||
if (otherToX < 0) {
|
||||
// "to" should the be the first value not included, so, the first value off
|
||||
// the edge is -1
|
||||
otherToX = -1;
|
||||
} else if (otherToX >= (int)image_->getWidth()) {
|
||||
otherToX = image_->getWidth();
|
||||
}
|
||||
int otherToY = fromY - (toY - fromY);
|
||||
if (otherToY < 0) {
|
||||
otherToY = -1;
|
||||
} else if (otherToY >= (int)image_->getHeight()) {
|
||||
otherToY = image_->getHeight();
|
||||
}
|
||||
result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
|
||||
return result - 1.0f; // -1 because we counted the middle pixel twice
|
||||
// Now count other way -- don't run off image though of course
|
||||
int otherToX = fromX - (toX - fromX);
|
||||
if (otherToX < 0) {
|
||||
// "to" should the be the first value not included, so, the first value off
|
||||
// the edge is -1
|
||||
otherToX = -1;
|
||||
} else if (otherToX >= (int)image_->getWidth()) {
|
||||
otherToX = image_->getWidth();
|
||||
}
|
||||
int otherToY = fromY - (toY - fromY);
|
||||
if (otherToY < 0) {
|
||||
otherToY = -1;
|
||||
} else if (otherToY >= (int)image_->getHeight()) {
|
||||
otherToY = image_->getHeight();
|
||||
}
|
||||
result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
|
||||
return result - 1.0f; // -1 because we counted the middle pixel twice
|
||||
}
|
||||
|
||||
float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) {
|
||||
// Mild variant of Bresenham's algorithm;
|
||||
// see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
||||
bool steep = abs(toY - fromY) > abs(toX - fromX);
|
||||
if (steep) {
|
||||
int temp = fromX;
|
||||
fromX = fromY;
|
||||
fromY = temp;
|
||||
temp = toX;
|
||||
toX = toY;
|
||||
toY = temp;
|
||||
// Mild variant of Bresenham's algorithm;
|
||||
// see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
||||
bool steep = abs(toY - fromY) > abs(toX - fromX);
|
||||
if (steep) {
|
||||
int temp = fromX;
|
||||
fromX = fromY;
|
||||
fromY = temp;
|
||||
temp = toX;
|
||||
toX = toY;
|
||||
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);
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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));
|
||||
}
|
||||
int diffX = toX - fromX;
|
||||
int diffY = toY - fromY;
|
||||
return (float)sqrt((double)(diffX * diffX + diffY * diffY));
|
||||
error += dy;
|
||||
if (error > 0) {
|
||||
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,
|
||||
float allowanceFactor) {
|
||||
// Look for an alignment pattern (3 modules in size) around where it
|
||||
// should be
|
||||
int allowance = (int)(allowanceFactor * overallEstModuleSize);
|
||||
int alignmentAreaLeftX = max(0, estAlignmentX - allowance);
|
||||
int alignmentAreaRightX = min((int)(image_->getWidth() - 1), estAlignmentX + allowance);
|
||||
int alignmentAreaTopY = max(0, estAlignmentY - allowance);
|
||||
int alignmentAreaBottomY = min((int)(image_->getHeight() - 1), estAlignmentY + allowance);
|
||||
// Look for an alignment pattern (3 modules in size) around where it
|
||||
// should be
|
||||
int allowance = (int)(allowanceFactor * overallEstModuleSize);
|
||||
int alignmentAreaLeftX = max(0, estAlignmentX - allowance);
|
||||
int alignmentAreaRightX = min((int)(image_->getWidth() - 1), estAlignmentX + allowance);
|
||||
int alignmentAreaTopY = max(0, estAlignmentY - allowance);
|
||||
int alignmentAreaBottomY = min((int)(image_->getHeight() - 1), estAlignmentY + allowance);
|
||||
|
||||
AlignmentPatternFinder alignmentFinder(image_, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX
|
||||
- alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize);
|
||||
return alignmentFinder.find();
|
||||
AlignmentPatternFinder alignmentFinder(image_, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX
|
||||
- alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize);
|
||||
return alignmentFinder.find();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,19 +29,19 @@ namespace zxing {
|
|||
posX_(posX), posY_(posY), estimatedModuleSize_(estimatedModuleSize), counter_(1) {
|
||||
}
|
||||
|
||||
float FinderPattern::getX() {
|
||||
float FinderPattern::getX() const {
|
||||
return posX_;
|
||||
}
|
||||
|
||||
float FinderPattern::getY() {
|
||||
float FinderPattern::getY() const {
|
||||
return posY_;
|
||||
}
|
||||
|
||||
int FinderPattern::getCount() {
|
||||
int FinderPattern::getCount() const {
|
||||
return counter_;
|
||||
}
|
||||
|
||||
float FinderPattern::getEstimatedModuleSize() {
|
||||
float FinderPattern::getEstimatedModuleSize() const {
|
||||
return estimatedModuleSize_;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ namespace zxing {
|
|||
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_)
|
||||
<= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);
|
||||
}
|
||||
|
|
|
@ -36,12 +36,12 @@ namespace zxing {
|
|||
|
||||
public:
|
||||
FinderPattern(float posX, float posY, float estimatedModuleSize);
|
||||
float getX();
|
||||
float getY();
|
||||
int getCount();
|
||||
float getEstimatedModuleSize();
|
||||
float getX() const;
|
||||
float getY() const;
|
||||
int getCount() const;
|
||||
float getEstimatedModuleSize() const;
|
||||
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 <vector>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
||||
namespace zxing {
|
||||
namespace qrcode {
|
||||
|
@ -32,6 +34,8 @@ class ClosestToAverageComparator {
|
|||
private:
|
||||
float averageModuleSize_;
|
||||
public:
|
||||
ClosestToAverageComparator() : averageModuleSize_(0.0f) { }
|
||||
|
||||
ClosestToAverageComparator(float averageModuleSize) :
|
||||
averageModuleSize_(averageModuleSize) {
|
||||
}
|
||||
|
@ -393,7 +397,7 @@ Ref<FinderPatternInfo> FinderPatternFinder::find() {
|
|||
// 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
|
||||
|
||||
// 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];
|
||||
bool done = false;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <zxing/qrcode/detector/QREdgeDetector.h>
|
||||
#include <zxing/common/EdgeDetector.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
Loading…
Reference in a new issue