Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
matrix.h
Go to the documentation of this file.
1 /* -*-C-*-
2 ********************************************************************************
3 *
4 * File: matrix.h (Formerly matrix.h)
5 * Description: Ratings matrix code. (Used by associator)
6 * Author: Mark Seaman, OCR Technology
7 * Created: Wed May 16 13:22:06 1990
8 * Modified: Tue Mar 19 16:00:20 1991 (Mark Seaman) marks@hpgrlt
9 * Language: C
10 * Package: N/A
11 * Status: Experimental (Do Not Distribute)
12 *
13 * (c) Copyright 1990, Hewlett-Packard Company.
14 ** Licensed under the Apache License, Version 2.0 (the "License");
15 ** you may not use this file except in compliance with the License.
16 ** You may obtain a copy of the License at
17 ** http://www.apache.org/licenses/LICENSE-2.0
18 ** Unless required by applicable law or agreed to in writing, software
19 ** distributed under the License is distributed on an "AS IS" BASIS,
20 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 ** See the License for the specific language governing permissions and
22 ** limitations under the License.
23 *
24 *********************************************************************************/
25 #ifndef TESSERACT_CCSTRUCT_MATRIX_H__
26 #define TESSERACT_CCSTRUCT_MATRIX_H__
27
28 #include "ratngs.h"
29 #include "unicharset.h"
30
31 #define NOT_CLASSIFIED reinterpret_cast<BLOB_CHOICE_LIST*>(NULL)
32
33 // A generic class to store a matrix with entries of type T.
34 template <class T>
35 class GENERIC_2D_ARRAY {
36 public:
37 // Allocate a piece of memory to hold a 2d-array of the given dimension.
38 // Initialize all the elements of the array to empty instead of assuming
39 // that a default constructor can be used.
40 GENERIC_2D_ARRAY(int dim1, int dim2, const T& empty)
41 : empty_(empty), dim1_(dim1), dim2_(dim2) {
42 array_ = new T[dim1_ * dim2_];
43 for (int x = 0; x < dim1_; x++)
44 for (int y = 0; y < dim2_; y++)
45 this->put(x, y, empty_);
46 }
47 ~GENERIC_2D_ARRAY() { delete[] array_; }
48
49 // Writes to the given file. Returns false in case of error.
50 // Only works with bitwise-serializeable types!
51 bool Serialize(FILE* fp) const {
52 if (!SerializeSize(fp)) return false;
53 if (fwrite(&empty_, sizeof(empty_), 1, fp) != 1) return false;
54 int size = dim1_ * dim2_;
55 if (fwrite(array_, sizeof(*array_), size, fp) != size) return false;
56 return true;
57 }
58
59 // Reads from the given file. Returns false in case of error.
60 // Only works with bitwise-serializeable types!
61 // If swap is true, assumes a big/little-endian swap is needed.
62 bool DeSerialize(bool swap, FILE* fp) {
63 if (!DeSerializeSize(swap, fp)) return false;
64 if (fread(&empty_, sizeof(empty_), 1, fp) != 1) return false;
65 if (swap) ReverseN(&empty_, sizeof(empty_));
66 int size = dim1_ * dim2_;
67 if (fread(array_, sizeof(*array_), size, fp) != size) return false;
68 if (swap) {
69 for (int i = 0; i < size; ++i)
70 ReverseN(&array_[i], sizeof(array_[i]));
71 }
72 return true;
73 }
74
75 // Writes to the given file. Returns false in case of error.
76 // Assumes a T::Serialize(FILE*) const function.
77 bool SerializeClasses(FILE* fp) const {
78 if (!SerializeSize(fp)) return false;
79 if (!empty_.Serialize(fp)) return false;
80 int size = dim1_ * dim2_;
81 for (int i = 0; i < size; ++i) {
82 if (!array_[i].Serialize(fp)) return false;
83 }
84 return true;
85 }
86
87 // Reads from the given file. Returns false in case of error.
88 // Assumes a T::DeSerialize(bool swap, FILE*) function.
89 // If swap is true, assumes a big/little-endian swap is needed.
90 bool DeSerializeClasses(bool swap, FILE* fp) {
91 if (!DeSerializeSize(swap, fp)) return false;
92 if (!empty_.DeSerialize(swap, fp)) return false;
93 int size = dim1_ * dim2_;
94 for (int i = 0; i < size; ++i) {
95 if (!array_[i].DeSerialize(swap, fp)) return false;
96 }
97 return true;
98 }
99
100 // Provide the dimensions of this rectangular matrix.
101 int dim1() const { return dim1_; }
102 int dim2() const { return dim2_; }
103
104 // Expression to select a specific location in the matrix. The matrix is
105 // stored COLUMN-major, so the left-most index is the most significant.
106 // This allows [][] access to use indices in the same order as (,).
107 int index(int column, int row) const {
108 return (column * dim2_ + row);
109 }
110
111 // Put a list element into the matrix at a specific location.
112 void put(int column, int row, const T& thing) {
113 array_[this->index(column, row)] = thing;
114 }
115
116 // Get the item at a specified location from the matrix.
117 T get(int column, int row) const {
118 return array_[this->index(column, row)];
119 }
120 // Return a reference to the element at the specified location.
121 const T& operator()(int column, int row) const {
122 return array_[this->index(column, row)];
123 }
124 T& operator()(int column, int row) {
125 return array_[this->index(column, row)];
126 }
127 // Allow access using array[column][row]. NOTE that the indices are
128 // in the same left-to-right order as the () indexing.
129 T* operator[](int column) {
130 return &array_[this->index(column, 0)];
131 }
132
133 // Delete objects pointed to by array_[i].
134 void delete_matrix_pointers() {
135 for (int x = 0; x < dim1_; x++) {
136 for (int y = 0; y < dim2_; y++) {
137 T matrix_cell = this->get(x, y);
138 if (matrix_cell != empty_)
139 delete matrix_cell;
140 }
141 }
142 }
143
144 private:
145 // Factored helper to serialize the size.
146 bool SerializeSize(FILE* fp) const {
147 inT32 size = dim1_;
148 if (fwrite(&size, sizeof(size), 1, fp) != 1) return false;
149 size = dim2_;
150 if (fwrite(&size, sizeof(size), 1, fp) != 1) return false;
151 return true;
152 }
153 // Factored helper to deserialize the size.
154 // If swap is true, assumes a big/little-endian swap is needed.
155 bool DeSerializeSize(bool swap, FILE* fp) {
156 inT32 size1, size2;
157 if (fread(&size1, sizeof(size1), 1, fp) != 1) return false;
158 if (fread(&size2, sizeof(size2), 1, fp) != 1) return false;
159 if (swap) {
160 ReverseN(&size1, sizeof(size1));
161 ReverseN(&size2, sizeof(size2));
162 }
163 if (size1 != dim1_ || size2 != dim2_) {
164 dim1_ = size1;
165 dim2_ = size2;
166 delete [] array_;
167 array_ = new T[dim1_ * dim2_];
168 }
169 return true;
170 }
171
172 T* array_;
173 T empty_; // The unused cell.
174 int dim1_; // Size of the 1st dimension in indexing functions.
175 int dim2_; // Size of the 2nd dimension in indexing functions.
176 };
177
178 // A generic class to store a square matrix with entries of type T.
179 template <class T>
180 class GENERIC_MATRIX : public GENERIC_2D_ARRAY<T> {
181 public:
182 // Allocate a piece of memory to hold a matrix of the given dimension.
183 // Initialize all the elements of the matrix to empty instead of assuming
184 // that a default constructor can be used.
185 GENERIC_MATRIX(int dimension, const T& empty)
186 : GENERIC_2D_ARRAY<T>(dimension, dimension, empty) {
187 }
188
189 // Provide the dimension of this square matrix.
190 int dimension() const { return this->dim1(); }
191 };
192
193 class MATRIX : public GENERIC_MATRIX<BLOB_CHOICE_LIST *> {
194 public:
195 MATRIX(int dimension) : GENERIC_MATRIX<BLOB_CHOICE_LIST *>(dimension,
196 NOT_CLASSIFIED) {}
197 // Print a shortened version of the contents of the matrix.
198 void print(const UNICHARSET &unicharset) const;
199 };
200
201 struct MATRIX_COORD {
202 static void Delete(void *arg) {
203 MATRIX_COORD *c = static_cast<MATRIX_COORD *>(arg);
204 delete c;
205 }
206 MATRIX_COORD(int c, int r): col(c), row(r) {}
207 ~MATRIX_COORD() {}
208 bool Valid(const MATRIX &m) const {
209 return (col >= 0 && row >= 0 &&
210 col < m.dimension() && row < m.dimension());
211 }
212 int col;
213 int row;
214 };
215
216 #endif // TESSERACT_CCSTRUCT_MATRIX_H__