mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
minor C++ optimizations
This is mostly just inlining a couple of getter/setter pairs that are in the tightest loops. The only semantic change is making the retain() and release() methods of the reference counted objects non-virtual, which allows them to be inlined. See also http://groups.google.com/group/zxing/browse_thread/thread/6ea93730a7093199 git-svn-id: https://zxing.googlecode.com/svn/trunk@1974 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
70190f7805
commit
31cb655de2
|
@ -59,14 +59,6 @@ size_t BitArray::getSize() {
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitArray::get(size_t i) {
|
|
||||||
return (bits_[i >> logBits_] & (1 << (i & bitsMask_))) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitArray::set(size_t i) {
|
|
||||||
bits_[i >> logBits_] |= 1 << (i & bitsMask_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitArray::setBulk(size_t i, unsigned int newBits) {
|
void BitArray::setBulk(size_t i, unsigned int newBits) {
|
||||||
bits_[i >> logBits_] = newBits;
|
bits_[i >> logBits_] = newBits;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,15 @@ public:
|
||||||
BitArray(size_t size);
|
BitArray(size_t size);
|
||||||
~BitArray();
|
~BitArray();
|
||||||
size_t getSize();
|
size_t getSize();
|
||||||
bool get(size_t i);
|
|
||||||
void set(size_t i);
|
bool get(size_t i) {
|
||||||
|
return (bits_[i >> logBits_] & (1 << (i & bitsMask_))) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(size_t i) {
|
||||||
|
bits_[i >> logBits_] |= 1 << (i & bitsMask_);
|
||||||
|
}
|
||||||
|
|
||||||
void setBulk(size_t i, unsigned int newBits);
|
void setBulk(size_t i, unsigned int newBits);
|
||||||
void setRange(int start, int end);
|
void setRange(int start, int end);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using std::numeric_limits;
|
|
||||||
using std::ostream;
|
using std::ostream;
|
||||||
using std::ostringstream;
|
using std::ostringstream;
|
||||||
|
|
||||||
|
@ -34,21 +33,9 @@ using zxing::BitArray;
|
||||||
using zxing::Ref;
|
using zxing::Ref;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
unsigned int logDigits(unsigned digits) {
|
size_t wordsForSize(size_t width,
|
||||||
unsigned log = 0;
|
size_t height,
|
||||||
unsigned val = 1;
|
unsigned int logBits) {
|
||||||
while (val < digits) {
|
|
||||||
log++;
|
|
||||||
val <<= 1;
|
|
||||||
}
|
|
||||||
return log;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int bitsPerWord = numeric_limits<unsigned int>::digits;
|
|
||||||
const unsigned int logBits = logDigits(bitsPerWord);
|
|
||||||
const unsigned int bitsMask = (1 << logBits) - 1;
|
|
||||||
|
|
||||||
size_t wordsForSize(size_t width, size_t height) {
|
|
||||||
size_t bits = width * height;
|
size_t bits = width * height;
|
||||||
int arraySize = bits >> logBits;
|
int arraySize = bits >> logBits;
|
||||||
if (bits - (arraySize << logBits) != 0) {
|
if (bits - (arraySize << logBits) != 0) {
|
||||||
|
@ -60,16 +47,14 @@ namespace {
|
||||||
|
|
||||||
BitMatrix::BitMatrix(size_t dimension) :
|
BitMatrix::BitMatrix(size_t dimension) :
|
||||||
width_(dimension), height_(dimension), words_(0), bits_(NULL) {
|
width_(dimension), height_(dimension), words_(0), bits_(NULL) {
|
||||||
|
words_ = wordsForSize(width_, height_, logBits);
|
||||||
words_ = wordsForSize(width_, height_);
|
|
||||||
bits_ = new unsigned int[words_];
|
bits_ = new unsigned int[words_];
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
BitMatrix::BitMatrix(size_t width, size_t height) :
|
BitMatrix::BitMatrix(size_t width, size_t height) :
|
||||||
width_(width), height_(height), words_(0), bits_(NULL) {
|
width_(width), height_(height), words_(0), bits_(NULL) {
|
||||||
|
words_ = wordsForSize(width_, height_, logBits);
|
||||||
words_ = wordsForSize(width_, height_);
|
|
||||||
bits_ = new unsigned int[words_];
|
bits_ = new unsigned int[words_];
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
@ -79,16 +64,6 @@ BitMatrix::~BitMatrix() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BitMatrix::get(size_t x, size_t y) const {
|
|
||||||
size_t offset = x + width_ * y;
|
|
||||||
return ((bits_[offset >> logBits] >> (offset & bitsMask)) & 0x01) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitMatrix::set(size_t x, size_t y) {
|
|
||||||
size_t offset = x + width_ * y;
|
|
||||||
bits_[offset >> logBits] |= 1 << (offset & bitsMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BitMatrix::flip(size_t x, size_t y) {
|
void BitMatrix::flip(size_t x, size_t y) {
|
||||||
size_t offset = x + width_ * y;
|
size_t offset = x + width_ * y;
|
||||||
bits_[offset >> logBits] ^= 1 << (offset & bitsMask);
|
bits_[offset >> logBits] ^= 1 << (offset & bitsMask);
|
||||||
|
@ -135,7 +110,7 @@ Ref<BitArray> BitMatrix::getRow(int y, Ref<BitArray> row) {
|
||||||
size_t lastBit = i < lastWord ? bitsPerWord - 1 : end & bitsMask;
|
size_t lastBit = i < lastWord ? bitsPerWord - 1 : end & bitsMask;
|
||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
if (firstBit == 0 && lastBit == logBits) {
|
if (firstBit == 0 && lastBit == logBits) {
|
||||||
mask = numeric_limits<unsigned int>::max();
|
mask = std::numeric_limits<unsigned int>::max();
|
||||||
} else {
|
} else {
|
||||||
mask = 0;
|
mask = 0;
|
||||||
for (size_t j = firstBit; j <= lastBit; j++) {
|
for (size_t j = firstBit; j <= lastBit; j++) {
|
||||||
|
|
|
@ -34,14 +34,35 @@ private:
|
||||||
size_t words_;
|
size_t words_;
|
||||||
unsigned int* bits_;
|
unsigned int* bits_;
|
||||||
|
|
||||||
|
#define ZX_LOG_DIGITS(digits) \
|
||||||
|
((digits == 8) ? 3 : \
|
||||||
|
((digits == 16) ? 4 : \
|
||||||
|
((digits == 32) ? 5 : \
|
||||||
|
((digits == 64) ? 6 : \
|
||||||
|
((digits == 128) ? 7 : \
|
||||||
|
(-1))))))
|
||||||
|
|
||||||
|
static const unsigned int bitsPerWord =
|
||||||
|
std::numeric_limits<unsigned int>::digits;
|
||||||
|
static const unsigned int logBits = ZX_LOG_DIGITS(bitsPerWord);
|
||||||
|
static const unsigned int bitsMask = (1 << logBits) - 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BitMatrix(size_t dimension);
|
BitMatrix(size_t dimension);
|
||||||
BitMatrix(size_t width, size_t height);
|
BitMatrix(size_t width, size_t height);
|
||||||
|
|
||||||
~BitMatrix();
|
~BitMatrix();
|
||||||
// Inlining this does not really improve performance.
|
|
||||||
bool get(size_t x, size_t y) const;
|
bool get(size_t x, size_t y) const {
|
||||||
void set(size_t x, size_t y);
|
size_t offset = x + width_ * y;
|
||||||
|
return ((bits_[offset >> logBits] >> (offset & bitsMask)) & 0x01) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(size_t x, size_t y) {
|
||||||
|
size_t offset = x + width_ * y;
|
||||||
|
bits_[offset >> logBits] |= 1 << (offset & bitsMask);
|
||||||
|
}
|
||||||
|
|
||||||
void flip(size_t x, size_t y);
|
void flip(size_t x, size_t y);
|
||||||
void clear();
|
void clear();
|
||||||
void setRegion(size_t left, size_t top, size_t width, size_t height);
|
void setRegion(size_t left, size_t top, size_t width, size_t height);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define DEBUG_COUNTING
|
//#define DEBUG_COUNTING
|
||||||
//using namespace std;
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ public:
|
||||||
}
|
}
|
||||||
virtual ~Counted() {
|
virtual ~Counted() {
|
||||||
}
|
}
|
||||||
virtual Counted *retain() {
|
Counted *retain() {
|
||||||
#ifdef DEBUG_COUNTING
|
#ifdef DEBUG_COUNTING
|
||||||
cout << "retaining " << typeid(*this).name() << " " << this <<
|
cout << "retaining " << typeid(*this).name() << " " << this <<
|
||||||
" @ " << count_;
|
" @ " << count_;
|
||||||
|
@ -56,7 +55,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
virtual void release() {
|
void release() {
|
||||||
#ifdef DEBUG_COUNTING
|
#ifdef DEBUG_COUNTING
|
||||||
cout << "releasing " << typeid(*this).name() << " " << this <<
|
cout << "releasing " << typeid(*this).name() << " " << this <<
|
||||||
" @ " << count_;
|
" @ " << count_;
|
||||||
|
|
|
@ -44,19 +44,22 @@ HybridBinarizer::~HybridBinarizer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BitMatrix> HybridBinarizer::getBlackMatrix() {
|
Ref<BitMatrix> HybridBinarizer::getBlackMatrix() {
|
||||||
// Calculates the final BitMatrix once for all requests. This could be called once from the
|
// Calculates the final BitMatrix once for all requests. This could
|
||||||
// constructor instead, but there are some advantages to doing it lazily, such as making
|
// be called once from the constructor instead, but there are some
|
||||||
// profiling easier, and not doing heavy lifting when callers don't expect it.
|
// advantages to doing it lazily, such as making profiling easier,
|
||||||
|
// and not doing heavy lifting when callers don't expect it.
|
||||||
if (matrix_) {
|
if (matrix_) {
|
||||||
return matrix_;
|
return matrix_;
|
||||||
}
|
}
|
||||||
LuminanceSource& source = *getLuminanceSource();
|
LuminanceSource& source = *getLuminanceSource();
|
||||||
if (source.getWidth() >= MINIMUM_DIMENSION && source.getHeight() >= MINIMUM_DIMENSION) {
|
if (source.getWidth() >= MINIMUM_DIMENSION &&
|
||||||
|
source.getHeight() >= MINIMUM_DIMENSION) {
|
||||||
unsigned char* luminances = source.getMatrix();
|
unsigned char* luminances = source.getMatrix();
|
||||||
int width = source.getWidth();
|
int width = source.getWidth();
|
||||||
int height = source.getHeight();
|
int height = source.getHeight();
|
||||||
|
@ -68,14 +71,22 @@ Ref<BitMatrix> HybridBinarizer::getBlackMatrix() {
|
||||||
if ((height & BLOCK_SIZE_MASK) != 0) {
|
if ((height & BLOCK_SIZE_MASK) != 0) {
|
||||||
subHeight++;
|
subHeight++;
|
||||||
}
|
}
|
||||||
int* blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);
|
int* blackPoints =
|
||||||
|
calculateBlackPoints(luminances, subWidth, subHeight, width, height);
|
||||||
|
|
||||||
Ref<BitMatrix> newMatrix (new BitMatrix(width, height));
|
Ref<BitMatrix> newMatrix (new BitMatrix(width, height));
|
||||||
calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
|
calculateThresholdForBlock(luminances,
|
||||||
|
subWidth,
|
||||||
|
subHeight,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
blackPoints,
|
||||||
|
newMatrix);
|
||||||
matrix_ = newMatrix;
|
matrix_ = newMatrix;
|
||||||
|
|
||||||
// N.B.: these deletes are inadequate if anything between the new and this point can throw.
|
// N.B.: these deletes are inadequate if anything between the new
|
||||||
// As of this writing, it doesn't look like they do.
|
// and this point can throw. As of this writing, it doesn't look
|
||||||
|
// like they do.
|
||||||
|
|
||||||
delete [] blackPoints;
|
delete [] blackPoints;
|
||||||
delete [] luminances;
|
delete [] luminances;
|
||||||
|
@ -86,8 +97,14 @@ Ref<BitMatrix> HybridBinarizer::getBlackMatrix() {
|
||||||
return matrix_;
|
return matrix_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HybridBinarizer::calculateThresholdForBlock(unsigned char* luminances, int subWidth, int subHeight,
|
void
|
||||||
int width, int height, int blackPoints[], Ref<BitMatrix> matrix) {
|
HybridBinarizer::calculateThresholdForBlock(unsigned char* luminances,
|
||||||
|
int subWidth,
|
||||||
|
int subHeight,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int blackPoints[],
|
||||||
|
Ref<BitMatrix> const& matrix) {
|
||||||
for (int y = 0; y < subHeight; y++) {
|
for (int y = 0; y < subHeight; y++) {
|
||||||
int yoffset = y << BLOCK_SIZE_POWER;
|
int yoffset = y << BLOCK_SIZE_POWER;
|
||||||
if (yoffset + BLOCK_SIZE >= height) {
|
if (yoffset + BLOCK_SIZE >= height) {
|
||||||
|
@ -117,8 +134,12 @@ void HybridBinarizer::calculateThresholdForBlock(unsigned char* luminances, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HybridBinarizer::threshold8x8Block(unsigned char* luminances, int xoffset, int yoffset, int threshold,
|
void HybridBinarizer::threshold8x8Block(unsigned char* luminances,
|
||||||
int stride, Ref<BitMatrix> matrix) {
|
int xoffset,
|
||||||
|
int yoffset,
|
||||||
|
int threshold,
|
||||||
|
int stride,
|
||||||
|
Ref<BitMatrix> const& matrix) {
|
||||||
for (int y = 0, offset = yoffset * stride + xoffset;
|
for (int y = 0, offset = yoffset * stride + xoffset;
|
||||||
y < BLOCK_SIZE;
|
y < BLOCK_SIZE;
|
||||||
y++, offset += stride) {
|
y++, offset += stride) {
|
||||||
|
|
|
@ -41,15 +41,28 @@ namespace zxing {
|
||||||
virtual Ref<BitMatrix> getBlackMatrix();
|
virtual Ref<BitMatrix> getBlackMatrix();
|
||||||
Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source);
|
Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source);
|
||||||
private:
|
private:
|
||||||
// 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
|
||||||
int* calculateBlackPoints(unsigned char* luminances, int subWidth, int subHeight,
|
// arrays
|
||||||
int width, int height);
|
int* calculateBlackPoints(unsigned char* luminances,
|
||||||
void calculateThresholdForBlock(unsigned char* luminances, int subWidth, int subHeight,
|
int subWidth,
|
||||||
int width, int height, int blackPoints[], Ref<BitMatrix> matrix);
|
int subHeight,
|
||||||
void threshold8x8Block(unsigned char* luminances, int xoffset, int yoffset, int threshold,
|
int width,
|
||||||
int stride, Ref<BitMatrix> matrix);
|
int height);
|
||||||
|
void calculateThresholdForBlock(unsigned char* luminances,
|
||||||
|
int subWidth,
|
||||||
|
int subHeight,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int blackPoints[],
|
||||||
|
Ref<BitMatrix> const& matrix);
|
||||||
|
void threshold8x8Block(unsigned char* luminances,
|
||||||
|
int xoffset,
|
||||||
|
int yoffset,
|
||||||
|
int threshold,
|
||||||
|
int stride,
|
||||||
|
Ref<BitMatrix> const& matrix);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* GLOBALHISTOGRAMBINARIZER_H_ */
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue