Tesseract
3.02
|
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. The matrix is 00105 // stored COLUMN-major, so the left-most index is the most significant. 00106 // This allows [][] access to use indices in the same order as (,). 00107 int index(int column, int row) const { 00108 return (column * dim2_ + row); 00109 } 00110 00111 // Put a list element into the matrix at a specific location. 00112 void put(int column, int row, const T& thing) { 00113 array_[this->index(column, row)] = thing; 00114 } 00115 00116 // Get the item at a specified location from the matrix. 00117 T get(int column, int row) const { 00118 return array_[this->index(column, row)]; 00119 } 00120 // Return a reference to the element at the specified location. 00121 const T& operator()(int column, int row) const { 00122 return array_[this->index(column, row)]; 00123 } 00124 T& operator()(int column, int row) { 00125 return array_[this->index(column, row)]; 00126 } 00127 // Allow access using array[column][row]. NOTE that the indices are 00128 // in the same left-to-right order as the () indexing. 00129 T* operator[](int column) { 00130 return &array_[this->index(column, 0)]; 00131 } 00132 00133 // Delete objects pointed to by array_[i]. 00134 void delete_matrix_pointers() { 00135 for (int x = 0; x < dim1_; x++) { 00136 for (int y = 0; y < dim2_; y++) { 00137 T matrix_cell = this->get(x, y); 00138 if (matrix_cell != empty_) 00139 delete matrix_cell; 00140 } 00141 } 00142 } 00143 00144 private: 00145 // Factored helper to serialize the size. 00146 bool SerializeSize(FILE* fp) const { 00147 inT32 size = dim1_; 00148 if (fwrite(&size, sizeof(size), 1, fp) != 1) return false; 00149 size = dim2_; 00150 if (fwrite(&size, sizeof(size), 1, fp) != 1) return false; 00151 return true; 00152 } 00153 // Factored helper to deserialize the size. 00154 // If swap is true, assumes a big/little-endian swap is needed. 00155 bool DeSerializeSize(bool swap, FILE* fp) { 00156 inT32 size1, size2; 00157 if (fread(&size1, sizeof(size1), 1, fp) != 1) return false; 00158 if (fread(&size2, sizeof(size2), 1, fp) != 1) return false; 00159 if (swap) { 00160 ReverseN(&size1, sizeof(size1)); 00161 ReverseN(&size2, sizeof(size2)); 00162 } 00163 if (size1 != dim1_ || size2 != dim2_) { 00164 dim1_ = size1; 00165 dim2_ = size2; 00166 delete [] array_; 00167 array_ = new T[dim1_ * dim2_]; 00168 } 00169 return true; 00170 } 00171 00172 T* array_; 00173 T empty_; // The unused cell. 00174 int dim1_; // Size of the 1st dimension in indexing functions. 00175 int dim2_; // Size of the 2nd dimension in indexing functions. 00176 }; 00177 00178 // A generic class to store a square matrix with entries of type T. 00179 template <class T> 00180 class GENERIC_MATRIX : public GENERIC_2D_ARRAY<T> { 00181 public: 00182 // Allocate a piece of memory to hold a matrix of the given dimension. 00183 // Initialize all the elements of the matrix to empty instead of assuming 00184 // that a default constructor can be used. 00185 GENERIC_MATRIX(int dimension, const T& empty) 00186 : GENERIC_2D_ARRAY<T>(dimension, dimension, empty) { 00187 } 00188 00189 // Provide the dimension of this square matrix. 00190 int dimension() const { return this->dim1(); } 00191 }; 00192 00193 class MATRIX : public GENERIC_MATRIX<BLOB_CHOICE_LIST *> { 00194 public: 00195 MATRIX(int dimension) : GENERIC_MATRIX<BLOB_CHOICE_LIST *>(dimension, 00196 NOT_CLASSIFIED) {} 00197 // Print a shortened version of the contents of the matrix. 00198 void print(const UNICHARSET &unicharset) const; 00199 }; 00200 00201 struct MATRIX_COORD { 00202 static void Delete(void *arg) { 00203 MATRIX_COORD *c = static_cast<MATRIX_COORD *>(arg); 00204 delete c; 00205 } 00206 MATRIX_COORD(int c, int r): col(c), row(r) {} 00207 ~MATRIX_COORD() {} 00208 bool Valid(const MATRIX &m) const { 00209 return (col >= 0 && row >= 0 && 00210 col < m.dimension() && row < m.dimension()); 00211 } 00212 int col; 00213 int row; 00214 }; 00215 00216 #endif // TESSERACT_CCSTRUCT_MATRIX_H__