motion-ocr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +10 -0
  4. data/LICENSE +28 -0
  5. data/README.md +22 -0
  6. data/Rakefile +17 -0
  7. data/app/app_delegate.rb +2 -0
  8. data/lib/motion-ocr.rb +26 -0
  9. data/lib/motion-ocr/version.rb +3 -0
  10. data/motion-ocr.gemspec +20 -0
  11. data/resources/tessdata/configs/nodict +3 -0
  12. data/resources/tessdata/eng.traineddata +0 -0
  13. data/spec/motion_ocr_spec.rb +23 -0
  14. data/spec/support/phototest.gif +0 -0
  15. data/vendor/MotionOCR/MotionOCR.bridgesupport +14722 -0
  16. data/vendor/MotionOCR/MotionOCR.xcodeproj/project.pbxproj +390 -0
  17. data/vendor/MotionOCR/MotionOCR.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  18. data/vendor/MotionOCR/MotionOCR.xcodeproj/project.xcworkspace/xcuserdata/fer.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  19. data/vendor/MotionOCR/MotionOCR.xcodeproj/xcuserdata/fer.xcuserdatad/xcschemes/MotionOCR.xcscheme +59 -0
  20. data/vendor/MotionOCR/MotionOCR.xcodeproj/xcuserdata/fer.xcuserdatad/xcschemes/xcschememanagement.plist +22 -0
  21. data/vendor/MotionOCR/MotionOCR/MotionOCR-Prefix.pch +7 -0
  22. data/vendor/MotionOCR/MotionOCR/MotionOCR.h +22 -0
  23. data/vendor/MotionOCR/MotionOCR/MotionOCR.mm +89 -0
  24. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/allheaders.h +32 -0
  25. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/alltypes.h +49 -0
  26. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/array.h +125 -0
  27. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/arrayaccess.h +194 -0
  28. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/bbuffer.h +46 -0
  29. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/bmf.h +51 -0
  30. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/bmp.h +74 -0
  31. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/ccbord.h +103 -0
  32. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/dewarp.h +57 -0
  33. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/endianness.h +11 -0
  34. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/environ.h +281 -0
  35. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/freetype.h +23 -0
  36. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/gplot.h +77 -0
  37. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/heap.h +73 -0
  38. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/imageio.h +153 -0
  39. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/jbclass.h +122 -0
  40. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/leptprotos.h +2058 -0
  41. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/leptwin.h +34 -0
  42. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/list.h +76 -0
  43. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/morph.h +218 -0
  44. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/pix.h +945 -0
  45. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/ptra.h +80 -0
  46. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/queue.h +63 -0
  47. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/readbarcode.h +220 -0
  48. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/regutils.h +122 -0
  49. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/stack.h +55 -0
  50. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/sudoku.h +62 -0
  51. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/leptonica/watershed.h +52 -0
  52. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/apitypes.h +31 -0
  53. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/baseapi.h +664 -0
  54. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/errcode.h +104 -0
  55. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/genericvector.h +763 -0
  56. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/helpers.h +139 -0
  57. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/host.h +180 -0
  58. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/ndminx.h +31 -0
  59. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/ocrclass.h +335 -0
  60. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/platform.h +48 -0
  61. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/publictypes.h +202 -0
  62. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/tesscallback.h +1238 -0
  63. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/thresholder.h +170 -0
  64. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/include/tesseract/unichar.h +85 -0
  65. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/lib/liblept.a +0 -0
  66. data/vendor/MotionOCR/MotionOCR/build_dependencies/dependencies/lib/libtesseract_all.a +0 -0
  67. metadata +113 -0
@@ -0,0 +1,104 @@
1
+ /**********************************************************************
2
+ * File: errcode.h (Formerly error.h)
3
+ * Description: Header file for generic error handler class
4
+ * Author: Ray Smith
5
+ * Created: Tue May 1 16:23:36 BST 1990
6
+ *
7
+ * (C) Copyright 1990, Hewlett-Packard Ltd.
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 ERRCODE_H
21
+ #define ERRCODE_H
22
+
23
+ #include "host.h"
24
+
25
+ /*Control parameters for error()*/
26
+ #define DBG -1 /*log without alert */
27
+ #define TESSLOG 0 /*alert user */
28
+ #define TESSEXIT 1 /*exit after erro */
29
+ #define ABORT 2 /*abort after error */
30
+
31
+ /* Explicit Error Abort codes */
32
+ #define NO_ABORT_CODE 0
33
+ #define LIST_ABORT 1
34
+ #define MEMORY_ABORT 2
35
+ #define FILE_ABORT 3
36
+
37
+ /* Location of code at error codes Reserve 0..2 (status codes 0..23 for UNLV)*/
38
+ #define LOC_UNUSED0 0
39
+ #define LOC_UNUSED1 1
40
+ #define LOC_UNUSED2 2
41
+ #define LOC_INIT 3
42
+ #define LOC_EDGE_PROG 4
43
+ #define LOC_TEXT_ORD_ROWS 5
44
+ #define LOC_TEXT_ORD_WORDS 6
45
+ #define LOC_PASS1 7
46
+ #define LOC_PASS2 8
47
+ /* Reserve up to 8..13 for adding subloc 0/3 plus subsubloc 0/1/2 */
48
+ #define LOC_FUZZY_SPACE 14
49
+ /* Reserve up to 14..20 for adding subloc 0/3 plus subsubloc 0/1/2 */
50
+ #define LOC_MM_ADAPT 21
51
+ #define LOC_DOC_BLK_REJ 22
52
+ #define LOC_WRITE_RESULTS 23
53
+ #define LOC_ADAPTIVE 24
54
+ /* DONT DEFINE ANY LOCATION > 31 !!! */
55
+
56
+ /* Sub locatation determines whether pass2 was in normal mode or fix xht mode*/
57
+ #define SUBLOC_NORM 0
58
+ #define SUBLOC_FIX_XHT 3
59
+
60
+ /* Sub Sub locatation determines whether match_word_pass2 was in Tess
61
+ matcher, NN matcher or somewhere else */
62
+
63
+ #define SUBSUBLOC_OTHER 0
64
+ #define SUBSUBLOC_TESS 1
65
+ #define SUBSUBLOC_NN 2
66
+
67
+ class DLLSYM ERRCODE //error handler class
68
+ {
69
+ const char *message; //error message
70
+ public:
71
+ void error ( //error print function
72
+ const char *caller, //function location
73
+ inT8 action, //action to take
74
+ const char *format, ... //fprintf format
75
+ ) const;
76
+ ERRCODE(const char *string) {
77
+ message = string;
78
+ } //initialize with string
79
+ };
80
+
81
+ const ERRCODE ASSERT_FAILED = "Assert failed";
82
+
83
+ #define ASSERT_HOST(x) if (!(x)) \
84
+ { \
85
+ ASSERT_FAILED.error(#x,ABORT,"in file %s, line %d", \
86
+ __FILE__,__LINE__); \
87
+ }
88
+
89
+ void signal_exit( //
90
+ int signal_code //Signal which
91
+ );
92
+ extern "C"
93
+ {
94
+ void err_exit();
95
+ //The real signal
96
+ void signal_termination_handler(int sig);
97
+ };
98
+
99
+ void set_global_loc_code(int loc_code);
100
+
101
+ void set_global_subloc_code(int loc_code);
102
+
103
+ void set_global_subsubloc_code(int loc_code);
104
+ #endif
@@ -0,0 +1,763 @@
1
+ ///////////////////////////////////////////////////////////////////////
2
+ // File: genericvector.h
3
+ // Description: Generic vector class
4
+ // Author: Daria Antonova
5
+ // Created: Mon Jun 23 11:26:43 PDT 2008
6
+ //
7
+ // (C) Copyright 2007, 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_GENERICVECTOR_H_
21
+ #define TESSERACT_CCUTIL_GENERICVECTOR_H_
22
+
23
+ #include <stdio.h>
24
+ #include <stdlib.h>
25
+
26
+ #include "tesscallback.h"
27
+ #include "errcode.h"
28
+ #include "helpers.h"
29
+ #include "ndminx.h"
30
+
31
+ // Use PointerVector<T> below in preference to GenericVector<T*>, as that
32
+ // provides automatic deletion of pointers, [De]Serialize that works, and
33
+ // sort that works.
34
+ template <typename T>
35
+ class GenericVector {
36
+ public:
37
+ GenericVector() { this->init(kDefaultVectorSize); }
38
+ explicit GenericVector(int size) { this->init(size); }
39
+
40
+ // Copy
41
+ GenericVector(const GenericVector& other) {
42
+ this->init(other.size());
43
+ this->operator+=(other);
44
+ }
45
+ GenericVector<T> &operator+=(const GenericVector& other);
46
+ GenericVector<T> &operator=(const GenericVector& other);
47
+
48
+ virtual ~GenericVector();
49
+
50
+ // Reserve some memory.
51
+ void reserve(int size);
52
+ // Double the size of the internal array.
53
+ void double_the_size();
54
+
55
+ // Resizes to size and sets all values to t.
56
+ void init_to_size(int size, T t);
57
+
58
+ // Return the size used.
59
+ int size() const {
60
+ return size_used_;
61
+ }
62
+
63
+ int length() const {
64
+ return size_used_;
65
+ }
66
+
67
+ // Return true if empty.
68
+ bool empty() const {
69
+ return size_used_ == 0;
70
+ }
71
+
72
+ // Return the object from an index.
73
+ T &get(int index) const;
74
+ T &operator[](int index) const;
75
+
76
+ // Return the index of the T object.
77
+ // This method NEEDS a compare_callback to be passed to
78
+ // set_compare_callback.
79
+ int get_index(T object) const;
80
+
81
+ // Return true if T is in the array
82
+ bool contains(T object) const;
83
+
84
+ // Return true if the index is valid
85
+ T contains_index(int index) const;
86
+
87
+ // Push an element in the end of the array
88
+ int push_back(T object);
89
+ void operator+=(T t);
90
+
91
+ // Push an element in the front of the array
92
+ // Note: This function is O(n)
93
+ int push_front(T object);
94
+
95
+ // Set the value at the given index
96
+ void set(T t, int index);
97
+
98
+ // Insert t at the given index, push other elements to the right.
99
+ void insert(T t, int index);
100
+
101
+ // Removes an element at the given index and
102
+ // shifts the remaining elements to the left.
103
+ virtual void remove(int index);
104
+
105
+ // Truncates the array to the given size by removing the end.
106
+ // If the current size is less, the array is not expanded.
107
+ virtual void truncate(int size) {
108
+ if (size < size_used_)
109
+ size_used_ = size;
110
+ }
111
+
112
+ // Add a callback to be called to delete the elements when the array took
113
+ // their ownership.
114
+ void set_clear_callback(TessCallback1<T>* cb);
115
+
116
+ // Add a callback to be called to compare the elements when needed (contains,
117
+ // get_id, ...)
118
+ void set_compare_callback(TessResultCallback2<bool, T const &, T const &>* cb);
119
+
120
+ // Clear the array, calling the clear callback function if any.
121
+ // All the owned callbacks are also deleted.
122
+ // If you don't want the callbacks to be deleted, before calling clear, set
123
+ // the callback to NULL.
124
+ virtual void clear();
125
+
126
+ // Delete objects pointed to by data_[i]
127
+ void delete_data_pointers();
128
+
129
+ // This method clears the current object, then, does a shallow copy of
130
+ // its argument, and finally invalidate its argument.
131
+ // Callbacks are moved to the current object;
132
+ void move(GenericVector<T>* from);
133
+
134
+ // Read/Write the array to a file. This does _NOT_ read/write the callbacks.
135
+ // The callback given must be permanent since they will be called more than
136
+ // once. The given callback will be deleted at the end.
137
+ // If the callbacks are NULL, then the data is simply read/written using
138
+ // fread (and swapping)/fwrite.
139
+ // Returns false on error or if the callback returns false.
140
+ // DEPRECATED. Use [De]Serialize[Classes] instead.
141
+ bool write(FILE* f, TessResultCallback2<bool, FILE*, T const &>* cb) const;
142
+ bool read(FILE* f, TessResultCallback3<bool, FILE*, T*, bool>* cb, bool swap);
143
+ // Writes a vector of simple types to the given file. Assumes that bitwise
144
+ // read/write of T will work. Returns false in case of error.
145
+ virtual bool Serialize(FILE* fp) const;
146
+ // Reads a vector of simple types from the given file. Assumes that bitwise
147
+ // read/write will work with ReverseN according to sizeof(T).
148
+ // Returns false in case of error.
149
+ // If swap is true, assumes a big/little-endian swap is needed.
150
+ virtual bool DeSerialize(bool swap, FILE* fp);
151
+ // Writes a vector of classes to the given file. Assumes the existence of
152
+ // bool T::Serialize(FILE* fp) const that returns false in case of error.
153
+ // Returns false in case of error.
154
+ bool SerializeClasses(FILE* fp) const;
155
+ // Reads a vector of classes from the given file. Assumes the existence of
156
+ // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
157
+ // error. Also needs T::T() and T::T(constT&), as init_to_size is used in
158
+ // this function. Returns false in case of error.
159
+ // If swap is true, assumes a big/little-endian swap is needed.
160
+ bool DeSerializeClasses(bool swap, FILE* fp);
161
+
162
+ // Allocates a new array of double the current_size, copies over the
163
+ // information from data to the new location, deletes data and returns
164
+ // the pointed to the new larger array.
165
+ // This function uses memcpy to copy the data, instead of invoking
166
+ // operator=() for each element like double_the_size() does.
167
+ static T *double_the_size_memcpy(int current_size, T *data) {
168
+ T *data_new = new T[current_size * 2];
169
+ memcpy(data_new, data, sizeof(T) * current_size);
170
+ delete[] data;
171
+ return data_new;
172
+ }
173
+
174
+ // Sorts the members of this vector using the less than comparator (cmp_lt),
175
+ // which compares the values. Useful for GenericVectors to primitive types.
176
+ // Will not work so great for pointers (unless you just want to sort some
177
+ // pointers). You need to provide a specialization to sort_cmp to use
178
+ // your type.
179
+ void sort();
180
+
181
+ // Sort the array into the order defined by the qsort function comparator.
182
+ // The comparator function is as defined by qsort, ie. it receives pointers
183
+ // to two Ts and returns negative if the first element is to appear earlier
184
+ // in the result and positive if it is to appear later, with 0 for equal.
185
+ void sort(int (*comparator)(const void*, const void*)) {
186
+ qsort(data_, size_used_, sizeof(*data_), comparator);
187
+ }
188
+
189
+ // Searches the array (assuming sorted in ascending order, using sort()) for
190
+ // an element equal to target and returns true if it is present.
191
+ // Use binary_search to get the index of target, or its nearest candidate.
192
+ bool bool_binary_search(const T& target) const {
193
+ int index = binary_search(target);
194
+ if (index >= size_used_)
195
+ return false;
196
+ return data_[index] == target;
197
+ }
198
+ // Searches the array (assuming sorted in ascending order, using sort()) for
199
+ // an element equal to target and returns the index of the best candidate.
200
+ // The return value is the largest index i such that data_[i] <= target or 0.
201
+ int binary_search(const T& target) const {
202
+ int bottom = 0;
203
+ int top = size_used_;
204
+ do {
205
+ int middle = (bottom + top) / 2;
206
+ if (data_[middle] > target)
207
+ top = middle;
208
+ else
209
+ bottom = middle;
210
+ }
211
+ while (top - bottom > 1);
212
+ return bottom;
213
+ }
214
+
215
+ // Compact the vector by deleting elements using operator!= on basic types.
216
+ // The vector must be sorted.
217
+ void compact_sorted() {
218
+ if (size_used_ == 0)
219
+ return;
220
+
221
+ // First element is in no matter what, hence the i = 1.
222
+ int last_write = 0;
223
+ for (int i = 1; i < size_used_; ++i) {
224
+ // Finds next unique item and writes it.
225
+ if (data_[last_write] != data_[i])
226
+ data_[++last_write] = data_[i];
227
+ }
228
+ // last_write is the index of a valid data cell, so add 1.
229
+ size_used_ = last_write + 1;
230
+ }
231
+
232
+ // Compact the vector by deleting elements for which delete_cb returns
233
+ // true. delete_cb is a permanent callback and will be deleted.
234
+ void compact(TessResultCallback1<bool, int>* delete_cb) {
235
+ int new_size = 0;
236
+ int old_index = 0;
237
+ // Until the callback returns true, the elements stay the same.
238
+ while (old_index < size_used_ && !delete_cb->Run(old_index++))
239
+ ++new_size;
240
+ // Now just copy anything else that gets false from delete_cb.
241
+ for (; old_index < size_used_; ++old_index) {
242
+ if (!delete_cb->Run(old_index)) {
243
+ data_[new_size++] = data_[old_index];
244
+ }
245
+ }
246
+ size_used_ = new_size;
247
+ delete delete_cb;
248
+ }
249
+
250
+ T dot_product(const GenericVector<T>& other) const {
251
+ T result = static_cast<T>(0);
252
+ for (int i = MIN(size_used_, other.size_used_) - 1; i >= 0; --i)
253
+ result += data_[i] * other.data_[i];
254
+ return result;
255
+ }
256
+
257
+ protected:
258
+
259
+ // Init the object, allocating size memory.
260
+ void init(int size);
261
+
262
+ // We are assuming that the object generally placed in thie
263
+ // vector are small enough that for efficiency it makes sence
264
+ // to start with a larger initial size.
265
+ static const int kDefaultVectorSize = 4;
266
+ inT32 size_used_;
267
+ inT32 size_reserved_;
268
+ T* data_;
269
+ TessCallback1<T>* clear_cb_;
270
+ // Mutable because Run method is not const
271
+ mutable TessResultCallback2<bool, T const &, T const &>* compare_cb_;
272
+ };
273
+
274
+ namespace tesseract {
275
+
276
+ template <typename T>
277
+ bool cmp_eq(T const & t1, T const & t2) {
278
+ return t1 == t2;
279
+ }
280
+
281
+ // Used by sort()
282
+ // return < 0 if t1 < t2
283
+ // return 0 if t1 == t2
284
+ // return > 0 if t1 > t2
285
+ template <typename T>
286
+ int sort_cmp(const void* t1, const void* t2) {
287
+ const T* a = static_cast<const T *> (t1);
288
+ const T* b = static_cast<const T *> (t2);
289
+ if (*a < *b) {
290
+ return -1;
291
+ } else if (*b < *a) {
292
+ return 1;
293
+ } else {
294
+ return 0;
295
+ }
296
+ }
297
+
298
+ // Used by PointerVector::sort()
299
+ // return < 0 if t1 < t2
300
+ // return 0 if t1 == t2
301
+ // return > 0 if t1 > t2
302
+ template <typename T>
303
+ int sort_ptr_cmp(const void* t1, const void* t2) {
304
+ const T* a = *reinterpret_cast<T * const *>(t1);
305
+ const T* b = *reinterpret_cast<T * const *>(t2);
306
+ if (*a < *b) {
307
+ return -1;
308
+ } else if (*b < *a) {
309
+ return 1;
310
+ } else {
311
+ return 0;
312
+ }
313
+ }
314
+
315
+ // Subclass for a vector of pointers. Use in preference to GenericVector<T*>
316
+ // as it provides automatic deletion and correct serialization, with the
317
+ // corollary that all copy operations are deep copies of the pointed-to objects.
318
+ template<typename T>
319
+ class PointerVector : public GenericVector<T*> {
320
+ public:
321
+ PointerVector() : GenericVector<T*>() { }
322
+ explicit PointerVector(int size) : GenericVector<T*>(size) { }
323
+ virtual ~PointerVector() {
324
+ // Clear must be called here, even though it is called again by the base,
325
+ // as the base will call the wrong clear.
326
+ clear();
327
+ }
328
+ // Copy must be deep, as the pointers will be automatically deleted on
329
+ // destruction.
330
+ PointerVector(const PointerVector& other) {
331
+ init(other.size());
332
+ this->operator+=(other);
333
+ }
334
+ PointerVector<T>& operator+=(const PointerVector& other) {
335
+ reserve(this->size_used_ + other.size_used_);
336
+ for (int i = 0; i < other.size(); ++i) {
337
+ push_back(new T(*other.data_[i]));
338
+ }
339
+ return *this;
340
+ }
341
+
342
+ PointerVector<T>& operator=(const PointerVector& other) {
343
+ this->truncate(0);
344
+ this->operator+=(other);
345
+ return *this;
346
+ }
347
+
348
+ // Removes an element at the given index and
349
+ // shifts the remaining elements to the left.
350
+ virtual void remove(int index) {
351
+ delete GenericVector<T*>::data_[index];
352
+ GenericVector<T*>::remove(index);
353
+ }
354
+
355
+ // Truncates the array to the given size by removing the end.
356
+ // If the current size is less, the array is not expanded.
357
+ virtual void truncate(int size) {
358
+ for (int i = size; i < GenericVector<T*>::size_used_; ++i)
359
+ delete GenericVector<T*>::data_[i];
360
+ GenericVector<T*>::truncate(size);
361
+ }
362
+
363
+ // Clear the array, calling the clear callback function if any.
364
+ // All the owned callbacks are also deleted.
365
+ // If you don't want the callbacks to be deleted, before calling clear, set
366
+ // the callback to NULL.
367
+ virtual void clear() {
368
+ GenericVector<T*>::delete_data_pointers();
369
+ GenericVector<T*>::clear();
370
+ }
371
+
372
+ // Writes a vector of simple types to the given file. Assumes that bitwise
373
+ // read/write of T will work. Returns false in case of error.
374
+ virtual bool Serialize(FILE* fp) const {
375
+ inT32 used = GenericVector<T*>::size_used_;
376
+ if (fwrite(&used, sizeof(used), 1, fp) != 1) return false;
377
+ for (int i = 0; i < used; ++i) {
378
+ inT8 non_null = GenericVector<T*>::data_[i] != NULL;
379
+ if (fwrite(&non_null, sizeof(non_null), 1, fp) != 1) return false;
380
+ if (non_null && !GenericVector<T*>::data_[i]->Serialize(fp)) return false;
381
+ }
382
+ return true;
383
+ }
384
+ // Reads a vector of simple types from the given file. Assumes that bitwise
385
+ // read/write will work with ReverseN according to sizeof(T).
386
+ // Also needs T::T(), as new T is used in this function.
387
+ // Returns false in case of error.
388
+ // If swap is true, assumes a big/little-endian swap is needed.
389
+ virtual bool DeSerialize(bool swap, FILE* fp) {
390
+ inT32 reserved;
391
+ if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false;
392
+ if (swap) Reverse32(&reserved);
393
+ GenericVector<T*>::reserve(reserved);
394
+ for (int i = 0; i < reserved; ++i) {
395
+ inT8 non_null;
396
+ if (fread(&non_null, sizeof(non_null), 1, fp) != 1) return false;
397
+ T* item = NULL;
398
+ if (non_null) {
399
+ item = new T;
400
+ if (!item->DeSerialize(swap, fp)) return false;
401
+ }
402
+ push_back(item);
403
+ }
404
+ return true;
405
+ }
406
+
407
+ // Sorts the items pointed to by the members of this vector using
408
+ // t::operator<().
409
+ void sort() {
410
+ sort(&sort_ptr_cmp<T>);
411
+ }
412
+ };
413
+
414
+ } // namespace tesseract
415
+
416
+ // A useful vector that uses operator== to do comparisons.
417
+ template <typename T>
418
+ class GenericVectorEqEq : public GenericVector<T> {
419
+ public:
420
+ GenericVectorEqEq() {
421
+ GenericVector<T>::set_compare_callback(
422
+ NewPermanentTessCallback(tesseract::cmp_eq<T>));
423
+ }
424
+ GenericVectorEqEq(int size) : GenericVector<T>(size) {
425
+ GenericVector<T>::set_compare_callback(
426
+ NewPermanentTessCallback(tesseract::cmp_eq<T>));
427
+ }
428
+ };
429
+
430
+ template <typename T>
431
+ void GenericVector<T>::init(int size) {
432
+ size_used_ = 0;
433
+ size_reserved_ = 0;
434
+ data_ = 0;
435
+ clear_cb_ = 0;
436
+ compare_cb_ = 0;
437
+ reserve(size);
438
+ }
439
+
440
+ template <typename T>
441
+ GenericVector<T>::~GenericVector() {
442
+ clear();
443
+ }
444
+
445
+ // Reserve some memory. If the internal array contains elements, they are
446
+ // copied.
447
+ template <typename T>
448
+ void GenericVector<T>::reserve(int size) {
449
+ if (size_reserved_ >= size || size <= 0)
450
+ return;
451
+ T* new_array = new T[size];
452
+ for (int i = 0; i < size_used_; ++i)
453
+ new_array[i] = data_[i];
454
+ if (data_ != NULL) delete[] data_;
455
+ data_ = new_array;
456
+ size_reserved_ = size;
457
+ }
458
+
459
+ template <typename T>
460
+ void GenericVector<T>::double_the_size() {
461
+ if (size_reserved_ == 0) {
462
+ reserve(kDefaultVectorSize);
463
+ }
464
+ else {
465
+ reserve(2 * size_reserved_);
466
+ }
467
+ }
468
+
469
+ // Resizes to size and sets all values to t.
470
+ template <typename T>
471
+ void GenericVector<T>::init_to_size(int size, T t) {
472
+ reserve(size);
473
+ size_used_ = size;
474
+ for (int i = 0; i < size; ++i)
475
+ data_[i] = t;
476
+ }
477
+
478
+
479
+ // Return the object from an index.
480
+ template <typename T>
481
+ T &GenericVector<T>::get(int index) const {
482
+ ASSERT_HOST(index >= 0 && index < size_used_);
483
+ return data_[index];
484
+ }
485
+
486
+ template <typename T>
487
+ T &GenericVector<T>::operator[](int index) const {
488
+ return data_[index];
489
+ }
490
+
491
+ // Return the object from an index.
492
+ template <typename T>
493
+ void GenericVector<T>::set(T t, int index) {
494
+ ASSERT_HOST(index >= 0 && index < size_used_);
495
+ data_[index] = t;
496
+ }
497
+
498
+ // Shifts the rest of the elements to the right to make
499
+ // space for the new elements and inserts the given element
500
+ // at the specified index.
501
+ template <typename T>
502
+ void GenericVector<T>::insert(T t, int index) {
503
+ ASSERT_HOST(index >= 0 && index < size_used_);
504
+ if (size_reserved_ == size_used_)
505
+ double_the_size();
506
+ for (int i = size_used_; i > index; --i) {
507
+ data_[i] = data_[i-1];
508
+ }
509
+ data_[index] = t;
510
+ size_used_++;
511
+ }
512
+
513
+ // Removes an element at the given index and
514
+ // shifts the remaining elements to the left.
515
+ template <typename T>
516
+ void GenericVector<T>::remove(int index) {
517
+ ASSERT_HOST(index >= 0 && index < size_used_);
518
+ for (int i = index; i < size_used_ - 1; ++i) {
519
+ data_[i] = data_[i+1];
520
+ }
521
+ size_used_--;
522
+ }
523
+
524
+ // Return true if the index is valindex
525
+ template <typename T>
526
+ T GenericVector<T>::contains_index(int index) const {
527
+ return index >= 0 && index < size_used_;
528
+ }
529
+
530
+ // Return the index of the T object.
531
+ template <typename T>
532
+ int GenericVector<T>::get_index(T object) const {
533
+ for (int i = 0; i < size_used_; ++i) {
534
+ ASSERT_HOST(compare_cb_ != NULL);
535
+ if (compare_cb_->Run(object, data_[i]))
536
+ return i;
537
+ }
538
+ return -1;
539
+ }
540
+
541
+ // Return true if T is in the array
542
+ template <typename T>
543
+ bool GenericVector<T>::contains(T object) const {
544
+ return get_index(object) != -1;
545
+ }
546
+
547
+ // Add an element in the array
548
+ template <typename T>
549
+ int GenericVector<T>::push_back(T object) {
550
+ int index = 0;
551
+ if (size_used_ == size_reserved_)
552
+ double_the_size();
553
+ index = size_used_++;
554
+ data_[index] = object;
555
+ return index;
556
+ }
557
+
558
+ // Add an element in the array (front)
559
+ template <typename T>
560
+ int GenericVector<T>::push_front(T object) {
561
+ if (size_used_ == size_reserved_)
562
+ double_the_size();
563
+ for (int i = size_used_; i > 0; --i)
564
+ data_[i] = data_[i-1];
565
+ data_[0] = object;
566
+ ++size_used_;
567
+ return 0;
568
+ }
569
+
570
+ template <typename T>
571
+ void GenericVector<T>::operator+=(T t) {
572
+ push_back(t);
573
+ }
574
+
575
+ template <typename T>
576
+ GenericVector<T> &GenericVector<T>::operator+=(const GenericVector& other) {
577
+ this->reserve(size_used_ + other.size_used_);
578
+ for (int i = 0; i < other.size(); ++i) {
579
+ this->operator+=(other.data_[i]);
580
+ }
581
+ return *this;
582
+ }
583
+
584
+ template <typename T>
585
+ GenericVector<T> &GenericVector<T>::operator=(const GenericVector& other) {
586
+ this->truncate(0);
587
+ this->operator+=(other);
588
+ return *this;
589
+ }
590
+
591
+ // Add a callback to be called to delete the elements when the array took
592
+ // their ownership.
593
+ template <typename T>
594
+ void GenericVector<T>::set_clear_callback(TessCallback1<T>* cb) {
595
+ clear_cb_ = cb;
596
+ }
597
+
598
+ // Add a callback to be called to delete the elements when the array took
599
+ // their ownership.
600
+ template <typename T>
601
+ void GenericVector<T>::set_compare_callback(TessResultCallback2<bool, T const &, T const &>* cb) {
602
+ compare_cb_ = cb;
603
+ }
604
+
605
+ // Clear the array, calling the callback function if any.
606
+ template <typename T>
607
+ void GenericVector<T>::clear() {
608
+ if (size_reserved_ > 0) {
609
+ if (clear_cb_ != NULL)
610
+ for (int i = 0; i < size_used_; ++i)
611
+ clear_cb_->Run(data_[i]);
612
+ delete[] data_;
613
+ data_ = NULL;
614
+ size_used_ = 0;
615
+ size_reserved_ = 0;
616
+ }
617
+ if (clear_cb_ != NULL) {
618
+ delete clear_cb_;
619
+ clear_cb_ = NULL;
620
+ }
621
+ if (compare_cb_ != NULL) {
622
+ delete compare_cb_;
623
+ compare_cb_ = NULL;
624
+ }
625
+ }
626
+
627
+ template <typename T>
628
+ void GenericVector<T>::delete_data_pointers() {
629
+ for (int i = 0; i < size_used_; ++i)
630
+ if (data_[i]) {
631
+ delete data_[i];
632
+ }
633
+ }
634
+
635
+
636
+ template <typename T>
637
+ bool GenericVector<T>::write(
638
+ FILE* f, TessResultCallback2<bool, FILE*, T const &>* cb) const {
639
+ if (fwrite(&size_reserved_, sizeof(size_reserved_), 1, f) != 1) return false;
640
+ if (fwrite(&size_used_, sizeof(size_used_), 1, f) != 1) return false;
641
+ if (cb != NULL) {
642
+ for (int i = 0; i < size_used_; ++i) {
643
+ if (!cb->Run(f, data_[i])) {
644
+ delete cb;
645
+ return false;
646
+ }
647
+ }
648
+ delete cb;
649
+ } else {
650
+ if (fwrite(data_, sizeof(T), size_used_, f) != size_used_) return false;
651
+ }
652
+ return true;
653
+ }
654
+
655
+ template <typename T>
656
+ bool GenericVector<T>::read(FILE* f,
657
+ TessResultCallback3<bool, FILE*, T*, bool>* cb,
658
+ bool swap) {
659
+ inT32 reserved;
660
+ if (fread(&reserved, sizeof(reserved), 1, f) != 1) return false;
661
+ if (swap) Reverse32(&reserved);
662
+ reserve(reserved);
663
+ if (fread(&size_used_, sizeof(size_used_), 1, f) != 1) return false;
664
+ if (swap) Reverse32(&size_used_);
665
+ if (cb != NULL) {
666
+ for (int i = 0; i < size_used_; ++i) {
667
+ if (!cb->Run(f, data_ + i, swap)) {
668
+ delete cb;
669
+ return false;
670
+ }
671
+ }
672
+ delete cb;
673
+ } else {
674
+ if (fread(data_, sizeof(T), size_used_, f) != size_used_) return false;
675
+ if (swap) {
676
+ for (int i = 0; i < size_used_; ++i)
677
+ ReverseN(&data_[i], sizeof(T));
678
+ }
679
+ }
680
+ return true;
681
+ }
682
+
683
+ // Writes a vector of simple types to the given file. Assumes that bitwise
684
+ // read/write of T will work. Returns false in case of error.
685
+ template <typename T>
686
+ bool GenericVector<T>::Serialize(FILE* fp) const {
687
+ if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) return false;
688
+ if (fwrite(data_, sizeof(*data_), size_used_, fp) != size_used_) return false;
689
+ return true;
690
+ }
691
+
692
+ // Reads a vector of simple types from the given file. Assumes that bitwise
693
+ // read/write will work with ReverseN according to sizeof(T).
694
+ // Returns false in case of error.
695
+ // If swap is true, assumes a big/little-endian swap is needed.
696
+ template <typename T>
697
+ bool GenericVector<T>::DeSerialize(bool swap, FILE* fp) {
698
+ inT32 reserved;
699
+ if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false;
700
+ if (swap) Reverse32(&reserved);
701
+ reserve(reserved);
702
+ size_used_ = reserved;
703
+ if (fread(data_, sizeof(T), size_used_, fp) != size_used_) return false;
704
+ if (swap) {
705
+ for (int i = 0; i < size_used_; ++i)
706
+ ReverseN(&data_[i], sizeof(data_[i]));
707
+ }
708
+ return true;
709
+ }
710
+
711
+ // Writes a vector of classes to the given file. Assumes the existence of
712
+ // bool T::Serialize(FILE* fp) const that returns false in case of error.
713
+ // Returns false in case of error.
714
+ template <typename T>
715
+ bool GenericVector<T>::SerializeClasses(FILE* fp) const {
716
+ if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) return false;
717
+ for (int i = 0; i < size_used_; ++i) {
718
+ if (!data_[i].Serialize(fp)) return false;
719
+ }
720
+ return true;
721
+ }
722
+
723
+ // Reads a vector of classes from the given file. Assumes the existence of
724
+ // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
725
+ // error. Alse needs T::T() and T::T(constT&), as init_to_size is used in
726
+ // this function. Returns false in case of error.
727
+ // If swap is true, assumes a big/little-endian swap is needed.
728
+ template <typename T>
729
+ bool GenericVector<T>::DeSerializeClasses(bool swap, FILE* fp) {
730
+ uinT32 reserved;
731
+ if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false;
732
+ if (swap) Reverse32(&reserved);
733
+ T empty;
734
+ init_to_size(reserved, empty);
735
+ for (int i = 0; i < reserved; ++i) {
736
+ if (!data_[i].DeSerialize(swap, fp)) return false;
737
+ }
738
+ return true;
739
+ }
740
+
741
+ // This method clear the current object, then, does a shallow copy of
742
+ // its argument, and finally invalindate its argument.
743
+ template <typename T>
744
+ void GenericVector<T>::move(GenericVector<T>* from) {
745
+ this->clear();
746
+ this->data_ = from->data_;
747
+ this->size_reserved_ = from->size_reserved_;
748
+ this->size_used_ = from->size_used_;
749
+ this->compare_cb_ = from->compare_cb_;
750
+ this->clear_cb_ = from->clear_cb_;
751
+ from->data_ = NULL;
752
+ from->clear_cb_ = NULL;
753
+ from->compare_cb_ = NULL;
754
+ from->size_used_ = 0;
755
+ from->size_reserved_ = 0;
756
+ }
757
+
758
+ template <typename T>
759
+ void GenericVector<T>::sort() {
760
+ sort(&tesseract::sort_cmp<T>);
761
+ }
762
+
763
+ #endif // TESSERACT_CCUTIL_GENERICVECTOR_H_