tesseract 4.1.1
Loading...
Searching...
No Matches
helpers.h
Go to the documentation of this file.
1/* -*-C-*-
2 ********************************************************************************
3 *
4 * File: helpers.h
5 * Description: General utility functions
6 * Author: Daria Antonova
7 *
8 * (c) Copyright 2009, Google Inc.
9 ** Licensed under the Apache License, Version 2.0 (the "License");
10 ** you may not use this file except in compliance with the License.
11 ** You may obtain a copy of the License at
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 ** Unless required by applicable law or agreed to in writing, software
14 ** distributed under the License is distributed on an "AS IS" BASIS,
15 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 ** See the License for the specific language governing permissions and
17 ** limitations under the License.
18 *
19 ********************************************************************************/
20
21#ifndef TESSERACT_CCUTIL_HELPERS_H_
22#define TESSERACT_CCUTIL_HELPERS_H_
23
24#include <cassert>
25#include <cstdio>
26#include <cstring>
27#include <functional>
28#include <string>
29
30// TODO(rays) Put the rest of the helpers in the namespace.
31namespace tesseract {
32
33// A simple linear congruential random number generator, using Knuth's
34// constants from:
35// http://en.wikipedia.org/wiki/Linear_congruential_generator.
36class TRand {
37 public:
38 TRand() = default;
39 // Sets the seed to the given value.
40 void set_seed(uint64_t seed) {
41 seed_ = seed;
42 }
43 // Sets the seed using a hash of a string.
44 void set_seed(const std::string& str) {
45 std::hash<std::string> hasher;
46 set_seed(static_cast<uint64_t>(hasher(str)));
47 }
48
49 // Returns an integer in the range 0 to INT32_MAX.
50 int32_t IntRand() {
51 Iterate();
52 return seed_ >> 33;
53 }
54 // Returns a floating point value in the range [-range, range].
55 double SignedRand(double range) {
56 return range * 2.0 * IntRand() / INT32_MAX - range;
57 }
58 // Returns a floating point value in the range [0, range].
59 double UnsignedRand(double range) {
60 return range * IntRand() / INT32_MAX;
61 }
62
63 private:
64 // Steps the generator to the next value.
65 void Iterate() {
66 seed_ *= 6364136223846793005ULL;
67 seed_ += 1442695040888963407ULL;
68 }
69
70 // The current value of the seed.
71 uint64_t seed_{1};
72};
73
74} // namespace tesseract
75
76// Remove newline (if any) at the end of the string.
77inline void chomp_string(char* str) {
78 int last_index = static_cast<int>(strlen(str)) - 1;
79 while (last_index >= 0 &&
80 (str[last_index] == '\n' || str[last_index] == '\r')) {
81 str[last_index--] = '\0';
82 }
83}
84
85// Advance the current pointer of the file if it points to a newline character.
86inline void SkipNewline(FILE* file) {
87 if (fgetc(file) != '\n') {
88 fseek(file, -1, SEEK_CUR);
89 }
90}
91
92// Swaps the two args pointed to by the pointers.
93// Operator= and copy constructor must work on T.
94template <typename T>
95inline void Swap(T* p1, T* p2) {
96 T tmp(*p2);
97 *p2 = *p1;
98 *p1 = tmp;
99}
100
101// return the smallest multiple of block_size greater than or equal to n.
102inline int RoundUp(int n, int block_size) {
103 return block_size * ((n + block_size - 1) / block_size);
104}
105
106// Clip a numeric value to the interval [lower_bound, upper_bound].
107template <typename T>
108inline T ClipToRange(const T& x, const T& lower_bound, const T& upper_bound) {
109 if (x < lower_bound) {
110 return lower_bound;
111 }
112 if (x > upper_bound) {
113 return upper_bound;
114 }
115 return x;
116}
117
118// Extend the range [lower_bound, upper_bound] to include x.
119template <typename T1, typename T2>
120inline void UpdateRange(const T1& x, T2* lower_bound, T2* upper_bound) {
121 if (x < *lower_bound) {
122 *lower_bound = x;
123 }
124 if (x > *upper_bound) {
125 *upper_bound = x;
126 }
127}
128
129// Decrease lower_bound to be <= x_lo AND increase upper_bound to be >= x_hi.
130template <typename T1, typename T2>
131inline void UpdateRange(const T1& x_lo, const T1& x_hi, T2* lower_bound,
132 T2* upper_bound) {
133 if (x_lo < *lower_bound) {
134 *lower_bound = x_lo;
135 }
136 if (x_hi > *upper_bound) {
137 *upper_bound = x_hi;
138 }
139}
140
141// Intersect the range [*lower2, *upper2] with the range [lower1, upper1],
142// putting the result back in [*lower2, *upper2].
143// If non-intersecting ranges are given, we end up with *lower2 > *upper2.
144template <typename T>
145inline void IntersectRange(const T& lower1, const T& upper1, T* lower2,
146 T* upper2) {
147 if (lower1 > *lower2) {
148 *lower2 = lower1;
149 }
150 if (upper1 < *upper2) {
151 *upper2 = upper1;
152 }
153}
154
155// Proper modulo arithmetic operator. Returns a mod b that works for -ve a.
156// For any integer a and positive b, returns r : 0<=r<b and a=n*b + r for
157// some integer n.
158inline int Modulo(int a, int b) {
159 return (a % b + b) % b;
160}
161
162// Integer division operator with rounding that works for negative input.
163// Returns a divided by b, rounded to the nearest integer, without double
164// counting at 0. With simple rounding 1/3 = 0, 0/3 = 0 -1/3 = 0, -2/3 = 0,
165// -3/3 = 0 and -4/3 = -1.
166// I want 1/3 = 0, 0/3 = 0, -1/3 = 0, -2/3 = -1, -3/3 = -1 and -4/3 = -1.
167inline int DivRounded(int a, int b) {
168 if (b < 0) {
169 return -DivRounded(a, -b);
170 }
171 return a >= 0 ? (a + b / 2) / b : (a - b / 2) / b;
172}
173
174// Return a double cast to int with rounding.
175inline int IntCastRounded(double x) {
176 return x >= 0.0 ? static_cast<int>(x + 0.5) : -static_cast<int>(-x + 0.5);
177}
178
179// Return a float cast to int with rounding.
180inline int IntCastRounded(float x) {
181 return x >= 0.0F ? static_cast<int>(x + 0.5F) : -static_cast<int>(-x + 0.5F);
182}
183
184// Reverse the order of bytes in a n byte quantity for big/little-endian switch.
185inline void ReverseN(void* ptr, int num_bytes) {
186 assert(num_bytes == 1 || num_bytes == 2 || num_bytes == 4 || num_bytes == 8);
187 char* cptr = static_cast<char*>(ptr);
188 int halfsize = num_bytes / 2;
189 for (int i = 0; i < halfsize; ++i) {
190 char tmp = cptr[i];
191 cptr[i] = cptr[num_bytes - 1 - i];
192 cptr[num_bytes - 1 - i] = tmp;
193 }
194}
195
196// Reverse the order of bytes in a 16 bit quantity for big/little-endian switch.
197inline void Reverse16(void* ptr) {
198 ReverseN(ptr, 2);
199}
200
201// Reverse the order of bytes in a 32 bit quantity for big/little-endian switch.
202inline void Reverse32(void* ptr) {
203 ReverseN(ptr, 4);
204}
205
206// Reverse the order of bytes in a 64 bit quantity for big/little-endian switch.
207inline void Reverse64(void* ptr) {
208 ReverseN(ptr, 8);
209}
210
211#endif // TESSERACT_CCUTIL_HELPERS_H_
void Reverse64(void *ptr)
Definition: helpers.h:207
int DivRounded(int a, int b)
Definition: helpers.h:167
void SkipNewline(FILE *file)
Definition: helpers.h:86
void chomp_string(char *str)
Definition: helpers.h:77
void Reverse16(void *ptr)
Definition: helpers.h:197
int Modulo(int a, int b)
Definition: helpers.h:158
void IntersectRange(const T &lower1, const T &upper1, T *lower2, T *upper2)
Definition: helpers.h:145
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:120
void Reverse32(void *ptr)
Definition: helpers.h:202
int IntCastRounded(double x)
Definition: helpers.h:175
void ReverseN(void *ptr, int num_bytes)
Definition: helpers.h:185
void Swap(T *p1, T *p2)
Definition: helpers.h:95
int RoundUp(int n, int block_size)
Definition: helpers.h:102
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:108
void set_seed(const std::string &str)
Definition: helpers.h:44
double SignedRand(double range)
Definition: helpers.h:55
int32_t IntRand()
Definition: helpers.h:50
double UnsignedRand(double range)
Definition: helpers.h:59
void set_seed(uint64_t seed)
Definition: helpers.h:40