• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*-C-*-
2  ********************************************************************************
3  *
4  * File:        choices.c  (Formerly choices.c)
5  * Description:  Handle the new ratings choices for Wise Owl
6  * Author:       Mark Seaman, OCR Technology
7  * Created:      Fri Sep 22 14:05:51 1989
8  * Modified:     Wed May 22 14:12:34 1991 (Mark Seaman) marks@hpgrlt
9  * Language:     C
10  * Package:      N/A
11  * Status:       Experimental (Do Not Distribute)
12  *
13  * (c) Copyright 1989, 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 #include "choices.h"
26 #include "emalloc.h"
27 #include "globals.h"
28 #include "host.h"
29 #include "danerror.h"
30 #include "structures.h"
31 #include "tordvars.h"
32 #include "tprintf.h"
33 #include "unicharset.h"
34 #include "dict.h"
35 #include "image.h"
36 
37 /*----------------------------------------------------------------------
38             Variables
39 ------------------------------------------------------------------------*/
40 #define CHOICEBLOCK 100          /*  Cells per block */
41 
42 makestructure (newchoice, oldchoice, printchoice, A_CHOICE,
43 freechoice, CHOICEBLOCK, "A_CHOICE", choicecount)
44 /*----------------------------------------------------------------------
45               F u n c t i o n s
46 ----------------------------------------------------------------------*/
47 /**********************************************************************
48  * append_char_choice
49  *
50  * Create a new choice record. Store the string value in a safe place.
51  * Add the new choice record to the list.
52  *
53  * NB - This is only used by matchers, so permuter is always NO_PERM
54  * SPC 16/9/92
55  **********************************************************************/
append_char_choice(CHOICES ratings,const char * string,const char * lengths,float rating,float certainty,inT8 config,int script_id)56 CHOICES append_char_choice(CHOICES ratings,
57                            const char *string,
58                            const char *lengths,
59                            float rating,
60                            float certainty,
61                            inT8 config,
62                            int script_id) {
63   A_CHOICE *this_choice;
64 
65   this_choice = new_choice (string, lengths, rating, certainty,
66                             config, script_id, NO_PERM, false, NULL);
67   ratings = push_last (ratings, (LIST) this_choice);
68   return (ratings);
69 }
70 
71 /**********************************************************************
72  * copy_choices
73  *
74  * Copy a list of choices.  This means that there will be two copies
75  * in memory.
76  **********************************************************************/
copy_choices(CHOICES choices)77 CHOICES copy_choices(CHOICES choices) {
78   CHOICES l;
79   CHOICES result = NIL;
80 
81   iterate_list(l, choices) {
82     A_CHOICE *choice = (A_CHOICE *)(first_node(l));
83     result = push (result,
84       (LIST) new_choice (class_string(choice),
85                          class_lengths(choice),
86                          class_rating(choice),
87                          class_certainty(choice),
88                          class_config(choice),
89                          class_script_id(choice),
90                          class_permuter(choice),
91                          class_fragment_mark(choice),
92                          class_fragment_lengths(choice)));
93   }
94   return (reverse_d (result));
95 }
96 
97 /**********************************************************************
98  * clone_choice
99  *
100  * Copy the contents of the given values to the corresponding values in
101  * a given choice replacing any previous values it might have had.
102  **********************************************************************/
clone_choice(A_CHOICE * choice,const char * string,const char * lengths,float rating,float certainty,inT8 permuter,bool fragment_mark,const char * fragment_lengths)103 void clone_choice(A_CHOICE *choice, const char *string,
104                   const char *lengths, float rating, float certainty,
105                   inT8 permuter, bool fragment_mark,
106                   const char *fragment_lengths) {
107   if (choice->string) strfree (class_string (choice));
108   if (choice->lengths) strfree (class_lengths (choice));
109   if (choice->fragment_lengths) strfree(choice->fragment_lengths);
110 
111   choice->string = strsave (string);
112   choice->lengths = strsave (lengths);
113   choice->rating = rating;
114   choice->certainty = certainty;
115   choice->permuter = permuter;
116   choice->fragment_mark = fragment_mark;
117   choice->fragment_lengths =
118     fragment_lengths ? strsave(fragment_lengths) : NULL;
119 }
120 
121 /**********************************************************************
122  * clear_choice
123  *
124  * Set the fields in this choice to be defaulted bad initial values.
125  **********************************************************************/
clear_choice(A_CHOICE * choice)126 void clear_choice(A_CHOICE *choice) {
127   choice->string = NULL;
128   choice->lengths =  NULL;
129   choice->rating =  MAX_FLOAT32;
130   choice->certainty = -MAX_FLOAT32;
131   choice->fragment_mark = false;
132   choice->fragment_lengths = NULL;
133 }
134 
135 
136 /**********************************************************************
137  * free_choice
138  *
139  * Free up the memory taken by one choice rating.
140  **********************************************************************/
free_choice(void * arg)141 void free_choice(void *arg) {  //LIST choice)
142   A_CHOICE *this_choice;
143   LIST choice = (LIST) arg;
144 
145   this_choice = (A_CHOICE *) choice;
146   if (this_choice) {
147     if (this_choice->string)
148       strfree (this_choice->string);
149     if (this_choice->lengths)
150       strfree (this_choice->lengths);
151     if (this_choice->fragment_lengths)
152       strfree (this_choice->fragment_lengths);
153     oldchoice(this_choice);
154   }
155 }
156 
157 /**********************************************************************
158  * get_best_free_other
159  *
160  * Returns the best of two choices and frees the other (worse) choice.
161  * A choice is better if it has a non-NULL string and has a lower rating
162  * than the other choice.
163  **********************************************************************/
get_best_free_other(A_CHOICE * choice_1,A_CHOICE * choice_2)164 A_CHOICE *get_best_free_other(A_CHOICE *choice_1, A_CHOICE *choice_2) {
165   if (!choice_1) return choice_2;
166   if (!choice_2) return choice_1;
167   if (class_rating (choice_1) < class_rating (choice_2) ||
168       class_string (choice_2) == NULL) {
169     free_choice(choice_2);
170     return choice_1;
171   } else {
172     free_choice(choice_1);
173     return choice_2;
174   }
175 }
176 
177 /**********************************************************************
178  * new_choice
179  *
180  * Create a new choice record. Store the string value in a safe place.
181  **********************************************************************/
new_choice(const char * string,const char * lengths,float rating,float certainty,inT8 config,int script_id,char permuter,bool fragment_mark,const char * fragment_lengths)182 A_CHOICE *new_choice(const char *string,
183                      const char *lengths,
184                      float rating,
185                      float certainty,
186                      inT8 config,
187                      int script_id,
188                      char permuter,
189                      bool fragment_mark,
190                      const char *fragment_lengths) {
191   A_CHOICE *this_choice;
192 
193   this_choice = newchoice();
194   this_choice->string = strsave(string);
195   this_choice->lengths = strsave(lengths);
196   this_choice->rating = rating;
197   this_choice->certainty = certainty;
198   this_choice->config = config;
199   this_choice->permuter = permuter;
200   this_choice->script_id = script_id;
201   this_choice->fragment_mark = fragment_mark;
202   this_choice->fragment_lengths =
203     fragment_lengths ? strsave(fragment_lengths) : NULL;
204 
205   return (this_choice);
206 }
207 
new_choice(const char * string,const char * lengths,float rating,float certainty,inT8 config,char permuter)208 A_CHOICE *new_choice(const char *string,
209                      const char *lengths,
210                      float rating,
211                      float certainty,
212                      inT8 config,
213                      char permuter) {
214   return new_choice(string, lengths, rating, certainty,
215                     config, -1, permuter, false, NULL);
216 }
217 
218 
219 /**********************************************************************
220  * print_choices
221  *
222  * Print the rating for a particular blob or word.
223  **********************************************************************/
224 namespace tesseract {
print_choices(const char * label,CHOICES choices)225 void Dict::print_choices(const char *label,
226                          CHOICES choices) {   // List of (A_CHOICE*).
227   tprintf("%s\n", label);
228   if (choices == NIL)
229     tprintf(" No rating ");
230 
231   iterate(choices) {
232     tprintf("%.2f %.2f", best_rating(choices), best_certainty(choices));
233     print_word_string(best_string(choices));
234   }
235   tprintf("\n");
236 }
237 
238 /**********************************************************************
239  * print_word_choice
240  *
241  * Print the string in a human-readable format and ratings for a word.
242  **********************************************************************/
print_word_choice(const char * label,A_CHOICE * choice)243 void Dict::print_word_choice(const char *label, A_CHOICE* choice) {
244   tprintf("%s : ", label);
245   if (choice == NULL) {
246     tprintf("No rating\n");
247   } else {
248     tprintf("%.2f %.2f", class_rating(choice), class_certainty(choice));
249     print_word_string(class_string(choice));
250     tprintf("\n");
251   }
252 }
253 
254 /**********************************************************************
255  * print_word_string
256  *
257  * Print the string in a human-readable format.
258  * The output is not newline terminated.
259  **********************************************************************/
print_word_string(const char * str)260 void Dict::print_word_string(const char* str) {
261   int step = 1;
262   for (int i = 0; str[i] != '\0'; i += step) {
263     step = (getUnicharset().get_fragment(str) ?
264       strlen(str) : getUnicharset().step(str + i));
265     int unichar_id = getUnicharset().unichar_to_id(str + i, step);
266     tprintf(" : %s ", getUnicharset().debug_str(unichar_id).string());
267   }
268 }
269 } // namespace tesseract
270