1 /******************************************************************************
2 ** Filename: features.c
3 ** Purpose: Generic definition of a feature.
4 ** Author: Dan Johnson
5 ** History: Mon May 21 10:49:04 1990, DSJ, Created.
6 **
7 ** (c) Copyright Hewlett-Packard Company, 1988.
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 Include Files and Type Defines
20 ----------------------------------------------------------------------------**/
21 #include "ocrfeatures.h"
22 #include "emalloc.h"
23 #include "callcpp.h"
24 #include "danerror.h"
25 #include "freelist.h"
26 #include "scanutils.h"
27
28 #include <assert.h>
29 #include <math.h>
30
31 /**----------------------------------------------------------------------------
32 Public Code
33 ----------------------------------------------------------------------------**/
34 /*---------------------------------------------------------------------------*/
AddFeature(FEATURE_SET FeatureSet,FEATURE Feature)35 BOOL8 AddFeature(FEATURE_SET FeatureSet, FEATURE Feature) {
36 /*
37 ** Parameters:
38 ** FeatureSet set of features to add Feature to
39 ** Feature feature to be added to FeatureSet
40 ** Globals: none
41 ** Operation: Add a feature to a feature set. If the feature set is
42 ** already full, FALSE is returned to indicate that the
43 ** feature could not be added to the set; otherwise, TRUE is
44 ** returned.
45 ** Return: TRUE if feature added to set, FALSE if set is already full.
46 ** Exceptions: none
47 ** History: Tue May 22 17:22:23 1990, DSJ, Created.
48 */
49 if (FeatureSet->NumFeatures >= FeatureSet->MaxNumFeatures) {
50 FreeFeature(Feature);
51 return FALSE;
52 }
53
54 FeatureSet->Features[FeatureSet->NumFeatures++] = Feature;
55 return TRUE;
56 } /* AddFeature */
57
58 /*---------------------------------------------------------------------------*/
FreeFeature(FEATURE Feature)59 void FreeFeature(FEATURE Feature) {
60 /*
61 ** Parameters:
62 ** Feature feature to be deallocated.
63 ** Globals: none
64 ** Operation: Release the memory consumed by the specified feature.
65 ** Return: none
66 ** Exceptions: none
67 ** History: Mon May 21 13:33:27 1990, DSJ, Created.
68 */
69 if (Feature) {
70 free_struct (Feature, sizeof (FEATURE_STRUCT)
71 + sizeof (FLOAT32) * (Feature->Type->NumParams - 1),
72 "sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)");
73 }
74
75 } /* FreeFeature */
76
77
78 /*---------------------------------------------------------------------------*/
FreeFeatureSet(FEATURE_SET FeatureSet)79 void FreeFeatureSet(FEATURE_SET FeatureSet) {
80 /*
81 ** Parameters:
82 ** FeatureSet set of features to be freed
83 ** Globals: none
84 ** Operation: Release the memory consumed by the specified feature
85 ** set. This routine also frees the memory consumed by the
86 ** features contained in the set.
87 ** Return: none
88 ** Exceptions: none
89 ** History: Mon May 21 13:59:46 1990, DSJ, Created.
90 */
91 int i;
92
93 if (FeatureSet) {
94 for (i = 0; i < FeatureSet->NumFeatures; i++)
95 FreeFeature(FeatureSet->Features[i]);
96 memfree(FeatureSet);
97 }
98 } /* FreeFeatureSet */
99
100
101 /*---------------------------------------------------------------------------*/
NewFeature(FEATURE_DESC FeatureDesc)102 FEATURE NewFeature(FEATURE_DESC FeatureDesc) {
103 /*
104 ** Parameters:
105 ** FeatureDesc description of feature to be created.
106 ** Globals: none
107 ** Operation: Allocate and return a new feature of the specified
108 ** type.
109 ** Return: New feature.
110 ** Exceptions: none
111 ** History: Mon May 21 14:06:42 1990, DSJ, Created.
112 */
113 FEATURE Feature;
114
115 Feature = (FEATURE) alloc_struct (sizeof (FEATURE_STRUCT) +
116 (FeatureDesc->NumParams - 1) *
117 sizeof (FLOAT32),
118 "sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)");
119 Feature->Type = FeatureDesc;
120 return (Feature);
121
122 } /* NewFeature */
123
124
125 /*---------------------------------------------------------------------------*/
NewFeatureSet(int NumFeatures)126 FEATURE_SET NewFeatureSet(int NumFeatures) {
127 /*
128 ** Parameters:
129 ** NumFeatures maximum # of features to be put in feature set
130 ** Globals: none
131 ** Operation: Allocate and return a new feature set large enough to
132 ** hold the specified number of features.
133 ** Return: New feature set.
134 ** Exceptions: none
135 ** History: Mon May 21 14:22:40 1990, DSJ, Created.
136 */
137 FEATURE_SET FeatureSet;
138
139 FeatureSet = (FEATURE_SET) Emalloc (sizeof (FEATURE_SET_STRUCT) +
140 (NumFeatures - 1) * sizeof (FEATURE));
141 FeatureSet->MaxNumFeatures = NumFeatures;
142 FeatureSet->NumFeatures = 0;
143 return (FeatureSet);
144
145 } /* NewFeatureSet */
146
147
148 /*---------------------------------------------------------------------------*/
ReadFeature(FILE * File,FEATURE_DESC FeatureDesc)149 FEATURE ReadFeature(FILE *File, FEATURE_DESC FeatureDesc) {
150 /*
151 ** Parameters:
152 ** File open text file to read feature from
153 ** FeatureDesc specifies type of feature to read from File
154 ** Globals: none
155 ** Operation: Create a new feature of the specified type and read in
156 ** the value of its parameters from File. The extra penalty
157 ** for the feature is also computed by calling the appropriate
158 ** function for the specified feature type. The correct text
159 ** representation for a feature is a list of N floats where
160 ** N is the number of parameters in the feature.
161 ** Return: New feature read from File.
162 ** Exceptions: ILLEGAL_FEATURE_PARAM if text file doesn't match expected format
163 ** History: Wed May 23 08:53:16 1990, DSJ, Created.
164 */
165 FEATURE Feature;
166 int i;
167
168 Feature = NewFeature (FeatureDesc);
169 for (i = 0; i < Feature->Type->NumParams; i++) {
170 if (fscanf (File, "%f", &(Feature->Params[i])) != 1)
171 DoError (ILLEGAL_FEATURE_PARAM, "Illegal feature parameter spec");
172 #ifndef __MSW32__
173 assert (!isnan(Feature->Params[i]));
174 #endif
175 }
176 return (Feature);
177
178 } /* ReadFeature */
179
180
181 /*---------------------------------------------------------------------------*/
ReadFeatureSet(FILE * File,FEATURE_DESC FeatureDesc)182 FEATURE_SET ReadFeatureSet(FILE *File, FEATURE_DESC FeatureDesc) {
183 /*
184 ** Parameters:
185 ** File open text file to read new feature set from
186 ** FeatureDesc specifies type of feature to read from File
187 ** Globals: none
188 ** Operation: Create a new feature set of the specified type and read in
189 ** the features from File. The correct text representation
190 ** for a feature set is an integer which specifies the number (N)
191 ** of features in a set followed by a list of N feature
192 ** descriptions.
193 ** Return: New feature set read from File.
194 ** Exceptions: none
195 ** History: Wed May 23 09:17:31 1990, DSJ, Created.
196 */
197 FEATURE_SET FeatureSet;
198 int NumFeatures;
199 int i;
200
201 if (fscanf (File, "%d", &NumFeatures) != 1 || NumFeatures < 0)
202 DoError (ILLEGAL_NUM_FEATURES, "Illegal number of features in set");
203
204 FeatureSet = NewFeatureSet (NumFeatures);
205 for (i = 0; i < NumFeatures; i++)
206 AddFeature (FeatureSet, ReadFeature (File, FeatureDesc));
207
208 return (FeatureSet);
209
210 } /* ReadFeatureSet */
211
212
213 /*---------------------------------------------------------------------------*/
WriteFeature(FILE * File,FEATURE Feature)214 void WriteFeature(FILE *File, FEATURE Feature) {
215 /*
216 ** Parameters:
217 ** File open text file to write Feature to
218 ** Feature feature to write out to File
219 ** Globals: none
220 ** Operation: Write a textual representation of Feature to File.
221 ** This representation is simply a list of the N parameters
222 ** of the feature, terminated with a newline. It is assumed
223 ** that the ExtraPenalty field can be reconstructed from the
224 ** parameters of the feature. It is also assumed that the
225 ** feature type information is specified or assumed elsewhere.
226 ** Return: none
227 ** Exceptions: none
228 ** History: Wed May 23 09:28:18 1990, DSJ, Created.
229 */
230 int i;
231
232 for (i = 0; i < Feature->Type->NumParams; i++) {
233 #ifndef __MSW32__
234 assert (!isnan(Feature->Params[i]));
235 #endif
236 fprintf (File, " %12g", Feature->Params[i]);
237 }
238 fprintf (File, "\n");
239
240 } /* WriteFeature */
241
242
243 /*---------------------------------------------------------------------------*/
WriteFeatureSet(FILE * File,FEATURE_SET FeatureSet)244 void WriteFeatureSet(FILE *File, FEATURE_SET FeatureSet) {
245 /*
246 ** Parameters:
247 ** File open text file to write FeatureSet to
248 ** FeatureSet feature set to write to File
249 ** Globals: none
250 ** Operation: Write a textual representation of FeatureSet to File.
251 ** This representation is an integer specifying the number of
252 ** features in the set, followed by a newline, followed by
253 ** text representations for each feature in the set.
254 ** Return: none
255 ** Exceptions: none
256 ** History: Wed May 23 10:06:03 1990, DSJ, Created.
257 */
258 int i;
259
260 if (FeatureSet) {
261 fprintf (File, "%d\n", FeatureSet->NumFeatures);
262 for (i = 0; i < FeatureSet->NumFeatures; i++)
263 WriteFeature (File, FeatureSet->Features[i]);
264 }
265 } /* WriteFeatureSet */
266
267
268 /*---------------------------------------------------------------------------*/
WriteOldParamDesc(FILE * File,FEATURE_DESC FeatureDesc)269 void WriteOldParamDesc(FILE *File, FEATURE_DESC FeatureDesc) {
270 /*
271 ** Parameters:
272 ** File open text file to write FeatureDesc to
273 ** FeatureDesc feature descriptor to write to File
274 ** Globals: none
275 ** Operation: Write a textual representation of FeatureDesc to File
276 ** in the old format (i.e. the format used by the clusterer).
277 ** This format is:
278 ** Number of Params
279 ** Description of Param 1
280 ** ...
281 ** Return: none
282 ** Exceptions: none
283 ** History: Fri May 25 15:27:18 1990, DSJ, Created.
284 */
285 int i;
286
287 fprintf (File, "%d\n", FeatureDesc->NumParams);
288 for (i = 0; i < FeatureDesc->NumParams; i++) {
289 if (FeatureDesc->ParamDesc[i].Circular)
290 fprintf (File, "circular ");
291 else
292 fprintf (File, "linear ");
293
294 if (FeatureDesc->ParamDesc[i].NonEssential)
295 fprintf (File, "non-essential ");
296 else
297 fprintf (File, "essential ");
298
299 fprintf (File, "%f %f\n",
300 FeatureDesc->ParamDesc[i].Min, FeatureDesc->ParamDesc[i].Max);
301 }
302 } /* WriteOldParamDesc */
303