Tesseract 3.01
|
00001 /* -*-C-*- 00002 ******************************************************************************** 00003 * 00004 * File: matrix.h (Formerly matrix.h) 00005 * Description: Ratings matrix code. (Used by associator) 00006 * Author: Mark Seaman, OCR Technology 00007 * Created: Wed May 16 13:22:06 1990 00008 * Modified: Tue Mar 19 16:00:20 1991 (Mark Seaman) marks@hpgrlt 00009 * Language: C 00010 * Package: N/A 00011 * Status: Experimental (Do Not Distribute) 00012 * 00013 * (c) Copyright 1990, Hewlett-Packard Company. 00014 ** Licensed under the Apache License, Version 2.0 (the "License"); 00015 ** you may not use this file except in compliance with the License. 00016 ** You may obtain a copy of the License at 00017 ** http://www.apache.org/licenses/LICENSE-2.0 00018 ** Unless required by applicable law or agreed to in writing, software 00019 ** distributed under the License is distributed on an "AS IS" BASIS, 00020 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00021 ** See the License for the specific language governing permissions and 00022 ** limitations under the License. 00023 * 00024 *********************************************************************************/ 00025 #ifndef TESSERACT_CCSTRUCT_MATRIX_H__ 00026 #define TESSERACT_CCSTRUCT_MATRIX_H__ 00027 00028 #include "ratngs.h" 00029 #include "unicharset.h" 00030 00031 #define NOT_CLASSIFIED reinterpret_cast<BLOB_CHOICE_LIST*>(NULL) 00032 00033 // A generic class to store a matrix with entries of type T. 00034 template <class T> 00035 class GENERIC_2D_ARRAY { 00036 public: 00037 // Allocate a piece of memory to hold a 2d-array of the given dimension. 00038 // Initialize all the elements of the array to empty instead of assuming 00039 // that a default constructor can be used. 00040 GENERIC_2D_ARRAY(int dim1, int dim2, const T& empty) 00041 : empty_(empty), dim1_(dim1), dim2_(dim2) { 00042 array_ = new T[dim1_ * dim2_]; 00043 for (int x = 0; x < dim1_; x++) 00044 for (int y = 0; y < dim2_; y++) 00045 this->put(x, y, empty_); 00046 } 00047 ~GENERIC_2D_ARRAY() { delete[] array_; } 00048 00049 // Writes to the given file. Returns false in case of error. 00050 // Only works with bitwise-serializeable types! 00051 bool Serialize(FILE* fp) const { 00052 if (!SerializeSize(fp)) return false; 00053 if (fwrite(&empty_, sizeof(empty_), 1, fp) != 1) return false; 00054 int size = dim1_ * dim2_; 00055 if (fwrite(array_, sizeof(*array_), size, fp) != size) return false; 00056 return true; 00057 } 00058 00059 // Reads from the given file. Returns false in case of error. 00060 // Only works with bitwise-serializeable types! 00061 // If swap is true, assumes a big/little-endian swap is needed. 00062 bool DeSerialize(bool swap, FILE* fp) { 00063 if (!DeSerializeSize(swap, fp)) return false; 00064 if (fread(&empty_, sizeof(empty_), 1, fp) != 1) return false; 00065 if (swap) ReverseN(&empty_, sizeof(empty_)); 00066 int size = dim1_ * dim2_; 00067 if (fread(array_, sizeof(*array_), size, fp) != size) return false; 00068 if (swap) { 00069 for (int i = 0; i < size; ++i) 00070 ReverseN(&array_[i], sizeof(array_[i])); 00071 } 00072 return true; 00073 } 00074 00075 // Writes to the given file. Returns false in case of error. 00076 // Assumes a T::Serialize(FILE*) const function. 00077 bool SerializeClasses(FILE* fp) const { 00078 if (!SerializeSize(fp)) return false; 00079 if (!empty_.Serialize(fp)) return false; 00080 int size = dim1_ * dim2_; 00081 for (int i = 0; i < size; ++i) { 00082 if (!array_[i].Serialize(fp)) return false; 00083 } 00084 return true; 00085 } 00086 00087 // Reads from the given file. Returns false in case of error. 00088 // Assumes a T::DeSerialize(bool swap, FILE*) function. 00089 // If swap is true, assumes a big/little-endian swap is needed. 00090 bool DeSerializeClasses(bool swap, FILE* fp) { 00091 if (!DeSerializeSize(swap, fp)) return false; 00092 if (!empty_.DeSerialize(swap, fp)) return false; 00093 int size = dim1_ * dim2_; 00094 for (int i = 0; i < size; ++i) { 00095 if (!array_[i].DeSerialize(swap, fp)) return false; 00096 } 00097 return true; 00098 } 00099 00100 // Provide the dimensions of this rectangular matrix. 00101 int dim1() const { return dim1_; } 00102 int dim2() const { return dim2_; } 00103 00104 // Expression to select a specific location in the matrix. 00105 int index(int column, int row) const { 00106 return (row * dim1_ + column); 00107 } 00108 00109 // Put a list element into the matrix at a specific location. 00110 void put(int column, int row, const T& thing) { 00111 array_[this->index(column, row)] = thing; 00112 } 00113 00114 // Get the item at a specified location from the matrix. 00115 T get(int column, int row) const { 00116 return array_[this->index(column, row)]; 00117 } 00118 // Return a reference to the element at the specified location. 00119 const T& operator()(int column, int row) const { 00120 return array_[this->index(column, row)]; 00121 } 00122 T& operator()(int column, int row) { 00123 return array_[this->index(column, row)]; 00124 } 00125 00126 // Delete objects pointed to by array_[i]. 00127 void delete_matrix_pointers() { 00128 for (int x = 0; x < dim1_; x++) { 00129 for (int y = 0; y < dim2_; y++) { 00130 T matrix_cell = this->get(x, y); 00131 if (matrix_cell != empty_) 00132 delete matrix_cell; 00133 } 00134 } 00135 } 00136 00137 private: 00138 // Factored helper to serialize the size. 00139 bool SerializeSize(FILE* fp) const { 00140 inT32 size = dim1_; 00141 if (fwrite(&size, sizeof(size), 1, fp) != 1) return false; 00142 size = dim2_; 00143 if (fwrite(&size, sizeof(size), 1, fp) != 1) return false; 00144 return true; 00145 } 00146 // Factored helper to deserialize the size. 00147 // If swap is true, assumes a big/little-endian swap is needed. 00148 bool DeSerializeSize(bool swap, FILE* fp) { 00149 inT32 size1, size2; 00150 if (fread(&size1, sizeof(size1), 1, fp) != 1) return false; 00151 if (fread(&size2, sizeof(size2), 1, fp) != 1) return false; 00152 if (swap) { 00153 ReverseN(&size1, sizeof(size1)); 00154 ReverseN(&size2, sizeof(size2)); 00155 } 00156 if (size1 != dim1_ || size2 != dim2_) { 00157 dim1_ = size1; 00158 dim2_ = size2; 00159 delete [] array_; 00160 array_ = new T[dim1_ * dim2_]; 00161 } 00162 return true; 00163 } 00164 00165 T* array_; 00166 T empty_; // The unused cell. 00167 int dim1_; // Size of the 1st dimension in indexing functions. 00168 int dim2_; // Size of the 2nd dimension in indexing functions. 00169 }; 00170 00171 // A generic class to store a square matrix with entries of type T. 00172 template <class T> 00173 class GENERIC_MATRIX : public GENERIC_2D_ARRAY<T> { 00174 public: 00175 // Allocate a piece of memory to hold a matrix of the given dimension. 00176 // Initialize all the elements of the matrix to empty instead of assuming 00177 // that a default constructor can be used. 00178 GENERIC_MATRIX(int dimension, const T& empty) 00179 : GENERIC_2D_ARRAY<T>(dimension, dimension, empty) { 00180 } 00181 00182 // Provide the dimension of this square matrix. 00183 int dimension() const { return this->dim1(); } 00184 }; 00185 00186 class MATRIX : public GENERIC_MATRIX<BLOB_CHOICE_LIST *> { 00187 public: 00188 MATRIX(int dimension) : GENERIC_MATRIX<BLOB_CHOICE_LIST *>(dimension, 00189 NOT_CLASSIFIED) {} 00190 // Print a shortened version of the contents of the matrix. 00191 void print(const UNICHARSET &unicharset); 00192 }; 00193 00194 struct MATRIX_COORD { 00195 static void Delete(void *arg) { 00196 MATRIX_COORD *c = static_cast<MATRIX_COORD *>(arg); 00197 delete c; 00198 } 00199 MATRIX_COORD(int c, int r): col(c), row(r) {} 00200 ~MATRIX_COORD() {} 00201 bool Valid(const MATRIX &m) const { 00202 return (col >= 0 && row >= 0 && 00203 col < m.dimension() && row < m.dimension()); 00204 } 00205 int col; 00206 int row; 00207 }; 00208 00209 #endif // TESSERACT_CCSTRUCT_MATRIX_H__