helpers.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. #ifndef TESSERACT_CCUTIL_HELPERS_H_
  21. #define TESSERACT_CCUTIL_HELPERS_H_
  22. #include <cassert>
  23. #include <cstdio>
  24. #include <cstring>
  25. #include <functional>
  26. #include <string>
  27. // TODO(rays) Put the rest of the helpers in the namespace.
  28. namespace tesseract {
  29. // A simple linear congruential random number generator, using Knuth's
  30. // constants from:
  31. // http://en.wikipedia.org/wiki/Linear_congruential_generator.
  32. class TRand {
  33. public:
  34. TRand() = default;
  35. // Sets the seed to the given value.
  36. void set_seed(uint64_t seed) {
  37. seed_ = seed;
  38. }
  39. // Sets the seed using a hash of a string.
  40. void set_seed(const std::string& str) {
  41. std::hash<std::string> hasher;
  42. set_seed(static_cast<uint64_t>(hasher(str)));
  43. }
  44. // Returns an integer in the range 0 to INT32_MAX.
  45. int32_t IntRand() {
  46. Iterate();
  47. return seed_ >> 33;
  48. }
  49. // Returns a floating point value in the range [-range, range].
  50. double SignedRand(double range) {
  51. return range * 2.0 * IntRand() / INT32_MAX - range;
  52. }
  53. // Returns a floating point value in the range [0, range].
  54. double UnsignedRand(double range) {
  55. return range * IntRand() / INT32_MAX;
  56. }
  57. private:
  58. // Steps the generator to the next value.
  59. void Iterate() {
  60. seed_ *= 6364136223846793005ULL;
  61. seed_ += 1442695040888963407ULL;
  62. }
  63. // The current value of the seed.
  64. uint64_t seed_{1};
  65. };
  66. } // namespace tesseract
  67. // Remove newline (if any) at the end of the string.
  68. inline void chomp_string(char* str) {
  69. int last_index = static_cast<int>(strlen(str)) - 1;
  70. while (last_index >= 0 &&
  71. (str[last_index] == '\n' || str[last_index] == '\r')) {
  72. str[last_index--] = '\0';
  73. }
  74. }
  75. // Advance the current pointer of the file if it points to a newline character.
  76. inline void SkipNewline(FILE* file) {
  77. if (fgetc(file) != '\n') {
  78. fseek(file, -1, SEEK_CUR);
  79. }
  80. }
  81. // Swaps the two args pointed to by the pointers.
  82. // Operator= and copy constructor must work on T.
  83. template <typename T>
  84. inline void Swap(T* p1, T* p2) {
  85. T tmp(*p2);
  86. *p2 = *p1;
  87. *p1 = tmp;
  88. }
  89. // return the smallest multiple of block_size greater than or equal to n.
  90. inline int RoundUp(int n, int block_size) {
  91. return block_size * ((n + block_size - 1) / block_size);
  92. }
  93. // Clip a numeric value to the interval [lower_bound, upper_bound].
  94. template <typename T>
  95. inline T ClipToRange(const T& x, const T& lower_bound, const T& upper_bound) {
  96. if (x < lower_bound) {
  97. return lower_bound;
  98. }
  99. if (x > upper_bound) {
  100. return upper_bound;
  101. }
  102. return x;
  103. }
  104. // Extend the range [lower_bound, upper_bound] to include x.
  105. template <typename T1, typename T2>
  106. inline void UpdateRange(const T1& x, T2* lower_bound, T2* upper_bound) {
  107. if (x < *lower_bound) {
  108. *lower_bound = x;
  109. }
  110. if (x > *upper_bound) {
  111. *upper_bound = x;
  112. }
  113. }
  114. // Decrease lower_bound to be <= x_lo AND increase upper_bound to be >= x_hi.
  115. template <typename T1, typename T2>
  116. inline void UpdateRange(const T1& x_lo, const T1& x_hi, T2* lower_bound,
  117. T2* upper_bound) {
  118. if (x_lo < *lower_bound) {
  119. *lower_bound = x_lo;
  120. }
  121. if (x_hi > *upper_bound) {
  122. *upper_bound = x_hi;
  123. }
  124. }
  125. // Intersect the range [*lower2, *upper2] with the range [lower1, upper1],
  126. // putting the result back in [*lower2, *upper2].
  127. // If non-intersecting ranges are given, we end up with *lower2 > *upper2.
  128. template <typename T>
  129. inline void IntersectRange(const T& lower1, const T& upper1, T* lower2,
  130. T* upper2) {
  131. if (lower1 > *lower2) {
  132. *lower2 = lower1;
  133. }
  134. if (upper1 < *upper2) {
  135. *upper2 = upper1;
  136. }
  137. }
  138. // Proper modulo arithmetic operator. Returns a mod b that works for -ve a.
  139. // For any integer a and positive b, returns r : 0<=r<b and a=n*b + r for
  140. // some integer n.
  141. inline int Modulo(int a, int b) {
  142. return (a % b + b) % b;
  143. }
  144. // Integer division operator with rounding that works for negative input.
  145. // Returns a divided by b, rounded to the nearest integer, without double
  146. // counting at 0. With simple rounding 1/3 = 0, 0/3 = 0 -1/3 = 0, -2/3 = 0,
  147. // -3/3 = 0 and -4/3 = -1.
  148. // I want 1/3 = 0, 0/3 = 0, -1/3 = 0, -2/3 = -1, -3/3 = -1 and -4/3 = -1.
  149. inline int DivRounded(int a, int b) {
  150. if (b < 0) {
  151. return -DivRounded(a, -b);
  152. }
  153. return a >= 0 ? (a + b / 2) / b : (a - b / 2) / b;
  154. }
  155. // Return a double cast to int with rounding.
  156. inline int IntCastRounded(double x) {
  157. return x >= 0.0 ? static_cast<int>(x + 0.5) : -static_cast<int>(-x + 0.5);
  158. }
  159. // Return a float cast to int with rounding.
  160. inline int IntCastRounded(float x) {
  161. return x >= 0.0F ? static_cast<int>(x + 0.5F) : -static_cast<int>(-x + 0.5F);
  162. }
  163. // Reverse the order of bytes in a n byte quantity for big/little-endian switch.
  164. inline void ReverseN(void* ptr, int num_bytes) {
  165. assert(num_bytes == 1 || num_bytes == 2 || num_bytes == 4 || num_bytes == 8);
  166. char* cptr = static_cast<char*>(ptr);
  167. int halfsize = num_bytes / 2;
  168. for (int i = 0; i < halfsize; ++i) {
  169. char tmp = cptr[i];
  170. cptr[i] = cptr[num_bytes - 1 - i];
  171. cptr[num_bytes - 1 - i] = tmp;
  172. }
  173. }
  174. // Reverse the order of bytes in a 16 bit quantity for big/little-endian switch.
  175. inline void Reverse16(void* ptr) {
  176. ReverseN(ptr, 2);
  177. }
  178. // Reverse the order of bytes in a 32 bit quantity for big/little-endian switch.
  179. inline void Reverse32(void* ptr) {
  180. ReverseN(ptr, 4);
  181. }
  182. // Reverse the order of bytes in a 64 bit quantity for big/little-endian switch.
  183. inline void Reverse64(void* ptr) {
  184. ReverseN(ptr, 8);
  185. }
  186. #endif // TESSERACT_CCUTIL_HELPERS_H_