tesseract  4.0.0-1-g2a2b
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 <algorithm>
23 #include <cmath> // for std::floor
24 #include <cstdio>
25 #include <cassert>
26 
27 #include "classify.h"
28 #include "callcpp.h" // for cprintf
29 #include "emalloc.h"
30 #include "fontinfo.h"
31 #include "genericvector.h"
32 #include "globals.h"
33 #include "helpers.h"
34 #include "intproto.h"
35 #include "mfoutline.h"
36 #include "picofeat.h"
37 #include "points.h"
38 #include "shapetable.h"
39 #include "svmnode.h"
40 
41 // Include automatically generated configuration file if running autoconf.
42 #ifdef HAVE_CONFIG_H
43 #include "config_auto.h"
44 #endif
45 
46 using tesseract::FontSet;
47 
48 /* match debug display constants*/
49 #define PROTO_PRUNER_SCALE (4.0)
50 
51 #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE)
52 #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE)
53 #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE)
54 #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE)
55 
56 #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE)
57 #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE)
58 #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE)
59 #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE)
60 #define INT_MIN_X 0
61 #define INT_MIN_Y 0
62 #define INT_MAX_X INT_CHAR_NORM_RANGE
63 #define INT_MAX_Y INT_CHAR_NORM_RANGE
64 
66 #define HV_TOLERANCE (0.0025) /* approx 0.9 degrees */
67 
68 typedef enum
71 #define MAX_NUM_SWITCHES 3
72 
73 typedef struct
74 {
76  int8_t X, Y;
77  int16_t YInit;
78  int16_t Delta;
79 }
80 
81 
83 
84 typedef struct
85 {
86  uint8_t NextSwitch;
87  uint8_t AngleStart, AngleEnd;
88  int8_t X;
89  int16_t YStart, YEnd;
90  int16_t StartDelta, EndDelta;
92 }
93 
94 
96 
97 typedef struct
98 {
99  int8_t X;
100  int8_t YStart, YEnd;
101  uint8_t AngleStart, AngleEnd;
102 }
103 
104 
105 FILL_SPEC;
106 
107 
108 /* constants for conversion from old inttemp format */
109 #define OLD_MAX_NUM_CONFIGS 32
110 #define OLD_WERDS_PER_CONFIG_VEC ((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\
111  BITS_PER_WERD)
112 
113 /*-----------------------------------------------------------------------------
114  Macros
115 -----------------------------------------------------------------------------*/
117 #define CircularIncrement(i,r) (((i) < (r) - 1)?((i)++):((i) = 0))
118 
120 #define MapParam(P,O,N) (std::floor(((P) + (O)) * (N)))
121 
122 /*---------------------------------------------------------------------------
123  Private Function Prototypes
124 ----------------------------------------------------------------------------*/
125 float BucketStart(int Bucket, float Offset, int NumBuckets);
126 
127 float BucketEnd(int Bucket, float Offset, int NumBuckets);
128 
129 void DoFill(FILL_SPEC *FillSpec,
130  CLASS_PRUNER_STRUCT* Pruner,
131  uint32_t ClassMask,
132  uint32_t ClassCount,
133  uint32_t WordIndex);
134 
135 bool FillerDone(TABLE_FILLER* Filler);
136 
137 void FillPPCircularBits(uint32_t
138  ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
139  int Bit, float Center, float Spread, bool debug);
140 
141 void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
142  int Bit, float Center, float Spread, bool debug);
143 
144 void GetCPPadsForLevel(int Level,
145  float *EndPad,
146  float *SidePad,
147  float *AnglePad);
148 
149 ScrollView::Color GetMatchColorFor(float Evidence);
150 
151 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill);
152 
153 void InitTableFiller(float EndPad,
154  float SidePad,
155  float AnglePad,
156  PROTO Proto,
157  TABLE_FILLER *Filler);
158 
159 #ifndef GRAPHICS_DISABLED
160 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
161  ScrollView::Color color);
162 
163 void RenderIntProto(ScrollView *window,
164  INT_CLASS Class,
165  PROTO_ID ProtoId,
166  ScrollView::Color color);
167 #endif // GRAPHICS_DISABLED
168 
169 int TruncateParam(float Param, int Min, int Max, char *Id);
170 
171 /*-----------------------------------------------------------------------------
172  Global Data Definitions and Declarations
173 -----------------------------------------------------------------------------*/
174 
175 /* global display lists used to display proto and feature match information*/
179 
180 /*-----------------------------------------------------------------------------
181  Variables
182 -----------------------------------------------------------------------------*/
183 
184 /* control knobs */
185 INT_VAR(classify_num_cp_levels, 3, "Number of Class Pruner Levels");
187  "Class Pruner Angle Pad Loose");
189  "Class Pruner Angle Pad Medium");
191  "CLass Pruner Angle Pad Tight");
192 double_VAR(classify_cp_end_pad_loose, 0.5, "Class Pruner End Pad Loose");
193 double_VAR(classify_cp_end_pad_medium, 0.5, "Class Pruner End Pad Medium");
194 double_VAR(classify_cp_end_pad_tight, 0.5, "Class Pruner End Pad Tight");
195 double_VAR(classify_cp_side_pad_loose, 2.5, "Class Pruner Side Pad Loose");
196 double_VAR(classify_cp_side_pad_medium, 1.2, "Class Pruner Side Pad Medium");
197 double_VAR(classify_cp_side_pad_tight, 0.6, "Class Pruner Side Pad Tight");
198 double_VAR(classify_pp_angle_pad, 45.0, "Proto Pruner Angle Pad");
199 double_VAR(classify_pp_end_pad, 0.5, "Proto Prune End Pad");
200 double_VAR(classify_pp_side_pad, 2.5, "Proto Pruner Side Pad");
201 
202 /*-----------------------------------------------------------------------------
203  Public Code
204 -----------------------------------------------------------------------------*/
208  : X(ClipToRange<int16_t>(static_cast<int16_t>(pos.x() + 0.5), 0, 255)),
209  Y(ClipToRange<int16_t>(static_cast<int16_t>(pos.y() + 0.5), 0, 255)),
210  Theta(theta),
211  CP_misses(0) {
212 }
215  : X(static_cast<uint8_t>(ClipToRange<int>(x, 0, UINT8_MAX))),
216  Y(static_cast<uint8_t>(ClipToRange<int>(y, 0, UINT8_MAX))),
217  Theta(static_cast<uint8_t>(ClipToRange<int>(theta, 0, UINT8_MAX))),
218  CP_misses(0) {
219 }
220 
232 void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) {
233  int Pruner;
234 
235  assert (LegalClassId (ClassId));
236  if (ClassId != Templates->NumClasses) {
237  fprintf(stderr, "Please make sure that classes are added to templates");
238  fprintf(stderr, " in increasing order of ClassIds\n");
239  exit(1);
240  }
241  ClassForClassId (Templates, ClassId) = Class;
242  Templates->NumClasses++;
243 
244  if (Templates->NumClasses > MaxNumClassesIn (Templates)) {
245  Pruner = Templates->NumClassPruners++;
246  Templates->ClassPruners[Pruner] = new CLASS_PRUNER_STRUCT;
247  memset(Templates->ClassPruners[Pruner], 0, sizeof(CLASS_PRUNER_STRUCT));
248  }
249 } /* AddIntClass */
250 
251 
263  int Index;
264 
265  assert(Class->NumConfigs < MAX_NUM_CONFIGS);
266 
267  Index = Class->NumConfigs++;
268  Class->ConfigLengths[Index] = 0;
269  return Index;
270 } /* AddIntConfig */
271 
272 
283 int AddIntProto(INT_CLASS Class) {
284  int Index;
285  int ProtoSetId;
286  PROTO_SET ProtoSet;
287  INT_PROTO Proto;
288  uint32_t *Word;
289 
290  if (Class->NumProtos >= MAX_NUM_PROTOS)
291  return (NO_PROTO);
292 
293  Index = Class->NumProtos++;
294 
295  if (Class->NumProtos > MaxNumIntProtosIn(Class)) {
296  ProtoSetId = Class->NumProtoSets++;
297 
298  ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
299  Class->ProtoSets[ProtoSetId] = ProtoSet;
300  memset(ProtoSet, 0, sizeof(*ProtoSet));
301 
302  /* reallocate space for the proto lengths and install in class */
303  Class->ProtoLengths =
304  (uint8_t *)Erealloc(Class->ProtoLengths,
305  MaxNumIntProtosIn(Class) * sizeof(uint8_t));
306  memset(&Class->ProtoLengths[Index], 0,
307  sizeof(*Class->ProtoLengths) * (MaxNumIntProtosIn(Class) - Index));
308  }
309 
310  /* initialize proto so its length is zero and it isn't in any configs */
311  Class->ProtoLengths[Index] = 0;
312  Proto = ProtoForProtoId (Class, Index);
313  for (Word = Proto->Configs;
314  Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0);
315 
316  return (Index);
317 }
318 
330 void AddProtoToClassPruner (PROTO Proto, CLASS_ID ClassId,
331  INT_TEMPLATES Templates)
332 #define MAX_LEVEL 2
333 {
334  CLASS_PRUNER_STRUCT* Pruner;
335  uint32_t ClassMask;
336  uint32_t ClassCount;
337  uint32_t WordIndex;
338  int Level;
339  float EndPad, SidePad, AnglePad;
340  TABLE_FILLER TableFiller;
341  FILL_SPEC FillSpec;
342 
343  Pruner = CPrunerFor (Templates, ClassId);
344  WordIndex = CPrunerWordIndexFor (ClassId);
345  ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassId);
346 
347  for (Level = classify_num_cp_levels - 1; Level >= 0; Level--) {
348  GetCPPadsForLevel(Level, &EndPad, &SidePad, &AnglePad);
349  ClassCount = CPrunerMaskFor (Level, ClassId);
350  InitTableFiller(EndPad, SidePad, AnglePad, Proto, &TableFiller);
351 
352  while (!FillerDone (&TableFiller)) {
353  GetNextFill(&TableFiller, &FillSpec);
354  DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
355  }
356  }
357 } /* AddProtoToClassPruner */
358 
370 void AddProtoToProtoPruner(PROTO Proto, int ProtoId,
371  INT_CLASS Class, bool debug) {
372  float Angle, X, Y, Length;
373  float Pad;
374  int Index;
375  PROTO_SET ProtoSet;
376 
377  if (ProtoId >= Class->NumProtos)
378  cprintf("AddProtoToProtoPruner:assert failed: %d < %d",
379  ProtoId, Class->NumProtos);
380  assert(ProtoId < Class->NumProtos);
381 
382  Index = IndexForProto (ProtoId);
383  ProtoSet = Class->ProtoSets[SetForProto (ProtoId)];
384 
385  Angle = Proto->Angle;
386 #ifndef _WIN32
387  assert(!std::isnan(Angle));
388 #endif
389 
390  FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index,
391  Angle + ANGLE_SHIFT, classify_pp_angle_pad / 360.0,
392  debug);
393 
394  Angle *= 2.0 * M_PI;
395  Length = Proto->Length;
396 
397  X = Proto->X + X_SHIFT;
398  Pad = std::max(fabs (cos (Angle)) * (Length / 2.0 +
401  fabs (sin (Angle)) * (classify_pp_side_pad *
403 
404  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad, debug);
405 
406  Y = Proto->Y + Y_SHIFT;
407  Pad = std::max(fabs (sin (Angle)) * (Length / 2.0 +
410  fabs (cos (Angle)) * (classify_pp_side_pad *
412 
413  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_Y], Index, Y, Pad, debug);
414 } /* AddProtoToProtoPruner */
415 
421 uint8_t Bucket8For(float param, float offset, int num_buckets) {
422  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
423  return static_cast<uint8_t>(ClipToRange<int>(bucket, 0, num_buckets - 1));
424 }
425 uint16_t Bucket16For(float param, float offset, int num_buckets) {
426  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
427  return static_cast<uint16_t>(ClipToRange<int>(bucket, 0, num_buckets - 1));
428 }
429 
435 uint8_t CircBucketFor(float param, float offset, int num_buckets) {
436  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
437  return static_cast<uint8_t>(Modulo(bucket, num_buckets));
438 } /* CircBucketFor */
439 
440 
441 #ifndef GRAPHICS_DISABLED
442 
452  if (IntMatchWindow != nullptr)
454 } /* ClearMatchDisplay */
455 #endif
456 
469 void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class) {
470  int ProtoId;
471  INT_PROTO Proto;
472  int TotalLength;
473 
474  for (ProtoId = 0, TotalLength = 0;
475  ProtoId < Class->NumProtos; ProtoId++) {
476  if (test_bit(Config, ProtoId)) {
477  Proto = ProtoForProtoId(Class, ProtoId);
478  SET_BIT(Proto->Configs, ConfigId);
479  TotalLength += Class->ProtoLengths[ProtoId];
480  }
481  }
482  Class->ConfigLengths[ConfigId] = TotalLength;
483 } /* ConvertConfig */
484 
485 
486 namespace tesseract {
496 void Classify::ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class) {
497  INT_PROTO P;
498  float Param;
499 
500  assert(ProtoId < Class->NumProtos);
501 
502  P = ProtoForProtoId(Class, ProtoId);
503 
504  Param = Proto->A * 128;
505  P->A = TruncateParam(Param, -128, 127, nullptr);
506 
507  Param = -Proto->B * 256;
508  P->B = TruncateParam(Param, 0, 255, nullptr);
509 
510  Param = Proto->C * 128;
511  P->C = TruncateParam(Param, -128, 127, nullptr);
512 
513  Param = Proto->Angle * 256;
514  if (Param < 0 || Param >= 256)
515  P->Angle = 0;
516  else
517  P->Angle = (uint8_t) Param;
518 
519  /* round proto length to nearest integer number of pico-features */
520  Param = (Proto->Length / GetPicoFeatureLength()) + 0.5;
521  Class->ProtoLengths[ProtoId] = TruncateParam(Param, 1, 255, nullptr);
523  cprintf("Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
524  P->A, P->B, P->C, Class->ProtoLengths[ProtoId]);
525 } /* ConvertProto */
526 
536  const UNICHARSET&
537  target_unicharset) {
538  INT_TEMPLATES IntTemplates;
539  CLASS_TYPE FClass;
540  INT_CLASS IClass;
541  int ClassId;
542  int ProtoId;
543  int ConfigId;
544 
545  IntTemplates = NewIntTemplates();
546 
547  for (ClassId = 0; ClassId < target_unicharset.size(); ClassId++) {
548  FClass = &(FloatProtos[ClassId]);
549  if (FClass->NumProtos == 0 && FClass->NumConfigs == 0 &&
550  strcmp(target_unicharset.id_to_unichar(ClassId), " ") != 0) {
551  cprintf("Warning: no protos/configs for %s in CreateIntTemplates()\n",
552  target_unicharset.id_to_unichar(ClassId));
553  }
554  assert(UnusedClassIdIn(IntTemplates, ClassId));
555  IClass = NewIntClass(FClass->NumProtos, FClass->NumConfigs);
556  FontSet fs;
557  fs.size = FClass->font_set.size();
558  fs.configs = new int[fs.size];
559  for (int i = 0; i < fs.size; ++i) {
560  fs.configs[i] = FClass->font_set.get(i);
561  }
562  if (this->fontset_table_.contains(fs)) {
563  IClass->font_set_id = this->fontset_table_.get_id(fs);
564  delete[] fs.configs;
565  } else {
566  IClass->font_set_id = this->fontset_table_.push_back(fs);
567  }
568  AddIntClass(IntTemplates, ClassId, IClass);
569 
570  for (ProtoId = 0; ProtoId < FClass->NumProtos; ProtoId++) {
571  AddIntProto(IClass);
572  ConvertProto(ProtoIn(FClass, ProtoId), ProtoId, IClass);
573  AddProtoToProtoPruner(ProtoIn(FClass, ProtoId), ProtoId, IClass,
575  AddProtoToClassPruner(ProtoIn(FClass, ProtoId), ClassId, IntTemplates);
576  }
577 
578  for (ConfigId = 0; ConfigId < FClass->NumConfigs; ConfigId++) {
579  AddIntConfig(IClass);
580  ConvertConfig(FClass->Configurations[ConfigId], ConfigId, IClass);
581  }
582  }
583  return (IntTemplates);
584 } /* CreateIntTemplates */
585 } // namespace tesseract
586 
587 
588 #ifndef GRAPHICS_DISABLED
589 
599 void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, float Evidence) {
600  ScrollView::Color color = GetMatchColorFor(Evidence);
601  RenderIntFeature(IntMatchWindow, Feature, color);
602  if (FeatureDisplayWindow) {
603  RenderIntFeature(FeatureDisplayWindow, Feature, color);
604  }
605 } /* DisplayIntFeature */
606 
618 void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, float Evidence) {
619  ScrollView::Color color = GetMatchColorFor(Evidence);
620  RenderIntProto(IntMatchWindow, Class, ProtoId, color);
621  if (ProtoDisplayWindow) {
622  RenderIntProto(ProtoDisplayWindow, Class, ProtoId, color);
623  }
624 } /* DisplayIntProto */
625 #endif
626 
636 INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs) {
637  INT_CLASS Class;
638  PROTO_SET ProtoSet;
639  int i;
640 
641  assert(MaxNumConfigs <= MAX_NUM_CONFIGS);
642 
643  Class = (INT_CLASS) Emalloc(sizeof(INT_CLASS_STRUCT));
644  Class->NumProtoSets = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) /
646 
647  assert(Class->NumProtoSets <= MAX_NUM_PROTO_SETS);
648 
649  Class->NumProtos = 0;
650  Class->NumConfigs = 0;
651 
652  for (i = 0; i < Class->NumProtoSets; i++) {
653  /* allocate space for a proto set, install in class, and initialize */
654  ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
655  memset(ProtoSet, 0, sizeof(*ProtoSet));
656  Class->ProtoSets[i] = ProtoSet;
657 
658  /* allocate space for the proto lengths and install in class */
659  }
660  if (MaxNumIntProtosIn (Class) > 0) {
661  Class->ProtoLengths =
662  (uint8_t *)Emalloc(MaxNumIntProtosIn (Class) * sizeof (uint8_t));
663  memset(Class->ProtoLengths, 0,
664  MaxNumIntProtosIn(Class) * sizeof(*Class->ProtoLengths));
665  } else {
666  Class->ProtoLengths = nullptr;
667  }
668  memset(Class->ConfigLengths, 0, sizeof(Class->ConfigLengths));
669 
670  return (Class);
671 
672 } /* NewIntClass */
673 
674 static void free_int_class(INT_CLASS int_class) {
675  int i;
676 
677  for (i = 0; i < int_class->NumProtoSets; i++) {
678  Efree (int_class->ProtoSets[i]);
679  }
680  if (int_class->ProtoLengths != nullptr) {
681  Efree (int_class->ProtoLengths);
682  }
683  Efree(int_class);
684 }
685 
693  INT_TEMPLATES T;
694  int i;
695 
696  T = (INT_TEMPLATES) Emalloc (sizeof (INT_TEMPLATES_STRUCT));
697  T->NumClasses = 0;
698  T->NumClassPruners = 0;
699 
700  for (i = 0; i < MAX_NUM_CLASSES; i++)
701  ClassForClassId (T, i) = nullptr;
702 
703  return (T);
704 } /* NewIntTemplates */
705 
706 
707 /*---------------------------------------------------------------------------*/
709  int i;
710 
711  for (i = 0; i < templates->NumClasses; i++)
712  free_int_class(templates->Class[i]);
713  for (i = 0; i < templates->NumClassPruners; i++)
714  delete templates->ClassPruners[i];
715  Efree(templates);
716 }
717 
718 
719 namespace tesseract {
729  int i, j, w, x, y, z;
730  int unicharset_size;
731  int version_id = 0;
732  INT_TEMPLATES Templates;
733  CLASS_PRUNER_STRUCT* Pruner;
734  INT_CLASS Class;
735  uint8_t *Lengths;
736  PROTO_SET ProtoSet;
737 
738  /* variables for conversion from older inttemp formats */
739  int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
740  CLASS_ID class_id, max_class_id;
741  int16_t *IndexFor = new int16_t[MAX_NUM_CLASSES];
742  CLASS_ID *ClassIdFor = new CLASS_ID[MAX_NUM_CLASSES];
743  CLASS_PRUNER_STRUCT **TempClassPruner =
745  uint32_t SetBitsForMask = // word with NUM_BITS_PER_CLASS
746  (1 << NUM_BITS_PER_CLASS) - 1; // set starting at bit 0
747  uint32_t Mask, NewMask, ClassBits;
748  int MaxNumConfigs = MAX_NUM_CONFIGS;
749  int WerdsPerConfigVec = WERDS_PER_CONFIG_VEC;
750 
751  /* first read the high level template struct */
752  Templates = NewIntTemplates();
753  // Read Templates in parts for 64 bit compatibility.
754  if (fp->FReadEndian(&unicharset_size, sizeof(unicharset_size), 1) != 1)
755  tprintf("Bad read of inttemp!\n");
756  if (fp->FReadEndian(&Templates->NumClasses, sizeof(Templates->NumClasses),
757  1) != 1 ||
758  fp->FReadEndian(&Templates->NumClassPruners,
759  sizeof(Templates->NumClassPruners), 1) != 1)
760  tprintf("Bad read of inttemp!\n");
761  if (Templates->NumClasses < 0) {
762  // This file has a version id!
763  version_id = -Templates->NumClasses;
764  if (fp->FReadEndian(&Templates->NumClasses, sizeof(Templates->NumClasses),
765  1) != 1)
766  tprintf("Bad read of inttemp!\n");
767  }
768 
769  if (version_id < 3) {
770  MaxNumConfigs = OLD_MAX_NUM_CONFIGS;
771  WerdsPerConfigVec = OLD_WERDS_PER_CONFIG_VEC;
772  }
773 
774  if (version_id < 2) {
775  if (fp->FReadEndian(IndexFor, sizeof(IndexFor[0]), unicharset_size) !=
776  unicharset_size) {
777  tprintf("Bad read of inttemp!\n");
778  }
779  if (fp->FReadEndian(ClassIdFor, sizeof(ClassIdFor[0]),
780  Templates->NumClasses) != Templates->NumClasses) {
781  tprintf("Bad read of inttemp!\n");
782  }
783  }
784 
785  /* then read in the class pruners */
786  const int kNumBuckets =
788  for (i = 0; i < Templates->NumClassPruners; i++) {
789  Pruner = new CLASS_PRUNER_STRUCT;
790  if (fp->FReadEndian(Pruner, sizeof(Pruner->p[0][0][0][0]), kNumBuckets) !=
791  kNumBuckets) {
792  tprintf("Bad read of inttemp!\n");
793  }
794  if (version_id < 2) {
795  TempClassPruner[i] = Pruner;
796  } else {
797  Templates->ClassPruners[i] = Pruner;
798  }
799  }
800 
801  /* fix class pruners if they came from an old version of inttemp */
802  if (version_id < 2) {
803  // Allocate enough class pruners to cover all the class ids.
804  max_class_id = 0;
805  for (i = 0; i < Templates->NumClasses; i++)
806  if (ClassIdFor[i] > max_class_id)
807  max_class_id = ClassIdFor[i];
808  for (i = 0; i <= CPrunerIdFor(max_class_id); i++) {
809  Templates->ClassPruners[i] = new CLASS_PRUNER_STRUCT;
810  memset(Templates->ClassPruners[i], 0, sizeof(CLASS_PRUNER_STRUCT));
811  }
812  // Convert class pruners from the old format (indexed by class index)
813  // to the new format (indexed by class id).
814  last_cp_bit_number = NUM_BITS_PER_CLASS * Templates->NumClasses - 1;
815  for (i = 0; i < Templates->NumClassPruners; i++) {
816  for (x = 0; x < NUM_CP_BUCKETS; x++)
817  for (y = 0; y < NUM_CP_BUCKETS; y++)
818  for (z = 0; z < NUM_CP_BUCKETS; z++)
819  for (w = 0; w < WERDS_PER_CP_VECTOR; w++) {
820  if (TempClassPruner[i]->p[x][y][z][w] == 0)
821  continue;
822  for (b = 0; b < BITS_PER_WERD; b += NUM_BITS_PER_CLASS) {
823  bit_number = i * BITS_PER_CP_VECTOR + w * BITS_PER_WERD + b;
824  if (bit_number > last_cp_bit_number)
825  break; // the rest of the bits in this word are not used
826  class_id = ClassIdFor[bit_number / NUM_BITS_PER_CLASS];
827  // Single out NUM_BITS_PER_CLASS bits relating to class_id.
828  Mask = SetBitsForMask << b;
829  ClassBits = TempClassPruner[i]->p[x][y][z][w] & Mask;
830  // Move these bits to the new position in which they should
831  // appear (indexed corresponding to the class_id).
832  new_i = CPrunerIdFor(class_id);
833  new_w = CPrunerWordIndexFor(class_id);
834  new_b = CPrunerBitIndexFor(class_id) * NUM_BITS_PER_CLASS;
835  if (new_b > b) {
836  ClassBits <<= (new_b - b);
837  } else {
838  ClassBits >>= (b - new_b);
839  }
840  // Copy bits relating to class_id to the correct position
841  // in Templates->ClassPruner.
842  NewMask = SetBitsForMask << new_b;
843  Templates->ClassPruners[new_i]->p[x][y][z][new_w] &= ~NewMask;
844  Templates->ClassPruners[new_i]->p[x][y][z][new_w] |= ClassBits;
845  }
846  }
847  }
848  for (i = 0; i < Templates->NumClassPruners; i++) {
849  delete TempClassPruner[i];
850  }
851  }
852 
853  /* then read in each class */
854  for (i = 0; i < Templates->NumClasses; i++) {
855  /* first read in the high level struct for the class */
856  Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT));
857  if (fp->FReadEndian(&Class->NumProtos, sizeof(Class->NumProtos), 1) != 1 ||
858  fp->FRead(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1) != 1 ||
859  fp->FRead(&Class->NumConfigs, sizeof(Class->NumConfigs), 1) != 1)
860  tprintf("Bad read of inttemp!\n");
861  if (version_id == 0) {
862  // Only version 0 writes 5 pointless pointers to the file.
863  for (j = 0; j < 5; ++j) {
864  int32_t junk;
865  if (fp->FRead(&junk, sizeof(junk), 1) != 1)
866  tprintf("Bad read of inttemp!\n");
867  }
868  }
869  int num_configs = version_id < 4 ? MaxNumConfigs : Class->NumConfigs;
870  ASSERT_HOST(num_configs <= MaxNumConfigs);
871  if (fp->FReadEndian(Class->ConfigLengths, sizeof(uint16_t), num_configs) !=
872  num_configs) {
873  tprintf("Bad read of inttemp!\n");
874  }
875  if (version_id < 2) {
876  ClassForClassId (Templates, ClassIdFor[i]) = Class;
877  } else {
878  ClassForClassId (Templates, i) = Class;
879  }
880 
881  /* then read in the proto lengths */
882  Lengths = nullptr;
883  if (MaxNumIntProtosIn (Class) > 0) {
884  Lengths = (uint8_t *)Emalloc(sizeof(uint8_t) * MaxNumIntProtosIn(Class));
885  if (fp->FRead(Lengths, sizeof(uint8_t), MaxNumIntProtosIn(Class)) !=
886  MaxNumIntProtosIn(Class))
887  tprintf("Bad read of inttemp!\n");
888  }
889  Class->ProtoLengths = Lengths;
890 
891  /* then read in the proto sets */
892  for (j = 0; j < Class->NumProtoSets; j++) {
893  ProtoSet = (PROTO_SET)Emalloc(sizeof(PROTO_SET_STRUCT));
894  int num_buckets = NUM_PP_PARAMS * NUM_PP_BUCKETS * WERDS_PER_PP_VECTOR;
895  if (fp->FReadEndian(&ProtoSet->ProtoPruner,
896  sizeof(ProtoSet->ProtoPruner[0][0][0]),
897  num_buckets) != num_buckets)
898  tprintf("Bad read of inttemp!\n");
899  for (x = 0; x < PROTOS_PER_PROTO_SET; x++) {
900  if (fp->FRead(&ProtoSet->Protos[x].A, sizeof(ProtoSet->Protos[x].A),
901  1) != 1 ||
902  fp->FRead(&ProtoSet->Protos[x].B, sizeof(ProtoSet->Protos[x].B),
903  1) != 1 ||
904  fp->FRead(&ProtoSet->Protos[x].C, sizeof(ProtoSet->Protos[x].C),
905  1) != 1 ||
906  fp->FRead(&ProtoSet->Protos[x].Angle,
907  sizeof(ProtoSet->Protos[x].Angle), 1) != 1)
908  tprintf("Bad read of inttemp!\n");
909  if (fp->FReadEndian(&ProtoSet->Protos[x].Configs,
910  sizeof(ProtoSet->Protos[x].Configs[0]),
911  WerdsPerConfigVec) != WerdsPerConfigVec)
912  cprintf("Bad read of inttemp!\n");
913  }
914  Class->ProtoSets[j] = ProtoSet;
915  }
916  if (version_id < 4) {
917  Class->font_set_id = -1;
918  } else {
919  fp->FReadEndian(&Class->font_set_id, sizeof(Class->font_set_id), 1);
920  }
921  }
922 
923  if (version_id < 2) {
924  /* add an empty nullptr class with class id 0 */
925  assert(UnusedClassIdIn (Templates, 0));
926  ClassForClassId (Templates, 0) = NewIntClass (1, 1);
927  ClassForClassId (Templates, 0)->font_set_id = -1;
928  Templates->NumClasses++;
929  /* make sure the classes are contiguous */
930  for (i = 0; i < MAX_NUM_CLASSES; i++) {
931  if (i < Templates->NumClasses) {
932  if (ClassForClassId (Templates, i) == nullptr) {
933  fprintf(stderr, "Non-contiguous class ids in inttemp\n");
934  exit(1);
935  }
936  } else {
937  if (ClassForClassId (Templates, i) != nullptr) {
938  fprintf(stderr, "Class id %d exceeds NumClassesIn (Templates) %d\n",
939  i, Templates->NumClasses);
940  exit(1);
941  }
942  }
943  }
944  }
945  if (version_id >= 4) {
947  if (version_id >= 5) {
948  this->fontinfo_table_.read(fp,
950  }
952  }
953 
954  // Clean up.
955  delete[] IndexFor;
956  delete[] ClassIdFor;
957  delete[] TempClassPruner;
958 
959  return (Templates);
960 } /* ReadIntTemplates */
961 
962 
963 #ifndef GRAPHICS_DISABLED
964 
975  if (ProtoDisplayWindow) {
977  }
978  if (FeatureDisplayWindow) {
980  }
982  static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
986  if (ProtoDisplayWindow) {
989  }
990  if (FeatureDisplayWindow) {
993  }
994 } /* ShowMatchDisplay */
995 
998 void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView* window) {
999  window->Clear();
1000 
1001  window->Pen(ScrollView::GREY);
1002  // Draw the feature space limit rectangle.
1003  window->Rectangle(0, 0, INT_MAX_X, INT_MAX_Y);
1004  if (norm_method == baseline) {
1005  window->SetCursor(0, INT_DESCENDER);
1006  window->DrawTo(INT_MAX_X, INT_DESCENDER);
1007  window->SetCursor(0, INT_BASELINE);
1008  window->DrawTo(INT_MAX_X, INT_BASELINE);
1009  window->SetCursor(0, INT_XHEIGHT);
1010  window->DrawTo(INT_MAX_X, INT_XHEIGHT);
1011  window->SetCursor(0, INT_CAPHEIGHT);
1012  window->DrawTo(INT_MAX_X, INT_CAPHEIGHT);
1013  } else {
1016  }
1017 }
1018 #endif
1019 
1031  const UNICHARSET& target_unicharset) {
1032  int i, j;
1033  INT_CLASS Class;
1034  int unicharset_size = target_unicharset.size();
1035  int version_id = -5; // When negated by the reader -1 becomes +1 etc.
1036 
1037  if (Templates->NumClasses != unicharset_size) {
1038  cprintf("Warning: executing WriteIntTemplates() with %d classes in"
1039  " Templates, while target_unicharset size is %d\n",
1040  Templates->NumClasses, unicharset_size);
1041  }
1042 
1043  /* first write the high level template struct */
1044  fwrite(&unicharset_size, sizeof(unicharset_size), 1, File);
1045  fwrite(&version_id, sizeof(version_id), 1, File);
1046  fwrite(&Templates->NumClassPruners, sizeof(Templates->NumClassPruners),
1047  1, File);
1048  fwrite(&Templates->NumClasses, sizeof(Templates->NumClasses), 1, File);
1049 
1050  /* then write out the class pruners */
1051  for (i = 0; i < Templates->NumClassPruners; i++)
1052  fwrite(Templates->ClassPruners[i],
1053  sizeof(CLASS_PRUNER_STRUCT), 1, File);
1054 
1055  /* then write out each class */
1056  for (i = 0; i < Templates->NumClasses; i++) {
1057  Class = Templates->Class[i];
1058 
1059  /* first write out the high level struct for the class */
1060  fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
1061  fwrite(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File);
1062  ASSERT_HOST(Class->NumConfigs == this->fontset_table_.get(Class->font_set_id).size);
1063  fwrite(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File);
1064  for (j = 0; j < Class->NumConfigs; ++j) {
1065  fwrite(&Class->ConfigLengths[j], sizeof(uint16_t), 1, File);
1066  }
1067 
1068  /* then write out the proto lengths */
1069  if (MaxNumIntProtosIn (Class) > 0) {
1070  fwrite(Class->ProtoLengths, sizeof(uint8_t),
1071  MaxNumIntProtosIn(Class), File);
1072  }
1073 
1074  /* then write out the proto sets */
1075  for (j = 0; j < Class->NumProtoSets; j++)
1076  fwrite(Class->ProtoSets[j], sizeof(PROTO_SET_STRUCT), 1, File);
1077 
1078  /* then write the fonts info */
1079  fwrite(&Class->font_set_id, sizeof(int), 1, File);
1080  }
1081 
1082  /* Write the fonts info tables */
1084  this->fontinfo_table_.write(File,
1087 } /* WriteIntTemplates */
1088 } // namespace tesseract
1089 
1090 
1091 /*-----------------------------------------------------------------------------
1092  Private Code
1093 -----------------------------------------------------------------------------*/
1105 float BucketStart(int Bucket, float Offset, int NumBuckets) {
1106  return (((float) Bucket / NumBuckets) - Offset);
1107 
1108 } /* BucketStart */
1109 
1121 float BucketEnd(int Bucket, float Offset, int NumBuckets) {
1122  return (((float) (Bucket + 1) / NumBuckets) - Offset);
1123 } /* BucketEnd */
1124 
1137 void DoFill(FILL_SPEC *FillSpec,
1138  CLASS_PRUNER_STRUCT* Pruner,
1139  uint32_t ClassMask,
1140  uint32_t ClassCount,
1141  uint32_t WordIndex) {
1142  int X, Y, Angle;
1143  uint32_t OldWord;
1144 
1145  X = FillSpec->X;
1146  if (X < 0)
1147  X = 0;
1148  if (X >= NUM_CP_BUCKETS)
1149  X = NUM_CP_BUCKETS - 1;
1150 
1151  if (FillSpec->YStart < 0)
1152  FillSpec->YStart = 0;
1153  if (FillSpec->YEnd >= NUM_CP_BUCKETS)
1154  FillSpec->YEnd = NUM_CP_BUCKETS - 1;
1155 
1156  for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
1157  for (Angle = FillSpec->AngleStart;
1159  OldWord = Pruner->p[X][Y][Angle][WordIndex];
1160  if (ClassCount > (OldWord & ClassMask)) {
1161  OldWord &= ~ClassMask;
1162  OldWord |= ClassCount;
1163  Pruner->p[X][Y][Angle][WordIndex] = OldWord;
1164  }
1165  if (Angle == FillSpec->AngleEnd)
1166  break;
1167  }
1168 } /* DoFill */
1169 
1177 bool FillerDone(TABLE_FILLER* Filler) {
1178  FILL_SWITCH *Next;
1179 
1180  Next = &(Filler->Switch[Filler->NextSwitch]);
1181 
1182  return Filler->X > Next->X && Next->Type == LastSwitch;
1183 
1184 } /* FillerDone */
1185 
1202  int Bit, float Center, float Spread, bool debug) {
1203  int i, FirstBucket, LastBucket;
1204 
1205  if (Spread > 0.5)
1206  Spread = 0.5;
1207 
1208  FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1209  if (FirstBucket < 0)
1210  FirstBucket += NUM_PP_BUCKETS;
1211 
1212  LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1213  if (LastBucket >= NUM_PP_BUCKETS)
1214  LastBucket -= NUM_PP_BUCKETS;
1215  if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
1216  for (i = FirstBucket; TRUE; CircularIncrement (i, NUM_PP_BUCKETS)) {
1217  SET_BIT (ParamTable[i], Bit);
1218 
1219  /* exit loop after we have set the bit for the last bucket */
1220  if (i == LastBucket)
1221  break;
1222  }
1223 
1224 } /* FillPPCircularBits */
1225 
1243  int Bit, float Center, float Spread, bool debug) {
1244  int i, FirstBucket, LastBucket;
1245 
1246  FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1247  if (FirstBucket < 0)
1248  FirstBucket = 0;
1249 
1250  LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1251  if (LastBucket >= NUM_PP_BUCKETS)
1252  LastBucket = NUM_PP_BUCKETS - 1;
1253 
1254  if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
1255  for (i = FirstBucket; i <= LastBucket; i++)
1256  SET_BIT (ParamTable[i], Bit);
1257 
1258 } /* FillPPLinearBits */
1259 
1260 
1261 /*---------------------------------------------------------------------------*/
1262 #ifndef GRAPHICS_DISABLED
1263 namespace tesseract {
1274 CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool* adaptive_on,
1275  bool* pretrained_on, int* shape_id) {
1276  tprintf("%s\n", Prompt);
1277  SVEvent* ev;
1278  SVEventType ev_type;
1279  int unichar_id = INVALID_UNICHAR_ID;
1280  // Wait until a click or popup event.
1281  do {
1283  ev_type = ev->type;
1284  if (ev_type == SVET_POPUP) {
1285  if (ev->command_id == IDA_SHAPE_INDEX) {
1286  if (shape_table_ != nullptr) {
1287  *shape_id = atoi(ev->parameter);
1288  *adaptive_on = false;
1289  *pretrained_on = true;
1290  if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1291  int font_id;
1292  shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1293  &font_id);
1294  tprintf("Shape %d, first unichar=%d, font=%d\n",
1295  *shape_id, unichar_id, font_id);
1296  return unichar_id;
1297  }
1298  tprintf("Shape index '%s' not found in shape table\n", ev->parameter);
1299  } else {
1300  tprintf("No shape table loaded!\n");
1301  }
1302  } else {
1304  unichar_id = unicharset.unichar_to_id(ev->parameter);
1305  if (ev->command_id == IDA_ADAPTIVE) {
1306  *adaptive_on = true;
1307  *pretrained_on = false;
1308  *shape_id = -1;
1309  } else if (ev->command_id == IDA_STATIC) {
1310  *adaptive_on = false;
1311  *pretrained_on = true;
1312  } else {
1313  *adaptive_on = true;
1314  *pretrained_on = true;
1315  }
1316  if (ev->command_id == IDA_ADAPTIVE || shape_table_ == nullptr) {
1317  *shape_id = -1;
1318  return unichar_id;
1319  }
1320  for (int s = 0; s < shape_table_->NumShapes(); ++s) {
1321  if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1322  tprintf("%s\n", shape_table_->DebugStr(s).string());
1323  }
1324  }
1325  } else {
1326  tprintf("Char class '%s' not found in unicharset",
1327  ev->parameter);
1328  }
1329  }
1330  }
1331  delete ev;
1332  } while (ev_type != SVET_CLICK);
1333  return 0;
1334 } /* GetClassToDebug */
1335 
1336 } // namespace tesseract
1337 #endif
1338 
1352 void GetCPPadsForLevel(int Level,
1353  float *EndPad,
1354  float *SidePad,
1355  float *AnglePad) {
1356  switch (Level) {
1357  case 0:
1360  *AnglePad = classify_cp_angle_pad_loose / 360.0;
1361  break;
1362 
1363  case 1:
1366  *AnglePad = classify_cp_angle_pad_medium / 360.0;
1367  break;
1368 
1369  case 2:
1372  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1373  break;
1374 
1375  default:
1378  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1379  break;
1380  }
1381  if (*AnglePad > 0.5)
1382  *AnglePad = 0.5;
1383 
1384 } /* GetCPPadsForLevel */
1385 
1392  assert (Evidence >= 0.0);
1393  assert (Evidence <= 1.0);
1394 
1395  if (Evidence >= 0.90)
1396  return ScrollView::WHITE;
1397  else if (Evidence >= 0.75)
1398  return ScrollView::GREEN;
1399  else if (Evidence >= 0.50)
1400  return ScrollView::RED;
1401  else
1402  return ScrollView::BLUE;
1403 } /* GetMatchColorFor */
1404 
1415 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {
1416  FILL_SWITCH *Next;
1417 
1418  /* compute the fill assuming no switches will be encountered */
1419  Fill->AngleStart = Filler->AngleStart;
1420  Fill->AngleEnd = Filler->AngleEnd;
1421  Fill->X = Filler->X;
1422  Fill->YStart = Filler->YStart >> 8;
1423  Fill->YEnd = Filler->YEnd >> 8;
1424 
1425  /* update the fill info and the filler for ALL switches at this X value */
1426  Next = &(Filler->Switch[Filler->NextSwitch]);
1427  while (Filler->X >= Next->X) {
1428  Fill->X = Filler->X = Next->X;
1429  if (Next->Type == StartSwitch) {
1430  Fill->YStart = Next->Y;
1431  Filler->StartDelta = Next->Delta;
1432  Filler->YStart = Next->YInit;
1433  }
1434  else if (Next->Type == EndSwitch) {
1435  Fill->YEnd = Next->Y;
1436  Filler->EndDelta = Next->Delta;
1437  Filler->YEnd = Next->YInit;
1438  }
1439  else { /* Type must be LastSwitch */
1440  break;
1441  }
1442  Filler->NextSwitch++;
1443  Next = &(Filler->Switch[Filler->NextSwitch]);
1444  }
1445 
1446  /* prepare the filler for the next call to this routine */
1447  Filler->X++;
1448  Filler->YStart += Filler->StartDelta;
1449  Filler->YEnd += Filler->EndDelta;
1450 
1451 } /* GetNextFill */
1452 
1465 void InitTableFiller (float EndPad, float SidePad,
1466  float AnglePad, PROTO Proto, TABLE_FILLER * Filler)
1467 #define XS X_SHIFT
1468 #define YS Y_SHIFT
1469 #define AS ANGLE_SHIFT
1470 #define NB NUM_CP_BUCKETS
1471 {
1472  float Angle;
1473  float X, Y, HalfLength;
1474  float Cos, Sin;
1475  float XAdjust, YAdjust;
1476  FPOINT Start, Switch1, Switch2, End;
1477  int S1 = 0;
1478  int S2 = 1;
1479 
1480  Angle = Proto->Angle;
1481  X = Proto->X;
1482  Y = Proto->Y;
1483  HalfLength = Proto->Length / 2.0;
1484 
1485  Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
1486  Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
1487  Filler->NextSwitch = 0;
1488 
1489  if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
1490  /* horizontal proto - handle as special case */
1491  Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
1492  Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
1493  Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
1494  Filler->StartDelta = 0;
1495  Filler->EndDelta = 0;
1496  Filler->Switch[0].Type = LastSwitch;
1497  Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
1498  } else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
1499  fabs(Angle - 0.75) < HV_TOLERANCE) {
1500  /* vertical proto - handle as special case */
1501  Filler->X = Bucket8For(X - SidePad, XS, NB);
1502  Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
1503  Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
1504  Filler->StartDelta = 0;
1505  Filler->EndDelta = 0;
1506  Filler->Switch[0].Type = LastSwitch;
1507  Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
1508  } else {
1509  /* diagonal proto */
1510 
1511  if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1512  /* rising diagonal proto */
1513  Angle *= 2.0 * M_PI;
1514  Cos = fabs(cos(Angle));
1515  Sin = fabs(sin(Angle));
1516 
1517  /* compute the positions of the corners of the acceptance region */
1518  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1519  Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1520  End.x = 2.0 * X - Start.x;
1521  End.y = 2.0 * Y - Start.y;
1522  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1523  Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1524  Switch2.x = 2.0 * X - Switch1.x;
1525  Switch2.y = 2.0 * Y - Switch1.y;
1526 
1527  if (Switch1.x > Switch2.x) {
1528  S1 = 1;
1529  S2 = 0;
1530  }
1531 
1532  /* translate into bucket positions and deltas */
1533  Filler->X = Bucket8For(Start.x, XS, NB);
1534  Filler->StartDelta = -(int16_t) ((Cos / Sin) * 256);
1535  Filler->EndDelta = (int16_t) ((Sin / Cos) * 256);
1536 
1537  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1538  YAdjust = XAdjust * Cos / Sin;
1539  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1540  YAdjust = XAdjust * Sin / Cos;
1541  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1542 
1543  Filler->Switch[S1].Type = StartSwitch;
1544  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1545  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1546  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1547  YAdjust = XAdjust * Sin / Cos;
1548  Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
1549  Filler->Switch[S1].Delta = Filler->EndDelta;
1550 
1551  Filler->Switch[S2].Type = EndSwitch;
1552  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1553  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1554  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1555  YAdjust = XAdjust * Cos / Sin;
1556  Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
1557  Filler->Switch[S2].Delta = Filler->StartDelta;
1558 
1559  Filler->Switch[2].Type = LastSwitch;
1560  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1561  } else {
1562  /* falling diagonal proto */
1563  Angle *= 2.0 * M_PI;
1564  Cos = fabs(cos(Angle));
1565  Sin = fabs(sin(Angle));
1566 
1567  /* compute the positions of the corners of the acceptance region */
1568  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1569  Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1570  End.x = 2.0 * X - Start.x;
1571  End.y = 2.0 * Y - Start.y;
1572  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1573  Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1574  Switch2.x = 2.0 * X - Switch1.x;
1575  Switch2.y = 2.0 * Y - Switch1.y;
1576 
1577  if (Switch1.x > Switch2.x) {
1578  S1 = 1;
1579  S2 = 0;
1580  }
1581 
1582  /* translate into bucket positions and deltas */
1583  Filler->X = Bucket8For(Start.x, XS, NB);
1584  Filler->StartDelta = static_cast<int16_t>(ClipToRange<int>(
1585  -IntCastRounded((Sin / Cos) * 256), INT16_MIN, INT16_MAX));
1586  Filler->EndDelta = static_cast<int16_t>(ClipToRange<int>(
1587  IntCastRounded((Cos / Sin) * 256), INT16_MIN, INT16_MAX));
1588 
1589  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1590  YAdjust = XAdjust * Sin / Cos;
1591  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1592  YAdjust = XAdjust * Cos / Sin;
1593  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1594 
1595  Filler->Switch[S1].Type = EndSwitch;
1596  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1597  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1598  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1599  YAdjust = XAdjust * Sin / Cos;
1600  Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
1601  Filler->Switch[S1].Delta = Filler->StartDelta;
1602 
1603  Filler->Switch[S2].Type = StartSwitch;
1604  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1605  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1606  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1607  YAdjust = XAdjust * Cos / Sin;
1608  Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
1609  Filler->Switch[S2].Delta = Filler->EndDelta;
1610 
1611  Filler->Switch[2].Type = LastSwitch;
1612  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1613  }
1614  }
1615 } /* InitTableFiller */
1616 
1617 
1618 /*---------------------------------------------------------------------------*/
1619 #ifndef GRAPHICS_DISABLED
1620 
1628 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
1629  ScrollView::Color color) {
1630  float X, Y, Dx, Dy, Length;
1631 
1632  window->Pen(color);
1633  assert(Feature != nullptr);
1634  assert(color != 0);
1635 
1636  X = Feature->X;
1637  Y = Feature->Y;
1638  Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
1639  // The -PI has no significant effect here, but the value of Theta is computed
1640  // using BinaryAnglePlusPi in intfx.cpp.
1641  Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1642  Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1643 
1644  window->SetCursor(X, Y);
1645  window->DrawTo(X + Dx, Y + Dy);
1646 } /* RenderIntFeature */
1647 
1663  INT_CLASS Class,
1664  PROTO_ID ProtoId,
1665  ScrollView::Color color) {
1666  PROTO_SET ProtoSet;
1667  INT_PROTO Proto;
1668  int ProtoSetIndex;
1669  int ProtoWordIndex;
1670  float Length;
1671  int Xmin, Xmax, Ymin, Ymax;
1672  float X, Y, Dx, Dy;
1673  uint32_t ProtoMask;
1674  int Bucket;
1675 
1676  assert(ProtoId >= 0);
1677  assert(Class != nullptr);
1678  assert(ProtoId < Class->NumProtos);
1679  assert(color != 0);
1680  window->Pen(color);
1681 
1682  ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
1683  ProtoSetIndex = IndexForProto(ProtoId);
1684  Proto = &(ProtoSet->Protos[ProtoSetIndex]);
1685  Length = (Class->ProtoLengths[ProtoId] *
1687  ProtoMask = PPrunerMaskFor(ProtoId);
1688  ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
1689 
1690  // find the x and y extent of the proto from the proto pruning table
1691  Xmin = Ymin = NUM_PP_BUCKETS;
1692  Xmax = Ymax = 0;
1693  for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
1694  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
1695  UpdateRange(Bucket, &Xmin, &Xmax);
1696  }
1697 
1698  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
1699  UpdateRange(Bucket, &Ymin, &Ymax);
1700  }
1701  }
1702  X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1703  Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
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((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1707  Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1708 
1709  window->SetCursor(X - Dx, Y - Dy);
1710  window->DrawTo(X + Dx, Y + Dy);
1711 } /* RenderIntProto */
1712 #endif
1713 
1727 int TruncateParam(float Param, int Min, int Max, char *Id) {
1728  if (Param < Min) {
1729  if (Id)
1730  cprintf("Warning: Param %s truncated from %f to %d!\n",
1731  Id, Param, Min);
1732  Param = Min;
1733  } else if (Param > Max) {
1734  if (Id)
1735  cprintf("Warning: Param %s truncated from %f to %d!\n",
1736  Id, Param, Max);
1737  Param = Max;
1738  }
1739  return static_cast<int>(std::floor(Param));
1740 } /* TruncateParam */
1741 
1742 
1743 #ifndef GRAPHICS_DISABLED
1744 
1749  if (IntMatchWindow == nullptr) {
1750  IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
1751  SVMenuNode* popup_menu = new SVMenuNode();
1752 
1753  popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
1754  "x", "Class to debug");
1755  popup_menu->AddChild("Debug Static classes", IDA_STATIC,
1756  "x", "Class to debug");
1757  popup_menu->AddChild("Debug Both", IDA_BOTH,
1758  "x", "Class to debug");
1759  popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
1760  "0", "Index to debug");
1761  popup_menu->BuildMenu(IntMatchWindow, false);
1762  }
1763 }
1764 
1770  if (ProtoDisplayWindow == nullptr) {
1771  ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
1772  550, 200);
1773  }
1774 }
1775 
1781  if (FeatureDisplayWindow == nullptr) {
1782  FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
1783  50, 700);
1784  }
1785 }
1786 
1789 ScrollView* CreateFeatureSpaceWindow(const char* name, int xpos, int ypos) {
1790  return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
1791 }
1792 #endif // GRAPHICS_DISABLED
double classify_cp_angle_pad_loose
Definition: intproto.cpp:187
SWITCH_TYPE Type
Definition: intproto.cpp:75
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:197
ScrollView::Color GetMatchColorFor(float Evidence)
Definition: intproto.cpp:1391
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:162
#define BITS_PER_CP_VECTOR
Definition: intproto.h:59
int16_t NumProtos
Definition: protos.h:61
uint16_t Bucket16For(float param, float offset, int num_buckets)
Definition: intproto.cpp:425
void DrawTo(int x, int y)
Definition: scrollview.cpp:527
CLUSTERCONFIG Config
int FRead(void *buffer, size_t size, int count)
Definition: serialis.cpp:270
double classify_cp_angle_pad_medium
Definition: intproto.cpp:189
void InitTableFiller(float EndPad, float SidePad, float AnglePad, PROTO Proto, TABLE_FILLER *Filler)
Definition: intproto.cpp:1465
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:998
#define TRUE
Definition: capi.h:51
#define INT_MIN_Y
Definition: intproto.cpp:61
#define INT_CAPHEIGHT
Definition: intproto.cpp:54
#define PRUNER_ANGLE
Definition: intproto.h:37
void UpdateMatchDisplay()
Definition: intproto.cpp:451
void cprintf(const char *format,...)
Definition: callcpp.cpp:33
int8_t YEnd
Definition: intproto.cpp:100
float X
Definition: protos.h:46
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:708
int8_t X
Definition: intproto.cpp:88
INT_CLASS Class[MAX_NUM_CLASSES]
Definition: intproto.h:121
#define NUM_PP_PARAMS
Definition: intproto.h:51
float B
Definition: protos.h:44
int16_t Delta
Definition: intproto.cpp:78
uint32_t Configs[WERDS_PER_CONFIG_VEC]
Definition: intproto.h:86
int classify_num_cp_levels
Definition: intproto.cpp:185
#define double_VAR(name, val, comment)
Definition: params.h:285
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, float Evidence)
Definition: intproto.cpp:599
STRING DebugStr(int shape_id) const
Definition: shapetable.cpp:281
bool FillerDone(TABLE_FILLER *Filler)
Definition: intproto.cpp:1177
uint8_t CircBucketFor(float param, float offset, int num_buckets)
Definition: intproto.cpp:435
void ZoomToRectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:760
struct INT_CLASS_STRUCT * INT_CLASS
#define INT_YRADIUS
Definition: intproto.cpp:59
const char * string() const
Definition: strngs.cpp:196
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class)
Definition: intproto.cpp:496
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
Definition: intproto.cpp:91
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
Definition: intproto.h:122
void * Emalloc(int Size)
Definition: emalloc.cpp:31
int8_t Y
Definition: intproto.cpp:76
#define NUM_BITS_PER_CLASS
Definition: intproto.h:55
#define INT_CHAR_NORM_RANGE
Definition: intproto.h:130
SVEventType
Definition: scrollview.h:45
void Efree(void *ptr)
Definition: emalloc.cpp:45
#define MAX_NUM_PROTO_SETS
Definition: intproto.h:50
ScrollView * FeatureDisplayWindow
Definition: intproto.cpp:177
int Modulo(int a, int b)
Definition: helpers.h:153
#define PRUNER_X
Definition: intproto.h:35
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:209
uint8_t AngleEnd
Definition: intproto.cpp:101
#define INT_XCENTER
Definition: intproto.cpp:56
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
Definition: intproto.cpp:1415
uint32_t * BIT_VECTOR
Definition: bitvec.h:28
#define ProtoForProtoId(C, P)
Definition: intproto.h:166
double classify_pp_angle_pad
Definition: intproto.cpp:198
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
Definition: tesscallback.h:116
#define CPrunerIdFor(c)
Definition: intproto.h:178
void InitProtoDisplayWindowIfReqd()
Definition: intproto.cpp:1769
UNICHAR_ID CLASS_ID
Definition: matchdefs.h:36
void SetCursor(int x, int y)
Definition: scrollview.cpp:521
#define UnusedClassIdIn(T, c)
Definition: intproto.h:175
double classify_pp_end_pad
Definition: intproto.cpp:199
uint32_t p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
Definition: intproto.h:78
Definition: fpoint.h:30
uint8_t NumProtoSets
Definition: intproto.h:107
int AddIntProto(INT_CLASS Class)
Definition: intproto.cpp:283
static void Update()
Definition: scrollview.cpp:711
double classify_cp_angle_pad_tight
Definition: intproto.cpp:191
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:535
UnicityTableEqEq< int > font_set
Definition: protos.h:67
#define ProtoIn(Class, Pid)
Definition: protos.h:121
#define CPrunerWordIndexFor(c)
Definition: intproto.h:180
#define Y_SHIFT
Definition: intproto.h:42
int16_t NumConfigs
Definition: protos.h:64
int size() const
Definition: unicharset.h:336
uint8_t * ProtoLengths
Definition: intproto.h:110
float Y
Definition: protos.h:47
#define GetPicoFeatureLength()
Definition: picofeat.h:57
float Length
Definition: protos.h:49
#define MapParam(P, O, N)
Definition: intproto.cpp:120
int FReadEndian(void *buffer, size_t size, int count)
Definition: serialis.cpp:259
#define CPrunerMaskFor(L, c)
Definition: intproto.h:182
#define XS
#define HV_TOLERANCE
Definition: intproto.cpp:66
double classify_cp_end_pad_tight
Definition: intproto.cpp:194
uint8_t AngleStart
Definition: intproto.cpp:87
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
Definition: intproto.h:109
uint8_t NumConfigs
Definition: intproto.h:108
double classify_cp_end_pad_medium
Definition: intproto.cpp:193
#define LegalClassId(c)
Definition: intproto.h:174
#define MAX_NUM_CONFIGS
Definition: intproto.h:47
void GetCPPadsForLevel(int Level, float *EndPad, float *SidePad, float *AnglePad)
Definition: intproto.cpp:1352
#define MAX_NUM_PROTOS
Definition: intproto.h:48
double classify_cp_side_pad_loose
Definition: intproto.cpp:195
#define WERDS_PER_PP_VECTOR
Definition: intproto.h:63
#define BITS_PER_WERD
Definition: intproto.h:45
#define MaxNumIntProtosIn(C)
Definition: intproto.h:163
bool read_spacing_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:169
int16_t StartDelta
Definition: intproto.cpp:90
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:445
int classify_learning_debug_level
Definition: classify.h:460
UNICHARSET unicharset
Definition: ccutil.h:68
#define MAX_LEVEL
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
Definition: intproto.h:97
#define INT_XRADIUS
Definition: intproto.cpp:58
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:670
double classify_cp_end_pad_loose
Definition: intproto.cpp:192
#define ANGLE_SHIFT
Definition: intproto.h:40
float y
Definition: fpoint.h:31
int TruncateParam(float Param, int Min, int Max, char *Id)
Definition: intproto.cpp:1727
int size() const
Return the size used.
float C
Definition: protos.h:45
int16_t YInit
Definition: intproto.cpp:77
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:58
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:1030
int16_t EndDelta
Definition: intproto.cpp:90
int IntCastRounded(double x)
Definition: helpers.h:168
int16_t YEnd
Definition: intproto.cpp:89
uint16_t ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:111
uint8_t AngleStart
Definition: intproto.cpp:101
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1628
SVEventType type
Definition: scrollview.h:64
struct PROTO_SET_STRUCT * PROTO_SET
ShapeTable * shape_table_
Definition: classify.h:553
int8_t YStart
Definition: intproto.cpp:100
float BucketEnd(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1121
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:37
#define PROTOS_PER_PROTO_SET
Definition: intproto.h:49
#define INT_XHEIGHT
Definition: intproto.cpp:53
#define NUM_CP_BUCKETS
Definition: intproto.h:53
int8_t X
Definition: intproto.cpp:76
double classify_pp_side_pad
Definition: intproto.cpp:200
bool read_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:152
#define MaxNumClassesIn(T)
Definition: intproto.h:173
#define PPrunerWordIndexFor(I)
Definition: intproto.h:168
#define INT_YCENTER
Definition: intproto.cpp:57
PROTO_PRUNER ProtoPruner
Definition: intproto.h:96
SWITCH_TYPE
Definition: intproto.cpp:68
const Shape & GetShape(int shape_id) const
Definition: shapetable.h:320
#define INT_MAX_X
Definition: intproto.cpp:62
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, uint32_t ClassMask, uint32_t ClassCount, uint32_t WordIndex)
Definition: intproto.cpp:1137
uint8_t Bucket8For(float param, float offset, int num_buckets)
Definition: intproto.cpp:421
int AddIntConfig(INT_CLASS Class)
Definition: intproto.cpp:262
int16_t PROTO_ID
Definition: matchdefs.h:42
#define CPrunerBitIndexFor(c)
Definition: intproto.h:181
float BucketStart(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1105
#define SetForProto(P)
Definition: intproto.h:164
float Angle
Definition: protos.h:48
#define YS
uint8_t AngleEnd
Definition: intproto.cpp:87
void FillPPCircularBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1201
UnicityTable< FontInfo > fontinfo_table_
Definition: classify.h:529
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
Definition: intproto.cpp:370
const T & get(int id) const
Return the object from an id.
#define OLD_WERDS_PER_CONFIG_VEC
Definition: intproto.cpp:110
ScrollView * ProtoDisplayWindow
Definition: intproto.cpp:178
void InitFeatureDisplayWindowIfReqd()
Definition: intproto.cpp:1780
#define INT_MIN_X
Definition: intproto.cpp:60
double classify_cp_side_pad_tight
Definition: intproto.cpp:197
void * Erealloc(void *ptr, int size)
Definition: emalloc.cpp:38
int command_id
Definition: scrollview.h:70
INT_TEMPLATES ReadIntTemplates(TFile *fp)
Definition: intproto.cpp:728
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1789
char * parameter
Definition: scrollview.h:71
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
Definition: intproto.cpp:1662
const char * id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:290
INT_TEMPLATES NewIntTemplates()
Definition: intproto.cpp:692
#define INT_BASELINE
Definition: intproto.cpp:52
#define PROTO_PRUNER_SCALE
Definition: intproto.cpp:49
int8_t X
Definition: intproto.cpp:99
#define CPrunerFor(T, c)
Definition: intproto.h:179
#define WERDS_PER_CP_VECTOR
Definition: intproto.h:62
Definition: points.h:189
ScrollView * IntMatchWindow
Definition: intproto.cpp:176
void Clear()
Definition: scrollview.cpp:591
#define IndexForProto(P)
Definition: intproto.h:165
bool ContainsUnichar(int unichar_id) const
Definition: shapetable.cpp:147
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, float Evidence)
Definition: intproto.cpp:618
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
Definition: intproto.cpp:232
void GetFirstUnicharAndFont(int shape_id, int *unichar_id, int *font_id) const
Definition: shapetable.cpp:404
#define INT_DESCENDER
Definition: intproto.cpp:51
#define X_SHIFT
Definition: intproto.h:41
uint16_t NumProtos
Definition: intproto.h:106
void InitIntMatchWindowIfReqd()
Definition: intproto.cpp:1748
bool read_set(TFile *f, FontSet *fs)
Definition: fontinfo.cpp:225
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:602
CONFIGS Configurations
Definition: protos.h:66
#define NO_PROTO
Definition: matchdefs.h:43
#define MAX_NUM_SWITCHES
Definition: intproto.cpp:71
#define AS
bool write_set(FILE *f, const FontSet &fs)
Definition: fontinfo.cpp:231
#define NUM_PP_BUCKETS
Definition: intproto.h:52
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:111
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:120
uint8_t Angle
Definition: intproto.h:85
#define PRUNER_Y
Definition: intproto.h:36
#define NB
#define ClassForClassId(T, c)
Definition: intproto.h:176
double classify_cp_side_pad_medium
Definition: intproto.cpp:196
uint8_t NextSwitch
Definition: intproto.cpp:86
int16_t YStart
Definition: intproto.cpp:89
void Pen(Color color)
Definition: scrollview.cpp:722
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
Definition: intproto.cpp:636
#define INT_MAX_Y
Definition: intproto.cpp:63
int NumShapes() const
Definition: shapetable.h:275
#define MAX_NUM_CLASSES
Definition: matchdefs.h:32
#define MAX_NUM_CLASS_PRUNERS
Definition: intproto.h:60
#define CircularIncrement(i, r)
Definition: intproto.cpp:117
float x
Definition: fpoint.h:31
NORM_METHOD
Definition: mfoutline.h:54
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
Definition: intproto.cpp:330
float A
Definition: protos.h:43
#define test_bit(array, bit)
Definition: bitvec.h:61
UnicityTable< FontSet > fontset_table_
Definition: classify.h:537
#define SET_BIT(array, bit)
Definition: bitvec.h:57
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
Definition: intproto.cpp:469
CLASS_ID GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on, int *shape_id)
Definition: intproto.cpp:1274
#define INT_VAR(name, val, comment)
Definition: params.h:276
struct INT_TEMPLATES_STRUCT * INT_TEMPLATES
#define OLD_MAX_NUM_CONFIGS
Definition: intproto.cpp:109
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:121
#define ASSERT_HOST(x)
Definition: errcode.h:84
#define PPrunerMaskFor(I)
Definition: intproto.h:171
void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1242
#define WERDS_PER_CONFIG_VEC
Definition: intproto.h:68