1 /******************************************************************************
2  ** Filename:    ocrfeatures.cpp
3  ** Purpose:     Generic definition of a feature.
4  ** Author:      Dan Johnson
5  **
6  ** (c) Copyright Hewlett-Packard Company, 1988.
7  ** Licensed under the Apache License, Version 2.0 (the "License");
8  ** you may not use this file except in compliance with the License.
9  ** You may obtain a copy of the License at
10  ** http://www.apache.org/licenses/LICENSE-2.0
11  ** Unless required by applicable law or agreed to in writing, software
12  ** distributed under the License is distributed on an "AS IS" BASIS,
13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  ** See the License for the specific language governing permissions and
15  ** limitations under the License.
16  ******************************************************************************/
17 
18 #include "ocrfeatures.h"
19 
20 #include "scanutils.h"
21 
22 #include <cassert>
23 #include <cmath>
24 
25 namespace tesseract {
26 
27 /*----------------------------------------------------------------------------
28               Public Code
29 ----------------------------------------------------------------------------*/
30 /**
31  * Add a feature to a feature set.  If the feature set is
32  * already full, false is returned to indicate that the
33  * feature could not be added to the set; otherwise, true is
34  * returned.
35  * @param FeatureSet set of features to add Feature to
36  * @param Feature feature to be added to FeatureSet
37  * @return  true if feature added to set, false if set is already full.
38  */
AddFeature(FEATURE_SET FeatureSet,FEATURE Feature)39 bool AddFeature(FEATURE_SET FeatureSet, FEATURE Feature) {
40   if (FeatureSet->NumFeatures >= FeatureSet->MaxNumFeatures) {
41     delete Feature;
42     return false;
43   }
44 
45   FeatureSet->Features[FeatureSet->NumFeatures++] = Feature;
46   return true;
47 } /* AddFeature */
48 
49 /**
50  * Create a new feature of the specified type and read in
51  * the value of its parameters from File.  The extra penalty
52  * for the feature is also computed by calling the appropriate
53  * function for the specified feature type.  The correct text
54  * representation for a feature is a list of N floats where
55  * N is the number of parameters in the feature.
56  * @param File open text file to read feature from
57  * @param FeatureDesc specifies type of feature to read from File
58  * @return New #FEATURE read from File.
59  */
ReadFeature(FILE * File,const FEATURE_DESC_STRUCT * FeatureDesc)60 static FEATURE ReadFeature(FILE *File, const FEATURE_DESC_STRUCT *FeatureDesc) {
61   auto Feature = new FEATURE_STRUCT(FeatureDesc);
62   for (int i = 0; i < Feature->Type->NumParams; i++) {
63     ASSERT_HOST(tfscanf(File, "%f", &(Feature->Params[i])) == 1);
64 #ifndef _WIN32
65     assert(!std::isnan(Feature->Params[i]));
66 #endif
67   }
68   return Feature;
69 }
70 
71 /**
72  * Create a new feature set of the specified type and read in
73  * the features from File.  The correct text representation
74  * for a feature set is an integer which specifies the number (N)
75  * of features in a set followed by a list of N feature
76  * descriptions.
77  * @param File open text file to read new feature set from
78  * @param FeatureDesc specifies type of feature to read from File
79  * @return New feature set read from File.
80  */
ReadFeatureSet(FILE * File,const FEATURE_DESC_STRUCT * FeatureDesc)81 FEATURE_SET ReadFeatureSet(FILE *File, const FEATURE_DESC_STRUCT *FeatureDesc) {
82   int NumFeatures;
83   ASSERT_HOST(tfscanf(File, "%d", &NumFeatures) == 1);
84   ASSERT_HOST(NumFeatures >= 0);
85 
86   auto FeatureSet = new FEATURE_SET_STRUCT(NumFeatures);
87   for (int i = 0; i < NumFeatures; i++) {
88     AddFeature(FeatureSet, ReadFeature(File, FeatureDesc));
89   }
90 
91   return FeatureSet;
92 }
93 
94 /**
95  * Appends a textual representation of Feature to str.
96  * This representation is simply a list of the N parameters
97  * of the feature, terminated with a newline.  It is assumed
98  * that the ExtraPenalty field can be reconstructed from the
99  * parameters of the feature.  It is also assumed that the
100  * feature type information is specified or assumed elsewhere.
101  * @param Feature feature to write out to str
102  * @param str string to write Feature to
103  */
WriteFeature(FEATURE Feature,std::string & str)104 static void WriteFeature(FEATURE Feature, std::string &str) {
105   for (int i = 0; i < Feature->Type->NumParams; i++) {
106 #ifndef WIN32
107     assert(!std::isnan(Feature->Params[i]));
108 #endif
109     str += " " + std::to_string(Feature->Params[i]);
110   }
111   str += "\n";
112 } /* WriteFeature */
113 
114 /**
115  * Write a textual representation of FeatureSet to File.
116  * This representation is an integer specifying the number of
117  * features in the set, followed by a newline, followed by
118  * text representations for each feature in the set.
119  * @param FeatureSet feature set to write to File
120  * @param str string to write Feature to
121  */
WriteFeatureSet(FEATURE_SET FeatureSet,std::string & str)122 void WriteFeatureSet(FEATURE_SET FeatureSet, std::string &str) {
123   if (FeatureSet) {
124     str += "" + std::to_string(FeatureSet->NumFeatures);
125     str += "\n";
126     for (int i = 0; i < FeatureSet->NumFeatures; i++) {
127       WriteFeature(FeatureSet->Features[i], str);
128     }
129   }
130 } /* WriteFeatureSet */
131 
132 } // namespace tesseract
133