port relevant parts of r1937 to C++

git-svn-id: https://zxing.googlecode.com/svn/trunk@1962 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
smparkes@smparkes.net 2011-10-12 18:11:40 +00:00
parent ccf08aabe8
commit 9558d83d71
10 changed files with 71 additions and 60 deletions

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/* /*
* Binarizer.cpp * Binarizer.cpp
* zxing * zxing
@ -24,7 +25,7 @@
namespace zxing { namespace zxing {
Binarizer::Binarizer(Ref<LuminanceSource> source) : source_(source) { Binarizer::Binarizer(Ref<LuminanceSource> source) : source_(source) {
} }
Binarizer::~Binarizer() { Binarizer::~Binarizer() {
} }

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/* /*
* Result.cpp * Result.cpp
* zxing * zxing
@ -25,7 +26,7 @@ using namespace std;
Result::Result(Ref<String> text, ArrayRef<unsigned char> rawBytes, std::vector<Ref<ResultPoint> > resultPoints, Result::Result(Ref<String> text, ArrayRef<unsigned char> rawBytes, std::vector<Ref<ResultPoint> > resultPoints,
BarcodeFormat format) : BarcodeFormat format) :
text_(text), rawBytes_(rawBytes), resultPoints_(resultPoints), format_(format) { text_(text), rawBytes_(rawBytes), resultPoints_(resultPoints), format_(format) {
} }
Result::~Result() { Result::~Result() {

View file

@ -73,7 +73,7 @@ void BitArray::setBulk(size_t i, unsigned int newBits) {
void BitArray::setRange(int start, int end) { void BitArray::setRange(int start, int end) {
if (end < start) { if (end < start) {
throw new IllegalArgumentException("invalid call to BitArray::setRange"); throw IllegalArgumentException("invalid call to BitArray::setRange");
} }
if (end == start) { if (end == start) {
return; return;

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/* /*
* DetectorResult.cpp * DetectorResult.cpp
* zxing * zxing
@ -23,7 +24,7 @@
namespace zxing { namespace zxing {
DetectorResult::DetectorResult(Ref<BitMatrix> bits, std::vector<Ref<ResultPoint> > points, Ref<PerspectiveTransform> transform) : DetectorResult::DetectorResult(Ref<BitMatrix> bits, std::vector<Ref<ResultPoint> > points, Ref<PerspectiveTransform> transform) :
bits_(bits), points_(points), transform_(transform) { bits_(bits), points_(points), transform_(transform) {
} }
Ref<BitMatrix> DetectorResult::getBits() { Ref<BitMatrix> DetectorResult::getBits() {

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/* /*
* GlobalHistogramBinarizer.cpp * GlobalHistogramBinarizer.cpp
* zxing * zxing

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/* /*
* HybridBinarizer.cpp * HybridBinarizer.cpp
* zxing * zxing
@ -31,7 +32,7 @@ static const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
static const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; static const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
HybridBinarizer::HybridBinarizer(Ref<LuminanceSource> source) : HybridBinarizer::HybridBinarizer(Ref<LuminanceSource> source) :
GlobalHistogramBinarizer(source), cached_matrix_(NULL), cached_row_(NULL), cached_row_num_(-1) { GlobalHistogramBinarizer(source), matrix_(NULL), cached_row_(NULL), cached_row_num_(-1) {
} }
@ -39,40 +40,43 @@ HybridBinarizer::~HybridBinarizer() {
} }
Ref<BitMatrix> HybridBinarizer::getBlackMatrix() {
binarizeEntireImage();
return cached_matrix_;
}
Ref<Binarizer> HybridBinarizer::createBinarizer(Ref<LuminanceSource> source) { Ref<Binarizer> HybridBinarizer::createBinarizer(Ref<LuminanceSource> source) {
return Ref<Binarizer> (new HybridBinarizer(source)); return Ref<Binarizer> (new HybridBinarizer(source));
} }
void HybridBinarizer::binarizeEntireImage() { Ref<BitMatrix> HybridBinarizer::getBlackMatrix() {
if (cached_matrix_ == NULL) { // Calculates the final BitMatrix once for all requests. This could be called once from the
Ref<LuminanceSource> source = getLuminanceSource(); // constructor instead, but there are some advantages to doing it lazily, such as making
if (source->getWidth() >= MINIMUM_DIMENSION && source->getHeight() >= MINIMUM_DIMENSION) { // profiling easier, and not doing heavy lifting when callers don't expect it.
unsigned char* luminances = source->getMatrix(); if (matrix_) {
int width = source->getWidth(); return matrix_;
int height = source->getHeight();
int subWidth = width >> 3;
if (width & 0x07) {
subWidth++;
}
int subHeight = height >> 3;
if (height & 0x07) {
subHeight++;
}
int *blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);
cached_matrix_.reset(new BitMatrix(width,height));
calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, cached_matrix_);
delete [] blackPoints;
delete [] luminances;
} else {
// If the image is too small, fall back to the global histogram approach.
cached_matrix_.reset(GlobalHistogramBinarizer::getBlackMatrix());
}
} }
LuminanceSource& source = *getLuminanceSource();
if (source.getWidth() >= MINIMUM_DIMENSION && source.getHeight() >= MINIMUM_DIMENSION) {
unsigned char* luminances = source.getMatrix();
int width = source.getWidth();
int height = source.getHeight();
int subWidth = width >> 3;
if ((width & 0x07) != 0) {
subWidth++;
}
int subHeight = height >> 3;
if ((height & 0x07) != 0) {
subHeight++;
}
int* blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);
Ref<BitMatrix> newMatrix (new BitMatrix(width, height));
calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
matrix_ = newMatrix;
delete [] blackPoints;
delete [] luminances;
} else {
// If the image is too small, fall back to the global histogram approach.
matrix_ = GlobalHistogramBinarizer::getBlackMatrix();
}
return matrix_;
} }
void HybridBinarizer::calculateThresholdForBlock(unsigned char* luminances, int subWidth, int subHeight, void HybridBinarizer::calculateThresholdForBlock(unsigned char* luminances, int subWidth, int subHeight,

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __HYBRIDBINARIZER_H__ #ifndef __HYBRIDBINARIZER_H__
#define __HYBRIDBINARIZER_H__ #define __HYBRIDBINARIZER_H__
/* /*
@ -29,7 +30,7 @@ namespace zxing {
class HybridBinarizer : public GlobalHistogramBinarizer { class HybridBinarizer : public GlobalHistogramBinarizer {
private: private:
Ref<BitMatrix> cached_matrix_; Ref<BitMatrix> matrix_;
Ref<BitArray> cached_row_; Ref<BitArray> cached_row_;
int cached_row_num_; int cached_row_num_;
@ -40,7 +41,6 @@ namespace zxing {
virtual Ref<BitMatrix> getBlackMatrix(); virtual Ref<BitMatrix> getBlackMatrix();
Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source); Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source);
private: private:
void binarizeEntireImage();
// We'll be using one-D arrays because C++ can't dynamically allocate 2D arrays // We'll be using one-D arrays because C++ can't dynamically allocate 2D arrays
int* calculateBlackPoints(unsigned char* luminances, int subWidth, int subHeight, int* calculateBlackPoints(unsigned char* luminances, int subWidth, int subHeight,
int width, int height); int width, int height);

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/* /*
* Detector.cpp * Detector.cpp
* zxing * zxing

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __DETECTOR_H__ #ifndef __DETECTOR_H__
#define __DETECTOR_H__ #define __DETECTOR_H__
@ -21,17 +22,17 @@
* limitations under the License. * limitations under the License.
*/ */
#include <zxing/common/Counted.h> #include <zxing/common/Counted.h>
#include <zxing/common/DetectorResult.h> #include <zxing/common/DetectorResult.h>
#include <zxing/common/BitMatrix.h> #include <zxing/common/BitMatrix.h>
#include <zxing/common/PerspectiveTransform.h> #include <zxing/common/PerspectiveTransform.h>
#include <zxing/datamatrix/detector/MonochromeRectangleDetector.h> #include <zxing/datamatrix/detector/MonochromeRectangleDetector.h>
namespace zxing { namespace zxing {
namespace datamatrix { namespace datamatrix {
class ResultPointsAndTransitions : public Counted { class ResultPointsAndTransitions : public Counted {
private: private:
Ref<CornerPoint> to_; Ref<CornerPoint> to_;
@ -45,11 +46,11 @@ public:
Ref<CornerPoint> getTo(); Ref<CornerPoint> getTo();
int getTransitions(); int getTransitions();
}; };
class Detector : public Counted { class Detector : public Counted {
private: private:
Ref<BitMatrix> image_; Ref<BitMatrix> image_;
protected: protected:
Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform); Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform);
@ -57,14 +58,14 @@ protected:
Ref<ResultPointsAndTransitions> transitionsBetween(Ref<CornerPoint> from, Ref<CornerPoint> to); Ref<ResultPointsAndTransitions> transitionsBetween(Ref<CornerPoint> from, Ref<CornerPoint> to);
int min(int a, int b) { return a > b ? b : a; }; int min(int a, int b) { return a > b ? b : a; };
public: public:
Ref<BitMatrix> getImage(); Ref<BitMatrix> getImage();
Detector(Ref<BitMatrix> image); Detector(Ref<BitMatrix> image);
virtual Ref<PerspectiveTransform> createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref < virtual Ref<PerspectiveTransform> createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <
ResultPoint > bottomLeft, Ref<ResultPoint> bottomRight, int dimension); ResultPoint > bottomLeft, Ref<ResultPoint> bottomRight, int dimension);
Ref<DetectorResult> detect(); Ref<DetectorResult> detect();
void orderBestPatterns(std::vector<Ref<CornerPoint> > &patterns); void orderBestPatterns(std::vector<Ref<CornerPoint> > &patterns);
float distance(float x1, float x2, float y1, float y2); float distance(float x1, float x2, float y1, float y2);
@ -72,8 +73,8 @@ private:
int compare(Ref<ResultPointsAndTransitions> a, Ref<ResultPointsAndTransitions> b); int compare(Ref<ResultPointsAndTransitions> a, Ref<ResultPointsAndTransitions> b);
float crossProductZ(Ref<ResultPoint> pointA, Ref<ResultPoint> pointB, Ref<ResultPoint> pointC); float crossProductZ(Ref<ResultPoint> pointA, Ref<ResultPoint> pointB, Ref<ResultPoint> pointC);
}; };
} }
} }
#endif // __DETECTOR_H__ #endif // __DETECTOR_H__

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/* /*
* OneDReader.cpp * OneDReader.cpp
* ZXing * ZXing