Commit 56e87318 for tesseract
commit 56e873189891ba28d9b009445c2f65e0ae5c0496
Author: Stefan Weil <sw@weilnetz.de>
Date: Fri Jun 5 06:07:37 2026 +0200
Use more `constexpr`
Assisted-by: OpenCode / BigPickle
Signed-off-by: Stefan Weil <sw@weilnetz.de>
diff --git a/src/ccstruct/points.h b/src/ccstruct/points.h
index 3110a017..87aa48b7 100644
--- a/src/ccstruct/points.h
+++ b/src/ccstruct/points.h
@@ -38,16 +38,11 @@ class ICOORD {
public:
/// empty constructor
- ICOORD() {
- xcoord = ycoord = 0; // default zero
- }
+ constexpr ICOORD() : xcoord(0), ycoord(0) {}
/// constructor
///@param xin x value
///@param yin y value
- ICOORD(TDimension xin, TDimension yin) {
- xcoord = xin;
- ycoord = yin;
- }
+ constexpr ICOORD(TDimension xin, TDimension yin) : xcoord(xin), ycoord(yin) {}
/// destructor
~ICOORD() = default;
@@ -113,31 +108,31 @@ public:
return xcoord != other.xcoord || ycoord != other.ycoord;
}
/// rotate 90 deg anti
- friend ICOORD operator!(const ICOORD &);
+ friend constexpr ICOORD operator!(const ICOORD &);
/// unary minus
- friend ICOORD operator-(const ICOORD &);
+ friend constexpr ICOORD operator-(const ICOORD &);
/// add
- friend ICOORD operator+(const ICOORD &, const ICOORD &);
+ friend constexpr ICOORD operator+(const ICOORD &, const ICOORD &);
/// add
- friend ICOORD &operator+=(ICOORD &, const ICOORD &);
+ friend constexpr ICOORD &operator+=(ICOORD &, const ICOORD &);
/// subtract
- friend ICOORD operator-(const ICOORD &, const ICOORD &);
+ friend constexpr ICOORD operator-(const ICOORD &, const ICOORD &);
/// subtract
- friend ICOORD &operator-=(ICOORD &, const ICOORD &);
+ friend constexpr ICOORD &operator-=(ICOORD &, const ICOORD &);
/// scalar product
- friend int32_t operator%(const ICOORD &, const ICOORD &);
+ friend constexpr int32_t operator%(const ICOORD &, const ICOORD &);
/// cross product
- friend int32_t operator*(const ICOORD &, const ICOORD &);
+ friend constexpr int32_t operator*(const ICOORD &, const ICOORD &);
/// multiply
- friend ICOORD operator*(const ICOORD &, TDimension);
+ friend constexpr ICOORD operator*(const ICOORD &, TDimension);
/// multiply
- friend ICOORD operator*(TDimension, const ICOORD &);
+ friend constexpr ICOORD operator*(TDimension, const ICOORD &);
/// multiply
- friend ICOORD &operator*=(ICOORD &, TDimension);
+ friend constexpr ICOORD &operator*=(ICOORD &, TDimension);
/// divide
- friend ICOORD operator/(const ICOORD &, TDimension);
+ friend constexpr ICOORD operator/(const ICOORD &, TDimension);
/// divide
- friend ICOORD &operator/=(ICOORD &, TDimension);
+ friend constexpr ICOORD &operator/=(ICOORD &, TDimension);
/// rotate
///@param vec by vector
void rotate(const FCOORD &vec);
@@ -197,16 +192,13 @@ public:
xcoord = xvalue; // set coords
ycoord = yvalue;
}
- FCOORD( // make from ICOORD
- ICOORD icoord) { // coords to set
- xcoord = icoord.xcoord;
- ycoord = icoord.ycoord;
- }
+ constexpr FCOORD( // make from ICOORD
+ ICOORD icoord) : xcoord(icoord.xcoord), ycoord(icoord.ycoord) {}
- float x() const { // get coords
+ constexpr float x() const { // get coords
return xcoord;
}
- float y() const {
+ constexpr float y() const {
return ycoord;
}
/// rewrite function
@@ -277,28 +269,28 @@ public:
return xcoord != other.xcoord || ycoord != other.ycoord;
}
/// rotate 90 deg anti
- friend FCOORD operator!(const FCOORD &);
+ friend constexpr FCOORD operator!(const FCOORD &);
/// unary minus
- friend FCOORD operator-(const FCOORD &);
+ friend constexpr FCOORD operator-(const FCOORD &);
/// add
- friend FCOORD operator+(const FCOORD &, const FCOORD &);
+ friend constexpr FCOORD operator+(const FCOORD &, const FCOORD &);
/// add
- friend FCOORD &operator+=(FCOORD &, const FCOORD &);
+ friend constexpr FCOORD &operator+=(FCOORD &, const FCOORD &);
/// subtract
- friend FCOORD operator-(const FCOORD &, const FCOORD &);
+ friend constexpr FCOORD operator-(const FCOORD &, const FCOORD &);
/// subtract
- friend FCOORD &operator-=(FCOORD &, const FCOORD &);
+ friend constexpr FCOORD &operator-=(FCOORD &, const FCOORD &);
/// scalar product
- friend float operator%(const FCOORD &, const FCOORD &);
+ friend constexpr float operator%(const FCOORD &, const FCOORD &);
/// cross product
- friend float operator*(const FCOORD &, const FCOORD &);
+ friend constexpr float operator*(const FCOORD &, const FCOORD &);
/// multiply
- friend FCOORD operator*(const FCOORD &, float);
+ friend constexpr FCOORD operator*(const FCOORD &, float);
/// multiply
- friend FCOORD operator*(float, const FCOORD &);
+ friend constexpr FCOORD operator*(float, const FCOORD &);
/// multiply
- friend FCOORD &operator*=(FCOORD &, float);
+ friend constexpr FCOORD &operator*=(FCOORD &, float);
/// divide
friend FCOORD operator/(const FCOORD &, float);
/// rotate
@@ -321,7 +313,7 @@ private:
* Rotate an ICOORD 90 degrees anticlockwise.
**********************************************************************/
-inline ICOORD operator!( // rotate 90 deg anti
+constexpr inline ICOORD operator!( // rotate 90 deg anti
const ICOORD &src // thing to rotate
) {
ICOORD result; // output
@@ -337,7 +329,7 @@ inline ICOORD operator!( // rotate 90 deg anti
* Unary minus of an ICOORD.
**********************************************************************/
-inline ICOORD operator-( // unary minus
+constexpr inline ICOORD operator-( // unary minus
const ICOORD &src // thing to minus
) {
ICOORD result; // output
@@ -353,7 +345,7 @@ inline ICOORD operator-( // unary minus
* Add 2 ICOORDS.
**********************************************************************/
-inline ICOORD operator+( // sum vectors
+constexpr inline ICOORD operator+( // sum vectors
const ICOORD &op1, // operands
const ICOORD &op2) {
ICOORD sum; // result
@@ -369,7 +361,7 @@ inline ICOORD operator+( // sum vectors
* Add 2 ICOORDS.
**********************************************************************/
-inline ICOORD &operator+=( // sum vectors
+constexpr inline ICOORD &operator+=( // sum vectors
ICOORD &op1, // operands
const ICOORD &op2) {
op1.xcoord += op2.xcoord;
@@ -383,7 +375,7 @@ inline ICOORD &operator+=( // sum vectors
* Subtract 2 ICOORDS.
**********************************************************************/
-inline ICOORD operator-( // subtract vectors
+constexpr inline ICOORD operator-( // subtract vectors
const ICOORD &op1, // operands
const ICOORD &op2) {
ICOORD sum; // result
@@ -399,7 +391,7 @@ inline ICOORD operator-( // subtract vectors
* Subtract 2 ICOORDS.
**********************************************************************/
-inline ICOORD &operator-=( // subtract vectors
+constexpr inline ICOORD &operator-=( // subtract vectors
ICOORD &op1, // operands
const ICOORD &op2) {
op1.xcoord -= op2.xcoord;
@@ -413,7 +405,7 @@ inline ICOORD &operator-=( // subtract vectors
* Scalar product of 2 ICOORDS.
**********************************************************************/
-inline int32_t operator%( // scalar product
+constexpr inline int32_t operator%( // scalar product
const ICOORD &op1, // operands
const ICOORD &op2) {
return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
@@ -425,7 +417,7 @@ inline int32_t operator%( // scalar product
* Cross product of 2 ICOORDS.
**********************************************************************/
-inline int32_t operator*( // cross product
+constexpr inline int32_t operator*( // cross product
const ICOORD &op1, // operands
const ICOORD &op2) {
return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
@@ -437,7 +429,7 @@ inline int32_t operator*( // cross product
* Scalar multiply of an ICOORD.
**********************************************************************/
-inline ICOORD operator*( // scalar multiply
+constexpr inline ICOORD operator*( // scalar multiply
const ICOORD &op1, // operands
TDimension scale) {
ICOORD result; // output
@@ -447,7 +439,7 @@ inline ICOORD operator*( // scalar multiply
return result;
}
-inline ICOORD operator*( // scalar multiply
+constexpr inline ICOORD operator*( // scalar multiply
TDimension scale,
const ICOORD &op1 // operands
) {
@@ -464,7 +456,7 @@ inline ICOORD operator*( // scalar multiply
* Scalar multiply of an ICOORD.
**********************************************************************/
-inline ICOORD &operator*=( // scalar multiply
+constexpr inline ICOORD &operator*=( // scalar multiply
ICOORD &op1, // operands
TDimension scale) {
op1.xcoord *= scale;
@@ -478,7 +470,7 @@ inline ICOORD &operator*=( // scalar multiply
* Scalar divide of an ICOORD.
**********************************************************************/
-inline ICOORD operator/( // scalar divide
+constexpr inline ICOORD operator/( // scalar divide
const ICOORD &op1, // operands
TDimension scale) {
ICOORD result; // output
@@ -494,7 +486,7 @@ inline ICOORD operator/( // scalar divide
* Scalar divide of an ICOORD.
**********************************************************************/
-inline ICOORD &operator/=( // scalar divide
+constexpr inline ICOORD &operator/=( // scalar divide
ICOORD &op1, // operands
TDimension scale) {
op1.xcoord /= scale;
@@ -521,7 +513,7 @@ inline void ICOORD::rotate( // rotate by vector
* Rotate an FCOORD 90 degrees anticlockwise.
**********************************************************************/
-inline FCOORD operator!( // rotate 90 deg anti
+constexpr inline FCOORD operator!( // rotate 90 deg anti
const FCOORD &src // thing to rotate
) {
FCOORD result; // output
@@ -537,7 +529,7 @@ inline FCOORD operator!( // rotate 90 deg anti
* Unary minus of an FCOORD.
**********************************************************************/
-inline FCOORD operator-( // unary minus
+constexpr inline FCOORD operator-( // unary minus
const FCOORD &src // thing to minus
) {
FCOORD result; // output
@@ -553,7 +545,7 @@ inline FCOORD operator-( // unary minus
* Add 2 FCOORDS.
**********************************************************************/
-inline FCOORD operator+( // sum vectors
+constexpr inline FCOORD operator+( // sum vectors
const FCOORD &op1, // operands
const FCOORD &op2) {
FCOORD sum; // result
@@ -569,7 +561,7 @@ inline FCOORD operator+( // sum vectors
* Add 2 FCOORDS.
**********************************************************************/
-inline FCOORD &operator+=( // sum vectors
+constexpr inline FCOORD &operator+=( // sum vectors
FCOORD &op1, // operands
const FCOORD &op2) {
op1.xcoord += op2.xcoord;
@@ -583,7 +575,7 @@ inline FCOORD &operator+=( // sum vectors
* Subtract 2 FCOORDS.
**********************************************************************/
-inline FCOORD operator-( // subtract vectors
+constexpr inline FCOORD operator-( // subtract vectors
const FCOORD &op1, // operands
const FCOORD &op2) {
FCOORD sum; // result
@@ -599,7 +591,7 @@ inline FCOORD operator-( // subtract vectors
* Subtract 2 FCOORDS.
**********************************************************************/
-inline FCOORD &operator-=( // subtract vectors
+constexpr inline FCOORD &operator-=( // subtract vectors
FCOORD &op1, // operands
const FCOORD &op2) {
op1.xcoord -= op2.xcoord;
@@ -613,7 +605,7 @@ inline FCOORD &operator-=( // subtract vectors
* Scalar product of 2 FCOORDS.
**********************************************************************/
-inline float operator%( // scalar product
+constexpr inline float operator%( // scalar product
const FCOORD &op1, // operands
const FCOORD &op2) {
return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
@@ -625,7 +617,7 @@ inline float operator%( // scalar product
* Cross product of 2 FCOORDS.
**********************************************************************/
-inline float operator*( // cross product
+constexpr inline float operator*( // cross product
const FCOORD &op1, // operands
const FCOORD &op2) {
return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
@@ -637,7 +629,7 @@ inline float operator*( // cross product
* Scalar multiply of an FCOORD.
**********************************************************************/
-inline FCOORD operator*( // scalar multiply
+constexpr inline FCOORD operator*( // scalar multiply
const FCOORD &op1, // operands
float scale) {
FCOORD result; // output
@@ -647,7 +639,7 @@ inline FCOORD operator*( // scalar multiply
return result;
}
-inline FCOORD operator*( // scalar multiply
+constexpr inline FCOORD operator*( // scalar multiply
float scale,
const FCOORD &op1 // operands
) {
@@ -664,7 +656,7 @@ inline FCOORD operator*( // scalar multiply
* Scalar multiply of an FCOORD.
**********************************************************************/
-inline FCOORD &operator*=( // scalar multiply
+constexpr inline FCOORD &operator*=( // scalar multiply
FCOORD &op1, // operands
float scale) {
op1.xcoord *= scale;
diff --git a/src/ccstruct/rect.h b/src/ccstruct/rect.h
index b6bb7fbf..6ca80ac3 100644
--- a/src/ccstruct/rect.h
+++ b/src/ccstruct/rect.h
@@ -57,65 +57,65 @@ public:
TBOX( // box around FCOORD
const FCOORD pt);
- bool null_box() const { // Is box null
+ constexpr bool null_box() const { // Is box null
return ((left() >= right()) || (top() <= bottom()));
}
- bool operator==(const TBOX &other) const {
+ constexpr bool operator==(const TBOX &other) const {
return bot_left == other.bot_left && top_right == other.top_right;
}
- TDimension top() const { // coord of top
+ constexpr TDimension top() const { // coord of top
return top_right.y();
}
void set_top(int y) {
top_right.set_y(y);
}
- TDimension bottom() const { // coord of bottom
+ constexpr TDimension bottom() const { // coord of bottom
return bot_left.y();
}
void set_bottom(int y) {
bot_left.set_y(y);
}
- TDimension left() const { // coord of left
+ constexpr TDimension left() const { // coord of left
return bot_left.x();
}
void set_left(int x) {
bot_left.set_x(x);
}
- TDimension right() const { // coord of right
+ constexpr TDimension right() const { // coord of right
return top_right.x();
}
void set_right(int x) {
top_right.set_x(x);
}
- int x_middle() const {
+ constexpr int x_middle() const {
return (bot_left.x() + top_right.x()) / 2;
}
- int y_middle() const {
+ constexpr int y_middle() const {
return (bot_left.y() + top_right.y()) / 2;
}
- const ICOORD &botleft() const { // access function
+ constexpr const ICOORD &botleft() const { // access function
return bot_left;
}
- ICOORD botright() const { // ~ access function
+ constexpr ICOORD botright() const { // ~ access function
return ICOORD(top_right.x(), bot_left.y());
}
- ICOORD topleft() const { // ~ access function
+ constexpr ICOORD topleft() const { // ~ access function
return ICOORD(bot_left.x(), top_right.y());
}
- const ICOORD &topright() const { // access function
+ constexpr const ICOORD &topright() const { // access function
return top_right;
}
- TDimension height() const { // how high is it?
+ constexpr TDimension height() const { // how high is it?
if (!null_box()) {
return top_right.y() - bot_left.y();
} else {
@@ -123,7 +123,7 @@ public:
}
}
- TDimension width() const { // how wide is it?
+ constexpr TDimension width() const { // how wide is it?
if (!null_box()) {
return top_right.x() - bot_left.x();
} else {
@@ -131,7 +131,7 @@ public:
}
}
- int32_t area() const { // what is the area?
+ constexpr int32_t area() const { // what is the area?
if (!null_box()) {
return width() * height();
} else {
@@ -217,54 +217,54 @@ public:
// original content is contained within, but also slightly enlarges the box.
void rotate_large(const FCOORD &vec);
- bool contains( // is pt inside box
+ constexpr bool contains( // is pt inside box
const FCOORD pt) const;
- bool contains( // is box inside box
+ constexpr bool contains( // is box inside box
const TBOX &box) const;
- bool overlap( // do boxes overlap
+ constexpr bool overlap( // do boxes overlap
const TBOX &box) const;
- bool major_overlap( // do boxes overlap more than half
+ constexpr bool major_overlap( // do boxes overlap more than half
const TBOX &box) const;
// Do boxes overlap on x axis.
- bool x_overlap(const TBOX &box) const;
+ constexpr bool x_overlap(const TBOX &box) const;
// Return the horizontal gap between the boxes. If the boxes
// overlap horizontally then the return value is negative, indicating
// the amount of the overlap.
- int x_gap(const TBOX &box) const {
+ constexpr int x_gap(const TBOX &box) const {
return std::max(bot_left.x(), box.bot_left.x()) - std::min(top_right.x(), box.top_right.x());
}
// Return the vertical gap between the boxes. If the boxes
// overlap vertically then the return value is negative, indicating
// the amount of the overlap.
- int y_gap(const TBOX &box) const {
+ constexpr int y_gap(const TBOX &box) const {
return std::max(bot_left.y(), box.bot_left.y()) - std::min(top_right.y(), box.top_right.y());
}
// Do boxes overlap on x axis by more than
// half of the width of the narrower box.
- bool major_x_overlap(const TBOX &box) const;
+ constexpr bool major_x_overlap(const TBOX &box) const;
// Do boxes overlap on y axis.
- bool y_overlap(const TBOX &box) const;
+ constexpr bool y_overlap(const TBOX &box) const;
// Do boxes overlap on y axis by more than
// half of the height of the shorter box.
- bool major_y_overlap(const TBOX &box) const;
+ constexpr bool major_y_overlap(const TBOX &box) const;
// fraction of current box's area covered by other
double overlap_fraction(const TBOX &box) const;
// fraction of the current box's projected area covered by the other's
- double x_overlap_fraction(const TBOX &box) const;
+ constexpr double x_overlap_fraction(const TBOX &box) const;
// fraction of the current box's projected area covered by the other's
- double y_overlap_fraction(const TBOX &box) const;
+ constexpr double y_overlap_fraction(const TBOX &box) const;
// Returns true if the boxes are almost equal on x axis.
bool x_almost_equal(const TBOX &box, int tolerance) const;
@@ -341,7 +341,7 @@ inline TBOX::TBOX( // constructor
*
**********************************************************************/
-inline bool TBOX::contains(const FCOORD pt) const {
+inline constexpr bool TBOX::contains(const FCOORD pt) const {
return ((pt.x() >= bot_left.x()) && (pt.x() <= top_right.x()) && (pt.y() >= bot_left.y()) &&
(pt.y() <= top_right.y()));
}
@@ -351,7 +351,7 @@ inline bool TBOX::contains(const FCOORD pt) const {
*
**********************************************************************/
-inline bool TBOX::contains(const TBOX &box) const {
+inline constexpr bool TBOX::contains(const TBOX &box) const {
return (contains(box.bot_left) && contains(box.top_right));
}
@@ -360,7 +360,7 @@ inline bool TBOX::contains(const TBOX &box) const {
*
**********************************************************************/
-inline bool TBOX::overlap( // do boxes overlap
+inline constexpr bool TBOX::overlap( // do boxes overlap
const TBOX &box) const {
return ((box.bot_left.x() <= top_right.x()) && (box.top_right.x() >= bot_left.x()) &&
(box.bot_left.y() <= top_right.y()) && (box.top_right.y() >= bot_left.y()));
@@ -371,7 +371,7 @@ inline bool TBOX::overlap( // do boxes overlap
*
**********************************************************************/
-inline bool TBOX::major_overlap( // Do boxes overlap more that half.
+inline constexpr bool TBOX::major_overlap( // Do boxes overlap more that half.
const TBOX &box) const {
int overlap = std::min(box.top_right.x(), top_right.x());
overlap -= std::max(box.bot_left.x(), bot_left.x());
@@ -406,7 +406,7 @@ inline double TBOX::overlap_fraction(const TBOX &box) const {
*
**********************************************************************/
-inline bool TBOX::x_overlap(const TBOX &box) const {
+inline constexpr bool TBOX::x_overlap(const TBOX &box) const {
return ((box.bot_left.x() <= top_right.x()) && (box.top_right.x() >= bot_left.x()));
}
@@ -416,7 +416,7 @@ inline bool TBOX::x_overlap(const TBOX &box) const {
*
**********************************************************************/
-inline bool TBOX::major_x_overlap(const TBOX &box) const {
+inline constexpr bool TBOX::major_x_overlap(const TBOX &box) const {
TDimension overlap = box.width();
if (this->left() > box.left()) {
overlap -= this->left() - box.left();
@@ -432,7 +432,7 @@ inline bool TBOX::major_x_overlap(const TBOX &box) const {
*
**********************************************************************/
-inline bool TBOX::y_overlap(const TBOX &box) const {
+inline constexpr bool TBOX::y_overlap(const TBOX &box) const {
return ((box.bot_left.y() <= top_right.y()) && (box.top_right.y() >= bot_left.y()));
}
@@ -442,7 +442,7 @@ inline bool TBOX::y_overlap(const TBOX &box) const {
*
**********************************************************************/
-inline bool TBOX::major_y_overlap(const TBOX &box) const {
+inline constexpr bool TBOX::major_y_overlap(const TBOX &box) const {
TDimension overlap = box.height();
if (this->bottom() > box.bottom()) {
overlap -= this->bottom() - box.bottom();
@@ -460,7 +460,7 @@ inline bool TBOX::major_y_overlap(const TBOX &box) const {
*
**********************************************************************/
-inline double TBOX::x_overlap_fraction(const TBOX &other) const {
+inline constexpr double TBOX::x_overlap_fraction(const TBOX &other) const {
int low = std::max(left(), other.left());
int high = std::min(right(), other.right());
int width = right() - left();
@@ -483,7 +483,7 @@ inline double TBOX::x_overlap_fraction(const TBOX &other) const {
*
**********************************************************************/
-inline double TBOX::y_overlap_fraction(const TBOX &other) const {
+inline constexpr double TBOX::y_overlap_fraction(const TBOX &other) const {
int low = std::max(bottom(), other.bottom());
int high = std::min(top(), other.top());
int height = top() - bottom();
diff --git a/src/classify/cluster.cpp b/src/classify/cluster.cpp
index b926f7e4..ed5a8b5d 100644
--- a/src/classify/cluster.cpp
+++ b/src/classify/cluster.cpp
@@ -32,13 +32,13 @@
namespace tesseract {
-#define HOTELLING 1 // If true use Hotelling's test to decide where to split.
-#define FTABLE_X 10 // Size of FTable.
-#define FTABLE_Y 100 // Size of FTable.
+constexpr int HOTELLING = 1; // If true use Hotelling's test to decide where to split.
+constexpr int FTABLE_X = 10; // Size of FTable.
+constexpr int FTABLE_Y = 100; // Size of FTable.
// Table of values approximating the cumulative F-distribution for a confidence
// of 1%.
-const double FTable[FTABLE_Y][FTABLE_X] = {
+constexpr double FTable[FTABLE_Y][FTABLE_X] = {
{
4052.19,
4999.52,
@@ -1233,7 +1233,7 @@ const double FTable[FTABLE_Y][FTABLE_X] = {
dimension of any feature. Since most features are calculated from numbers
with a precision no better than 1 in 128, the variance should never be
less than the square of this number for parameters whose range is 1. */
-#define MINVARIANCE 0.0004
+constexpr double MINVARIANCE = 0.0004;
/** define the absolute minimum number of samples which must be present in
order to accurately test hypotheses about underlying probability
@@ -1241,9 +1241,9 @@ const double FTable[FTABLE_Y][FTABLE_X] = {
before a statistical analysis is attempted; this number should be
equal to MINSAMPLES but can be set to a lower number for early testing
when very few samples are available. */
-#define MINSAMPLESPERBUCKET 5
-#define MINSAMPLES (MINBUCKETS * MINSAMPLESPERBUCKET)
-#define MINSAMPLESNEEDED 1
+constexpr int MINSAMPLESPERBUCKET = 5;
+constexpr int MINSAMPLES = MINBUCKETS * MINSAMPLESPERBUCKET;
+constexpr int MINSAMPLESNEEDED = 1;
/** define the size of the table which maps normalized samples to
histogram buckets. Also define the number of standard deviations
@@ -1251,8 +1251,8 @@ const double FTable[FTABLE_Y][FTABLE_X] = {
The mapping table will be defined in such a way that it covers
the specified number of standard deviations on either side of
the mean. BUCKETTABLESIZE should always be even. */
-#define BUCKETTABLESIZE 1024
-#define NORMALEXTENT 3.0
+constexpr int BUCKETTABLESIZE = 1024;
+constexpr double NORMALEXTENT = 3.0;
struct TEMPCLUSTER {
CLUSTER *Cluster;
@@ -1311,9 +1311,18 @@ struct ClusteringContext {
using DENSITYFUNC = double (*)(int32_t);
using SOLVEFUNC = double (*)(CHISTRUCT *, double);
-#define Odd(N) ((N) % 2)
-#define Mirror(N, R) ((R) - (N)-1)
-#define Abs(N) (((N) < 0) ? (-(N)) : (N))
+template <typename T>
+inline constexpr bool Odd(T N) {
+ return (N % 2) != 0;
+}
+template <typename T>
+inline constexpr T Mirror(T N, T R) {
+ return R - N - 1;
+}
+template <typename T>
+inline constexpr T Abs(T N) {
+ return N < 0 ? -N : N;
+}
//--------------Global Data Definitions and Declarations----------------------
/** the following variables describe a discrete normal distribution
@@ -1323,22 +1332,22 @@ using SOLVEFUNC = double (*)(CHISTRUCT *, double);
discrete range of x. x=0 is mapped to -NORMALEXTENT standard
deviations and x=BUCKETTABLESIZE is mapped to
+NORMALEXTENT standard deviations. */
-#define SqrtOf2Pi 2.506628275
-static const double kNormalStdDev = BUCKETTABLESIZE / (2.0 * NORMALEXTENT);
-static const double kNormalVariance =
+constexpr double SqrtOf2Pi = 2.506628275;
+static constexpr double kNormalStdDev = BUCKETTABLESIZE / (2.0 * NORMALEXTENT);
+static constexpr double kNormalVariance =
(BUCKETTABLESIZE * BUCKETTABLESIZE) / (4.0 * NORMALEXTENT * NORMALEXTENT);
-static const double kNormalMagnitude = (2.0 * NORMALEXTENT) / (SqrtOf2Pi * BUCKETTABLESIZE);
-static const double kNormalMean = BUCKETTABLESIZE / 2;
+static constexpr double kNormalMagnitude = (2.0 * NORMALEXTENT) / (SqrtOf2Pi * BUCKETTABLESIZE);
+static constexpr double kNormalMean = BUCKETTABLESIZE / 2;
/** define lookup tables used to compute the number of histogram buckets
that should be used for a given number of samples. */
-#define LOOKUPTABLESIZE 8
-#define MAXDEGREESOFFREEDOM MAXBUCKETS
+constexpr int LOOKUPTABLESIZE = 8;
+constexpr int MAXDEGREESOFFREEDOM = MAXBUCKETS;
-static const uint32_t kCountTable[LOOKUPTABLESIZE] = {MINSAMPLES, 200, 400, 600, 800,
- 1000, 1500, 2000}; // number of samples
+static constexpr uint32_t kCountTable[LOOKUPTABLESIZE] = {MINSAMPLES, 200, 400, 600, 800,
+ 1000, 1500, 2000}; // number of samples
-static const uint16_t kBucketsTable[LOOKUPTABLESIZE] = {
+static constexpr uint16_t kBucketsTable[LOOKUPTABLESIZE] = {
MINBUCKETS, 16, 20, 24, 27, 30, 35, MAXBUCKETS}; // number of buckets
/*-------------------------------------------------------------------------
@@ -1795,10 +1804,9 @@ static void MakePotentialClusters(ClusteringContext *context, CLUSTER *Cluster,
* @param Distance ptr to variable to report distance found
* @return Pointer to the nearest neighbor of Cluster, or nullptr
*/
-static CLUSTER *FindNearestNeighbor(KDTREE *Tree, CLUSTER *Cluster, float *Distance)
-#define MAXNEIGHBORS 2
-#define MAXDISTANCE FLT_MAX
-{
+static CLUSTER *FindNearestNeighbor(KDTREE *Tree, CLUSTER *Cluster, float *Distance) {
+ constexpr int MAXNEIGHBORS = 2;
+ constexpr float MAXDISTANCE = FLT_MAX;
CLUSTER *Neighbor[MAXNEIGHBORS];
float Dist[MAXNEIGHBORS];
int NumberOfNeighbors;
@@ -2758,10 +2766,9 @@ static uint16_t OptimumNumberOfBuckets(uint32_t SampleCount) {
* @param Alpha probability of right tail
* @return Desired chi-squared value
*/
-static double ComputeChiSquared(uint16_t DegreesOfFreedom, double Alpha)
-#define CHIACCURACY 0.01
-#define MINALPHA (1e-200)
-{
+static double ComputeChiSquared(uint16_t DegreesOfFreedom, double Alpha) {
+ constexpr double CHIACCURACY = 0.01;
+ constexpr double MINALPHA = 1e-200;
static LIST ChiWith[MAXDEGREESOFFREEDOM + 1];
// limit the minimum alpha that can be used - if alpha is too small
@@ -3106,10 +3113,9 @@ static int AlphaMatch(void *arg1, // CHISTRUCT *ChiStruct,
* @param Accuracy maximum allowed error
* @return Solution of function (x for which f(x) = 0).
*/
-static double Solve(SOLVEFUNC Function, void *FunctionParams, double InitialGuess, double Accuracy)
-#define INITIALDELTA 0.1
-#define DELTARATIO 0.1
-{
+static double Solve(SOLVEFUNC Function, void *FunctionParams, double InitialGuess, double Accuracy) {
+ constexpr double INITIALDELTA = 0.1;
+ constexpr double DELTARATIO = 0.1;
double x;
double f;
double Slope;
@@ -3212,9 +3218,8 @@ static double ChiArea(CHISTRUCT *ChiParams, double x) {
* more than 1 feature in the cluster
* @return true if the cluster should be split, false otherwise.
*/
-static bool MultipleCharSamples(CLUSTERER *Clusterer, CLUSTER *Cluster, float MaxIllegal)
-#define ILLEGAL_CHAR 2
-{
+static bool MultipleCharSamples(CLUSTERER *Clusterer, CLUSTER *Cluster, float MaxIllegal) {
+ constexpr int ILLEGAL_CHAR = 2;
static std::vector<uint8_t> CharFlags;
LIST SearchState;
SAMPLE *Sample;
diff --git a/src/classify/cluster.h b/src/classify/cluster.h
index 33f0afda..3caf7474 100644
--- a/src/classify/cluster.h
+++ b/src/classify/cluster.h
@@ -25,8 +25,8 @@ namespace tesseract {
struct BUCKETS;
-#define MINBUCKETS 5
-#define MAXBUCKETS 39
+constexpr int MINBUCKETS = 5;
+constexpr int MAXBUCKETS = 39;
/*----------------------------------------------------------------------
Types
diff --git a/src/classify/fpoint.h b/src/classify/fpoint.h
index 69f13d0d..ccca05f1 100644
--- a/src/classify/fpoint.h
+++ b/src/classify/fpoint.h
@@ -34,13 +34,22 @@ using FVECTOR = FPOINT;
/**----------------------------------------------------------------------------
Macros
----------------------------------------------------------------------------**/
-/* macros for computing miscellaneous functions of 2 points */
-#define XDelta(A, B) ((B).x - (A).x)
-#define YDelta(A, B) ((B).y - (A).y)
-#define SlopeFrom(A, B) (YDelta(A, B) / XDelta(A, B))
-#define AngleFrom(A, B) (atan2(static_cast<double>(YDelta(A, B)), static_cast<double>(XDelta(A, B))))
-
-#define XIntersectionOf(A, B, X) (SlopeFrom(A, B) * ((X)-A.x) + A.y)
+/* functions for computing miscellaneous properties of 2 points */
+inline constexpr float XDelta(const FPOINT &A, const FPOINT &B) {
+ return B.x - A.x;
+}
+inline constexpr float YDelta(const FPOINT &A, const FPOINT &B) {
+ return B.y - A.y;
+}
+inline constexpr float SlopeFrom(const FPOINT &A, const FPOINT &B) {
+ return YDelta(A, B) / XDelta(A, B);
+}
+inline double AngleFrom(const FPOINT &A, const FPOINT &B) {
+ return std::atan2(static_cast<double>(YDelta(A, B)), static_cast<double>(XDelta(A, B)));
+}
+inline constexpr float XIntersectionOf(const FPOINT &A, const FPOINT &B, float X) {
+ return SlopeFrom(A, B) * (X - A.x) + A.y;
+}
/*-------------------------------------------------------------------------
Public Function Prototypes
diff --git a/src/classify/intmatcher.cpp b/src/classify/intmatcher.cpp
index d32aee57..5e5d1a0e 100644
--- a/src/classify/intmatcher.cpp
+++ b/src/classify/intmatcher.cpp
@@ -38,11 +38,6 @@ namespace tesseract {
/*----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------*/
-// Parameters of the sigmoid used to convert similarity to evidence in the
-// similarity_evidence_table_ that is used to convert distance metric to an
-// 8 bit evidence value in the secondary matcher. (See IntMatcher::Init).
-const float IntegerMatcher::kSEExponentialMultiplier = 0.0f;
-const float IntegerMatcher::kSimilarityCenter = 0.0075f;
static const uint8_t offset_table[] = {
255, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,
@@ -668,8 +663,8 @@ int IntegerMatcher::FindBadFeatures(INT_CLASS_STRUCT *ClassTemplate, BIT_VECTOR
IntegerMatcher::IntegerMatcher(tesseract::IntParam *classify_debug_level)
: classify_debug_level_(classify_debug_level) {
/* Initialize table for evidence to similarity lookup */
- for (int i = 0; i < SE_TABLE_SIZE; i++) {
- uint32_t IntSimilarity = i << (27 - SE_TABLE_BITS);
+ for (int i = 0; i < kSETableSize; i++) {
+ uint32_t IntSimilarity = i << (27 - kSETableBits);
double Similarity = (static_cast<double>(IntSimilarity)) / 65536.0 / 65536.0;
double evidence = Similarity / kSimilarityCenter;
evidence = 255.0 / (evidence * evidence + 1.0);
@@ -677,17 +672,17 @@ IntegerMatcher::IntegerMatcher(tesseract::IntParam *classify_debug_level)
if (kSEExponentialMultiplier > 0.0) {
double scale =
1.0 - std::exp(-kSEExponentialMultiplier) *
- exp(kSEExponentialMultiplier * (static_cast<double>(i) / SE_TABLE_SIZE));
+ exp(kSEExponentialMultiplier * (static_cast<double>(i) / kSETableSize));
evidence *= ClipToRange(scale, 0.0, 1.0);
}
similarity_evidence_table_[i] = static_cast<uint8_t>(evidence + 0.5);
}
- /* Initialize evidence computation variables */
+ // Initialize evidence computation variables
evidence_table_mask_ = ((1 << kEvidenceTableBits) - 1) << (9 - kEvidenceTableBits);
mult_trunc_shift_bits_ = (14 - kIntEvidenceTruncBits);
- table_trunc_shift_bits_ = (27 - SE_TABLE_BITS - (mult_trunc_shift_bits_ << 1));
+ table_trunc_shift_bits_ = (27 - kSETableBits - (mult_trunc_shift_bits_ << 1));
evidence_mult_mask_ = ((1 << kIntEvidenceTruncBits) - 1);
}
diff --git a/src/classify/intmatcher.h b/src/classify/intmatcher.h
index 167e87a5..d7dd0c1f 100644
--- a/src/classify/intmatcher.h
+++ b/src/classify/intmatcher.h
@@ -43,8 +43,8 @@ struct CP_RESULT_STRUCT {
Public Function Prototypes
----------------------------------------------------------------------------**/
-#define SE_TABLE_BITS 9
-#define SE_TABLE_SIZE 512
+constexpr int kSETableBits = 9;
+constexpr int kSETableSize = 512;
struct ScratchEvidence {
uint8_t feature_evidence_[MAX_NUM_CONFIGS];
@@ -60,15 +60,20 @@ struct ScratchEvidence {
class IntegerMatcher {
public:
// Integer Matcher Theta Fudge (0-255).
- static const int kIntThetaFudge = 128;
+ static constexpr int kIntThetaFudge = 128;
// Bits in Similarity to Evidence Lookup (8-9).
- static const int kEvidenceTableBits = 9;
+ static constexpr int kEvidenceTableBits = 9;
// Integer Evidence Truncation Bits (8-14).
- static const int kIntEvidenceTruncBits = 14;
+ static constexpr int kIntEvidenceTruncBits = 14;
+
+ // Parameters of the sigmoid used to convert similarity to evidence in the
+ // similarity_evidence_table_ that is used to convert distance metric to an
+ // 8 bit evidence value in the secondary matcher. (See IntMatcher::Init).
+
// Similarity to Evidence Table Exponential Multiplier.
- static const float kSEExponentialMultiplier;
+ static constexpr float kSEExponentialMultiplier = 0.0f;
// Center of Similarity Curve.
- static const float kSimilarityCenter;
+ static constexpr float kSimilarityCenter = 0.0075f;
IntegerMatcher(tesseract::IntParam *classify_debug_level);
@@ -112,7 +117,7 @@ private:
private:
tesseract::IntParam *classify_debug_level_;
- uint8_t similarity_evidence_table_[SE_TABLE_SIZE];
+ uint8_t similarity_evidence_table_[kSETableSize];
uint32_t evidence_table_mask_;
uint32_t mult_trunc_shift_bits_;
uint32_t table_trunc_shift_bits_;
diff --git a/src/classify/intproto.h b/src/classify/intproto.h
index 35a1c75e..a90e43cb 100644
--- a/src/classify/intproto.h
+++ b/src/classify/intproto.h
@@ -32,37 +32,37 @@ namespace tesseract {
class FCOORD;
/* define order of params in pruners */
-#define PRUNER_X 0
-#define PRUNER_Y 1
-#define PRUNER_ANGLE 2
+constexpr int PRUNER_X = 0;
+constexpr int PRUNER_Y = 1;
+constexpr int PRUNER_ANGLE = 2;
/* definition of coordinate system offsets for each table parameter */
-#define ANGLE_SHIFT (0.0)
-#define X_SHIFT (0.5)
-#define Y_SHIFT (0.5)
+constexpr double ANGLE_SHIFT = 0.0;
+constexpr double X_SHIFT = 0.5;
+constexpr double Y_SHIFT = 0.5;
-#define MAX_PROTO_INDEX 24
-#define BITS_PER_WERD static_cast<int>(8 * sizeof(uint32_t))
+constexpr int MAX_PROTO_INDEX = 24;
+constexpr int BITS_PER_WERD = static_cast<int>(8 * sizeof(uint32_t));
/* Script detection: increase this number to 128 */
-#define MAX_NUM_CONFIGS 64
-#define MAX_NUM_PROTOS 512
-#define PROTOS_PER_PROTO_SET 64
-#define MAX_NUM_PROTO_SETS (MAX_NUM_PROTOS / PROTOS_PER_PROTO_SET)
-#define NUM_PP_PARAMS 3
-#define NUM_PP_BUCKETS 64
-#define NUM_CP_BUCKETS 24
-#define CLASSES_PER_CP 32
-#define NUM_BITS_PER_CLASS 2
-#define CLASS_PRUNER_CLASS_MASK (~(~0u << NUM_BITS_PER_CLASS))
-#define CLASSES_PER_CP_WERD (CLASSES_PER_CP / NUM_BITS_PER_CLASS)
-#define PROTOS_PER_PP_WERD BITS_PER_WERD
-#define BITS_PER_CP_VECTOR (CLASSES_PER_CP * NUM_BITS_PER_CLASS)
-#define MAX_NUM_CLASS_PRUNERS ((MAX_NUM_CLASSES + CLASSES_PER_CP - 1) / CLASSES_PER_CP)
-#define WERDS_PER_CP_VECTOR (BITS_PER_CP_VECTOR / BITS_PER_WERD)
-#define WERDS_PER_PP_VECTOR ((PROTOS_PER_PROTO_SET + BITS_PER_WERD - 1) / BITS_PER_WERD)
-#define WERDS_PER_PP (NUM_PP_PARAMS * NUM_PP_BUCKETS * WERDS_PER_PP_VECTOR)
-#define WERDS_PER_CP (NUM_CP_BUCKETS * NUM_CP_BUCKETS * NUM_CP_BUCKETS * WERDS_PER_CP_VECTOR)
-#define WERDS_PER_CONFIG_VEC ((MAX_NUM_CONFIGS + BITS_PER_WERD - 1) / BITS_PER_WERD)
+constexpr int MAX_NUM_CONFIGS = 64;
+constexpr int MAX_NUM_PROTOS = 512;
+constexpr int PROTOS_PER_PROTO_SET = 64;
+constexpr int MAX_NUM_PROTO_SETS = MAX_NUM_PROTOS / PROTOS_PER_PROTO_SET;
+constexpr int NUM_PP_PARAMS = 3;
+constexpr int NUM_PP_BUCKETS = 64;
+constexpr int NUM_CP_BUCKETS = 24;
+constexpr int CLASSES_PER_CP = 32;
+constexpr int NUM_BITS_PER_CLASS = 2;
+constexpr uint32_t CLASS_PRUNER_CLASS_MASK = ~(~0u << NUM_BITS_PER_CLASS);
+constexpr int CLASSES_PER_CP_WERD = CLASSES_PER_CP / NUM_BITS_PER_CLASS;
+constexpr int PROTOS_PER_PP_WERD = BITS_PER_WERD;
+constexpr int BITS_PER_CP_VECTOR = CLASSES_PER_CP * NUM_BITS_PER_CLASS;
+constexpr int MAX_NUM_CLASS_PRUNERS = (MAX_NUM_CLASSES + CLASSES_PER_CP - 1) / CLASSES_PER_CP;
+constexpr int WERDS_PER_CP_VECTOR = BITS_PER_CP_VECTOR / BITS_PER_WERD;
+constexpr int WERDS_PER_PP_VECTOR = (PROTOS_PER_PROTO_SET + BITS_PER_WERD - 1) / BITS_PER_WERD;
+constexpr int WERDS_PER_PP = NUM_PP_PARAMS * NUM_PP_BUCKETS * WERDS_PER_PP_VECTOR;
+constexpr int WERDS_PER_CP = NUM_CP_BUCKETS * NUM_CP_BUCKETS * NUM_CP_BUCKETS * WERDS_PER_CP_VECTOR;
+constexpr int WERDS_PER_CONFIG_VEC = (MAX_NUM_CONFIGS + BITS_PER_WERD - 1) / BITS_PER_WERD;
/* The first 3 dimensions of the CLASS_PRUNER_STRUCT are the
* 3 axes of the quantized feature space.
@@ -113,8 +113,8 @@ struct TESS_API INT_TEMPLATES_STRUCT {
};
/* definitions of integer features*/
-#define MAX_NUM_INT_FEATURES 512
-#define INT_CHAR_NORM_RANGE 256
+constexpr int MAX_NUM_INT_FEATURES = 512;
+constexpr int INT_CHAR_NORM_RANGE = 256;
struct INT_FEATURE_STRUCT {
INT_FEATURE_STRUCT() : X(0), Y(0), Theta(0), CP_misses(0) {}
@@ -142,40 +142,46 @@ enum IntmatcherDebugAction { IDA_ADAPTIVE, IDA_STATIC, IDA_SHAPE_INDEX, IDA_BOTH
Macros
----------------------------------------------------------------------------**/
-#define MaxNumIntProtosIn(C) (C->NumProtoSets * PROTOS_PER_PROTO_SET)
-#define SetForProto(P) (P / PROTOS_PER_PROTO_SET)
-#define IndexForProto(P) (P % PROTOS_PER_PROTO_SET)
-#define ProtoForProtoId(C, P) (&((C->ProtoSets[SetForProto(P)])->Protos[IndexForProto(P)]))
-#define PPrunerWordIndexFor(I) (((I) % PROTOS_PER_PROTO_SET) / PROTOS_PER_PP_WERD)
-#define PPrunerBitIndexFor(I) ((I) % PROTOS_PER_PP_WERD)
-#define PPrunerMaskFor(I) (1 << PPrunerBitIndexFor(I))
-
-#define MaxNumClassesIn(T) (T->NumClassPruners * CLASSES_PER_CP)
-#define LegalClassId(c) ((c) >= 0 && (c) < MAX_NUM_CLASSES)
-#define UnusedClassIdIn(T, c) ((T)->Class[c] == nullptr)
-#define ClassForClassId(T, c) ((T)->Class[c])
-#define ClassPrunersFor(T) ((T)->ClassPruner)
-#define CPrunerIdFor(c) ((c) / CLASSES_PER_CP)
-#define CPrunerFor(T, c) ((T)->ClassPruners[CPrunerIdFor(c)])
-#define CPrunerWordIndexFor(c) (((c) % CLASSES_PER_CP) / CLASSES_PER_CP_WERD)
-#define CPrunerBitIndexFor(c) (((c) % CLASSES_PER_CP) % CLASSES_PER_CP_WERD)
-#define CPrunerMaskFor(L, c) (((L) + 1) << CPrunerBitIndexFor(c) * NUM_BITS_PER_CLASS)
-
-/* DEBUG macros*/
-#define PRINT_MATCH_SUMMARY 0x001
-#define DISPLAY_FEATURE_MATCHES 0x002
-#define DISPLAY_PROTO_MATCHES 0x004
-#define PRINT_FEATURE_MATCHES 0x008
-#define PRINT_PROTO_MATCHES 0x010
-#define CLIP_MATCH_EVIDENCE 0x020
-
-#define MatchDebuggingOn(D) (D)
-#define PrintMatchSummaryOn(D) ((D)&PRINT_MATCH_SUMMARY)
-#define DisplayFeatureMatchesOn(D) ((D)&DISPLAY_FEATURE_MATCHES)
-#define DisplayProtoMatchesOn(D) ((D)&DISPLAY_PROTO_MATCHES)
-#define PrintFeatureMatchesOn(D) ((D)&PRINT_FEATURE_MATCHES)
-#define PrintProtoMatchesOn(D) ((D)&PRINT_PROTO_MATCHES)
-#define ClipMatchEvidenceOn(D) ((D)&CLIP_MATCH_EVIDENCE)
+inline constexpr int MaxNumIntProtosIn(const INT_CLASS_STRUCT *C) { return C->NumProtoSets * PROTOS_PER_PROTO_SET; }
+inline constexpr int SetForProto(int P) { return P / PROTOS_PER_PROTO_SET; }
+inline constexpr int IndexForProto(int P) { return P % PROTOS_PER_PROTO_SET; }
+inline constexpr INT_PROTO_STRUCT *ProtoForProtoId(INT_CLASS_STRUCT *C, int P) {
+ return &(C->ProtoSets[SetForProto(P)]->Protos[IndexForProto(P)]);
+}
+inline constexpr int PPrunerWordIndexFor(int I) { return (I % PROTOS_PER_PROTO_SET) / PROTOS_PER_PP_WERD; }
+inline constexpr int PPrunerBitIndexFor(int I) { return I % PROTOS_PER_PP_WERD; }
+inline constexpr uint32_t PPrunerMaskFor(int I) { return 1u << PPrunerBitIndexFor(I); }
+
+inline constexpr int MaxNumClassesIn(const INT_TEMPLATES_STRUCT *T) { return T->NumClassPruners * CLASSES_PER_CP; }
+inline constexpr bool LegalClassId(int c) { return c >= 0 && c < MAX_NUM_CLASSES; }
+inline constexpr bool UnusedClassIdIn(INT_TEMPLATES_STRUCT *T, int c) { return T->Class[c] == nullptr; }
+inline constexpr INT_CLASS_STRUCT *&ClassForClassId(INT_TEMPLATES_STRUCT *T, int c) { return T->Class[c]; }
+
+inline constexpr int CPrunerIdFor(int c) { return c / CLASSES_PER_CP; }
+inline constexpr CLASS_PRUNER_STRUCT *CPrunerFor(INT_TEMPLATES_STRUCT *T, int c) {
+ return T->ClassPruners[CPrunerIdFor(c)];
+}
+inline constexpr int CPrunerWordIndexFor(int c) { return (c % CLASSES_PER_CP) / CLASSES_PER_CP_WERD; }
+inline constexpr int CPrunerBitIndexFor(int c) { return (c % CLASSES_PER_CP) % CLASSES_PER_CP_WERD; }
+inline constexpr uint32_t CPrunerMaskFor(int L, int c) {
+ return (static_cast<uint32_t>(L) + 1) << (CPrunerBitIndexFor(c) * NUM_BITS_PER_CLASS);
+}
+
+/* DEBUG constants */
+constexpr int PRINT_MATCH_SUMMARY = 0x001;
+constexpr int DISPLAY_FEATURE_MATCHES = 0x002;
+constexpr int DISPLAY_PROTO_MATCHES = 0x004;
+constexpr int PRINT_FEATURE_MATCHES = 0x008;
+constexpr int PRINT_PROTO_MATCHES = 0x010;
+constexpr int CLIP_MATCH_EVIDENCE = 0x020;
+
+inline constexpr int MatchDebuggingOn(int D) { return D; }
+inline constexpr bool PrintMatchSummaryOn(int D) { return (D & PRINT_MATCH_SUMMARY) != 0; }
+inline constexpr bool DisplayFeatureMatchesOn(int D) { return (D & DISPLAY_FEATURE_MATCHES) != 0; }
+inline constexpr bool DisplayProtoMatchesOn(int D) { return (D & DISPLAY_PROTO_MATCHES) != 0; }
+inline constexpr bool PrintFeatureMatchesOn(int D) { return (D & PRINT_FEATURE_MATCHES) != 0; }
+inline constexpr bool PrintProtoMatchesOn(int D) { return (D & PRINT_PROTO_MATCHES) != 0; }
+inline constexpr bool ClipMatchEvidenceOn(int D) { return (D & CLIP_MATCH_EVIDENCE) != 0; }
/**----------------------------------------------------------------------------
Public Function Prototypes
diff --git a/src/classify/mfoutline.h b/src/classify/mfoutline.h
index dece79ef..3aa318e7 100644
--- a/src/classify/mfoutline.h
+++ b/src/classify/mfoutline.h
@@ -55,10 +55,13 @@ enum NORM_METHOD { baseline, character };
/**----------------------------------------------------------------------------
Macros
----------------------------------------------------------------------------**/
-#define AverageOf(A, B) (((A) + (B)) / 2)
+template <typename T>
+inline constexpr T AverageOf(T A, T B) {
+ return (A + B) / T{2};
+}
// Constant for computing the scale factor to use to normalize characters.
-const float MF_SCALE_FACTOR = 0.5f / kBlnXHeight;
+constexpr float MF_SCALE_FACTOR = 0.5f / kBlnXHeight;
// Inline functions for manipulating micro-feature outlines.
diff --git a/src/classify/normfeat.h b/src/classify/normfeat.h
index 05f0ae8b..0b9b1867 100644
--- a/src/classify/normfeat.h
+++ b/src/classify/normfeat.h
@@ -23,7 +23,7 @@
namespace tesseract {
-#define LENGTH_COMPRESSION (10.0)
+constexpr double LENGTH_COMPRESSION = 10.0;
struct INT_FX_RESULT_STRUCT;
diff --git a/src/classify/ocrfeatures.h b/src/classify/ocrfeatures.h
index e9aa4d5e..a22b6f4b 100644
--- a/src/classify/ocrfeatures.h
+++ b/src/classify/ocrfeatures.h
@@ -29,7 +29,7 @@ class DENORM;
#undef Min
#undef Max
-#define FEAT_NAME_SIZE 80
+constexpr int FEAT_NAME_SIZE = 80;
// A character is described by multiple sets of extracted features. Each
// set contains a number of features of a particular type, for example, a
diff --git a/src/classify/picofeat.h b/src/classify/picofeat.h
index 391aaa2f..443a7109 100644
--- a/src/classify/picofeat.h
+++ b/src/classify/picofeat.h
@@ -51,14 +51,14 @@ typedef enum { PicoFeatY, PicoFeatDir, PicoFeatX } PICO_FEAT_PARAM_NAME;
extern double_VAR_H(classify_pico_feature_length);
/**----------------------------------------------------------------------------
- Public Function Prototypes
+ Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
-#define GetPicoFeatureLength() (PicoFeatureLength)
+extern TESS_API float PicoFeatureLength;
/**----------------------------------------------------------------------------
- Global Data Definitions and Declarations
+ Public Function Prototypes
----------------------------------------------------------------------------**/
-extern TESS_API float PicoFeatureLength;
+inline float GetPicoFeatureLength() { return PicoFeatureLength; }
} // namespace tesseract
diff --git a/src/dict/matchdefs.h b/src/dict/matchdefs.h
index 2228968f..3e5aeac8 100644
--- a/src/dict/matchdefs.h
+++ b/src/dict/matchdefs.h
@@ -28,17 +28,17 @@ namespace tesseract {
/* define the maximum number of classes defined for any matcher
and the maximum class id for any matcher. This must be changed
if more different classes need to be classified */
-#define MAX_NUM_CLASSES INT16_MAX
+constexpr int MAX_NUM_CLASSES = INT16_MAX;
/** a CLASS_ID is the ascii character to be associated with a class */
using CLASS_ID = UNICHAR_ID;
-#define NO_CLASS (0)
+constexpr CLASS_ID NO_CLASS = 0;
/** a PROTO_ID is the index of a prototype within it's class. Valid proto
id's are 0 to N-1 where N is the number of prototypes that make up the
class. */
using PROTO_ID = int16_t;
-#define NO_PROTO (-1)
+constexpr PROTO_ID NO_PROTO = -1;
/** FEATURE_ID is the index of a feature within a character description
The feature id ranges from 0 to N-1 where N is the number
diff --git a/src/wordrec/outlines.h b/src/wordrec/outlines.h
index c099d7e6..1d8afef0 100644
--- a/src/wordrec/outlines.h
+++ b/src/wordrec/outlines.h
@@ -28,9 +28,9 @@
/*----------------------------------------------------------------------
C o n s t a n t s
----------------------------------------------------------------------*/
-#define LARGE_DISTANCE 100000 /* Used for closest dist */
-#define MIN_BLOB_SIZE 10 /* Big units */
-#define MAX_ASPECT_RATIO 2.5 /* Widest character */
+constexpr int LARGE_DISTANCE = 100000; /* Used for closest dist */
+constexpr int MIN_BLOB_SIZE = 10; /* Big units */
+constexpr double MAX_ASPECT_RATIO = 2.5; /* Widest character */
/*----------------------------------------------------------------------
M a c r o s
@@ -51,7 +51,10 @@
* parameters must be of type POINT.
**********************************************************************/
-#define dist_square(p1, p2) ((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y))
+template <typename Point>
+inline constexpr auto dist_square(const Point &p1, const Point &p2) {
+ return (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
+}
/**********************************************************************
* closest
@@ -60,10 +63,12 @@
* question. All three parameters must be of type EDGEPT.
**********************************************************************/
-#define closest(test_p, p1, p2) \
- (p1 ? (p2 ? ((dist_square(test_p->pos, p1->pos) < dist_square(test_p->pos, p2->pos)) ? p1 : p2) \
- : p1) \
- : p2)
+template <typename Edgept>
+inline Edgept *closest(Edgept *test_p, Edgept *p1, Edgept *p2) {
+ if (!p1) return p2;
+ if (!p2) return p1;
+ return dist_square(test_p->pos, p1->pos) < dist_square(test_p->pos, p2->pos) ? p1 : p2;
+}
/**********************************************************************
* edgept_dist
@@ -71,7 +76,10 @@
* Return the distance (squared) between the two edge points.
**********************************************************************/
-#define edgept_dist(p1, p2) (dist_square((p1)->pos, (p2)->pos))
+template <typename Edgept>
+inline constexpr auto edgept_dist(const Edgept *p1, const Edgept *p2) {
+ return dist_square(p1->pos, p2->pos);
+}
/**********************************************************************
* is_exterior_point
@@ -90,7 +98,10 @@
* Return true if the POINTs are equal.
**********************************************************************/
-#define is_equal(p1, p2) (((p1).x == (p2).x) && ((p1).y == (p2).y))
+template <typename Point>
+inline constexpr bool is_equal(const Point &p1, const Point &p2) {
+ return p1.x == p2.x && p1.y == p2.y;
+}
/**********************************************************************
* is_on_line
@@ -100,16 +111,14 @@
* parameters must be of type POINT.
**********************************************************************/
-#define is_on_line(p, p0, p1) \
- (within_range((p).x, (p0).x, (p1).x) && within_range((p).y, (p0).y, (p1).y))
+template <typename T>
+inline constexpr bool within_range(T x, T x0, T x1) {
+ return (x0 <= x && x <= x1) || (x1 <= x && x <= x0);
+}
-/**********************************************************************
- * within_range
- *
- * Return true if the first number is in between the second two numbers.
- * Return false otherwise.
- **********************************************************************/
-
-#define within_range(x, x0, x1) (((x0 <= x) && (x <= x1)) || ((x1 <= x) && (x <= x0)))
+template <typename Point>
+inline constexpr bool is_on_line(const Point &p, const Point &p0, const Point &p1) {
+ return within_range(p.x, p0.x, p1.x) && within_range(p.y, p0.y, p1.y);
+}
#endif