Tesseract  3.02
 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>
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].
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) {}
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__