tesseract  3.05.02
intproto.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  ** Filename: intproto.c
3  ** Purpose: Definition of data structures for integer protos.
4  ** Author: Dan Johnson
5  ** History: Thu Feb 7 14:38:16 1991, 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 
22 #include <math.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #ifdef __UNIX__
26 #include <unistd.h>
27 #endif
28 
29 #include "classify.h"
30 #include "const.h"
31 #include "emalloc.h"
32 #include "fontinfo.h"
33 #include "genericvector.h"
34 #include "globals.h"
35 #include "helpers.h"
36 #include "intproto.h"
37 #include "mfoutline.h"
38 #include "ndminx.h"
39 #include "picofeat.h"
40 #include "points.h"
41 #include "shapetable.h"
42 #include "svmnode.h"
43 
44 // Include automatically generated configuration file if running autoconf.
45 #ifdef HAVE_CONFIG_H
46 #include "config_auto.h"
47 #endif
48 
49 using tesseract::FontSet;
50 
51 /* match debug display constants*/
52 #define PROTO_PRUNER_SCALE (4.0)
53 
54 #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE)
55 #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE)
56 #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE)
57 #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE)
58 
59 #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE)
60 #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE)
61 #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE)
62 #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE)
63 #define INT_MIN_X 0
64 #define INT_MIN_Y 0
65 #define INT_MAX_X INT_CHAR_NORM_RANGE
66 #define INT_MAX_Y INT_CHAR_NORM_RANGE
67 
69 #define HV_TOLERANCE (0.0025) /* approx 0.9 degrees */
70 
71 typedef enum
74 #define MAX_NUM_SWITCHES 3
75 
76 typedef struct
77 {
79  inT8 X, Y;
82 }
83 
84 
86 
87 typedef struct
88 {
90  uinT8 AngleStart, AngleEnd;
92  inT16 YStart, YEnd;
93  inT16 StartDelta, EndDelta;
95 }
96 
97 
99 
100 typedef struct
101 {
103  inT8 YStart, YEnd;
104  uinT8 AngleStart, AngleEnd;
105 }
106 
107 
108 FILL_SPEC;
109 
110 
111 /* constants for conversion from old inttemp format */
112 #define OLD_MAX_NUM_CONFIGS 32
113 #define OLD_WERDS_PER_CONFIG_VEC ((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\
114  BITS_PER_WERD)
115 
116 /*-----------------------------------------------------------------------------
117  Macros
118 -----------------------------------------------------------------------------*/
120 #define CircularIncrement(i,r) (((i) < (r) - 1)?((i)++):((i) = 0))
121 
123 #define MapParam(P,O,N) (floor (((P) + (O)) * (N)))
124 
125 /*---------------------------------------------------------------------------
126  Private Function Prototypes
127 ----------------------------------------------------------------------------*/
128 FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets);
129 
130 FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets);
131 
132 void DoFill(FILL_SPEC *FillSpec,
133  CLASS_PRUNER_STRUCT* Pruner,
134  register uinT32 ClassMask,
135  register uinT32 ClassCount,
136  register uinT32 WordIndex);
137 
138 BOOL8 FillerDone(TABLE_FILLER *Filler);
139 
141  ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
142  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug);
143 
145  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug);
146 
147 void GetCPPadsForLevel(int Level,
148  FLOAT32 *EndPad,
149  FLOAT32 *SidePad,
150  FLOAT32 *AnglePad);
151 
153 
154 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill);
155 
156 void InitTableFiller(FLOAT32 EndPad,
157  FLOAT32 SidePad,
158  FLOAT32 AnglePad,
159  PROTO Proto,
160  TABLE_FILLER *Filler);
161 
162 #ifndef GRAPHICS_DISABLED
163 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
164  ScrollView::Color color);
165 
166 void RenderIntProto(ScrollView *window,
167  INT_CLASS Class,
168  PROTO_ID ProtoId,
169  ScrollView::Color color);
170 #endif // GRAPHICS_DISABLED
171 
172 int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id);
173 
174 /*-----------------------------------------------------------------------------
175  Global Data Definitions and Declarations
176 -----------------------------------------------------------------------------*/
177 
178 /* global display lists used to display proto and feature match information*/
182 
183 /*-----------------------------------------------------------------------------
184  Variables
185 -----------------------------------------------------------------------------*/
186 
187 /* control knobs */
188 INT_VAR(classify_num_cp_levels, 3, "Number of Class Pruner Levels");
190  "Class Pruner Angle Pad Loose");
192  "Class Pruner Angle Pad Medium");
194  "CLass Pruner Angle Pad Tight");
195 double_VAR(classify_cp_end_pad_loose, 0.5, "Class Pruner End Pad Loose");
196 double_VAR(classify_cp_end_pad_medium, 0.5, "Class Pruner End Pad Medium");
197 double_VAR(classify_cp_end_pad_tight, 0.5, "Class Pruner End Pad Tight");
198 double_VAR(classify_cp_side_pad_loose, 2.5, "Class Pruner Side Pad Loose");
199 double_VAR(classify_cp_side_pad_medium, 1.2, "Class Pruner Side Pad Medium");
200 double_VAR(classify_cp_side_pad_tight, 0.6, "Class Pruner Side Pad Tight");
201 double_VAR(classify_pp_angle_pad, 45.0, "Proto Pruner Angle Pad");
202 double_VAR(classify_pp_end_pad, 0.5, "Proto Prune End Pad");
203 double_VAR(classify_pp_side_pad, 2.5, "Proto Pruner Side Pad");
204 
205 /*-----------------------------------------------------------------------------
206  Public Code
207 -----------------------------------------------------------------------------*/
211  : X(ClipToRange<inT16>(static_cast<inT16>(pos.x() + 0.5), 0, 255)),
212  Y(ClipToRange<inT16>(static_cast<inT16>(pos.y() + 0.5), 0, 255)),
213  Theta(theta),
214  CP_misses(0) {
215 }
218  : X(static_cast<uinT8>(ClipToRange(x, 0, MAX_UINT8))),
219  Y(static_cast<uinT8>(ClipToRange(y, 0, MAX_UINT8))),
220  Theta(static_cast<uinT8>(ClipToRange(theta, 0, MAX_UINT8))),
221  CP_misses(0) {
222 }
223 
238 void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) {
239  int Pruner;
240 
241  assert (LegalClassId (ClassId));
242  if (ClassId != Templates->NumClasses) {
243  fprintf(stderr, "Please make sure that classes are added to templates");
244  fprintf(stderr, " in increasing order of ClassIds\n");
245  exit(1);
246  }
247  ClassForClassId (Templates, ClassId) = Class;
248  Templates->NumClasses++;
249 
250  if (Templates->NumClasses > MaxNumClassesIn (Templates)) {
251  Pruner = Templates->NumClassPruners++;
252  Templates->ClassPruners[Pruner] = new CLASS_PRUNER_STRUCT;
253  memset(Templates->ClassPruners[Pruner], 0, sizeof(CLASS_PRUNER_STRUCT));
254  }
255 } /* AddIntClass */
256 
257 
271  int Index;
272 
273  assert(Class->NumConfigs < MAX_NUM_CONFIGS);
274 
275  Index = Class->NumConfigs++;
276  Class->ConfigLengths[Index] = 0;
277  return Index;
278 } /* AddIntConfig */
279 
280 
293 int AddIntProto(INT_CLASS Class) {
294  int Index;
295  int ProtoSetId;
296  PROTO_SET ProtoSet;
297  INT_PROTO Proto;
298  uinT32 *Word;
299 
300  if (Class->NumProtos >= MAX_NUM_PROTOS)
301  return (NO_PROTO);
302 
303  Index = Class->NumProtos++;
304 
305  if (Class->NumProtos > MaxNumIntProtosIn(Class)) {
306  ProtoSetId = Class->NumProtoSets++;
307 
308  ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
309  Class->ProtoSets[ProtoSetId] = ProtoSet;
310  memset(ProtoSet, 0, sizeof(*ProtoSet));
311 
312  /* reallocate space for the proto lengths and install in class */
313  Class->ProtoLengths =
314  (uinT8 *)Erealloc(Class->ProtoLengths,
315  MaxNumIntProtosIn(Class) * sizeof(uinT8));
316  memset(&Class->ProtoLengths[Index], 0,
317  sizeof(*Class->ProtoLengths) * (MaxNumIntProtosIn(Class) - Index));
318  }
319 
320  /* initialize proto so its length is zero and it isn't in any configs */
321  Class->ProtoLengths[Index] = 0;
322  Proto = ProtoForProtoId (Class, Index);
323  for (Word = Proto->Configs;
324  Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0);
325 
326  return (Index);
327 }
328 
342 void AddProtoToClassPruner (PROTO Proto, CLASS_ID ClassId,
343  INT_TEMPLATES Templates)
344 #define MAX_LEVEL 2
345 {
346  CLASS_PRUNER_STRUCT* Pruner;
347  uinT32 ClassMask;
348  uinT32 ClassCount;
349  uinT32 WordIndex;
350  int Level;
351  FLOAT32 EndPad, SidePad, AnglePad;
352  TABLE_FILLER TableFiller;
353  FILL_SPEC FillSpec;
354 
355  Pruner = CPrunerFor (Templates, ClassId);
356  WordIndex = CPrunerWordIndexFor (ClassId);
357  ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassId);
358 
359  for (Level = classify_num_cp_levels - 1; Level >= 0; Level--) {
360  GetCPPadsForLevel(Level, &EndPad, &SidePad, &AnglePad);
361  ClassCount = CPrunerMaskFor (Level, ClassId);
362  InitTableFiller(EndPad, SidePad, AnglePad, Proto, &TableFiller);
363 
364  while (!FillerDone (&TableFiller)) {
365  GetNextFill(&TableFiller, &FillSpec);
366  DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
367  }
368  }
369 } /* AddProtoToClassPruner */
370 
384 void AddProtoToProtoPruner(PROTO Proto, int ProtoId,
385  INT_CLASS Class, bool debug) {
386  FLOAT32 Angle, X, Y, Length;
387  FLOAT32 Pad;
388  int Index;
389  PROTO_SET ProtoSet;
390 
391  if (ProtoId >= Class->NumProtos)
392  cprintf("AddProtoToProtoPruner:assert failed: %d < %d",
393  ProtoId, Class->NumProtos);
394  assert(ProtoId < Class->NumProtos);
395 
396  Index = IndexForProto (ProtoId);
397  ProtoSet = Class->ProtoSets[SetForProto (ProtoId)];
398 
399  Angle = Proto->Angle;
400 #ifndef _WIN32
401  assert(!isnan(Angle));
402 #endif
403 
404  FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index,
405  Angle + ANGLE_SHIFT, classify_pp_angle_pad / 360.0,
406  debug);
407 
408  Angle *= 2.0 * PI;
409  Length = Proto->Length;
410 
411  X = Proto->X + X_SHIFT;
412  Pad = MAX (fabs (cos (Angle)) * (Length / 2.0 +
415  fabs (sin (Angle)) * (classify_pp_side_pad *
417 
418  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad, debug);
419 
420  Y = Proto->Y + Y_SHIFT;
421  Pad = MAX (fabs (sin (Angle)) * (Length / 2.0 +
424  fabs (cos (Angle)) * (classify_pp_side_pad *
426 
427  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_Y], Index, Y, Pad, debug);
428 } /* AddProtoToProtoPruner */
429 
435 uinT8 Bucket8For(FLOAT32 param, FLOAT32 offset, int num_buckets) {
436  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
437  return static_cast<uinT8>(ClipToRange(bucket, 0, num_buckets - 1));
438 }
439 uinT16 Bucket16For(FLOAT32 param, FLOAT32 offset, int num_buckets) {
440  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
441  return static_cast<uinT16>(ClipToRange(bucket, 0, num_buckets - 1));
442 }
443 
449 uinT8 CircBucketFor(FLOAT32 param, FLOAT32 offset, int num_buckets) {
450  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
451  return static_cast<uinT8>(Modulo(bucket, num_buckets));
452 } /* CircBucketFor */
453 
454 
455 #ifndef GRAPHICS_DISABLED
456 
468  if (IntMatchWindow != NULL)
470 } /* ClearMatchDisplay */
471 #endif
472 
487 void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class) {
488  int ProtoId;
489  INT_PROTO Proto;
490  int TotalLength;
491 
492  for (ProtoId = 0, TotalLength = 0;
493  ProtoId < Class->NumProtos; ProtoId++) {
494  if (test_bit(Config, ProtoId)) {
495  Proto = ProtoForProtoId(Class, ProtoId);
496  SET_BIT(Proto->Configs, ConfigId);
497  TotalLength += Class->ProtoLengths[ProtoId];
498  }
499  }
500  Class->ConfigLengths[ConfigId] = TotalLength;
501 } /* ConvertConfig */
502 
503 
504 namespace tesseract {
516 void Classify::ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class) {
517  INT_PROTO P;
518  FLOAT32 Param;
519 
520  assert(ProtoId < Class->NumProtos);
521 
522  P = ProtoForProtoId(Class, ProtoId);
523 
524  Param = Proto->A * 128;
525  P->A = TruncateParam(Param, -128, 127, NULL);
526 
527  Param = -Proto->B * 256;
528  P->B = TruncateParam(Param, 0, 255, NULL);
529 
530  Param = Proto->C * 128;
531  P->C = TruncateParam(Param, -128, 127, NULL);
532 
533  Param = Proto->Angle * 256;
534  if (Param < 0 || Param >= 256)
535  P->Angle = 0;
536  else
537  P->Angle = (uinT8) Param;
538 
539  /* round proto length to nearest integer number of pico-features */
540  Param = (Proto->Length / GetPicoFeatureLength()) + 0.5;
541  Class->ProtoLengths[ProtoId] = TruncateParam(Param, 1, 255, NULL);
543  cprintf("Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
544  P->A, P->B, P->C, Class->ProtoLengths[ProtoId]);
545 } /* ConvertProto */
546 
558  const UNICHARSET&
559  target_unicharset) {
560  INT_TEMPLATES IntTemplates;
561  CLASS_TYPE FClass;
562  INT_CLASS IClass;
563  int ClassId;
564  int ProtoId;
565  int ConfigId;
566 
567  IntTemplates = NewIntTemplates();
568 
569  for (ClassId = 0; ClassId < target_unicharset.size(); ClassId++) {
570  FClass = &(FloatProtos[ClassId]);
571  if (FClass->NumProtos == 0 && FClass->NumConfigs == 0 &&
572  strcmp(target_unicharset.id_to_unichar(ClassId), " ") != 0) {
573  cprintf("Warning: no protos/configs for %s in CreateIntTemplates()\n",
574  target_unicharset.id_to_unichar(ClassId));
575  }
576  assert(UnusedClassIdIn(IntTemplates, ClassId));
577  IClass = NewIntClass(FClass->NumProtos, FClass->NumConfigs);
578  FontSet fs;
579  fs.size = FClass->font_set.size();
580  fs.configs = new int[fs.size];
581  for (int i = 0; i < fs.size; ++i) {
582  fs.configs[i] = FClass->font_set.get(i);
583  }
584  if (this->fontset_table_.contains(fs)) {
585  IClass->font_set_id = this->fontset_table_.get_id(fs);
586  delete[] fs.configs;
587  } else {
588  IClass->font_set_id = this->fontset_table_.push_back(fs);
589  }
590  AddIntClass(IntTemplates, ClassId, IClass);
591 
592  for (ProtoId = 0; ProtoId < FClass->NumProtos; ProtoId++) {
593  AddIntProto(IClass);
594  ConvertProto(ProtoIn(FClass, ProtoId), ProtoId, IClass);
595  AddProtoToProtoPruner(ProtoIn(FClass, ProtoId), ProtoId, IClass,
597  AddProtoToClassPruner(ProtoIn(FClass, ProtoId), ClassId, IntTemplates);
598  }
599 
600  for (ConfigId = 0; ConfigId < FClass->NumConfigs; ConfigId++) {
601  AddIntConfig(IClass);
602  ConvertConfig(FClass->Configurations[ConfigId], ConfigId, IClass);
603  }
604  }
605  return (IntTemplates);
606 } /* CreateIntTemplates */
607 } // namespace tesseract
608 
609 
610 #ifndef GRAPHICS_DISABLED
611 
623 void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, FLOAT32 Evidence) {
624  ScrollView::Color color = GetMatchColorFor(Evidence);
625  RenderIntFeature(IntMatchWindow, Feature, color);
626  if (FeatureDisplayWindow) {
627  RenderIntFeature(FeatureDisplayWindow, Feature, color);
628  }
629 } /* DisplayIntFeature */
630 
644 void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence) {
645  ScrollView::Color color = GetMatchColorFor(Evidence);
646  RenderIntProto(IntMatchWindow, Class, ProtoId, color);
647  if (ProtoDisplayWindow) {
648  RenderIntProto(ProtoDisplayWindow, Class, ProtoId, color);
649  }
650 } /* DisplayIntProto */
651 #endif
652 
664 INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs) {
665  INT_CLASS Class;
666  PROTO_SET ProtoSet;
667  int i;
668 
669  assert(MaxNumConfigs <= MAX_NUM_CONFIGS);
670 
671  Class = (INT_CLASS) Emalloc(sizeof(INT_CLASS_STRUCT));
672  Class->NumProtoSets = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) /
674 
675  assert(Class->NumProtoSets <= MAX_NUM_PROTO_SETS);
676 
677  Class->NumProtos = 0;
678  Class->NumConfigs = 0;
679 
680  for (i = 0; i < Class->NumProtoSets; i++) {
681  /* allocate space for a proto set, install in class, and initialize */
682  ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
683  memset(ProtoSet, 0, sizeof(*ProtoSet));
684  Class->ProtoSets[i] = ProtoSet;
685 
686  /* allocate space for the proto lengths and install in class */
687  }
688  if (MaxNumIntProtosIn (Class) > 0) {
689  Class->ProtoLengths =
690  (uinT8 *)Emalloc(MaxNumIntProtosIn (Class) * sizeof (uinT8));
691  memset(Class->ProtoLengths, 0,
692  MaxNumIntProtosIn(Class) * sizeof(*Class->ProtoLengths));
693  } else {
694  Class->ProtoLengths = NULL;
695  }
696  memset(Class->ConfigLengths, 0, sizeof(Class->ConfigLengths));
697 
698  return (Class);
699 
700 } /* NewIntClass */
701 
702 
703 void free_int_class(INT_CLASS int_class) {
704  int i;
705 
706  for (i = 0; i < int_class->NumProtoSets; i++) {
707  Efree (int_class->ProtoSets[i]);
708  }
709  if (int_class->ProtoLengths != NULL) {
710  Efree (int_class->ProtoLengths);
711  }
712  Efree(int_class);
713 }
714 
724  INT_TEMPLATES T;
725  int i;
726 
727  T = (INT_TEMPLATES) Emalloc (sizeof (INT_TEMPLATES_STRUCT));
728  T->NumClasses = 0;
729  T->NumClassPruners = 0;
730 
731  for (i = 0; i < MAX_NUM_CLASSES; i++)
732  ClassForClassId (T, i) = NULL;
733 
734  return (T);
735 } /* NewIntTemplates */
736 
737 
738 /*---------------------------------------------------------------------------*/
740  int i;
741 
742  for (i = 0; i < templates->NumClasses; i++)
743  free_int_class(templates->Class[i]);
744  for (i = 0; i < templates->NumClassPruners; i++)
745  delete templates->ClassPruners[i];
746  Efree(templates);
747 }
748 
749 
750 namespace tesseract {
762  int i, j, w, x, y, z;
763  BOOL8 swap;
764  int nread;
765  int unicharset_size;
766  int version_id = 0;
767  INT_TEMPLATES Templates;
768  CLASS_PRUNER_STRUCT* Pruner;
769  INT_CLASS Class;
770  uinT8 *Lengths;
771  PROTO_SET ProtoSet;
772 
773  /* variables for conversion from older inttemp formats */
774  int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
775  CLASS_ID class_id, max_class_id;
776  inT16 *IndexFor = new inT16[MAX_NUM_CLASSES];
777  CLASS_ID *ClassIdFor = new CLASS_ID[MAX_NUM_CLASSES];
778  CLASS_PRUNER_STRUCT **TempClassPruner =
780  uinT32 SetBitsForMask = // word with NUM_BITS_PER_CLASS
781  (1 << NUM_BITS_PER_CLASS) - 1; // set starting at bit 0
782  uinT32 Mask, NewMask, ClassBits;
783  int MaxNumConfigs = MAX_NUM_CONFIGS;
784  int WerdsPerConfigVec = WERDS_PER_CONFIG_VEC;
785 
786  /* first read the high level template struct */
787  Templates = NewIntTemplates();
788  // Read Templates in parts for 64 bit compatibility.
789  if (fread(&unicharset_size, sizeof(int), 1, File) != 1)
790  cprintf("Bad read of inttemp!\n");
791  if (fread(&Templates->NumClasses,
792  sizeof(Templates->NumClasses), 1, File) != 1 ||
793  fread(&Templates->NumClassPruners,
794  sizeof(Templates->NumClassPruners), 1, File) != 1)
795  cprintf("Bad read of inttemp!\n");
796  // Swap status is determined automatically.
797  swap = Templates->NumClassPruners < 0 ||
799  if (swap) {
800  Reverse32(&Templates->NumClassPruners);
801  Reverse32(&Templates->NumClasses);
802  Reverse32(&unicharset_size);
803  }
804  if (Templates->NumClasses < 0) {
805  // This file has a version id!
806  version_id = -Templates->NumClasses;
807  if (fread(&Templates->NumClasses, sizeof(Templates->NumClasses),
808  1, File) != 1)
809  cprintf("Bad read of inttemp!\n");
810  if (swap)
811  Reverse32(&Templates->NumClasses);
812  }
813 
814  if (version_id < 3) {
815  MaxNumConfigs = OLD_MAX_NUM_CONFIGS;
816  WerdsPerConfigVec = OLD_WERDS_PER_CONFIG_VEC;
817  }
818 
819  if (version_id < 2) {
820  for (i = 0; i < unicharset_size; ++i) {
821  if (fread(&IndexFor[i], sizeof(inT16), 1, File) != 1)
822  cprintf("Bad read of inttemp!\n");
823  }
824  for (i = 0; i < Templates->NumClasses; ++i) {
825  if (fread(&ClassIdFor[i], sizeof(CLASS_ID), 1, File) != 1)
826  cprintf("Bad read of inttemp!\n");
827  }
828  if (swap) {
829  for (i = 0; i < Templates->NumClasses; i++)
830  Reverse16(&IndexFor[i]);
831  for (i = 0; i < Templates->NumClasses; i++)
832  Reverse32(&ClassIdFor[i]);
833  }
834  }
835 
836  /* then read in the class pruners */
837  for (i = 0; i < Templates->NumClassPruners; i++) {
838  Pruner = new CLASS_PRUNER_STRUCT;
839  if ((nread =
840  fread(Pruner, 1, sizeof(CLASS_PRUNER_STRUCT),
841  File)) != sizeof(CLASS_PRUNER_STRUCT))
842  cprintf("Bad read of inttemp!\n");
843  if (swap) {
844  for (x = 0; x < NUM_CP_BUCKETS; x++) {
845  for (y = 0; y < NUM_CP_BUCKETS; y++) {
846  for (z = 0; z < NUM_CP_BUCKETS; z++) {
847  for (w = 0; w < WERDS_PER_CP_VECTOR; w++) {
848  Reverse32(&Pruner->p[x][y][z][w]);
849  }
850  }
851  }
852  }
853  }
854  if (version_id < 2) {
855  TempClassPruner[i] = Pruner;
856  } else {
857  Templates->ClassPruners[i] = Pruner;
858  }
859  }
860 
861  /* fix class pruners if they came from an old version of inttemp */
862  if (version_id < 2) {
863  // Allocate enough class pruners to cover all the class ids.
864  max_class_id = 0;
865  for (i = 0; i < Templates->NumClasses; i++)
866  if (ClassIdFor[i] > max_class_id)
867  max_class_id = ClassIdFor[i];
868  for (i = 0; i <= CPrunerIdFor(max_class_id); i++) {
869  Templates->ClassPruners[i] = new CLASS_PRUNER_STRUCT;
870  memset(Templates->ClassPruners[i], 0, sizeof(CLASS_PRUNER_STRUCT));
871  }
872  // Convert class pruners from the old format (indexed by class index)
873  // to the new format (indexed by class id).
874  last_cp_bit_number = NUM_BITS_PER_CLASS * Templates->NumClasses - 1;
875  for (i = 0; i < Templates->NumClassPruners; i++) {
876  for (x = 0; x < NUM_CP_BUCKETS; x++)
877  for (y = 0; y < NUM_CP_BUCKETS; y++)
878  for (z = 0; z < NUM_CP_BUCKETS; z++)
879  for (w = 0; w < WERDS_PER_CP_VECTOR; w++) {
880  if (TempClassPruner[i]->p[x][y][z][w] == 0)
881  continue;
882  for (b = 0; b < BITS_PER_WERD; b += NUM_BITS_PER_CLASS) {
883  bit_number = i * BITS_PER_CP_VECTOR + w * BITS_PER_WERD + b;
884  if (bit_number > last_cp_bit_number)
885  break; // the rest of the bits in this word are not used
886  class_id = ClassIdFor[bit_number / NUM_BITS_PER_CLASS];
887  // Single out NUM_BITS_PER_CLASS bits relating to class_id.
888  Mask = SetBitsForMask << b;
889  ClassBits = TempClassPruner[i]->p[x][y][z][w] & Mask;
890  // Move these bits to the new position in which they should
891  // appear (indexed corresponding to the class_id).
892  new_i = CPrunerIdFor(class_id);
893  new_w = CPrunerWordIndexFor(class_id);
894  new_b = CPrunerBitIndexFor(class_id) * NUM_BITS_PER_CLASS;
895  if (new_b > b) {
896  ClassBits <<= (new_b - b);
897  } else {
898  ClassBits >>= (b - new_b);
899  }
900  // Copy bits relating to class_id to the correct position
901  // in Templates->ClassPruner.
902  NewMask = SetBitsForMask << new_b;
903  Templates->ClassPruners[new_i]->p[x][y][z][new_w] &= ~NewMask;
904  Templates->ClassPruners[new_i]->p[x][y][z][new_w] |= ClassBits;
905  }
906  }
907  }
908  for (i = 0; i < Templates->NumClassPruners; i++) {
909  delete TempClassPruner[i];
910  }
911  }
912 
913  /* then read in each class */
914  for (i = 0; i < Templates->NumClasses; i++) {
915  /* first read in the high level struct for the class */
916  Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT));
917  if (fread(&Class->NumProtos, sizeof(Class->NumProtos), 1, File) != 1 ||
918  fread(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File) != 1 ||
919  fread(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File) != 1)
920  cprintf ("Bad read of inttemp!\n");
921  if (version_id == 0) {
922  // Only version 0 writes 5 pointless pointers to the file.
923  for (j = 0; j < 5; ++j) {
924  int junk;
925  if (fread(&junk, sizeof(junk), 1, File) != 1)
926  cprintf ("Bad read of inttemp!\n");
927  }
928  }
929  if (version_id < 4) {
930  for (j = 0; j < MaxNumConfigs; ++j) {
931  if (fread(&Class->ConfigLengths[j], sizeof(uinT16), 1, File) != 1)
932  cprintf ("Bad read of inttemp!\n");
933  }
934  if (swap) {
935  Reverse16(&Class->NumProtos);
936  for (j = 0; j < MaxNumConfigs; j++)
937  Reverse16(&Class->ConfigLengths[j]);
938  }
939  } else {
940  ASSERT_HOST(Class->NumConfigs < MaxNumConfigs);
941  for (j = 0; j < Class->NumConfigs; ++j) {
942  if (fread(&Class->ConfigLengths[j], sizeof(uinT16), 1, File) != 1)
943  cprintf ("Bad read of inttemp!\n");
944  }
945  if (swap) {
946  Reverse16(&Class->NumProtos);
947  for (j = 0; j < MaxNumConfigs; j++)
948  Reverse16(&Class->ConfigLengths[j]);
949  }
950  }
951  if (version_id < 2) {
952  ClassForClassId (Templates, ClassIdFor[i]) = Class;
953  } else {
954  ClassForClassId (Templates, i) = Class;
955  }
956 
957  /* then read in the proto lengths */
958  Lengths = NULL;
959  if (MaxNumIntProtosIn (Class) > 0) {
960  Lengths = (uinT8 *)Emalloc(sizeof(uinT8) * MaxNumIntProtosIn(Class));
961  if ((nread =
962  fread((char *)Lengths, sizeof(uinT8),
963  MaxNumIntProtosIn(Class), File)) != MaxNumIntProtosIn (Class))
964  cprintf ("Bad read of inttemp!\n");
965  }
966  Class->ProtoLengths = Lengths;
967 
968  /* then read in the proto sets */
969  for (j = 0; j < Class->NumProtoSets; j++) {
970  ProtoSet = (PROTO_SET)Emalloc(sizeof(PROTO_SET_STRUCT));
971  if (version_id < 3) {
972  if ((nread =
973  fread((char *) &ProtoSet->ProtoPruner, 1,
974  sizeof(PROTO_PRUNER), File)) != sizeof(PROTO_PRUNER))
975  cprintf("Bad read of inttemp!\n");
976  for (x = 0; x < PROTOS_PER_PROTO_SET; x++) {
977  if ((nread = fread((char *) &ProtoSet->Protos[x].A, 1,
978  sizeof(inT8), File)) != sizeof(inT8) ||
979  (nread = fread((char *) &ProtoSet->Protos[x].B, 1,
980  sizeof(uinT8), File)) != sizeof(uinT8) ||
981  (nread = fread((char *) &ProtoSet->Protos[x].C, 1,
982  sizeof(inT8), File)) != sizeof(inT8) ||
983  (nread = fread((char *) &ProtoSet->Protos[x].Angle, 1,
984  sizeof(uinT8), File)) != sizeof(uinT8))
985  cprintf("Bad read of inttemp!\n");
986  for (y = 0; y < WerdsPerConfigVec; y++)
987  if ((nread = fread((char *) &ProtoSet->Protos[x].Configs[y], 1,
988  sizeof(uinT32), File)) != sizeof(uinT32))
989  cprintf("Bad read of inttemp!\n");
990  }
991  } else {
992  if ((nread =
993  fread((char *) ProtoSet, 1, sizeof(PROTO_SET_STRUCT),
994  File)) != sizeof(PROTO_SET_STRUCT))
995  cprintf("Bad read of inttemp!\n");
996  }
997  if (swap) {
998  for (x = 0; x < NUM_PP_PARAMS; x++)
999  for (y = 0; y < NUM_PP_BUCKETS; y++)
1000  for (z = 0; z < WERDS_PER_PP_VECTOR; z++)
1001  Reverse32(&ProtoSet->ProtoPruner[x][y][z]);
1002  for (x = 0; x < PROTOS_PER_PROTO_SET; x++)
1003  for (y = 0; y < WerdsPerConfigVec; y++)
1004  Reverse32(&ProtoSet->Protos[x].Configs[y]);
1005  }
1006  Class->ProtoSets[j] = ProtoSet;
1007  }
1008  if (version_id < 4)
1009  Class->font_set_id = -1;
1010  else {
1011  fread(&Class->font_set_id, sizeof(int), 1, File);
1012  if (swap)
1013  Reverse32(&Class->font_set_id);
1014  }
1015  }
1016 
1017  if (version_id < 2) {
1018  /* add an empty NULL class with class id 0 */
1019  assert(UnusedClassIdIn (Templates, 0));
1020  ClassForClassId (Templates, 0) = NewIntClass (1, 1);
1021  ClassForClassId (Templates, 0)->font_set_id = -1;
1022  Templates->NumClasses++;
1023  /* make sure the classes are contiguous */
1024  for (i = 0; i < MAX_NUM_CLASSES; i++) {
1025  if (i < Templates->NumClasses) {
1026  if (ClassForClassId (Templates, i) == NULL) {
1027  fprintf(stderr, "Non-contiguous class ids in inttemp\n");
1028  exit(1);
1029  }
1030  } else {
1031  if (ClassForClassId (Templates, i) != NULL) {
1032  fprintf(stderr, "Class id %d exceeds NumClassesIn (Templates) %d\n",
1033  i, Templates->NumClasses);
1034  exit(1);
1035  }
1036  }
1037  }
1038  }
1039  if (version_id >= 4) {
1040  this->fontinfo_table_.read(File, NewPermanentTessCallback(read_info), swap);
1041  if (version_id >= 5) {
1042  this->fontinfo_table_.read(File,
1044  swap);
1045  }
1046  this->fontset_table_.read(File, NewPermanentTessCallback(read_set), swap);
1047  }
1048 
1049  // Clean up.
1050  delete[] IndexFor;
1051  delete[] ClassIdFor;
1052  delete[] TempClassPruner;
1053 
1054  return (Templates);
1055 } /* ReadIntTemplates */
1056 
1057 
1058 #ifndef GRAPHICS_DISABLED
1059 
1072  if (ProtoDisplayWindow) {
1074  }
1075  if (FeatureDisplayWindow) {
1077  }
1079  static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
1080  IntMatchWindow);
1082  INT_MAX_X, INT_MAX_Y);
1083  if (ProtoDisplayWindow) {
1085  INT_MAX_X, INT_MAX_Y);
1086  }
1087  if (FeatureDisplayWindow) {
1089  INT_MAX_X, INT_MAX_Y);
1090  }
1091 } /* ShowMatchDisplay */
1092 
1095 void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView* window) {
1096  window->Clear();
1097 
1098  window->Pen(ScrollView::GREY);
1099  // Draw the feature space limit rectangle.
1100  window->Rectangle(0, 0, INT_MAX_X, INT_MAX_Y);
1101  if (norm_method == baseline) {
1102  window->SetCursor(0, INT_DESCENDER);
1103  window->DrawTo(INT_MAX_X, INT_DESCENDER);
1104  window->SetCursor(0, INT_BASELINE);
1105  window->DrawTo(INT_MAX_X, INT_BASELINE);
1106  window->SetCursor(0, INT_XHEIGHT);
1107  window->DrawTo(INT_MAX_X, INT_XHEIGHT);
1108  window->SetCursor(0, INT_CAPHEIGHT);
1109  window->DrawTo(INT_MAX_X, INT_CAPHEIGHT);
1110  } else {
1113  }
1114 }
1115 #endif
1116 
1130  const UNICHARSET& target_unicharset) {
1131  int i, j;
1132  INT_CLASS Class;
1133  int unicharset_size = target_unicharset.size();
1134  int version_id = -5; // When negated by the reader -1 becomes +1 etc.
1135 
1136  if (Templates->NumClasses != unicharset_size) {
1137  cprintf("Warning: executing WriteIntTemplates() with %d classes in"
1138  " Templates, while target_unicharset size is %d\n",
1139  Templates->NumClasses, unicharset_size);
1140  }
1141 
1142  /* first write the high level template struct */
1143  fwrite(&unicharset_size, sizeof(unicharset_size), 1, File);
1144  fwrite(&version_id, sizeof(version_id), 1, File);
1145  fwrite(&Templates->NumClassPruners, sizeof(Templates->NumClassPruners),
1146  1, File);
1147  fwrite(&Templates->NumClasses, sizeof(Templates->NumClasses), 1, File);
1148 
1149  /* then write out the class pruners */
1150  for (i = 0; i < Templates->NumClassPruners; i++)
1151  fwrite(Templates->ClassPruners[i],
1152  sizeof(CLASS_PRUNER_STRUCT), 1, File);
1153 
1154  /* then write out each class */
1155  for (i = 0; i < Templates->NumClasses; i++) {
1156  Class = Templates->Class[i];
1157 
1158  /* first write out the high level struct for the class */
1159  fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
1160  fwrite(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File);
1161  ASSERT_HOST(Class->NumConfigs == this->fontset_table_.get(Class->font_set_id).size);
1162  fwrite(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File);
1163  for (j = 0; j < Class->NumConfigs; ++j) {
1164  fwrite(&Class->ConfigLengths[j], sizeof(uinT16), 1, File);
1165  }
1166 
1167  /* then write out the proto lengths */
1168  if (MaxNumIntProtosIn (Class) > 0) {
1169  fwrite ((char *) (Class->ProtoLengths), sizeof (uinT8),
1170  MaxNumIntProtosIn (Class), File);
1171  }
1172 
1173  /* then write out the proto sets */
1174  for (j = 0; j < Class->NumProtoSets; j++)
1175  fwrite ((char *) Class->ProtoSets[j],
1176  sizeof (PROTO_SET_STRUCT), 1, File);
1177 
1178  /* then write the fonts info */
1179  fwrite(&Class->font_set_id, sizeof(int), 1, File);
1180  }
1181 
1182  /* Write the fonts info tables */
1184  this->fontinfo_table_.write(File,
1187 } /* WriteIntTemplates */
1188 } // namespace tesseract
1189 
1190 
1191 /*-----------------------------------------------------------------------------
1192  Private Code
1193 -----------------------------------------------------------------------------*/
1207 FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets) {
1208  return (((FLOAT32) Bucket / NumBuckets) - Offset);
1209 
1210 } /* BucketStart */
1211 
1225 FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets) {
1226  return (((FLOAT32) (Bucket + 1) / NumBuckets) - Offset);
1227 } /* BucketEnd */
1228 
1243 void DoFill(FILL_SPEC *FillSpec,
1244  CLASS_PRUNER_STRUCT* Pruner,
1245  register uinT32 ClassMask,
1246  register uinT32 ClassCount,
1247  register uinT32 WordIndex) {
1248  int X, Y, Angle;
1249  uinT32 OldWord;
1250 
1251  X = FillSpec->X;
1252  if (X < 0)
1253  X = 0;
1254  if (X >= NUM_CP_BUCKETS)
1255  X = NUM_CP_BUCKETS - 1;
1256 
1257  if (FillSpec->YStart < 0)
1258  FillSpec->YStart = 0;
1259  if (FillSpec->YEnd >= NUM_CP_BUCKETS)
1260  FillSpec->YEnd = NUM_CP_BUCKETS - 1;
1261 
1262  for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
1263  for (Angle = FillSpec->AngleStart;
1265  OldWord = Pruner->p[X][Y][Angle][WordIndex];
1266  if (ClassCount > (OldWord & ClassMask)) {
1267  OldWord &= ~ClassMask;
1268  OldWord |= ClassCount;
1269  Pruner->p[X][Y][Angle][WordIndex] = OldWord;
1270  }
1271  if (Angle == FillSpec->AngleEnd)
1272  break;
1273  }
1274 } /* DoFill */
1275 
1286  FILL_SWITCH *Next;
1287 
1288  Next = &(Filler->Switch[Filler->NextSwitch]);
1289 
1290  if (Filler->X > Next->X && Next->Type == LastSwitch)
1291  return (TRUE);
1292  else
1293  return (FALSE);
1294 
1295 } /* FillerDone */
1296 
1315  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) {
1316  int i, FirstBucket, LastBucket;
1317 
1318  if (Spread > 0.5)
1319  Spread = 0.5;
1320 
1321  FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
1322  if (FirstBucket < 0)
1323  FirstBucket += NUM_PP_BUCKETS;
1324 
1325  LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
1326  if (LastBucket >= NUM_PP_BUCKETS)
1327  LastBucket -= NUM_PP_BUCKETS;
1328  if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
1329  for (i = FirstBucket; TRUE; CircularIncrement (i, NUM_PP_BUCKETS)) {
1330  SET_BIT (ParamTable[i], Bit);
1331 
1332  /* exit loop after we have set the bit for the last bucket */
1333  if (i == LastBucket)
1334  break;
1335  }
1336 
1337 } /* FillPPCircularBits */
1338 
1358  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) {
1359  int i, FirstBucket, LastBucket;
1360 
1361  FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
1362  if (FirstBucket < 0)
1363  FirstBucket = 0;
1364 
1365  LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
1366  if (LastBucket >= NUM_PP_BUCKETS)
1367  LastBucket = NUM_PP_BUCKETS - 1;
1368 
1369  if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
1370  for (i = FirstBucket; i <= LastBucket; i++)
1371  SET_BIT (ParamTable[i], Bit);
1372 
1373 } /* FillPPLinearBits */
1374 
1375 
1376 /*---------------------------------------------------------------------------*/
1377 #ifndef GRAPHICS_DISABLED
1378 namespace tesseract {
1391 CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool* adaptive_on,
1392  bool* pretrained_on, int* shape_id) {
1393  tprintf("%s\n", Prompt);
1394  SVEvent* ev;
1395  SVEventType ev_type;
1396  int unichar_id = INVALID_UNICHAR_ID;
1397  // Wait until a click or popup event.
1398  do {
1400  ev_type = ev->type;
1401  if (ev_type == SVET_POPUP) {
1402  if (ev->command_id == IDA_SHAPE_INDEX) {
1403  if (shape_table_ != NULL) {
1404  *shape_id = atoi(ev->parameter);
1405  *adaptive_on = false;
1406  *pretrained_on = true;
1407  if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1408  int font_id;
1409  shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1410  &font_id);
1411  tprintf("Shape %d, first unichar=%d, font=%d\n",
1412  *shape_id, unichar_id, font_id);
1413  return unichar_id;
1414  }
1415  tprintf("Shape index '%s' not found in shape table\n", ev->parameter);
1416  } else {
1417  tprintf("No shape table loaded!\n");
1418  }
1419  } else {
1421  unichar_id = unicharset.unichar_to_id(ev->parameter);
1422  if (ev->command_id == IDA_ADAPTIVE) {
1423  *adaptive_on = true;
1424  *pretrained_on = false;
1425  *shape_id = -1;
1426  } else if (ev->command_id == IDA_STATIC) {
1427  *adaptive_on = false;
1428  *pretrained_on = true;
1429  } else {
1430  *adaptive_on = true;
1431  *pretrained_on = true;
1432  }
1433  if (ev->command_id == IDA_ADAPTIVE || shape_table_ == NULL) {
1434  *shape_id = -1;
1435  return unichar_id;
1436  }
1437  for (int s = 0; s < shape_table_->NumShapes(); ++s) {
1438  if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1439  tprintf("%s\n", shape_table_->DebugStr(s).string());
1440  }
1441  }
1442  } else {
1443  tprintf("Char class '%s' not found in unicharset",
1444  ev->parameter);
1445  }
1446  }
1447  }
1448  delete ev;
1449  } while (ev_type != SVET_CLICK);
1450  return 0;
1451 } /* GetClassToDebug */
1452 
1453 } // namespace tesseract
1454 #endif
1455 
1471 void GetCPPadsForLevel(int Level,
1472  FLOAT32 *EndPad,
1473  FLOAT32 *SidePad,
1474  FLOAT32 *AnglePad) {
1475  switch (Level) {
1476  case 0:
1479  *AnglePad = classify_cp_angle_pad_loose / 360.0;
1480  break;
1481 
1482  case 1:
1485  *AnglePad = classify_cp_angle_pad_medium / 360.0;
1486  break;
1487 
1488  case 2:
1491  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1492  break;
1493 
1494  default:
1497  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1498  break;
1499  }
1500  if (*AnglePad > 0.5)
1501  *AnglePad = 0.5;
1502 
1503 } /* GetCPPadsForLevel */
1504 
1513  assert (Evidence >= 0.0);
1514  assert (Evidence <= 1.0);
1515 
1516  if (Evidence >= 0.90)
1517  return ScrollView::WHITE;
1518  else if (Evidence >= 0.75)
1519  return ScrollView::GREEN;
1520  else if (Evidence >= 0.50)
1521  return ScrollView::RED;
1522  else
1523  return ScrollView::BLUE;
1524 } /* GetMatchColorFor */
1525 
1538 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {
1539  FILL_SWITCH *Next;
1540 
1541  /* compute the fill assuming no switches will be encountered */
1542  Fill->AngleStart = Filler->AngleStart;
1543  Fill->AngleEnd = Filler->AngleEnd;
1544  Fill->X = Filler->X;
1545  Fill->YStart = Filler->YStart >> 8;
1546  Fill->YEnd = Filler->YEnd >> 8;
1547 
1548  /* update the fill info and the filler for ALL switches at this X value */
1549  Next = &(Filler->Switch[Filler->NextSwitch]);
1550  while (Filler->X >= Next->X) {
1551  Fill->X = Filler->X = Next->X;
1552  if (Next->Type == StartSwitch) {
1553  Fill->YStart = Next->Y;
1554  Filler->StartDelta = Next->Delta;
1555  Filler->YStart = Next->YInit;
1556  }
1557  else if (Next->Type == EndSwitch) {
1558  Fill->YEnd = Next->Y;
1559  Filler->EndDelta = Next->Delta;
1560  Filler->YEnd = Next->YInit;
1561  }
1562  else { /* Type must be LastSwitch */
1563  break;
1564  }
1565  Filler->NextSwitch++;
1566  Next = &(Filler->Switch[Filler->NextSwitch]);
1567  }
1568 
1569  /* prepare the filler for the next call to this routine */
1570  Filler->X++;
1571  Filler->YStart += Filler->StartDelta;
1572  Filler->YEnd += Filler->EndDelta;
1573 
1574 } /* GetNextFill */
1575 
1590 void InitTableFiller (FLOAT32 EndPad, FLOAT32 SidePad,
1591  FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER * Filler)
1592 #define XS X_SHIFT
1593 #define YS Y_SHIFT
1594 #define AS ANGLE_SHIFT
1595 #define NB NUM_CP_BUCKETS
1596 {
1597  FLOAT32 Angle;
1598  FLOAT32 X, Y, HalfLength;
1599  FLOAT32 Cos, Sin;
1600  FLOAT32 XAdjust, YAdjust;
1601  FPOINT Start, Switch1, Switch2, End;
1602  int S1 = 0;
1603  int S2 = 1;
1604 
1605  Angle = Proto->Angle;
1606  X = Proto->X;
1607  Y = Proto->Y;
1608  HalfLength = Proto->Length / 2.0;
1609 
1610  Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
1611  Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
1612  Filler->NextSwitch = 0;
1613 
1614  if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
1615  /* horizontal proto - handle as special case */
1616  Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
1617  Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
1618  Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
1619  Filler->StartDelta = 0;
1620  Filler->EndDelta = 0;
1621  Filler->Switch[0].Type = LastSwitch;
1622  Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
1623  } else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
1624  fabs(Angle - 0.75) < HV_TOLERANCE) {
1625  /* vertical proto - handle as special case */
1626  Filler->X = Bucket8For(X - SidePad, XS, NB);
1627  Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
1628  Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
1629  Filler->StartDelta = 0;
1630  Filler->EndDelta = 0;
1631  Filler->Switch[0].Type = LastSwitch;
1632  Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
1633  } else {
1634  /* diagonal proto */
1635 
1636  if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1637  /* rising diagonal proto */
1638  Angle *= 2.0 * PI;
1639  Cos = fabs(cos(Angle));
1640  Sin = fabs(sin(Angle));
1641 
1642  /* compute the positions of the corners of the acceptance region */
1643  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1644  Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1645  End.x = 2.0 * X - Start.x;
1646  End.y = 2.0 * Y - Start.y;
1647  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1648  Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1649  Switch2.x = 2.0 * X - Switch1.x;
1650  Switch2.y = 2.0 * Y - Switch1.y;
1651 
1652  if (Switch1.x > Switch2.x) {
1653  S1 = 1;
1654  S2 = 0;
1655  }
1656 
1657  /* translate into bucket positions and deltas */
1658  Filler->X = Bucket8For(Start.x, XS, NB);
1659  Filler->StartDelta = -(inT16) ((Cos / Sin) * 256);
1660  Filler->EndDelta = (inT16) ((Sin / Cos) * 256);
1661 
1662  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1663  YAdjust = XAdjust * Cos / Sin;
1664  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1665  YAdjust = XAdjust * Sin / Cos;
1666  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1667 
1668  Filler->Switch[S1].Type = StartSwitch;
1669  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1670  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1671  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1672  YAdjust = XAdjust * Sin / Cos;
1673  Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
1674  Filler->Switch[S1].Delta = Filler->EndDelta;
1675 
1676  Filler->Switch[S2].Type = EndSwitch;
1677  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1678  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1679  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1680  YAdjust = XAdjust * Cos / Sin;
1681  Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
1682  Filler->Switch[S2].Delta = Filler->StartDelta;
1683 
1684  Filler->Switch[2].Type = LastSwitch;
1685  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1686  } else {
1687  /* falling diagonal proto */
1688  Angle *= 2.0 * PI;
1689  Cos = fabs(cos(Angle));
1690  Sin = fabs(sin(Angle));
1691 
1692  /* compute the positions of the corners of the acceptance region */
1693  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1694  Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1695  End.x = 2.0 * X - Start.x;
1696  End.y = 2.0 * Y - Start.y;
1697  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1698  Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1699  Switch2.x = 2.0 * X - Switch1.x;
1700  Switch2.y = 2.0 * Y - Switch1.y;
1701 
1702  if (Switch1.x > Switch2.x) {
1703  S1 = 1;
1704  S2 = 0;
1705  }
1706 
1707  /* translate into bucket positions and deltas */
1708  Filler->X = Bucket8For(Start.x, XS, NB);
1709  Filler->StartDelta = static_cast<inT16>(ClipToRange<int>(
1710  -IntCastRounded((Sin / Cos) * 256), MIN_INT16, MAX_INT16));
1711  Filler->EndDelta = static_cast<inT16>(ClipToRange<int>(
1712  IntCastRounded((Cos / Sin) * 256), MIN_INT16, MAX_INT16));
1713 
1714  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1715  YAdjust = XAdjust * Sin / Cos;
1716  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1717  YAdjust = XAdjust * Cos / Sin;
1718  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1719 
1720  Filler->Switch[S1].Type = EndSwitch;
1721  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1722  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1723  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1724  YAdjust = XAdjust * Sin / Cos;
1725  Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
1726  Filler->Switch[S1].Delta = Filler->StartDelta;
1727 
1728  Filler->Switch[S2].Type = StartSwitch;
1729  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1730  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1731  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1732  YAdjust = XAdjust * Cos / Sin;
1733  Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
1734  Filler->Switch[S2].Delta = Filler->EndDelta;
1735 
1736  Filler->Switch[2].Type = LastSwitch;
1737  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1738  }
1739  }
1740 } /* InitTableFiller */
1741 
1742 
1743 /*---------------------------------------------------------------------------*/
1744 #ifndef GRAPHICS_DISABLED
1745 
1755 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
1756  ScrollView::Color color) {
1757  FLOAT32 X, Y, Dx, Dy, Length;
1758 
1759  window->Pen(color);
1760  assert(Feature != NULL);
1761  assert(color != 0);
1762 
1763  X = Feature->X;
1764  Y = Feature->Y;
1765  Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
1766  // The -PI has no significant effect here, but the value of Theta is computed
1767  // using BinaryAnglePlusPi in intfx.cpp.
1768  Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * PI - PI);
1769  Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * PI - PI);
1770 
1771  window->SetCursor(X, Y);
1772  window->DrawTo(X + Dx, Y + Dy);
1773 } /* RenderIntFeature */
1774 
1792  INT_CLASS Class,
1793  PROTO_ID ProtoId,
1794  ScrollView::Color color) {
1795  PROTO_SET ProtoSet;
1796  INT_PROTO Proto;
1797  int ProtoSetIndex;
1798  int ProtoWordIndex;
1799  FLOAT32 Length;
1800  int Xmin, Xmax, Ymin, Ymax;
1801  FLOAT32 X, Y, Dx, Dy;
1802  uinT32 ProtoMask;
1803  int Bucket;
1804 
1805  assert(ProtoId >= 0);
1806  assert(Class != NULL);
1807  assert(ProtoId < Class->NumProtos);
1808  assert(color != 0);
1809  window->Pen(color);
1810 
1811  ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
1812  ProtoSetIndex = IndexForProto(ProtoId);
1813  Proto = &(ProtoSet->Protos[ProtoSetIndex]);
1814  Length = (Class->ProtoLengths[ProtoId] *
1816  ProtoMask = PPrunerMaskFor(ProtoId);
1817  ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
1818 
1819  // find the x and y extent of the proto from the proto pruning table
1820  Xmin = Ymin = NUM_PP_BUCKETS;
1821  Xmax = Ymax = 0;
1822  for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
1823  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
1824  UpdateRange(Bucket, &Xmin, &Xmax);
1825  }
1826 
1827  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
1828  UpdateRange(Bucket, &Ymin, &Ymax);
1829  }
1830  }
1831  X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1832  Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1833  // The -PI has no significant effect here, but the value of Theta is computed
1834  // using BinaryAnglePlusPi in intfx.cpp.
1835  Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * PI - PI);
1836  Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * PI - PI);
1837 
1838  window->SetCursor(X - Dx, Y - Dy);
1839  window->DrawTo(X + Dx, Y + Dy);
1840 } /* RenderIntProto */
1841 #endif
1842 
1858 int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id) {
1859  if (Param < Min) {
1860  if (Id)
1861  cprintf("Warning: Param %s truncated from %f to %d!\n",
1862  Id, Param, Min);
1863  Param = Min;
1864  } else if (Param > Max) {
1865  if (Id)
1866  cprintf("Warning: Param %s truncated from %f to %d!\n",
1867  Id, Param, Max);
1868  Param = Max;
1869  }
1870  return static_cast<int>(floor(Param));
1871 } /* TruncateParam */
1872 
1873 
1874 #ifndef GRAPHICS_DISABLED
1875 
1880  if (IntMatchWindow == NULL) {
1881  IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
1882  SVMenuNode* popup_menu = new SVMenuNode();
1883 
1884  popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
1885  "x", "Class to debug");
1886  popup_menu->AddChild("Debug Static classes", IDA_STATIC,
1887  "x", "Class to debug");
1888  popup_menu->AddChild("Debug Both", IDA_BOTH,
1889  "x", "Class to debug");
1890  popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
1891  "0", "Index to debug");
1892  popup_menu->BuildMenu(IntMatchWindow, false);
1893  }
1894 }
1895 
1901  if (ProtoDisplayWindow == NULL) {
1902  ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
1903  550, 200);
1904  }
1905 }
1906 
1912  if (FeatureDisplayWindow == NULL) {
1913  FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
1914  50, 700);
1915  }
1916 }
1917 
1920 ScrollView* CreateFeatureSpaceWindow(const char* name, int xpos, int ypos) {
1921  return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
1922 }
1923 #endif // GRAPHICS_DISABLED
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
Definition: intproto.cpp:238
#define OLD_WERDS_PER_CONFIG_VEC
Definition: intproto.cpp:113
ScrollView * FeatureDisplayWindow
Definition: intproto.cpp:180
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1920
void DrawTo(int x, int y)
Definition: scrollview.cpp:531
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
Definition: intproto.cpp:384
SVEventType
Definition: scrollview.h:45
UnicityTable< FontSet > fontset_table_
Definition: classify.h:496
INT_TEMPLATES ReadIntTemplates(FILE *File)
Definition: intproto.cpp:761
#define PPrunerWordIndexFor(I)
Definition: intproto.h:173
double classify_pp_angle_pad
Definition: intproto.cpp:201
int32_t * configs
Definition: fontinfo.h:141
double classify_cp_angle_pad_tight
Definition: intproto.cpp:194
uinT16 NumProtos
Definition: intproto.h:108
#define CPrunerIdFor(c)
Definition: intproto.h:183
void cprintf(const char *format,...)
Definition: callcpp.cpp:40
inT16 YStart
Definition: intproto.cpp:92
#define INT_XCENTER
Definition: intproto.cpp:59
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:125
int NumShapes() const
Definition: shapetable.h:278
#define PROTO_PRUNER_SCALE
Definition: intproto.cpp:52
struct INT_TEMPLATES_STRUCT * INT_TEMPLATES
SVEventType type
Definition: scrollview.h:64
#define WERDS_PER_PP_VECTOR
Definition: intproto.h:62
#define TRUE
Definition: capi.h:45
int IntCastRounded(double x)
Definition: helpers.h:172
bool read_info(FILE *f, FontInfo *fi, bool swap)
Definition: fontinfo.cpp:152
#define ProtoForProtoId(C, P)
Definition: intproto.h:171
#define INT_XRADIUS
Definition: intproto.cpp:61
#define INT_YRADIUS
Definition: intproto.cpp:62
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, FLOAT32 Evidence)
Definition: intproto.cpp:623
#define PRUNER_ANGLE
Definition: intproto.h:36
short inT16
Definition: host.h:33
ScrollView::Color GetMatchColorFor(FLOAT32 Evidence)
Definition: intproto.cpp:1512
CONFIGS Configurations
Definition: protos.h:64
uinT32 * BIT_VECTOR
Definition: bitvec.h:28
void InitIntMatchWindowIfReqd()
Definition: intproto.cpp:1879
#define HV_TOLERANCE
Definition: intproto.cpp:69
struct INT_CLASS_STRUCT * INT_CLASS
#define INT_MIN_Y
Definition: intproto.cpp:64
#define NUM_PP_PARAMS
Definition: intproto.h:50
#define ANGLE_SHIFT
Definition: intproto.h:39
bool TESS_API contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:644
FLOAT32 x
Definition: fpoint.h:31
static void Update()
Definition: scrollview.cpp:715
struct PROTO_SET_STRUCT * PROTO_SET
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
Definition: tesscallback.h:116
#define YS
void SetCursor(int x, int y)
Definition: scrollview.cpp:525
inT16 NumProtos
Definition: protos.h:59
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1755
int size() const
Definition: unicharset.h:297
void Reverse32(void *ptr)
Definition: helpers.h:193
inT8 YEnd
Definition: intproto.cpp:103
#define WERDS_PER_CP_VECTOR
Definition: intproto.h:61
#define PI
Definition: const.h:19
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
Definition: intproto.cpp:342
BOOL8 FillerDone(TABLE_FILLER *Filler)
Definition: intproto.cpp:1285
#define CPrunerFor(T, c)
Definition: intproto.h:184
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
Definition: intproto.cpp:1791
#define MAX_NUM_CLASS_PRUNERS
Definition: intproto.h:59
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
Definition: intproto.cpp:1538
#define UnusedClassIdIn(T, c)
Definition: intproto.h:180
#define INT_MAX_X
Definition: intproto.cpp:65
CLUSTERCONFIG Config
uinT8 AngleStart
Definition: intproto.cpp:104
void InitTableFiller(FLOAT32 EndPad, FLOAT32 SidePad, FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER *Filler)
Definition: intproto.cpp:1590
#define NUM_BITS_PER_CLASS
Definition: intproto.h:54
double classify_cp_side_pad_loose
Definition: intproto.cpp:198
#define OLD_MAX_NUM_CONFIGS
Definition: intproto.cpp:112
#define INT_CAPHEIGHT
Definition: intproto.cpp:57
CLASS_ID GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on, int *shape_id)
Definition: intproto.cpp:1391
UnicityTableEqEq< int > font_set
Definition: protos.h:65
FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets)
Definition: intproto.cpp:1207
#define BITS_PER_WERD
Definition: intproto.h:44
inT16 PROTO_ID
Definition: matchdefs.h:41
void Efree(void *ptr)
Definition: emalloc.cpp:79
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:115
bool ContainsUnichar(int unichar_id) const
Definition: shapetable.cpp:156
unsigned char uinT8
Definition: host.h:32
#define XS
void InitProtoDisplayWindowIfReqd()
Definition: intproto.cpp:1900
#define MaxNumIntProtosIn(C)
Definition: intproto.h:168
#define SetForProto(P)
Definition: intproto.h:169
FLOAT32 Angle
Definition: protos.h:49
unsigned char BOOL8
Definition: host.h:46
inT16 Delta
Definition: intproto.cpp:81
FLOAT32 y
Definition: fpoint.h:31
#define PROTOS_PER_PROTO_SET
Definition: intproto.h:48
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, register uinT32 ClassMask, register uinT32 ClassCount, register uinT32 WordIndex)
Definition: intproto.cpp:1243
void FillPPCircularBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
Definition: intproto.cpp:1314
FLOAT32 X
Definition: protos.h:47
#define MAX_NUM_PROTOS
Definition: intproto.h:47
UNICHAR_ID CLASS_ID
Definition: matchdefs.h:35
FLOAT32 Length
Definition: protos.h:50
void UpdateMatchDisplay()
Definition: intproto.cpp:467
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:211
int AddIntProto(INT_CLASS Class)
Definition: intproto.cpp:293
UnicityTable< FontInfo > fontinfo_table_
Definition: classify.h:488
double classify_cp_angle_pad_loose
Definition: intproto.cpp:190
void free_int_class(INT_CLASS int_class)
Definition: intproto.cpp:703
bool write_set(FILE *f, const FontSet &fs)
Definition: fontinfo.cpp:253
#define ClassForClassId(T, c)
Definition: intproto.h:181
NORM_METHOD
Definition: mfoutline.h:53
#define Y_SHIFT
Definition: intproto.h:41
inT16 YEnd
Definition: intproto.cpp:92
#define WERDS_PER_CONFIG_VEC
Definition: intproto.h:68
int size() const
Return the size used.
#define INT_BASELINE
Definition: intproto.cpp:55
#define PRUNER_X
Definition: intproto.h:34
#define INT_MIN_X
Definition: intproto.cpp:63
const char * string() const
Definition: strngs.cpp:201
#define MaxNumClassesIn(T)
Definition: intproto.h:178
#define MAX_UINT8
Definition: host.h:54
ScrollView * ProtoDisplayWindow
Definition: intproto.cpp:181
inT16 NumConfigs
Definition: protos.h:62
FLOAT32 C
Definition: protos.h:46
#define SET_BIT(array, bit)
Definition: bitvec.h:57
unsigned short uinT16
Definition: host.h:34
#define MAX_INT16
Definition: host.h:52
double classify_cp_end_pad_medium
Definition: intproto.cpp:196
uinT8 NumProtoSets
Definition: intproto.h:109
uinT32 PROTO_PRUNER[NUM_PP_PARAMS][NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR]
Definition: intproto.h:92
uinT8 Bucket8For(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:435
#define FALSE
Definition: capi.h:46
#define PRUNER_Y
Definition: intproto.h:35
uinT32 Configs[WERDS_PER_CONFIG_VEC]
Definition: intproto.h:86
inT16 EndDelta
Definition: intproto.cpp:93
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
Definition: intproto.cpp:664
char * parameter
Definition: scrollview.h:71
FLOAT32 A
Definition: protos.h:44
ScrollView * IntMatchWindow
Definition: intproto.cpp:179
#define BITS_PER_CP_VECTOR
Definition: intproto.h:58
#define CPrunerWordIndexFor(c)
Definition: intproto.h:185
#define CPrunerMaskFor(L, c)
Definition: intproto.h:187
SIGNED char inT8
Definition: host.h:31
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:449
float FLOAT32
Definition: host.h:44
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:1095
#define CPrunerBitIndexFor(c)
Definition: intproto.h:186
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:739
#define INT_XHEIGHT
Definition: intproto.cpp:56
#define AS
void Pen(Color color)
Definition: scrollview.cpp:726
void InitFeatureDisplayWindowIfReqd()
Definition: intproto.cpp:1911
#define NO_PROTO
Definition: matchdefs.h:42
int AddIntConfig(INT_CLASS Class)
Definition: intproto.cpp:270
inT16 StartDelta
Definition: intproto.cpp:93
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
Definition: intproto.h:97
void Clear()
Definition: scrollview.cpp:595
uinT8 AngleEnd
Definition: intproto.cpp:90
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
Definition: intproto.cpp:94
#define INT_DESCENDER
Definition: intproto.cpp:54
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence)
Definition: intproto.cpp:644
#define IndexForProto(P)
Definition: intproto.h:170
void * Erealloc(void *ptr, int size)
Definition: emalloc.cpp:64
double classify_cp_side_pad_tight
Definition: intproto.cpp:200
void GetFirstUnicharAndFont(int shape_id, int *unichar_id, int *font_id) const
Definition: shapetable.cpp:414
#define PPrunerMaskFor(I)
Definition: intproto.h:176
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:121
#define MAX(x, y)
Definition: ndminx.h:24
UNICHAR_ID TESS_API unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:194
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class)
Definition: intproto.cpp:516
#define MAX_NUM_PROTO_SETS
Definition: intproto.h:49
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
Definition: intproto.h:111
FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets)
Definition: intproto.cpp:1225
#define tprintf(...)
Definition: tprintf.h:31
double classify_pp_end_pad
Definition: intproto.cpp:202
uinT32 p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
Definition: intproto.h:77
int classify_learning_debug_level
Definition: classify.h:419
void GetCPPadsForLevel(int Level, FLOAT32 *EndPad, FLOAT32 *SidePad, FLOAT32 *AnglePad)
Definition: intproto.cpp:1471
INT_TEMPLATES NewIntTemplates()
Definition: intproto.cpp:723
ShapeTable * shape_table_
Definition: classify.h:512
#define MapParam(P, O, N)
Definition: intproto.cpp:123
Definition: points.h:189
void Reverse16(void *ptr)
Definition: helpers.h:188
#define CircularIncrement(i, r)
Definition: intproto.cpp:120
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:1129
double classify_cp_end_pad_tight
Definition: intproto.cpp:197
FLOAT32 Y
Definition: protos.h:48
inT8 YStart
Definition: intproto.cpp:103
const Shape & GetShape(int shape_id) const
Definition: shapetable.h:323
#define MAX_NUM_CLASSES
Definition: matchdefs.h:31
SWITCH_TYPE
Definition: intproto.cpp:71
inT16 YInit
Definition: intproto.cpp:80
#define NB
int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id)
Definition: intproto.cpp:1858
uinT8 AngleStart
Definition: intproto.cpp:90
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:59
#define ProtoIn(Class, Pid)
Definition: protos.h:123
#define test_bit(array, bit)
Definition: bitvec.h:61
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
Definition: intproto.cpp:487
#define INT_CHAR_NORM_RANGE
Definition: intproto.h:133
uinT8 NextSwitch
Definition: intproto.cpp:89
unsigned int uinT32
Definition: host.h:36
uinT16 Bucket16For(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:439
int Modulo(int a, int b)
Definition: helpers.h:157
#define LegalClassId(c)
Definition: intproto.h:179
uinT8 AngleEnd
Definition: intproto.cpp:104
#define INT_MAX_Y
Definition: intproto.cpp:66
const T & get(int id) const
Return the object from an id.
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
Definition: intproto.h:125
double classify_cp_side_pad_medium
Definition: intproto.cpp:199
void FillPPLinearBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
Definition: intproto.cpp:1357
void * Emalloc(int Size)
Definition: emalloc.cpp:47
uinT8 CircBucketFor(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:449
#define MAX_NUM_CONFIGS
Definition: intproto.h:46
double classify_pp_side_pad
Definition: intproto.cpp:203
UNICHARSET unicharset
Definition: ccutil.h:70
double classify_cp_end_pad_loose
Definition: intproto.cpp:195
#define double_VAR(name, val, comment)
Definition: params.h:286
double classify_cp_angle_pad_medium
Definition: intproto.cpp:192
int command_id
Definition: scrollview.h:70
#define NUM_CP_BUCKETS
Definition: intproto.h:52
#define X_SHIFT
Definition: intproto.h:40
const char * id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:266
uinT16 ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:113
bool read_spacing_info(FILE *f, FontInfo *fi, bool swap)
Definition: fontinfo.cpp:177
uinT8 NumConfigs
Definition: intproto.h:110
#define MAX_NUM_SWITCHES
Definition: intproto.cpp:74
#define INT_YCENTER
Definition: intproto.cpp:60
PROTO_PRUNER ProtoPruner
Definition: intproto.h:96
STRING DebugStr(int shape_id) const
Definition: shapetable.cpp:291
#define NUM_PP_BUCKETS
Definition: intproto.h:51
#define ASSERT_HOST(x)
Definition: errcode.h:84
SWITCH_TYPE Type
Definition: intproto.cpp:78
int classify_num_cp_levels
Definition: intproto.cpp:188
#define MIN_INT16
Definition: host.h:60
#define MAX_LEVEL
INT_CLASS Class[MAX_NUM_CLASSES]
Definition: intproto.h:124
#define INT_VAR(name, val, comment)
Definition: params.h:277
#define GetPicoFeatureLength()
Definition: picofeat.h:59
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:168
Definition: fpoint.h:29
uinT8 * ProtoLengths
Definition: intproto.h:112
bool read_set(FILE *f, FontSet *fs, bool swap)
Definition: fontinfo.cpp:240
void ZoomToRectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:765
FLOAT32 B
Definition: protos.h:45
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:557