tesseract  4.00.00dev
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)
469  IntMatchWindow->Update();
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);
542  if (classify_learning_debug_level >= 2)
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 
557 INT_TEMPLATES Classify::CreateIntTemplates(CLASSES FloatProtos,
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,
596  classify_learning_debug_level >= 2);
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 {
761 INT_TEMPLATES Classify::ReadIntTemplates(TFile *fp) {
762  int i, j, w, x, y, z;
763  int unicharset_size;
764  int version_id = 0;
765  INT_TEMPLATES Templates;
766  CLASS_PRUNER_STRUCT* Pruner;
767  INT_CLASS Class;
768  uinT8 *Lengths;
769  PROTO_SET ProtoSet;
770 
771  /* variables for conversion from older inttemp formats */
772  int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
773  CLASS_ID class_id, max_class_id;
774  inT16 *IndexFor = new inT16[MAX_NUM_CLASSES];
775  CLASS_ID *ClassIdFor = new CLASS_ID[MAX_NUM_CLASSES];
776  CLASS_PRUNER_STRUCT **TempClassPruner =
778  uinT32 SetBitsForMask = // word with NUM_BITS_PER_CLASS
779  (1 << NUM_BITS_PER_CLASS) - 1; // set starting at bit 0
780  uinT32 Mask, NewMask, ClassBits;
781  int MaxNumConfigs = MAX_NUM_CONFIGS;
782  int WerdsPerConfigVec = WERDS_PER_CONFIG_VEC;
783 
784  /* first read the high level template struct */
785  Templates = NewIntTemplates();
786  // Read Templates in parts for 64 bit compatibility.
787  if (fp->FReadEndian(&unicharset_size, sizeof(unicharset_size), 1) != 1)
788  tprintf("Bad read of inttemp!\n");
789  if (fp->FReadEndian(&Templates->NumClasses, sizeof(Templates->NumClasses),
790  1) != 1 ||
791  fp->FReadEndian(&Templates->NumClassPruners,
792  sizeof(Templates->NumClassPruners), 1) != 1)
793  tprintf("Bad read of inttemp!\n");
794  if (Templates->NumClasses < 0) {
795  // This file has a version id!
796  version_id = -Templates->NumClasses;
797  if (fp->FReadEndian(&Templates->NumClasses, sizeof(Templates->NumClasses),
798  1) != 1)
799  tprintf("Bad read of inttemp!\n");
800  }
801 
802  if (version_id < 3) {
803  MaxNumConfigs = OLD_MAX_NUM_CONFIGS;
804  WerdsPerConfigVec = OLD_WERDS_PER_CONFIG_VEC;
805  }
806 
807  if (version_id < 2) {
808  if (fp->FReadEndian(IndexFor, sizeof(IndexFor[0]), unicharset_size) !=
809  unicharset_size) {
810  tprintf("Bad read of inttemp!\n");
811  }
812  if (fp->FReadEndian(ClassIdFor, sizeof(ClassIdFor[0]),
813  Templates->NumClasses) != Templates->NumClasses) {
814  tprintf("Bad read of inttemp!\n");
815  }
816  }
817 
818  /* then read in the class pruners */
819  const int kNumBuckets =
821  for (i = 0; i < Templates->NumClassPruners; i++) {
822  Pruner = new CLASS_PRUNER_STRUCT;
823  if (fp->FReadEndian(Pruner, sizeof(Pruner->p[0][0][0][0]), kNumBuckets) !=
824  kNumBuckets) {
825  tprintf("Bad read of inttemp!\n");
826  }
827  if (version_id < 2) {
828  TempClassPruner[i] = Pruner;
829  } else {
830  Templates->ClassPruners[i] = Pruner;
831  }
832  }
833 
834  /* fix class pruners if they came from an old version of inttemp */
835  if (version_id < 2) {
836  // Allocate enough class pruners to cover all the class ids.
837  max_class_id = 0;
838  for (i = 0; i < Templates->NumClasses; i++)
839  if (ClassIdFor[i] > max_class_id)
840  max_class_id = ClassIdFor[i];
841  for (i = 0; i <= CPrunerIdFor(max_class_id); i++) {
842  Templates->ClassPruners[i] = new CLASS_PRUNER_STRUCT;
843  memset(Templates->ClassPruners[i], 0, sizeof(CLASS_PRUNER_STRUCT));
844  }
845  // Convert class pruners from the old format (indexed by class index)
846  // to the new format (indexed by class id).
847  last_cp_bit_number = NUM_BITS_PER_CLASS * Templates->NumClasses - 1;
848  for (i = 0; i < Templates->NumClassPruners; i++) {
849  for (x = 0; x < NUM_CP_BUCKETS; x++)
850  for (y = 0; y < NUM_CP_BUCKETS; y++)
851  for (z = 0; z < NUM_CP_BUCKETS; z++)
852  for (w = 0; w < WERDS_PER_CP_VECTOR; w++) {
853  if (TempClassPruner[i]->p[x][y][z][w] == 0)
854  continue;
855  for (b = 0; b < BITS_PER_WERD; b += NUM_BITS_PER_CLASS) {
856  bit_number = i * BITS_PER_CP_VECTOR + w * BITS_PER_WERD + b;
857  if (bit_number > last_cp_bit_number)
858  break; // the rest of the bits in this word are not used
859  class_id = ClassIdFor[bit_number / NUM_BITS_PER_CLASS];
860  // Single out NUM_BITS_PER_CLASS bits relating to class_id.
861  Mask = SetBitsForMask << b;
862  ClassBits = TempClassPruner[i]->p[x][y][z][w] & Mask;
863  // Move these bits to the new position in which they should
864  // appear (indexed corresponding to the class_id).
865  new_i = CPrunerIdFor(class_id);
866  new_w = CPrunerWordIndexFor(class_id);
867  new_b = CPrunerBitIndexFor(class_id) * NUM_BITS_PER_CLASS;
868  if (new_b > b) {
869  ClassBits <<= (new_b - b);
870  } else {
871  ClassBits >>= (b - new_b);
872  }
873  // Copy bits relating to class_id to the correct position
874  // in Templates->ClassPruner.
875  NewMask = SetBitsForMask << new_b;
876  Templates->ClassPruners[new_i]->p[x][y][z][new_w] &= ~NewMask;
877  Templates->ClassPruners[new_i]->p[x][y][z][new_w] |= ClassBits;
878  }
879  }
880  }
881  for (i = 0; i < Templates->NumClassPruners; i++) {
882  delete TempClassPruner[i];
883  }
884  }
885 
886  /* then read in each class */
887  for (i = 0; i < Templates->NumClasses; i++) {
888  /* first read in the high level struct for the class */
889  Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT));
890  if (fp->FReadEndian(&Class->NumProtos, sizeof(Class->NumProtos), 1) != 1 ||
891  fp->FRead(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1) != 1 ||
892  fp->FRead(&Class->NumConfigs, sizeof(Class->NumConfigs), 1) != 1)
893  tprintf("Bad read of inttemp!\n");
894  if (version_id == 0) {
895  // Only version 0 writes 5 pointless pointers to the file.
896  for (j = 0; j < 5; ++j) {
897  inT32 junk;
898  if (fp->FRead(&junk, sizeof(junk), 1) != 1)
899  tprintf("Bad read of inttemp!\n");
900  }
901  }
902  int num_configs = version_id < 4 ? MaxNumConfigs : Class->NumConfigs;
903  ASSERT_HOST(num_configs <= MaxNumConfigs);
904  if (fp->FReadEndian(Class->ConfigLengths, sizeof(uinT16), num_configs) !=
905  num_configs) {
906  tprintf("Bad read of inttemp!\n");
907  }
908  if (version_id < 2) {
909  ClassForClassId (Templates, ClassIdFor[i]) = Class;
910  } else {
911  ClassForClassId (Templates, i) = Class;
912  }
913 
914  /* then read in the proto lengths */
915  Lengths = NULL;
916  if (MaxNumIntProtosIn (Class) > 0) {
917  Lengths = (uinT8 *)Emalloc(sizeof(uinT8) * MaxNumIntProtosIn(Class));
918  if (fp->FRead(Lengths, sizeof(uinT8), MaxNumIntProtosIn(Class)) !=
919  MaxNumIntProtosIn(Class))
920  tprintf("Bad read of inttemp!\n");
921  }
922  Class->ProtoLengths = Lengths;
923 
924  /* then read in the proto sets */
925  for (j = 0; j < Class->NumProtoSets; j++) {
926  ProtoSet = (PROTO_SET)Emalloc(sizeof(PROTO_SET_STRUCT));
927  int num_buckets = NUM_PP_PARAMS * NUM_PP_BUCKETS * WERDS_PER_PP_VECTOR;
928  if (fp->FReadEndian(&ProtoSet->ProtoPruner,
929  sizeof(ProtoSet->ProtoPruner[0][0][0]),
930  num_buckets) != num_buckets)
931  tprintf("Bad read of inttemp!\n");
932  for (x = 0; x < PROTOS_PER_PROTO_SET; x++) {
933  if (fp->FRead(&ProtoSet->Protos[x].A, sizeof(ProtoSet->Protos[x].A),
934  1) != 1 ||
935  fp->FRead(&ProtoSet->Protos[x].B, sizeof(ProtoSet->Protos[x].B),
936  1) != 1 ||
937  fp->FRead(&ProtoSet->Protos[x].C, sizeof(ProtoSet->Protos[x].C),
938  1) != 1 ||
939  fp->FRead(&ProtoSet->Protos[x].Angle,
940  sizeof(ProtoSet->Protos[x].Angle), 1) != 1)
941  tprintf("Bad read of inttemp!\n");
942  if (fp->FReadEndian(&ProtoSet->Protos[x].Configs,
943  sizeof(ProtoSet->Protos[x].Configs[0]),
944  WerdsPerConfigVec) != WerdsPerConfigVec)
945  cprintf("Bad read of inttemp!\n");
946  }
947  Class->ProtoSets[j] = ProtoSet;
948  }
949  if (version_id < 4) {
950  Class->font_set_id = -1;
951  } else {
952  fp->FReadEndian(&Class->font_set_id, sizeof(Class->font_set_id), 1);
953  }
954  }
955 
956  if (version_id < 2) {
957  /* add an empty NULL class with class id 0 */
958  assert(UnusedClassIdIn (Templates, 0));
959  ClassForClassId (Templates, 0) = NewIntClass (1, 1);
960  ClassForClassId (Templates, 0)->font_set_id = -1;
961  Templates->NumClasses++;
962  /* make sure the classes are contiguous */
963  for (i = 0; i < MAX_NUM_CLASSES; i++) {
964  if (i < Templates->NumClasses) {
965  if (ClassForClassId (Templates, i) == NULL) {
966  fprintf(stderr, "Non-contiguous class ids in inttemp\n");
967  exit(1);
968  }
969  } else {
970  if (ClassForClassId (Templates, i) != NULL) {
971  fprintf(stderr, "Class id %d exceeds NumClassesIn (Templates) %d\n",
972  i, Templates->NumClasses);
973  exit(1);
974  }
975  }
976  }
977  }
978  if (version_id >= 4) {
979  this->fontinfo_table_.read(fp, NewPermanentTessCallback(read_info));
980  if (version_id >= 5) {
981  this->fontinfo_table_.read(fp,
983  }
984  this->fontset_table_.read(fp, NewPermanentTessCallback(read_set));
985  }
986 
987  // Clean up.
988  delete[] IndexFor;
989  delete[] ClassIdFor;
990  delete[] TempClassPruner;
991 
992  return (Templates);
993 } /* ReadIntTemplates */
994 
995 
996 #ifndef GRAPHICS_DISABLED
997 
1010  if (ProtoDisplayWindow) {
1011  ProtoDisplayWindow->Clear();
1012  }
1013  if (FeatureDisplayWindow) {
1014  FeatureDisplayWindow->Clear();
1015  }
1017  static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
1018  IntMatchWindow);
1019  IntMatchWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
1020  INT_MAX_X, INT_MAX_Y);
1021  if (ProtoDisplayWindow) {
1022  ProtoDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
1023  INT_MAX_X, INT_MAX_Y);
1024  }
1025  if (FeatureDisplayWindow) {
1026  FeatureDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
1027  INT_MAX_X, INT_MAX_Y);
1028  }
1029 } /* ShowMatchDisplay */
1030 
1033 void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView* window) {
1034  window->Clear();
1035 
1036  window->Pen(ScrollView::GREY);
1037  // Draw the feature space limit rectangle.
1038  window->Rectangle(0, 0, INT_MAX_X, INT_MAX_Y);
1039  if (norm_method == baseline) {
1040  window->SetCursor(0, INT_DESCENDER);
1041  window->DrawTo(INT_MAX_X, INT_DESCENDER);
1042  window->SetCursor(0, INT_BASELINE);
1043  window->DrawTo(INT_MAX_X, INT_BASELINE);
1044  window->SetCursor(0, INT_XHEIGHT);
1045  window->DrawTo(INT_MAX_X, INT_XHEIGHT);
1046  window->SetCursor(0, INT_CAPHEIGHT);
1047  window->DrawTo(INT_MAX_X, INT_CAPHEIGHT);
1048  } else {
1051  }
1052 }
1053 #endif
1054 
1067 void Classify::WriteIntTemplates(FILE *File, INT_TEMPLATES Templates,
1068  const UNICHARSET& target_unicharset) {
1069  int i, j;
1070  INT_CLASS Class;
1071  int unicharset_size = target_unicharset.size();
1072  int version_id = -5; // When negated by the reader -1 becomes +1 etc.
1073 
1074  if (Templates->NumClasses != unicharset_size) {
1075  cprintf("Warning: executing WriteIntTemplates() with %d classes in"
1076  " Templates, while target_unicharset size is %d\n",
1077  Templates->NumClasses, unicharset_size);
1078  }
1079 
1080  /* first write the high level template struct */
1081  fwrite(&unicharset_size, sizeof(unicharset_size), 1, File);
1082  fwrite(&version_id, sizeof(version_id), 1, File);
1083  fwrite(&Templates->NumClassPruners, sizeof(Templates->NumClassPruners),
1084  1, File);
1085  fwrite(&Templates->NumClasses, sizeof(Templates->NumClasses), 1, File);
1086 
1087  /* then write out the class pruners */
1088  for (i = 0; i < Templates->NumClassPruners; i++)
1089  fwrite(Templates->ClassPruners[i],
1090  sizeof(CLASS_PRUNER_STRUCT), 1, File);
1091 
1092  /* then write out each class */
1093  for (i = 0; i < Templates->NumClasses; i++) {
1094  Class = Templates->Class[i];
1095 
1096  /* first write out the high level struct for the class */
1097  fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
1098  fwrite(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File);
1099  ASSERT_HOST(Class->NumConfigs == this->fontset_table_.get(Class->font_set_id).size);
1100  fwrite(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File);
1101  for (j = 0; j < Class->NumConfigs; ++j) {
1102  fwrite(&Class->ConfigLengths[j], sizeof(uinT16), 1, File);
1103  }
1104 
1105  /* then write out the proto lengths */
1106  if (MaxNumIntProtosIn (Class) > 0) {
1107  fwrite ((char *) (Class->ProtoLengths), sizeof (uinT8),
1108  MaxNumIntProtosIn (Class), File);
1109  }
1110 
1111  /* then write out the proto sets */
1112  for (j = 0; j < Class->NumProtoSets; j++)
1113  fwrite ((char *) Class->ProtoSets[j],
1114  sizeof (PROTO_SET_STRUCT), 1, File);
1115 
1116  /* then write the fonts info */
1117  fwrite(&Class->font_set_id, sizeof(int), 1, File);
1118  }
1119 
1120  /* Write the fonts info tables */
1121  this->fontinfo_table_.write(File, NewPermanentTessCallback(write_info));
1122  this->fontinfo_table_.write(File,
1124  this->fontset_table_.write(File, NewPermanentTessCallback(write_set));
1125 } /* WriteIntTemplates */
1126 } // namespace tesseract
1127 
1128 
1129 /*-----------------------------------------------------------------------------
1130  Private Code
1131 -----------------------------------------------------------------------------*/
1145 FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets) {
1146  return (((FLOAT32) Bucket / NumBuckets) - Offset);
1147 
1148 } /* BucketStart */
1149 
1163 FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets) {
1164  return (((FLOAT32) (Bucket + 1) / NumBuckets) - Offset);
1165 } /* BucketEnd */
1166 
1181 void DoFill(FILL_SPEC *FillSpec,
1182  CLASS_PRUNER_STRUCT* Pruner,
1183  register uinT32 ClassMask,
1184  register uinT32 ClassCount,
1185  register uinT32 WordIndex) {
1186  int X, Y, Angle;
1187  uinT32 OldWord;
1188 
1189  X = FillSpec->X;
1190  if (X < 0)
1191  X = 0;
1192  if (X >= NUM_CP_BUCKETS)
1193  X = NUM_CP_BUCKETS - 1;
1194 
1195  if (FillSpec->YStart < 0)
1196  FillSpec->YStart = 0;
1197  if (FillSpec->YEnd >= NUM_CP_BUCKETS)
1198  FillSpec->YEnd = NUM_CP_BUCKETS - 1;
1199 
1200  for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
1201  for (Angle = FillSpec->AngleStart;
1203  OldWord = Pruner->p[X][Y][Angle][WordIndex];
1204  if (ClassCount > (OldWord & ClassMask)) {
1205  OldWord &= ~ClassMask;
1206  OldWord |= ClassCount;
1207  Pruner->p[X][Y][Angle][WordIndex] = OldWord;
1208  }
1209  if (Angle == FillSpec->AngleEnd)
1210  break;
1211  }
1212 } /* DoFill */
1213 
1224  FILL_SWITCH *Next;
1225 
1226  Next = &(Filler->Switch[Filler->NextSwitch]);
1227 
1228  if (Filler->X > Next->X && Next->Type == LastSwitch)
1229  return (TRUE);
1230  else
1231  return (FALSE);
1232 
1233 } /* FillerDone */
1234 
1253  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) {
1254  int i, FirstBucket, LastBucket;
1255 
1256  if (Spread > 0.5)
1257  Spread = 0.5;
1258 
1259  FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
1260  if (FirstBucket < 0)
1261  FirstBucket += NUM_PP_BUCKETS;
1262 
1263  LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
1264  if (LastBucket >= NUM_PP_BUCKETS)
1265  LastBucket -= NUM_PP_BUCKETS;
1266  if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
1267  for (i = FirstBucket; TRUE; CircularIncrement (i, NUM_PP_BUCKETS)) {
1268  SET_BIT (ParamTable[i], Bit);
1269 
1270  /* exit loop after we have set the bit for the last bucket */
1271  if (i == LastBucket)
1272  break;
1273  }
1274 
1275 } /* FillPPCircularBits */
1276 
1296  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) {
1297  int i, FirstBucket, LastBucket;
1298 
1299  FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
1300  if (FirstBucket < 0)
1301  FirstBucket = 0;
1302 
1303  LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
1304  if (LastBucket >= NUM_PP_BUCKETS)
1305  LastBucket = NUM_PP_BUCKETS - 1;
1306 
1307  if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
1308  for (i = FirstBucket; i <= LastBucket; i++)
1309  SET_BIT (ParamTable[i], Bit);
1310 
1311 } /* FillPPLinearBits */
1312 
1313 
1314 /*---------------------------------------------------------------------------*/
1315 #ifndef GRAPHICS_DISABLED
1316 namespace tesseract {
1329 CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool* adaptive_on,
1330  bool* pretrained_on, int* shape_id) {
1331  tprintf("%s\n", Prompt);
1332  SVEvent* ev;
1333  SVEventType ev_type;
1334  int unichar_id = INVALID_UNICHAR_ID;
1335  // Wait until a click or popup event.
1336  do {
1337  ev = IntMatchWindow->AwaitEvent(SVET_ANY);
1338  ev_type = ev->type;
1339  if (ev_type == SVET_POPUP) {
1340  if (ev->command_id == IDA_SHAPE_INDEX) {
1341  if (shape_table_ != NULL) {
1342  *shape_id = atoi(ev->parameter);
1343  *adaptive_on = false;
1344  *pretrained_on = true;
1345  if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1346  int font_id;
1347  shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1348  &font_id);
1349  tprintf("Shape %d, first unichar=%d, font=%d\n",
1350  *shape_id, unichar_id, font_id);
1351  return unichar_id;
1352  }
1353  tprintf("Shape index '%s' not found in shape table\n", ev->parameter);
1354  } else {
1355  tprintf("No shape table loaded!\n");
1356  }
1357  } else {
1358  if (unicharset.contains_unichar(ev->parameter)) {
1359  unichar_id = unicharset.unichar_to_id(ev->parameter);
1360  if (ev->command_id == IDA_ADAPTIVE) {
1361  *adaptive_on = true;
1362  *pretrained_on = false;
1363  *shape_id = -1;
1364  } else if (ev->command_id == IDA_STATIC) {
1365  *adaptive_on = false;
1366  *pretrained_on = true;
1367  } else {
1368  *adaptive_on = true;
1369  *pretrained_on = true;
1370  }
1371  if (ev->command_id == IDA_ADAPTIVE || shape_table_ == NULL) {
1372  *shape_id = -1;
1373  return unichar_id;
1374  }
1375  for (int s = 0; s < shape_table_->NumShapes(); ++s) {
1376  if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1377  tprintf("%s\n", shape_table_->DebugStr(s).string());
1378  }
1379  }
1380  } else {
1381  tprintf("Char class '%s' not found in unicharset",
1382  ev->parameter);
1383  }
1384  }
1385  }
1386  delete ev;
1387  } while (ev_type != SVET_CLICK);
1388  return 0;
1389 } /* GetClassToDebug */
1390 
1391 } // namespace tesseract
1392 #endif
1393 
1409 void GetCPPadsForLevel(int Level,
1410  FLOAT32 *EndPad,
1411  FLOAT32 *SidePad,
1412  FLOAT32 *AnglePad) {
1413  switch (Level) {
1414  case 0:
1417  *AnglePad = classify_cp_angle_pad_loose / 360.0;
1418  break;
1419 
1420  case 1:
1423  *AnglePad = classify_cp_angle_pad_medium / 360.0;
1424  break;
1425 
1426  case 2:
1429  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1430  break;
1431 
1432  default:
1435  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1436  break;
1437  }
1438  if (*AnglePad > 0.5)
1439  *AnglePad = 0.5;
1440 
1441 } /* GetCPPadsForLevel */
1442 
1451  assert (Evidence >= 0.0);
1452  assert (Evidence <= 1.0);
1453 
1454  if (Evidence >= 0.90)
1455  return ScrollView::WHITE;
1456  else if (Evidence >= 0.75)
1457  return ScrollView::GREEN;
1458  else if (Evidence >= 0.50)
1459  return ScrollView::RED;
1460  else
1461  return ScrollView::BLUE;
1462 } /* GetMatchColorFor */
1463 
1476 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {
1477  FILL_SWITCH *Next;
1478 
1479  /* compute the fill assuming no switches will be encountered */
1480  Fill->AngleStart = Filler->AngleStart;
1481  Fill->AngleEnd = Filler->AngleEnd;
1482  Fill->X = Filler->X;
1483  Fill->YStart = Filler->YStart >> 8;
1484  Fill->YEnd = Filler->YEnd >> 8;
1485 
1486  /* update the fill info and the filler for ALL switches at this X value */
1487  Next = &(Filler->Switch[Filler->NextSwitch]);
1488  while (Filler->X >= Next->X) {
1489  Fill->X = Filler->X = Next->X;
1490  if (Next->Type == StartSwitch) {
1491  Fill->YStart = Next->Y;
1492  Filler->StartDelta = Next->Delta;
1493  Filler->YStart = Next->YInit;
1494  }
1495  else if (Next->Type == EndSwitch) {
1496  Fill->YEnd = Next->Y;
1497  Filler->EndDelta = Next->Delta;
1498  Filler->YEnd = Next->YInit;
1499  }
1500  else { /* Type must be LastSwitch */
1501  break;
1502  }
1503  Filler->NextSwitch++;
1504  Next = &(Filler->Switch[Filler->NextSwitch]);
1505  }
1506 
1507  /* prepare the filler for the next call to this routine */
1508  Filler->X++;
1509  Filler->YStart += Filler->StartDelta;
1510  Filler->YEnd += Filler->EndDelta;
1511 
1512 } /* GetNextFill */
1513 
1528 void InitTableFiller (FLOAT32 EndPad, FLOAT32 SidePad,
1529  FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER * Filler)
1530 #define XS X_SHIFT
1531 #define YS Y_SHIFT
1532 #define AS ANGLE_SHIFT
1533 #define NB NUM_CP_BUCKETS
1534 {
1535  FLOAT32 Angle;
1536  FLOAT32 X, Y, HalfLength;
1537  FLOAT32 Cos, Sin;
1538  FLOAT32 XAdjust, YAdjust;
1539  FPOINT Start, Switch1, Switch2, End;
1540  int S1 = 0;
1541  int S2 = 1;
1542 
1543  Angle = Proto->Angle;
1544  X = Proto->X;
1545  Y = Proto->Y;
1546  HalfLength = Proto->Length / 2.0;
1547 
1548  Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
1549  Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
1550  Filler->NextSwitch = 0;
1551 
1552  if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
1553  /* horizontal proto - handle as special case */
1554  Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
1555  Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
1556  Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
1557  Filler->StartDelta = 0;
1558  Filler->EndDelta = 0;
1559  Filler->Switch[0].Type = LastSwitch;
1560  Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
1561  } else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
1562  fabs(Angle - 0.75) < HV_TOLERANCE) {
1563  /* vertical proto - handle as special case */
1564  Filler->X = Bucket8For(X - SidePad, XS, NB);
1565  Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
1566  Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
1567  Filler->StartDelta = 0;
1568  Filler->EndDelta = 0;
1569  Filler->Switch[0].Type = LastSwitch;
1570  Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
1571  } else {
1572  /* diagonal proto */
1573 
1574  if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1575  /* rising diagonal proto */
1576  Angle *= 2.0 * PI;
1577  Cos = fabs(cos(Angle));
1578  Sin = fabs(sin(Angle));
1579 
1580  /* compute the positions of the corners of the acceptance region */
1581  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1582  Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1583  End.x = 2.0 * X - Start.x;
1584  End.y = 2.0 * Y - Start.y;
1585  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1586  Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1587  Switch2.x = 2.0 * X - Switch1.x;
1588  Switch2.y = 2.0 * Y - Switch1.y;
1589 
1590  if (Switch1.x > Switch2.x) {
1591  S1 = 1;
1592  S2 = 0;
1593  }
1594 
1595  /* translate into bucket positions and deltas */
1596  Filler->X = Bucket8For(Start.x, XS, NB);
1597  Filler->StartDelta = -(inT16) ((Cos / Sin) * 256);
1598  Filler->EndDelta = (inT16) ((Sin / Cos) * 256);
1599 
1600  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1601  YAdjust = XAdjust * Cos / Sin;
1602  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1603  YAdjust = XAdjust * Sin / Cos;
1604  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1605 
1606  Filler->Switch[S1].Type = StartSwitch;
1607  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1608  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1609  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1610  YAdjust = XAdjust * Sin / Cos;
1611  Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
1612  Filler->Switch[S1].Delta = Filler->EndDelta;
1613 
1614  Filler->Switch[S2].Type = EndSwitch;
1615  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1616  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1617  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1618  YAdjust = XAdjust * Cos / Sin;
1619  Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
1620  Filler->Switch[S2].Delta = Filler->StartDelta;
1621 
1622  Filler->Switch[2].Type = LastSwitch;
1623  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1624  } else {
1625  /* falling diagonal proto */
1626  Angle *= 2.0 * PI;
1627  Cos = fabs(cos(Angle));
1628  Sin = fabs(sin(Angle));
1629 
1630  /* compute the positions of the corners of the acceptance region */
1631  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1632  Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1633  End.x = 2.0 * X - Start.x;
1634  End.y = 2.0 * Y - Start.y;
1635  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1636  Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1637  Switch2.x = 2.0 * X - Switch1.x;
1638  Switch2.y = 2.0 * Y - Switch1.y;
1639 
1640  if (Switch1.x > Switch2.x) {
1641  S1 = 1;
1642  S2 = 0;
1643  }
1644 
1645  /* translate into bucket positions and deltas */
1646  Filler->X = Bucket8For(Start.x, XS, NB);
1647  Filler->StartDelta = static_cast<inT16>(ClipToRange<int>(
1648  -IntCastRounded((Sin / Cos) * 256), MIN_INT16, MAX_INT16));
1649  Filler->EndDelta = static_cast<inT16>(ClipToRange<int>(
1650  IntCastRounded((Cos / Sin) * 256), MIN_INT16, MAX_INT16));
1651 
1652  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1653  YAdjust = XAdjust * Sin / Cos;
1654  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1655  YAdjust = XAdjust * Cos / Sin;
1656  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1657 
1658  Filler->Switch[S1].Type = EndSwitch;
1659  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1660  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1661  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1662  YAdjust = XAdjust * Sin / Cos;
1663  Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
1664  Filler->Switch[S1].Delta = Filler->StartDelta;
1665 
1666  Filler->Switch[S2].Type = StartSwitch;
1667  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1668  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1669  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1670  YAdjust = XAdjust * Cos / Sin;
1671  Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
1672  Filler->Switch[S2].Delta = Filler->EndDelta;
1673 
1674  Filler->Switch[2].Type = LastSwitch;
1675  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1676  }
1677  }
1678 } /* InitTableFiller */
1679 
1680 
1681 /*---------------------------------------------------------------------------*/
1682 #ifndef GRAPHICS_DISABLED
1683 
1693 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
1694  ScrollView::Color color) {
1695  FLOAT32 X, Y, Dx, Dy, Length;
1696 
1697  window->Pen(color);
1698  assert(Feature != NULL);
1699  assert(color != 0);
1700 
1701  X = Feature->X;
1702  Y = Feature->Y;
1703  Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
1704  // The -PI has no significant effect here, but the value of Theta is computed
1705  // using BinaryAnglePlusPi in intfx.cpp.
1706  Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * PI - PI);
1707  Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * PI - PI);
1708 
1709  window->SetCursor(X, Y);
1710  window->DrawTo(X + Dx, Y + Dy);
1711 } /* RenderIntFeature */
1712 
1730  INT_CLASS Class,
1731  PROTO_ID ProtoId,
1732  ScrollView::Color color) {
1733  PROTO_SET ProtoSet;
1734  INT_PROTO Proto;
1735  int ProtoSetIndex;
1736  int ProtoWordIndex;
1737  FLOAT32 Length;
1738  int Xmin, Xmax, Ymin, Ymax;
1739  FLOAT32 X, Y, Dx, Dy;
1740  uinT32 ProtoMask;
1741  int Bucket;
1742 
1743  assert(ProtoId >= 0);
1744  assert(Class != NULL);
1745  assert(ProtoId < Class->NumProtos);
1746  assert(color != 0);
1747  window->Pen(color);
1748 
1749  ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
1750  ProtoSetIndex = IndexForProto(ProtoId);
1751  Proto = &(ProtoSet->Protos[ProtoSetIndex]);
1752  Length = (Class->ProtoLengths[ProtoId] *
1754  ProtoMask = PPrunerMaskFor(ProtoId);
1755  ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
1756 
1757  // find the x and y extent of the proto from the proto pruning table
1758  Xmin = Ymin = NUM_PP_BUCKETS;
1759  Xmax = Ymax = 0;
1760  for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
1761  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
1762  UpdateRange(Bucket, &Xmin, &Xmax);
1763  }
1764 
1765  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
1766  UpdateRange(Bucket, &Ymin, &Ymax);
1767  }
1768  }
1769  X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1770  Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1771  // The -PI has no significant effect here, but the value of Theta is computed
1772  // using BinaryAnglePlusPi in intfx.cpp.
1773  Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * PI - PI);
1774  Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * PI - PI);
1775 
1776  window->SetCursor(X - Dx, Y - Dy);
1777  window->DrawTo(X + Dx, Y + Dy);
1778 } /* RenderIntProto */
1779 #endif
1780 
1796 int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id) {
1797  if (Param < Min) {
1798  if (Id)
1799  cprintf("Warning: Param %s truncated from %f to %d!\n",
1800  Id, Param, Min);
1801  Param = Min;
1802  } else if (Param > Max) {
1803  if (Id)
1804  cprintf("Warning: Param %s truncated from %f to %d!\n",
1805  Id, Param, Max);
1806  Param = Max;
1807  }
1808  return static_cast<int>(floor(Param));
1809 } /* TruncateParam */
1810 
1811 
1812 #ifndef GRAPHICS_DISABLED
1813 
1818  if (IntMatchWindow == NULL) {
1819  IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
1820  SVMenuNode* popup_menu = new SVMenuNode();
1821 
1822  popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
1823  "x", "Class to debug");
1824  popup_menu->AddChild("Debug Static classes", IDA_STATIC,
1825  "x", "Class to debug");
1826  popup_menu->AddChild("Debug Both", IDA_BOTH,
1827  "x", "Class to debug");
1828  popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
1829  "0", "Index to debug");
1830  popup_menu->BuildMenu(IntMatchWindow, false);
1831  }
1832 }
1833 
1839  if (ProtoDisplayWindow == NULL) {
1840  ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
1841  550, 200);
1842  }
1843 }
1844 
1850  if (FeatureDisplayWindow == NULL) {
1851  FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
1852  50, 700);
1853  }
1854 }
1855 
1858 ScrollView* CreateFeatureSpaceWindow(const char* name, int xpos, int ypos) {
1859  return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
1860 }
1861 #endif // GRAPHICS_DISABLED
void InitFeatureDisplayWindowIfReqd()
Definition: intproto.cpp:1849
#define CircularIncrement(i, r)
Definition: intproto.cpp:120
#define NUM_BITS_PER_CLASS
Definition: intproto.h:54
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
Definition: intproto.cpp:342
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:1033
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1858
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
Definition: intproto.h:111
uinT8 Bucket8For(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:435
#define BITS_PER_CP_VECTOR
Definition: intproto.h:58
bool read_spacing_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:173
Definition: fpoint.h:29
#define PRUNER_ANGLE
Definition: intproto.h:36
char * parameter
Definition: scrollview.h:71
#define CPrunerBitIndexFor(c)
Definition: intproto.h:186
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
Definition: intproto.h:97
SVEventType type
Definition: scrollview.h:64
#define PPrunerWordIndexFor(I)
Definition: intproto.h:173
#define INT_MAX_Y
Definition: intproto.cpp:66
#define TRUE
Definition: capi.h:45
Definition: points.h:189
double classify_cp_angle_pad_loose
Definition: intproto.cpp:190
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
Definition: intproto.h:125
bool read_set(TFile *f, FontSet *fs)
Definition: fontinfo.cpp:230
int32_t inT32
Definition: host.h:38
#define MAX_NUM_SWITCHES
Definition: intproto.cpp:74
inT16 YInit
Definition: intproto.cpp:80
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
Definition: tesscallback.h:116
void free_int_class(INT_CLASS int_class)
Definition: intproto.cpp:703
inT8 YEnd
Definition: intproto.cpp:103
bool write_set(FILE *f, const FontSet &fs)
Definition: fontinfo.cpp:238
uinT8 NumProtoSets
Definition: intproto.h:109
#define WERDS_PER_CP_VECTOR
Definition: intproto.h:61
inT8 YStart
Definition: intproto.cpp:103
#define YS
#define MAX_NUM_PROTOS
Definition: intproto.h:47
uinT8 NumConfigs
Definition: intproto.h:110
#define MAX_NUM_CLASS_PRUNERS
Definition: intproto.h:59
UNICHAR_ID CLASS_ID
Definition: matchdefs.h:35
#define UnusedClassIdIn(T, c)
Definition: intproto.h:180
#define MAX_UINT8
Definition: host.h:63
#define INT_MIN_X
Definition: intproto.cpp:63
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, FLOAT32 Evidence)
Definition: intproto.cpp:623
#define PRUNER_Y
Definition: intproto.h:35
struct PROTO_SET_STRUCT * PROTO_SET
FLOAT32 A
Definition: protos.h:44
inT16 YStart
Definition: intproto.cpp:92
void * Emalloc(int Size)
Definition: emalloc.cpp:47
int size() const
Return the size used.
#define MAX_INT16
Definition: host.h:61
#define INT_MAX_X
Definition: intproto.cpp:65
inT16 NumConfigs
Definition: protos.h:62
ScrollView * IntMatchWindow
Definition: intproto.cpp:179
double classify_cp_angle_pad_tight
Definition: intproto.cpp:194
void InitTableFiller(FLOAT32 EndPad, FLOAT32 SidePad, FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER *Filler)
Definition: intproto.cpp:1528
double classify_cp_side_pad_loose
Definition: intproto.cpp:198
#define tprintf(...)
Definition: tprintf.h:31
inT16 EndDelta
Definition: intproto.cpp:93
#define INT_YRADIUS
Definition: intproto.cpp:62
inT16 NumProtos
Definition: protos.h:59
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, register uinT32 ClassMask, register uinT32 ClassCount, register uinT32 WordIndex)
Definition: intproto.cpp:1181
void FillPPCircularBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
Definition: intproto.cpp:1252
uinT32 * BIT_VECTOR
Definition: bitvec.h:28
voidpf uLong offset
Definition: ioapi.h:42
int FReadEndian(void *buffer, int size, int count)
Definition: serialis.cpp:97
uinT8 AngleStart
Definition: intproto.cpp:104
#define MapParam(P, O, N)
Definition: intproto.cpp:123
uinT16 NumProtos
Definition: intproto.h:108
#define LegalClassId(c)
Definition: intproto.h:179
#define BITS_PER_WERD
Definition: intproto.h:44
#define HV_TOLERANCE
Definition: intproto.cpp:69
#define INT_XRADIUS
Definition: intproto.cpp:61
#define CPrunerWordIndexFor(c)
Definition: intproto.h:185
int IntCastRounded(double x)
Definition: helpers.h:179
double classify_cp_end_pad_medium
Definition: intproto.cpp:196
CLUSTERCONFIG Config
int classify_num_cp_levels
Definition: intproto.cpp:188
double classify_cp_side_pad_medium
Definition: intproto.cpp:199
uinT8 * ProtoLengths
Definition: intproto.h:112
#define INT_XHEIGHT
Definition: intproto.cpp:56
uinT32 p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
Definition: intproto.h:77
#define NUM_PP_PARAMS
Definition: intproto.h:50
double classify_pp_side_pad
Definition: intproto.cpp:203
CONFIGS Configurations
Definition: protos.h:64
int16_t inT16
Definition: host.h:36
inT16 YEnd
Definition: intproto.cpp:92
void SetCursor(int x, int y)
Definition: scrollview.cpp:525
inT16 StartDelta
Definition: intproto.cpp:93
#define AS
PROTO_PRUNER ProtoPruner
Definition: intproto.h:96
#define NUM_CP_BUCKETS
Definition: intproto.h:52
#define ASSERT_HOST(x)
Definition: errcode.h:84
uinT16 Bucket16For(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:439
const char * id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:266
int command_id
Definition: scrollview.h:70
uinT8 AngleStart
Definition: intproto.cpp:90
void Clear()
Definition: scrollview.cpp:595
#define ProtoForProtoId(C, P)
Definition: intproto.h:171
uinT8 NextSwitch
Definition: intproto.cpp:89
#define INT_XCENTER
Definition: intproto.cpp:59
FLOAT32 Length
Definition: protos.h:50
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
Definition: intproto.cpp:94
#define double_VAR(name, val, comment)
Definition: params.h:285
#define ClassForClassId(T, c)
Definition: intproto.h:181
uint32_t uinT32
Definition: host.h:39
#define PI
Definition: const.h:19
#define Y_SHIFT
Definition: intproto.h:41
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1693
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
Definition: intproto.cpp:1729
#define XS
int AddIntConfig(INT_CLASS Class)
Definition: intproto.cpp:270
double classify_cp_end_pad_tight
Definition: intproto.cpp:197
unsigned char BOOL8
Definition: host.h:44
#define OLD_MAX_NUM_CONFIGS
Definition: intproto.cpp:112
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:164
#define FALSE
Definition: capi.h:46
bool read_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:152
uinT16 ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:113
static void Update()
Definition: scrollview.cpp:715
#define CPrunerFor(T, c)
Definition: intproto.h:184
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:122
#define INT_MIN_Y
Definition: intproto.cpp:64
#define CPrunerIdFor(c)
Definition: intproto.h:183
#define INT_VAR(name, val, comment)
Definition: params.h:276
#define INT_CHAR_NORM_RANGE
Definition: intproto.h:133
#define X_SHIFT
Definition: intproto.h:40
#define IndexForProto(P)
Definition: intproto.h:170
void ZoomToRectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:765
#define isnan(x)
Definition: mathfix.h:31
INT_TEMPLATES NewIntTemplates()
Definition: intproto.cpp:723
INT_CLASS Class[MAX_NUM_CLASSES]
Definition: intproto.h:124
uinT32 Configs[WERDS_PER_CONFIG_VEC]
Definition: intproto.h:86
int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id)
Definition: intproto.cpp:1796
int AddIntProto(INT_CLASS Class)
Definition: intproto.cpp:293
FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets)
Definition: intproto.cpp:1163
FLOAT32 Y
Definition: protos.h:48
SVEventType
Definition: scrollview.h:45
#define NUM_PP_BUCKETS
Definition: intproto.h:51
FLOAT32 X
Definition: protos.h:47
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
Definition: intproto.cpp:238
#define MAX_NUM_PROTO_SETS
Definition: intproto.h:49
#define INT_DESCENDER
Definition: intproto.cpp:54
FLOAT32 y
Definition: fpoint.h:31
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
Definition: intproto.cpp:384
struct INT_CLASS_STRUCT * INT_CLASS
#define ANGLE_SHIFT
Definition: intproto.h:39
void InitIntMatchWindowIfReqd()
Definition: intproto.cpp:1817
#define MAX(x, y)
Definition: ndminx.h:24
#define SetForProto(P)
Definition: intproto.h:169
#define INT_BASELINE
Definition: intproto.cpp:55
uinT8 CircBucketFor(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:449
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
Definition: intproto.cpp:487
#define PROTO_PRUNER_SCALE
Definition: intproto.cpp:52
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:201
void GetCPPadsForLevel(int Level, FLOAT32 *EndPad, FLOAT32 *SidePad, FLOAT32 *AnglePad)
Definition: intproto.cpp:1409
float FLOAT32
Definition: host.h:42
#define PRUNER_X
Definition: intproto.h:34
FLOAT32 Angle
Definition: protos.h:49
int8_t inT8
Definition: host.h:34
#define PROTOS_PER_PROTO_SET
Definition: intproto.h:48
#define NO_PROTO
Definition: matchdefs.h:42
UnicityTableEqEq< int > font_set
Definition: protos.h:65
#define test_bit(array, bit)
Definition: bitvec.h:61
#define MIN_INT16
Definition: host.h:69
void * Erealloc(void *ptr, int size)
Definition: emalloc.cpp:64
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
void InitProtoDisplayWindowIfReqd()
Definition: intproto.cpp:1838
uint8_t uinT8
Definition: host.h:35
NORM_METHOD
Definition: mfoutline.h:53
#define WERDS_PER_PP_VECTOR
Definition: intproto.h:62
FLOAT32 x
Definition: fpoint.h:31
SWITCH_TYPE Type
Definition: intproto.cpp:78
int size() const
Definition: unicharset.h:299
#define NB
void cprintf(const char *format,...)
Definition: callcpp.cpp:40
ScrollView * FeatureDisplayWindow
Definition: intproto.cpp:180
#define MAX_NUM_CONFIGS
Definition: intproto.h:46
#define SET_BIT(array, bit)
Definition: bitvec.h:57
FLOAT32 C
Definition: protos.h:46
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
Definition: intproto.cpp:1476
double classify_pp_angle_pad
Definition: intproto.cpp:201
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence)
Definition: intproto.cpp:644
FLOAT32 B
Definition: protos.h:45
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:59
void FillPPLinearBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
Definition: intproto.cpp:1295
#define INT_CAPHEIGHT
Definition: intproto.cpp:57
#define MaxNumIntProtosIn(C)
Definition: intproto.h:168
const T & get(int id) const
Return the object from an id.
#define GetPicoFeatureLength()
Definition: picofeat.h:59
void Efree(void *ptr)
Definition: emalloc.cpp:79
double classify_pp_end_pad
Definition: intproto.cpp:202
struct INT_TEMPLATES_STRUCT * INT_TEMPLATES
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:739
#define MAX_NUM_CLASSES
Definition: matchdefs.h:31
#define CPrunerMaskFor(L, c)
Definition: intproto.h:187
void ShowMatchDisplay()
uinT8 AngleEnd
Definition: intproto.cpp:104
double classify_cp_angle_pad_medium
Definition: intproto.cpp:192
uint16_t uinT16
Definition: host.h:37
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:132
#define ProtoIn(Class, Pid)
Definition: protos.h:123
double classify_cp_side_pad_tight
Definition: intproto.cpp:200
void UpdateMatchDisplay()
Definition: intproto.cpp:467
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:121
#define INT_YCENTER
Definition: intproto.cpp:60
#define WERDS_PER_CONFIG_VEC
Definition: intproto.h:68
inT16 PROTO_ID
Definition: matchdefs.h:41
BOOL8 FillerDone(TABLE_FILLER *Filler)
Definition: intproto.cpp:1223
SWITCH_TYPE
Definition: intproto.cpp:71
void Pen(Color color)
Definition: scrollview.cpp:726
int Modulo(int a, int b)
Definition: helpers.h:164
#define MAX_LEVEL
#define MaxNumClassesIn(T)
Definition: intproto.h:178
double classify_cp_end_pad_loose
Definition: intproto.cpp:195
#define PPrunerMaskFor(I)
Definition: intproto.h:176
void DrawTo(int x, int y)
Definition: scrollview.cpp:531
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:449
ScrollView::Color GetMatchColorFor(FLOAT32 Evidence)
Definition: intproto.cpp:1450
inT16 Delta
Definition: intproto.cpp:81
FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets)
Definition: intproto.cpp:1145
uinT8 AngleEnd
Definition: intproto.cpp:90
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
Definition: intproto.cpp:664
int FRead(void *buffer, int size, int count)
Definition: serialis.cpp:108
#define OLD_WERDS_PER_CONFIG_VEC
Definition: intproto.cpp:113
ScrollView * ProtoDisplayWindow
Definition: intproto.cpp:181