|
tesseract 3.04.01
|
00001 /* -*-C-*- 00002 ******************************************************************************** 00003 * 00004 * File: helpers.h 00005 * Description: General utility functions 00006 * Author: Daria Antonova 00007 * Created: Wed Apr 8 14:37:00 2009 00008 * Language: C++ 00009 * Package: N/A 00010 * Status: Reusable Software Component 00011 * 00012 * (c) Copyright 2009, Google Inc. 00013 ** Licensed under the Apache License, Version 2.0 (the "License"); 00014 ** you may not use this file except in compliance with the License. 00015 ** You may obtain a copy of the License at 00016 ** http://www.apache.org/licenses/LICENSE-2.0 00017 ** Unless required by applicable law or agreed to in writing, software 00018 ** distributed under the License is distributed on an "AS IS" BASIS, 00019 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 ** See the License for the specific language governing permissions and 00021 ** limitations under the License. 00022 * 00023 ********************************************************************************/ 00024 00025 #ifndef TESSERACT_CCUTIL_HELPERS_H_ 00026 #define TESSERACT_CCUTIL_HELPERS_H_ 00027 00028 #include <stdio.h> 00029 #include <string.h> 00030 00031 #include "host.h" 00032 00033 // TODO(rays) Put the rest of the helpers in the namespace. 00034 namespace tesseract { 00035 00036 // A simple linear congruential random number generator, using Knuth's 00037 // constants from: 00038 // http://en.wikipedia.org/wiki/Linear_congruential_generator. 00039 class TRand { 00040 public: 00041 TRand() : seed_(1) {} 00042 // Sets the seed to the given value. 00043 void set_seed(uinT64 seed) { 00044 seed_ = seed; 00045 } 00046 00047 // Returns an integer in the range 0 to MAX_INT32. 00048 inT32 IntRand() { 00049 Iterate(); 00050 return seed_ >> 33; 00051 } 00052 // Returns a floating point value in the range [-range, range]. 00053 double SignedRand(double range) { 00054 return range * 2.0 * IntRand() / MAX_INT32 - range; 00055 } 00056 // Returns a floating point value in the range [0, range]. 00057 double UnsignedRand(double range) { 00058 return range * IntRand() / MAX_INT32; 00059 } 00060 00061 private: 00062 // Steps the generator to the next value. 00063 void Iterate() { 00064 seed_ *= 6364136223846793005ULL; 00065 seed_ += 1442695040888963407ULL; 00066 } 00067 00068 // The current value of the seed. 00069 uinT64 seed_; 00070 }; 00071 00072 } // namespace tesseract 00073 00074 // Remove newline (if any) at the end of the string. 00075 inline void chomp_string(char *str) { 00076 int last_index = (int)strlen(str) - 1; 00077 while (last_index >= 0 && 00078 (str[last_index] == '\n' || str[last_index] == '\r')) { 00079 str[last_index--] = '\0'; 00080 } 00081 } 00082 00083 // Advance the current pointer of the file if it points to a newline character. 00084 inline void SkipNewline(FILE *file) { 00085 if (fgetc(file) != '\n') fseek(file, -1, SEEK_CUR); 00086 } 00087 00088 // Swaps the two args pointed to by the pointers. 00089 // Operator= and copy constructor must work on T. 00090 template<typename T> inline void Swap(T* p1, T* p2) { 00091 T tmp(*p2); 00092 *p2 = *p1; 00093 *p1 = tmp; 00094 } 00095 00096 // qsort function to sort 2 floats. 00097 inline int sort_floats(const void *arg1, const void *arg2) { 00098 float diff = *((float *) arg1) - *((float *) arg2); 00099 if (diff > 0) { 00100 return 1; 00101 } else if (diff < 0) { 00102 return -1; 00103 } else { 00104 return 0; 00105 } 00106 } 00107 00108 // return the smallest multiple of block_size greater than or equal to n. 00109 inline int RoundUp(int n, int block_size) { 00110 return block_size * ((n + block_size - 1) / block_size); 00111 } 00112 00113 // Clip a numeric value to the interval [lower_bound, upper_bound]. 00114 template<typename T> 00115 inline T ClipToRange(const T& x, const T& lower_bound, const T& upper_bound) { 00116 if (x < lower_bound) 00117 return lower_bound; 00118 if (x > upper_bound) 00119 return upper_bound; 00120 return x; 00121 } 00122 00123 // Extend the range [lower_bound, upper_bound] to include x. 00124 template<typename T1, typename T2> 00125 inline void UpdateRange(const T1& x, T2* lower_bound, T2* upper_bound) { 00126 if (x < *lower_bound) 00127 *lower_bound = x; 00128 if (x > *upper_bound) 00129 *upper_bound = x; 00130 } 00131 00132 // Decrease lower_bound to be <= x_lo AND increase upper_bound to be >= x_hi. 00133 template<typename T1, typename T2> 00134 inline void UpdateRange(const T1& x_lo, const T1& x_hi, 00135 T2* lower_bound, T2* upper_bound) { 00136 if (x_lo < *lower_bound) 00137 *lower_bound = x_lo; 00138 if (x_hi > *upper_bound) 00139 *upper_bound = x_hi; 00140 } 00141 00142 // Intersect the range [*lower2, *upper2] with the range [lower1, upper1], 00143 // putting the result back in [*lower2, *upper2]. 00144 // If non-intersecting ranges are given, we end up with *lower2 > *upper2. 00145 template<typename T> 00146 inline void IntersectRange(const T& lower1, const T& upper1, 00147 T* lower2, T* upper2) { 00148 if (lower1 > *lower2) 00149 *lower2 = lower1; 00150 if (upper1 < *upper2) 00151 *upper2 = upper1; 00152 } 00153 00154 // Proper modulo arithmetic operator. Returns a mod b that works for -ve a. 00155 // For any integer a and positive b, returns r : 0<=r<b and a=n*b + r for 00156 // some integer n. 00157 inline int Modulo(int a, int b) { 00158 return (a % b + b) % b; 00159 } 00160 00161 // Integer division operator with rounding that works for negative input. 00162 // Returns a divided by b, rounded to the nearest integer, without double 00163 // counting at 0. With simple rounding 1/3 = 0, 0/3 = 0 -1/3 = 0, -2/3 = 0, 00164 // -3/3 = 0 and -4/3 = -1. 00165 // I want 1/3 = 0, 0/3 = 0, -1/3 = 0, -2/3 = -1, -3/3 = -1 and -4/3 = -1. 00166 inline int DivRounded(int a, int b) { 00167 if (b < 0) return -DivRounded(a, -b); 00168 return a >= 0 ? (a + b / 2) / b : (a - b / 2) / b; 00169 } 00170 00171 // Return a double cast to int with rounding. 00172 inline int IntCastRounded(double x) { 00173 return x >= 0.0 ? static_cast<int>(x + 0.5) : -static_cast<int>(-x + 0.5); 00174 } 00175 00176 // Reverse the order of bytes in a n byte quantity for big/little-endian switch. 00177 inline void ReverseN(void* ptr, int num_bytes) { 00178 char *cptr = reinterpret_cast<char *>(ptr); 00179 int halfsize = num_bytes / 2; 00180 for (int i = 0; i < halfsize; ++i) { 00181 char tmp = cptr[i]; 00182 cptr[i] = cptr[num_bytes - 1 - i]; 00183 cptr[num_bytes - 1 - i] = tmp; 00184 } 00185 } 00186 00187 // Reverse the order of bytes in a 16 bit quantity for big/little-endian switch. 00188 inline void Reverse16(void *ptr) { 00189 ReverseN(ptr, 2); 00190 } 00191 00192 // Reverse the order of bytes in a 32 bit quantity for big/little-endian switch. 00193 inline void Reverse32(void *ptr) { 00194 ReverseN(ptr, 4); 00195 } 00196 00197 // Reverse the order of bytes in a 64 bit quantity for big/little-endian switch. 00198 inline void Reverse64(void* ptr) { 00199 ReverseN(ptr, 8); 00200 } 00201 00202 00203 #endif // TESSERACT_CCUTIL_HELPERS_H_