tesseract  5.0.0
helpers.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * File: helpers.h
4  * Description: General utility functions
5  * Author: Daria Antonova
6  *
7  * (c) Copyright 2009, Google Inc.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  *****************************************************************************/
19 
20 #ifndef TESSERACT_CCUTIL_HELPERS_H_
21 #define TESSERACT_CCUTIL_HELPERS_H_
22 
23 #include <cassert>
24 #include <climits> // for INT_MIN, INT_MAX
25 #include <cmath> // std::isfinite
26 #include <cstdio>
27 #include <cstring>
28 #include <algorithm> // for std::find
29 #include <functional>
30 #include <random>
31 #include <string>
32 #include <vector>
33 
34 namespace tesseract {
35 
36 template <class T>
37 inline bool contains(const std::vector<T> &data, const T &value) {
38  return std::find(data.begin(), data.end(), value) != data.end();
39 }
40 
41 inline const std::vector<std::string> split(const std::string &s, char c) {
42  std::string buff;
43  std::vector<std::string> v;
44  for (auto n : s) {
45  if (n != c) {
46  buff += n;
47  } else if (n == c && !buff.empty()) {
48  v.push_back(buff);
49  buff.clear();
50  }
51  }
52  if (!buff.empty()) {
53  v.push_back(buff);
54  }
55  return v;
56 }
57 
58 // A simple linear congruential random number generator.
59 class TRand {
60 public:
61  // Sets the seed to the given value.
62  void set_seed(uint64_t seed) {
63  e.seed(seed);
64  }
65  // Sets the seed using a hash of a string.
66  void set_seed(const std::string &str) {
67  std::hash<std::string> hasher;
68  set_seed(static_cast<uint64_t>(hasher(str)));
69  }
70 
71  // Returns an integer in the range 0 to INT32_MAX.
72  int32_t IntRand() {
73  return e();
74  }
75  // Returns a floating point value in the range [-range, range].
76  double SignedRand(double range) {
77  return range * 2.0 * IntRand() / INT32_MAX - range;
78  }
79  // Returns a floating point value in the range [0, range].
80  double UnsignedRand(double range) {
81  return range * IntRand() / INT32_MAX;
82  }
83 
84 private:
85  std::minstd_rand e;
86 };
87 
88 // Remove newline (if any) at the end of the string.
89 inline void chomp_string(char *str) {
90  int last_index = static_cast<int>(strlen(str)) - 1;
91  while (last_index >= 0 && (str[last_index] == '\n' || str[last_index] == '\r')) {
92  str[last_index--] = '\0';
93  }
94 }
95 
96 // Advance the current pointer of the file if it points to a newline character.
97 inline void SkipNewline(FILE *file) {
98  if (fgetc(file) != '\n') {
99  fseek(file, -1, SEEK_CUR);
100  }
101 }
102 
103 // return the smallest multiple of block_size greater than or equal to n.
104 inline int RoundUp(int n, int block_size) {
105  return block_size * ((n + block_size - 1) / block_size);
106 }
107 
108 // Clip a numeric value to the interval [lower_bound, upper_bound].
109 template <typename T>
110 inline T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound) {
111  if (x < lower_bound) {
112  return lower_bound;
113  }
114  if (x > upper_bound) {
115  return upper_bound;
116  }
117  return x;
118 }
119 
120 // Extend the range [lower_bound, upper_bound] to include x.
121 template <typename T1, typename T2>
122 inline void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound) {
123  if (x < *lower_bound) {
124  *lower_bound = x;
125  }
126  if (x > *upper_bound) {
127  *upper_bound = x;
128  }
129 }
130 
131 // Decrease lower_bound to be <= x_lo AND increase upper_bound to be >= x_hi.
132 template <typename T1, typename T2>
133 inline void UpdateRange(const T1 &x_lo, const T1 &x_hi, T2 *lower_bound, T2 *upper_bound) {
134  if (x_lo < *lower_bound) {
135  *lower_bound = x_lo;
136  }
137  if (x_hi > *upper_bound) {
138  *upper_bound = x_hi;
139  }
140 }
141 
142 // Intersect the range [*lower2, *upper2] with the range [lower1, upper1],
143 // putting the result back in [*lower2, *upper2].
144 // If non-intersecting ranges are given, we end up with *lower2 > *upper2.
145 template <typename T>
146 inline void IntersectRange(const T &lower1, const T &upper1, T *lower2, 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.
158 inline 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.
167 inline 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.
175 inline int IntCastRounded(double x) {
176  assert(std::isfinite(x));
177  assert(x < INT_MAX);
178  assert(x > INT_MIN);
179  return x >= 0.0 ? static_cast<int>(x + 0.5) : -static_cast<int>(-x + 0.5);
180 }
181 
182 // Return a float cast to int with rounding.
183 inline int IntCastRounded(float x) {
184  assert(std::isfinite(x));
185  return x >= 0.0F ? static_cast<int>(x + 0.5F) : -static_cast<int>(-x + 0.5F);
186 }
187 
188 // Reverse the order of bytes in a n byte quantity for big/little-endian switch.
189 inline void ReverseN(void *ptr, int num_bytes) {
190  assert(num_bytes == 1 || num_bytes == 2 || num_bytes == 4 || num_bytes == 8);
191  char *cptr = static_cast<char *>(ptr);
192  int halfsize = num_bytes / 2;
193  for (int i = 0; i < halfsize; ++i) {
194  char tmp = cptr[i];
195  cptr[i] = cptr[num_bytes - 1 - i];
196  cptr[num_bytes - 1 - i] = tmp;
197  }
198 }
199 
200 // Reverse the order of bytes in a 16 bit quantity for big/little-endian switch.
201 inline void Reverse16(void *ptr) {
202  ReverseN(ptr, 2);
203 }
204 
205 // Reverse the order of bytes in a 32 bit quantity for big/little-endian switch.
206 inline void Reverse32(void *ptr) {
207  ReverseN(ptr, 4);
208 }
209 
210 // Reverse the order of bytes in a 64 bit quantity for big/little-endian switch.
211 inline void Reverse64(void *ptr) {
212  ReverseN(ptr, 8);
213 }
214 
215 // Reads a vector of simple types from the given file. Assumes that bitwise
216 // read/write will work with ReverseN according to sizeof(T).
217 // Returns false in case of error.
218 // If swap is true, assumes a big/little-endian swap is needed.
219 template <typename T>
220 bool DeSerialize(bool swap, FILE *fp, std::vector<T> &data) {
221  uint32_t size;
222  if (fread(&size, sizeof(size), 1, fp) != 1) {
223  return false;
224  }
225  if (swap) {
226  Reverse32(&size);
227  }
228  // Arbitrarily limit the number of elements to protect against bad data.
229  assert(size <= UINT16_MAX);
230  if (size > UINT16_MAX) {
231  return false;
232  }
233  // TODO: optimize.
234  data.resize(size);
235  if (size > 0) {
236  if (fread(&data[0], sizeof(T), size, fp) != size) {
237  return false;
238  }
239  if (swap) {
240  for (uint32_t i = 0; i < size; ++i) {
241  ReverseN(&data[i], sizeof(T));
242  }
243  }
244  }
245  return true;
246 }
247 
248 // Writes a vector of simple types to the given file. Assumes that bitwise
249 // read/write of T will work. Returns false in case of error.
250 template <typename T>
251 bool Serialize(FILE *fp, const std::vector<T> &data) {
252  uint32_t size = data.size();
253  if (fwrite(&size, sizeof(size), 1, fp) != 1) {
254  return false;
255  } else if constexpr (std::is_class<T>::value) {
256  // Serialize a tesseract class.
257  for (auto &item : data) {
258  if (!item.Serialize(fp)) {
259  return false;
260  }
261  }
262  } else if (size > 0) {
263  if (fwrite(&data[0], sizeof(T), size, fp) != size) {
264  return false;
265  }
266  }
267  return true;
268 }
269 
270 } // namespace tesseract
271 
272 #endif // TESSERACT_CCUTIL_HELPERS_H_
@ T1
Definition: rune.c:27
@ T2
Definition: rune.c:29
const std::vector< std::string > split(const std::string &s, char c)
Definition: helpers.h:41
void ReverseN(void *ptr, int num_bytes)
Definition: helpers.h:189
void Reverse64(void *ptr)
Definition: helpers.h:211
int IntCastRounded(double x)
Definition: helpers.h:175
int DivRounded(int a, int b)
Definition: helpers.h:167
bool DeSerialize(bool swap, FILE *fp, std::vector< T > &data)
Definition: helpers.h:220
void chomp_string(char *str)
Definition: helpers.h:89
bool Serialize(FILE *fp, const std::vector< T > &data)
Definition: helpers.h:251
int RoundUp(int n, int block_size)
Definition: helpers.h:104
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:110
void Reverse16(void *ptr)
Definition: helpers.h:201
void IntersectRange(const T &lower1, const T &upper1, T *lower2, T *upper2)
Definition: helpers.h:146
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:122
void Reverse32(void *ptr)
Definition: helpers.h:206
bool contains(const std::vector< T > &data, const T &value)
Definition: helpers.h:37
int Modulo(int a, int b)
Definition: helpers.h:158
void SkipNewline(FILE *file)
Definition: helpers.h:97
void set_seed(const std::string &str)
Definition: helpers.h:66
double SignedRand(double range)
Definition: helpers.h:76
int32_t IntRand()
Definition: helpers.h:72
double UnsignedRand(double range)
Definition: helpers.h:80
void set_seed(uint64_t seed)
Definition: helpers.h:62