tesseract  4.1.1
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  **
6  ** (c) Copyright Hewlett-Packard Company, 1988.
7  ** Licensed under the Apache License, Version 2.0 (the "License");
8  ** you may not use this file except in compliance with the License.
9  ** You may obtain a copy of the License at
10  ** http://www.apache.org/licenses/LICENSE-2.0
11  ** Unless required by applicable law or agreed to in writing, software
12  ** distributed under the License is distributed on an "AS IS" BASIS,
13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  ** See the License for the specific language governing permissions and
15  ** limitations under the License.
16  ******************************************************************************/
17 /*-----------------------------------------------------------------------------
18  Include Files and Type Defines
19 -----------------------------------------------------------------------------*/
20 
21 #define _USE_MATH_DEFINES // for M_PI
22 #include <algorithm>
23 #include <cmath> // for M_PI, 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 "helpers.h"
33 #include "intproto.h"
34 #include "mfoutline.h"
35 #include "picofeat.h"
36 #include "points.h"
37 #include "shapetable.h"
38 #include "svmnode.h"
39 
40 // Include automatically generated configuration file if running autoconf.
41 #ifdef HAVE_CONFIG_H
42 #include "config_auto.h"
43 #endif
44 
45 using tesseract::FontSet;
46 
47 /* match debug display constants*/
48 #define PROTO_PRUNER_SCALE (4.0)
49 
50 #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE)
51 #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE)
52 #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE)
53 #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE)
54 
55 #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE)
56 #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE)
57 #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE)
58 #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE)
59 #define INT_MIN_X 0
60 #define INT_MIN_Y 0
61 #define INT_MAX_X INT_CHAR_NORM_RANGE
62 #define INT_MAX_Y INT_CHAR_NORM_RANGE
63 
65 #define HV_TOLERANCE (0.0025) /* approx 0.9 degrees */
66 
67 typedef enum
70 #define MAX_NUM_SWITCHES 3
71 
72 typedef struct
73 {
75  int8_t X, Y;
76  int16_t YInit;
77  int16_t Delta;
78 }
79 
80 
82 
83 typedef struct
84 {
85  uint8_t NextSwitch;
86  uint8_t AngleStart, AngleEnd;
87  int8_t X;
88  int16_t YStart, YEnd;
89  int16_t StartDelta, EndDelta;
91 }
92 
93 
95 
96 typedef struct
97 {
98  int8_t X;
99  int8_t YStart, YEnd;
100  uint8_t AngleStart, AngleEnd;
101 }
102 
103 
104 FILL_SPEC;
105 
106 
107 /* constants for conversion from old inttemp format */
108 #define OLD_MAX_NUM_CONFIGS 32
109 #define OLD_WERDS_PER_CONFIG_VEC ((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\
110  BITS_PER_WERD)
111 
112 /*-----------------------------------------------------------------------------
113  Macros
114 -----------------------------------------------------------------------------*/
116 #define CircularIncrement(i,r) (((i) < (r) - 1)?((i)++):((i) = 0))
117 
119 #define MapParam(P,O,N) (std::floor(((P) + (O)) * (N)))
120 
121 /*---------------------------------------------------------------------------
122  Private Function Prototypes
123 ----------------------------------------------------------------------------*/
124 float BucketStart(int Bucket, float Offset, int NumBuckets);
125 
126 float BucketEnd(int Bucket, float Offset, int NumBuckets);
127 
128 void DoFill(FILL_SPEC *FillSpec,
129  CLASS_PRUNER_STRUCT* Pruner,
130  uint32_t ClassMask,
131  uint32_t ClassCount,
132  uint32_t WordIndex);
133 
134 bool FillerDone(TABLE_FILLER* Filler);
135 
136 void FillPPCircularBits(uint32_t
137  ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
138  int Bit, float Center, float Spread, bool debug);
139 
140 void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
141  int Bit, float Center, float Spread, bool debug);
142 
143 void GetCPPadsForLevel(int Level,
144  float *EndPad,
145  float *SidePad,
146  float *AnglePad);
147 
148 ScrollView::Color GetMatchColorFor(float Evidence);
149 
150 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill);
151 
152 void InitTableFiller(float EndPad,
153  float SidePad,
154  float AnglePad,
155  PROTO Proto,
156  TABLE_FILLER *Filler);
157 
158 #ifndef GRAPHICS_DISABLED
159 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
160  ScrollView::Color color);
161 
162 void RenderIntProto(ScrollView *window,
163  INT_CLASS Class,
164  PROTO_ID ProtoId,
165  ScrollView::Color color);
166 #endif // GRAPHICS_DISABLED
167 
168 int TruncateParam(float Param, int Min, int Max, char *Id);
169 
170 /*-----------------------------------------------------------------------------
171  Global Data Definitions and Declarations
172 -----------------------------------------------------------------------------*/
173 
174 /* global display lists used to display proto and feature match information*/
175 static ScrollView* IntMatchWindow = nullptr;
176 static ScrollView* FeatureDisplayWindow = nullptr;
177 static ScrollView* ProtoDisplayWindow = nullptr;
178 
179 /*-----------------------------------------------------------------------------
180  Variables
181 -----------------------------------------------------------------------------*/
182 
183 /* control knobs */
184 static INT_VAR(classify_num_cp_levels, 3, "Number of Class Pruner Levels");
185 static double_VAR(classify_cp_angle_pad_loose, 45.0,
186  "Class Pruner Angle Pad Loose");
187 static double_VAR(classify_cp_angle_pad_medium, 20.0,
188  "Class Pruner Angle Pad Medium");
189 static double_VAR(classify_cp_angle_pad_tight, 10.0,
190  "CLass Pruner Angle Pad Tight");
191 static double_VAR(classify_cp_end_pad_loose, 0.5, "Class Pruner End Pad Loose");
192 static double_VAR(classify_cp_end_pad_medium, 0.5, "Class Pruner End Pad Medium");
193 static double_VAR(classify_cp_end_pad_tight, 0.5, "Class Pruner End Pad Tight");
194 static double_VAR(classify_cp_side_pad_loose, 2.5, "Class Pruner Side Pad Loose");
195 static double_VAR(classify_cp_side_pad_medium, 1.2, "Class Pruner Side Pad Medium");
196 static double_VAR(classify_cp_side_pad_tight, 0.6, "Class Pruner Side Pad Tight");
197 static double_VAR(classify_pp_angle_pad, 45.0, "Proto Pruner Angle Pad");
198 static double_VAR(classify_pp_end_pad, 0.5, "Proto Prune End Pad");
199 static double_VAR(classify_pp_side_pad, 2.5, "Proto Pruner Side Pad");
200 
201 /*-----------------------------------------------------------------------------
202  Public Code
203 -----------------------------------------------------------------------------*/
207  : X(ClipToRange<int16_t>(static_cast<int16_t>(pos.x() + 0.5), 0, 255)),
208  Y(ClipToRange<int16_t>(static_cast<int16_t>(pos.y() + 0.5), 0, 255)),
209  Theta(theta),
210  CP_misses(0) {
211 }
214  : X(static_cast<uint8_t>(ClipToRange<int>(x, 0, UINT8_MAX))),
215  Y(static_cast<uint8_t>(ClipToRange<int>(y, 0, UINT8_MAX))),
216  Theta(static_cast<uint8_t>(ClipToRange<int>(theta, 0, UINT8_MAX))),
217  CP_misses(0) {
218 }
219 
231 void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) {
232  int Pruner;
233 
234  assert (LegalClassId (ClassId));
235  if (ClassId != Templates->NumClasses) {
236  fprintf(stderr, "Please make sure that classes are added to templates");
237  fprintf(stderr, " in increasing order of ClassIds\n");
238  exit(1);
239  }
240  ClassForClassId (Templates, ClassId) = Class;
241  Templates->NumClasses++;
242 
243  if (Templates->NumClasses > MaxNumClassesIn (Templates)) {
244  Pruner = Templates->NumClassPruners++;
245  Templates->ClassPruners[Pruner] = new CLASS_PRUNER_STRUCT;
246  memset(Templates->ClassPruners[Pruner], 0, sizeof(CLASS_PRUNER_STRUCT));
247  }
248 } /* AddIntClass */
249 
250 
262  int Index;
263 
264  assert(Class->NumConfigs < MAX_NUM_CONFIGS);
265 
266  Index = Class->NumConfigs++;
267  Class->ConfigLengths[Index] = 0;
268  return Index;
269 } /* AddIntConfig */
270 
271 
282 int AddIntProto(INT_CLASS Class) {
283  int Index;
284  int ProtoSetId;
285  PROTO_SET ProtoSet;
286  INT_PROTO Proto;
287  uint32_t *Word;
288 
289  if (Class->NumProtos >= MAX_NUM_PROTOS)
290  return (NO_PROTO);
291 
292  Index = Class->NumProtos++;
293 
294  if (Class->NumProtos > MaxNumIntProtosIn(Class)) {
295  ProtoSetId = Class->NumProtoSets++;
296 
297  ProtoSet = static_cast<PROTO_SET>(Emalloc(sizeof(PROTO_SET_STRUCT)));
298  Class->ProtoSets[ProtoSetId] = ProtoSet;
299  memset(ProtoSet, 0, sizeof(*ProtoSet));
300 
301  /* reallocate space for the proto lengths and install in class */
302  Class->ProtoLengths =
303  static_cast<uint8_t *>(Erealloc(Class->ProtoLengths,
304  MaxNumIntProtosIn(Class) * sizeof(uint8_t)));
305  memset(&Class->ProtoLengths[Index], 0,
306  sizeof(*Class->ProtoLengths) * (MaxNumIntProtosIn(Class) - Index));
307  }
308 
309  /* initialize proto so its length is zero and it isn't in any configs */
310  Class->ProtoLengths[Index] = 0;
311  Proto = ProtoForProtoId (Class, Index);
312  for (Word = Proto->Configs;
313  Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0);
314 
315  return (Index);
316 }
317 
328 void AddProtoToClassPruner (PROTO Proto, CLASS_ID ClassId,
329  INT_TEMPLATES Templates)
330 #define MAX_LEVEL 2
331 {
332  CLASS_PRUNER_STRUCT* Pruner;
333  uint32_t ClassMask;
334  uint32_t ClassCount;
335  uint32_t WordIndex;
336  int Level;
337  float EndPad, SidePad, AnglePad;
338  TABLE_FILLER TableFiller;
339  FILL_SPEC FillSpec;
340 
341  Pruner = CPrunerFor (Templates, ClassId);
342  WordIndex = CPrunerWordIndexFor (ClassId);
343  ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassId);
344 
345  for (Level = classify_num_cp_levels - 1; Level >= 0; Level--) {
346  GetCPPadsForLevel(Level, &EndPad, &SidePad, &AnglePad);
347  ClassCount = CPrunerMaskFor (Level, ClassId);
348  InitTableFiller(EndPad, SidePad, AnglePad, Proto, &TableFiller);
349 
350  while (!FillerDone (&TableFiller)) {
351  GetNextFill(&TableFiller, &FillSpec);
352  DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
353  }
354  }
355 } /* AddProtoToClassPruner */
356 
367 void AddProtoToProtoPruner(PROTO Proto, int ProtoId,
368  INT_CLASS Class, bool debug) {
369  float Angle, X, Y, Length;
370  float Pad;
371  int Index;
372  PROTO_SET ProtoSet;
373 
374  if (ProtoId >= Class->NumProtos)
375  cprintf("AddProtoToProtoPruner:assert failed: %d < %d",
376  ProtoId, Class->NumProtos);
377  assert(ProtoId < Class->NumProtos);
378 
379  Index = IndexForProto (ProtoId);
380  ProtoSet = Class->ProtoSets[SetForProto (ProtoId)];
381 
382  Angle = Proto->Angle;
383 #ifndef _WIN32
384  assert(!std::isnan(Angle));
385 #endif
386 
387  FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index,
388  Angle + ANGLE_SHIFT, classify_pp_angle_pad / 360.0,
389  debug);
390 
391  Angle *= 2.0 * M_PI;
392  Length = Proto->Length;
393 
394  X = Proto->X + X_SHIFT;
395  Pad = std::max(fabs (cos (Angle)) * (Length / 2.0 +
396  classify_pp_end_pad *
398  fabs (sin (Angle)) * (classify_pp_side_pad *
400 
401  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad, debug);
402 
403  Y = Proto->Y + Y_SHIFT;
404  Pad = std::max(fabs (sin (Angle)) * (Length / 2.0 +
405  classify_pp_end_pad *
407  fabs (cos (Angle)) * (classify_pp_side_pad *
409 
410  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_Y], Index, Y, Pad, debug);
411 } /* AddProtoToProtoPruner */
412 
418 uint8_t Bucket8For(float param, float offset, int num_buckets) {
419  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
420  return static_cast<uint8_t>(ClipToRange<int>(bucket, 0, num_buckets - 1));
421 }
422 uint16_t Bucket16For(float param, float offset, int num_buckets) {
423  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
424  return static_cast<uint16_t>(ClipToRange<int>(bucket, 0, num_buckets - 1));
425 }
426 
432 uint8_t CircBucketFor(float param, float offset, int num_buckets) {
433  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
434  return static_cast<uint8_t>(Modulo(bucket, num_buckets));
435 } /* CircBucketFor */
436 
437 
438 #ifndef GRAPHICS_DISABLED
439 
448  if (IntMatchWindow != nullptr)
449  IntMatchWindow->Update();
450 } /* ClearMatchDisplay */
451 #endif
452 
463 void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class) {
464  int ProtoId;
465  INT_PROTO Proto;
466  int TotalLength;
467 
468  for (ProtoId = 0, TotalLength = 0;
469  ProtoId < Class->NumProtos; ProtoId++) {
470  if (test_bit(Config, ProtoId)) {
471  Proto = ProtoForProtoId(Class, ProtoId);
472  SET_BIT(Proto->Configs, ConfigId);
473  TotalLength += Class->ProtoLengths[ProtoId];
474  }
475  }
476  Class->ConfigLengths[ConfigId] = TotalLength;
477 } /* ConvertConfig */
478 
479 
480 namespace tesseract {
488 void Classify::ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class) {
489  INT_PROTO P;
490  float Param;
491 
492  assert(ProtoId < Class->NumProtos);
493 
494  P = ProtoForProtoId(Class, ProtoId);
495 
496  Param = Proto->A * 128;
497  P->A = TruncateParam(Param, -128, 127, nullptr);
498 
499  Param = -Proto->B * 256;
500  P->B = TruncateParam(Param, 0, 255, nullptr);
501 
502  Param = Proto->C * 128;
503  P->C = TruncateParam(Param, -128, 127, nullptr);
504 
505  Param = Proto->Angle * 256;
506  if (Param < 0 || Param >= 256)
507  P->Angle = 0;
508  else
509  P->Angle = static_cast<uint8_t>(Param);
510 
511  /* round proto length to nearest integer number of pico-features */
512  Param = (Proto->Length / GetPicoFeatureLength()) + 0.5;
513  Class->ProtoLengths[ProtoId] = TruncateParam(Param, 1, 255, nullptr);
515  cprintf("Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
516  P->A, P->B, P->C, Class->ProtoLengths[ProtoId]);
517 } /* ConvertProto */
518 
528  const UNICHARSET&
529  target_unicharset) {
530  INT_TEMPLATES IntTemplates;
531  CLASS_TYPE FClass;
532  INT_CLASS IClass;
533  int ClassId;
534  int ProtoId;
535  int ConfigId;
536 
537  IntTemplates = NewIntTemplates();
538 
539  for (ClassId = 0; ClassId < target_unicharset.size(); ClassId++) {
540  FClass = &(FloatProtos[ClassId]);
541  if (FClass->NumProtos == 0 && FClass->NumConfigs == 0 &&
542  strcmp(target_unicharset.id_to_unichar(ClassId), " ") != 0) {
543  cprintf("Warning: no protos/configs for %s in CreateIntTemplates()\n",
544  target_unicharset.id_to_unichar(ClassId));
545  }
546  assert(UnusedClassIdIn(IntTemplates, ClassId));
547  IClass = NewIntClass(FClass->NumProtos, FClass->NumConfigs);
548  FontSet fs;
549  fs.size = FClass->font_set.size();
550  fs.configs = new int[fs.size];
551  for (int i = 0; i < fs.size; ++i) {
552  fs.configs[i] = FClass->font_set.get(i);
553  }
554  if (this->fontset_table_.contains(fs)) {
555  IClass->font_set_id = this->fontset_table_.get_id(fs);
556  delete[] fs.configs;
557  } else {
558  IClass->font_set_id = this->fontset_table_.push_back(fs);
559  }
560  AddIntClass(IntTemplates, ClassId, IClass);
561 
562  for (ProtoId = 0; ProtoId < FClass->NumProtos; ProtoId++) {
563  AddIntProto(IClass);
564  ConvertProto(ProtoIn(FClass, ProtoId), ProtoId, IClass);
565  AddProtoToProtoPruner(ProtoIn(FClass, ProtoId), ProtoId, IClass,
567  AddProtoToClassPruner(ProtoIn(FClass, ProtoId), ClassId, IntTemplates);
568  }
569 
570  for (ConfigId = 0; ConfigId < FClass->NumConfigs; ConfigId++) {
571  AddIntConfig(IClass);
572  ConvertConfig(FClass->Configurations[ConfigId], ConfigId, IClass);
573  }
574  }
575  return (IntTemplates);
576 } /* CreateIntTemplates */
577 } // namespace tesseract
578 
579 
580 #ifndef GRAPHICS_DISABLED
581 
590 void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, float Evidence) {
591  ScrollView::Color color = GetMatchColorFor(Evidence);
592  RenderIntFeature(IntMatchWindow, Feature, color);
593  if (FeatureDisplayWindow) {
594  RenderIntFeature(FeatureDisplayWindow, Feature, color);
595  }
596 } /* DisplayIntFeature */
597 
608 void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, float Evidence) {
609  ScrollView::Color color = GetMatchColorFor(Evidence);
610  RenderIntProto(IntMatchWindow, Class, ProtoId, color);
611  if (ProtoDisplayWindow) {
612  RenderIntProto(ProtoDisplayWindow, Class, ProtoId, color);
613  }
614 } /* DisplayIntProto */
615 #endif
616 
626 INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs) {
627  INT_CLASS Class;
628  PROTO_SET ProtoSet;
629  int i;
630 
631  assert(MaxNumConfigs <= MAX_NUM_CONFIGS);
632 
633  Class = static_cast<INT_CLASS>(Emalloc(sizeof(INT_CLASS_STRUCT)));
634  Class->NumProtoSets = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) /
636 
637  assert(Class->NumProtoSets <= MAX_NUM_PROTO_SETS);
638 
639  Class->NumProtos = 0;
640  Class->NumConfigs = 0;
641 
642  for (i = 0; i < Class->NumProtoSets; i++) {
643  /* allocate space for a proto set, install in class, and initialize */
644  ProtoSet = static_cast<PROTO_SET>(Emalloc(sizeof(PROTO_SET_STRUCT)));
645  memset(ProtoSet, 0, sizeof(*ProtoSet));
646  Class->ProtoSets[i] = ProtoSet;
647 
648  /* allocate space for the proto lengths and install in class */
649  }
650  if (MaxNumIntProtosIn (Class) > 0) {
651  Class->ProtoLengths =
652  static_cast<uint8_t *>(Emalloc(MaxNumIntProtosIn (Class) * sizeof (uint8_t)));
653  memset(Class->ProtoLengths, 0,
654  MaxNumIntProtosIn(Class) * sizeof(*Class->ProtoLengths));
655  } else {
656  Class->ProtoLengths = nullptr;
657  }
658  memset(Class->ConfigLengths, 0, sizeof(Class->ConfigLengths));
659 
660  return (Class);
661 
662 } /* NewIntClass */
663 
664 static void free_int_class(INT_CLASS int_class) {
665  int i;
666 
667  for (i = 0; i < int_class->NumProtoSets; i++) {
668  Efree (int_class->ProtoSets[i]);
669  }
670  if (int_class->ProtoLengths != nullptr) {
671  Efree (int_class->ProtoLengths);
672  }
673  Efree(int_class);
674 }
675 
683  INT_TEMPLATES T;
684  int i;
685 
686  T = static_cast<INT_TEMPLATES>(Emalloc (sizeof (INT_TEMPLATES_STRUCT)));
687  T->NumClasses = 0;
688  T->NumClassPruners = 0;
689 
690  for (i = 0; i < MAX_NUM_CLASSES; i++)
691  ClassForClassId (T, i) = nullptr;
692 
693  return (T);
694 } /* NewIntTemplates */
695 
696 
697 /*---------------------------------------------------------------------------*/
699  int i;
700 
701  for (i = 0; i < templates->NumClasses; i++)
702  free_int_class(templates->Class[i]);
703  for (i = 0; i < templates->NumClassPruners; i++)
704  delete templates->ClassPruners[i];
705  Efree(templates);
706 }
707 
708 
709 namespace tesseract {
719  int i, j, w, x, y, z;
720  int unicharset_size;
721  int version_id = 0;
722  INT_TEMPLATES Templates;
723  CLASS_PRUNER_STRUCT* Pruner;
724  INT_CLASS Class;
725  uint8_t *Lengths;
726  PROTO_SET ProtoSet;
727 
728  /* variables for conversion from older inttemp formats */
729  int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
730  CLASS_ID class_id, max_class_id;
731  auto *IndexFor = new int16_t[MAX_NUM_CLASSES];
732  auto *ClassIdFor = new CLASS_ID[MAX_NUM_CLASSES];
733  auto **TempClassPruner =
735  uint32_t SetBitsForMask = // word with NUM_BITS_PER_CLASS
736  (1 << NUM_BITS_PER_CLASS) - 1; // set starting at bit 0
737  uint32_t Mask, NewMask, ClassBits;
738  int MaxNumConfigs = MAX_NUM_CONFIGS;
739  int WerdsPerConfigVec = WERDS_PER_CONFIG_VEC;
740 
741  /* first read the high level template struct */
742  Templates = NewIntTemplates();
743  // Read Templates in parts for 64 bit compatibility.
744  if (fp->FReadEndian(&unicharset_size, sizeof(unicharset_size), 1) != 1)
745  tprintf("Bad read of inttemp!\n");
746  if (fp->FReadEndian(&Templates->NumClasses, sizeof(Templates->NumClasses),
747  1) != 1 ||
748  fp->FReadEndian(&Templates->NumClassPruners,
749  sizeof(Templates->NumClassPruners), 1) != 1)
750  tprintf("Bad read of inttemp!\n");
751  if (Templates->NumClasses < 0) {
752  // This file has a version id!
753  version_id = -Templates->NumClasses;
754  if (fp->FReadEndian(&Templates->NumClasses, sizeof(Templates->NumClasses),
755  1) != 1)
756  tprintf("Bad read of inttemp!\n");
757  }
758 
759  if (version_id < 3) {
760  MaxNumConfigs = OLD_MAX_NUM_CONFIGS;
761  WerdsPerConfigVec = OLD_WERDS_PER_CONFIG_VEC;
762  }
763 
764  if (version_id < 2) {
765  if (fp->FReadEndian(IndexFor, sizeof(IndexFor[0]), unicharset_size) !=
766  unicharset_size) {
767  tprintf("Bad read of inttemp!\n");
768  }
769  if (fp->FReadEndian(ClassIdFor, sizeof(ClassIdFor[0]),
770  Templates->NumClasses) != Templates->NumClasses) {
771  tprintf("Bad read of inttemp!\n");
772  }
773  }
774 
775  /* then read in the class pruners */
776  const int kNumBuckets =
778  for (i = 0; i < Templates->NumClassPruners; i++) {
779  Pruner = new CLASS_PRUNER_STRUCT;
780  if (fp->FReadEndian(Pruner, sizeof(Pruner->p[0][0][0][0]), kNumBuckets) !=
781  kNumBuckets) {
782  tprintf("Bad read of inttemp!\n");
783  }
784  if (version_id < 2) {
785  TempClassPruner[i] = Pruner;
786  } else {
787  Templates->ClassPruners[i] = Pruner;
788  }
789  }
790 
791  /* fix class pruners if they came from an old version of inttemp */
792  if (version_id < 2) {
793  // Allocate enough class pruners to cover all the class ids.
794  max_class_id = 0;
795  for (i = 0; i < Templates->NumClasses; i++)
796  if (ClassIdFor[i] > max_class_id)
797  max_class_id = ClassIdFor[i];
798  for (i = 0; i <= CPrunerIdFor(max_class_id); i++) {
799  Templates->ClassPruners[i] = new CLASS_PRUNER_STRUCT;
800  memset(Templates->ClassPruners[i], 0, sizeof(CLASS_PRUNER_STRUCT));
801  }
802  // Convert class pruners from the old format (indexed by class index)
803  // to the new format (indexed by class id).
804  last_cp_bit_number = NUM_BITS_PER_CLASS * Templates->NumClasses - 1;
805  for (i = 0; i < Templates->NumClassPruners; i++) {
806  for (x = 0; x < NUM_CP_BUCKETS; x++)
807  for (y = 0; y < NUM_CP_BUCKETS; y++)
808  for (z = 0; z < NUM_CP_BUCKETS; z++)
809  for (w = 0; w < WERDS_PER_CP_VECTOR; w++) {
810  if (TempClassPruner[i]->p[x][y][z][w] == 0)
811  continue;
812  for (b = 0; b < BITS_PER_WERD; b += NUM_BITS_PER_CLASS) {
813  bit_number = i * BITS_PER_CP_VECTOR + w * BITS_PER_WERD + b;
814  if (bit_number > last_cp_bit_number)
815  break; // the rest of the bits in this word are not used
816  class_id = ClassIdFor[bit_number / NUM_BITS_PER_CLASS];
817  // Single out NUM_BITS_PER_CLASS bits relating to class_id.
818  Mask = SetBitsForMask << b;
819  ClassBits = TempClassPruner[i]->p[x][y][z][w] & Mask;
820  // Move these bits to the new position in which they should
821  // appear (indexed corresponding to the class_id).
822  new_i = CPrunerIdFor(class_id);
823  new_w = CPrunerWordIndexFor(class_id);
824  new_b = CPrunerBitIndexFor(class_id) * NUM_BITS_PER_CLASS;
825  if (new_b > b) {
826  ClassBits <<= (new_b - b);
827  } else {
828  ClassBits >>= (b - new_b);
829  }
830  // Copy bits relating to class_id to the correct position
831  // in Templates->ClassPruner.
832  NewMask = SetBitsForMask << new_b;
833  Templates->ClassPruners[new_i]->p[x][y][z][new_w] &= ~NewMask;
834  Templates->ClassPruners[new_i]->p[x][y][z][new_w] |= ClassBits;
835  }
836  }
837  }
838  for (i = 0; i < Templates->NumClassPruners; i++) {
839  delete TempClassPruner[i];
840  }
841  }
842 
843  /* then read in each class */
844  for (i = 0; i < Templates->NumClasses; i++) {
845  /* first read in the high level struct for the class */
846  Class = static_cast<INT_CLASS>(Emalloc (sizeof (INT_CLASS_STRUCT)));
847  if (fp->FReadEndian(&Class->NumProtos, sizeof(Class->NumProtos), 1) != 1 ||
848  fp->FRead(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1) != 1 ||
849  fp->FRead(&Class->NumConfigs, sizeof(Class->NumConfigs), 1) != 1)
850  tprintf("Bad read of inttemp!\n");
851  if (version_id == 0) {
852  // Only version 0 writes 5 pointless pointers to the file.
853  for (j = 0; j < 5; ++j) {
854  int32_t junk;
855  if (fp->FRead(&junk, sizeof(junk), 1) != 1)
856  tprintf("Bad read of inttemp!\n");
857  }
858  }
859  int num_configs = version_id < 4 ? MaxNumConfigs : Class->NumConfigs;
860  ASSERT_HOST(num_configs <= MaxNumConfigs);
861  if (fp->FReadEndian(Class->ConfigLengths, sizeof(uint16_t), num_configs) !=
862  num_configs) {
863  tprintf("Bad read of inttemp!\n");
864  }
865  if (version_id < 2) {
866  ClassForClassId (Templates, ClassIdFor[i]) = Class;
867  } else {
868  ClassForClassId (Templates, i) = Class;
869  }
870 
871  /* then read in the proto lengths */
872  Lengths = nullptr;
873  if (MaxNumIntProtosIn (Class) > 0) {
874  Lengths = static_cast<uint8_t *>(Emalloc(sizeof(uint8_t) * MaxNumIntProtosIn(Class)));
875  if (fp->FRead(Lengths, sizeof(uint8_t), MaxNumIntProtosIn(Class)) !=
876  MaxNumIntProtosIn(Class))
877  tprintf("Bad read of inttemp!\n");
878  }
879  Class->ProtoLengths = Lengths;
880 
881  /* then read in the proto sets */
882  for (j = 0; j < Class->NumProtoSets; j++) {
883  ProtoSet = static_cast<PROTO_SET>(Emalloc(sizeof(PROTO_SET_STRUCT)));
884  int num_buckets = NUM_PP_PARAMS * NUM_PP_BUCKETS * WERDS_PER_PP_VECTOR;
885  if (fp->FReadEndian(&ProtoSet->ProtoPruner,
886  sizeof(ProtoSet->ProtoPruner[0][0][0]),
887  num_buckets) != num_buckets)
888  tprintf("Bad read of inttemp!\n");
889  for (x = 0; x < PROTOS_PER_PROTO_SET; x++) {
890  if (fp->FRead(&ProtoSet->Protos[x].A, sizeof(ProtoSet->Protos[x].A),
891  1) != 1 ||
892  fp->FRead(&ProtoSet->Protos[x].B, sizeof(ProtoSet->Protos[x].B),
893  1) != 1 ||
894  fp->FRead(&ProtoSet->Protos[x].C, sizeof(ProtoSet->Protos[x].C),
895  1) != 1 ||
896  fp->FRead(&ProtoSet->Protos[x].Angle,
897  sizeof(ProtoSet->Protos[x].Angle), 1) != 1)
898  tprintf("Bad read of inttemp!\n");
899  if (fp->FReadEndian(&ProtoSet->Protos[x].Configs,
900  sizeof(ProtoSet->Protos[x].Configs[0]),
901  WerdsPerConfigVec) != WerdsPerConfigVec)
902  cprintf("Bad read of inttemp!\n");
903  }
904  Class->ProtoSets[j] = ProtoSet;
905  }
906  if (version_id < 4) {
907  Class->font_set_id = -1;
908  } else {
909  fp->FReadEndian(&Class->font_set_id, sizeof(Class->font_set_id), 1);
910  }
911  }
912 
913  if (version_id < 2) {
914  /* add an empty nullptr class with class id 0 */
915  assert(UnusedClassIdIn (Templates, 0));
916  ClassForClassId (Templates, 0) = NewIntClass (1, 1);
917  ClassForClassId (Templates, 0)->font_set_id = -1;
918  Templates->NumClasses++;
919  /* make sure the classes are contiguous */
920  for (i = 0; i < MAX_NUM_CLASSES; i++) {
921  if (i < Templates->NumClasses) {
922  if (ClassForClassId (Templates, i) == nullptr) {
923  fprintf(stderr, "Non-contiguous class ids in inttemp\n");
924  exit(1);
925  }
926  } else {
927  if (ClassForClassId (Templates, i) != nullptr) {
928  fprintf(stderr, "Class id %d exceeds NumClassesIn (Templates) %d\n",
929  i, Templates->NumClasses);
930  exit(1);
931  }
932  }
933  }
934  }
935  if (version_id >= 4) {
937  if (version_id >= 5) {
938  this->fontinfo_table_.read(fp,
940  }
942  }
943 
944  // Clean up.
945  delete[] IndexFor;
946  delete[] ClassIdFor;
947  delete[] TempClassPruner;
948 
949  return (Templates);
950 } /* ReadIntTemplates */
951 
952 
953 #ifndef GRAPHICS_DISABLED
954 
964  if (ProtoDisplayWindow) {
965  ProtoDisplayWindow->Clear();
966  }
967  if (FeatureDisplayWindow) {
968  FeatureDisplayWindow->Clear();
969  }
971  static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
972  IntMatchWindow);
973  IntMatchWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
975  if (ProtoDisplayWindow) {
976  ProtoDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
978  }
979  if (FeatureDisplayWindow) {
980  FeatureDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
982  }
983 } /* ShowMatchDisplay */
984 
987 void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView* window) {
988  window->Clear();
989 
990  window->Pen(ScrollView::GREY);
991  // Draw the feature space limit rectangle.
992  window->Rectangle(0, 0, INT_MAX_X, INT_MAX_Y);
993  if (norm_method == baseline) {
994  window->SetCursor(0, INT_DESCENDER);
995  window->DrawTo(INT_MAX_X, INT_DESCENDER);
996  window->SetCursor(0, INT_BASELINE);
997  window->DrawTo(INT_MAX_X, INT_BASELINE);
998  window->SetCursor(0, INT_XHEIGHT);
999  window->DrawTo(INT_MAX_X, INT_XHEIGHT);
1000  window->SetCursor(0, INT_CAPHEIGHT);
1001  window->DrawTo(INT_MAX_X, INT_CAPHEIGHT);
1002  } else {
1005  }
1006 }
1007 #endif
1008 
1018  const UNICHARSET& target_unicharset) {
1019  int i, j;
1020  INT_CLASS Class;
1021  int unicharset_size = target_unicharset.size();
1022  int version_id = -5; // When negated by the reader -1 becomes +1 etc.
1023 
1024  if (Templates->NumClasses != unicharset_size) {
1025  cprintf("Warning: executing WriteIntTemplates() with %d classes in"
1026  " Templates, while target_unicharset size is %d\n",
1027  Templates->NumClasses, unicharset_size);
1028  }
1029 
1030  /* first write the high level template struct */
1031  fwrite(&unicharset_size, sizeof(unicharset_size), 1, File);
1032  fwrite(&version_id, sizeof(version_id), 1, File);
1033  fwrite(&Templates->NumClassPruners, sizeof(Templates->NumClassPruners),
1034  1, File);
1035  fwrite(&Templates->NumClasses, sizeof(Templates->NumClasses), 1, File);
1036 
1037  /* then write out the class pruners */
1038  for (i = 0; i < Templates->NumClassPruners; i++)
1039  fwrite(Templates->ClassPruners[i],
1040  sizeof(CLASS_PRUNER_STRUCT), 1, File);
1041 
1042  /* then write out each class */
1043  for (i = 0; i < Templates->NumClasses; i++) {
1044  Class = Templates->Class[i];
1045 
1046  /* first write out the high level struct for the class */
1047  fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
1048  fwrite(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File);
1049  ASSERT_HOST(Class->NumConfigs == this->fontset_table_.get(Class->font_set_id).size);
1050  fwrite(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File);
1051  for (j = 0; j < Class->NumConfigs; ++j) {
1052  fwrite(&Class->ConfigLengths[j], sizeof(uint16_t), 1, File);
1053  }
1054 
1055  /* then write out the proto lengths */
1056  if (MaxNumIntProtosIn (Class) > 0) {
1057  fwrite(Class->ProtoLengths, sizeof(uint8_t),
1058  MaxNumIntProtosIn(Class), File);
1059  }
1060 
1061  /* then write out the proto sets */
1062  for (j = 0; j < Class->NumProtoSets; j++)
1063  fwrite(Class->ProtoSets[j], sizeof(PROTO_SET_STRUCT), 1, File);
1064 
1065  /* then write the fonts info */
1066  fwrite(&Class->font_set_id, sizeof(int), 1, File);
1067  }
1068 
1069  /* Write the fonts info tables */
1071  this->fontinfo_table_.write(File,
1074 } /* WriteIntTemplates */
1075 } // namespace tesseract
1076 
1077 
1078 /*-----------------------------------------------------------------------------
1079  Private Code
1080 -----------------------------------------------------------------------------*/
1092 float BucketStart(int Bucket, float Offset, int NumBuckets) {
1093  return ((static_cast<float>(Bucket) / NumBuckets) - Offset);
1094 
1095 } /* BucketStart */
1096 
1108 float BucketEnd(int Bucket, float Offset, int NumBuckets) {
1109  return ((static_cast<float>(Bucket + 1) / NumBuckets) - Offset);
1110 } /* BucketEnd */
1111 
1122 void DoFill(FILL_SPEC *FillSpec,
1123  CLASS_PRUNER_STRUCT* Pruner,
1124  uint32_t ClassMask,
1125  uint32_t ClassCount,
1126  uint32_t WordIndex) {
1127  int X, Y, Angle;
1128  uint32_t OldWord;
1129 
1130  X = FillSpec->X;
1131  if (X < 0)
1132  X = 0;
1133  if (X >= NUM_CP_BUCKETS)
1134  X = NUM_CP_BUCKETS - 1;
1135 
1136  if (FillSpec->YStart < 0)
1137  FillSpec->YStart = 0;
1138  if (FillSpec->YEnd >= NUM_CP_BUCKETS)
1139  FillSpec->YEnd = NUM_CP_BUCKETS - 1;
1140 
1141  for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
1142  for (Angle = FillSpec->AngleStart; ;
1144  OldWord = Pruner->p[X][Y][Angle][WordIndex];
1145  if (ClassCount > (OldWord & ClassMask)) {
1146  OldWord &= ~ClassMask;
1147  OldWord |= ClassCount;
1148  Pruner->p[X][Y][Angle][WordIndex] = OldWord;
1149  }
1150  if (Angle == FillSpec->AngleEnd)
1151  break;
1152  }
1153 } /* DoFill */
1154 
1162 bool FillerDone(TABLE_FILLER* Filler) {
1163  FILL_SWITCH *Next;
1164 
1165  Next = &(Filler->Switch[Filler->NextSwitch]);
1166 
1167  return Filler->X > Next->X && Next->Type == LastSwitch;
1168 
1169 } /* FillerDone */
1170 
1185  int Bit, float Center, float Spread, bool debug) {
1186  int i, FirstBucket, LastBucket;
1187 
1188  if (Spread > 0.5)
1189  Spread = 0.5;
1190 
1191  FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1192  if (FirstBucket < 0)
1193  FirstBucket += NUM_PP_BUCKETS;
1194 
1195  LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1196  if (LastBucket >= NUM_PP_BUCKETS)
1197  LastBucket -= NUM_PP_BUCKETS;
1198  if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
1199  for (i = FirstBucket; true; CircularIncrement (i, NUM_PP_BUCKETS)) {
1200  SET_BIT (ParamTable[i], Bit);
1201 
1202  /* exit loop after we have set the bit for the last bucket */
1203  if (i == LastBucket)
1204  break;
1205  }
1206 
1207 } /* FillPPCircularBits */
1208 
1224  int Bit, float Center, float Spread, bool debug) {
1225  int i, FirstBucket, LastBucket;
1226 
1227  FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1228  if (FirstBucket < 0)
1229  FirstBucket = 0;
1230 
1231  LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1232  if (LastBucket >= NUM_PP_BUCKETS)
1233  LastBucket = NUM_PP_BUCKETS - 1;
1234 
1235  if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
1236  for (i = FirstBucket; i <= LastBucket; i++)
1237  SET_BIT (ParamTable[i], Bit);
1238 
1239 } /* FillPPLinearBits */
1240 
1241 
1242 /*---------------------------------------------------------------------------*/
1243 #ifndef GRAPHICS_DISABLED
1244 namespace tesseract {
1255 CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool* adaptive_on,
1256  bool* pretrained_on, int* shape_id) {
1257  tprintf("%s\n", Prompt);
1258  SVEvent* ev;
1259  SVEventType ev_type;
1260  int unichar_id = INVALID_UNICHAR_ID;
1261  // Wait until a click or popup event.
1262  do {
1263  ev = IntMatchWindow->AwaitEvent(SVET_ANY);
1264  ev_type = ev->type;
1265  if (ev_type == SVET_POPUP) {
1266  if (ev->command_id == IDA_SHAPE_INDEX) {
1267  if (shape_table_ != nullptr) {
1268  *shape_id = atoi(ev->parameter);
1269  *adaptive_on = false;
1270  *pretrained_on = true;
1271  if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1272  int font_id;
1273  shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1274  &font_id);
1275  tprintf("Shape %d, first unichar=%d, font=%d\n",
1276  *shape_id, unichar_id, font_id);
1277  return unichar_id;
1278  }
1279  tprintf("Shape index '%s' not found in shape table\n", ev->parameter);
1280  } else {
1281  tprintf("No shape table loaded!\n");
1282  }
1283  } else {
1285  unichar_id = unicharset.unichar_to_id(ev->parameter);
1286  if (ev->command_id == IDA_ADAPTIVE) {
1287  *adaptive_on = true;
1288  *pretrained_on = false;
1289  *shape_id = -1;
1290  } else if (ev->command_id == IDA_STATIC) {
1291  *adaptive_on = false;
1292  *pretrained_on = true;
1293  } else {
1294  *adaptive_on = true;
1295  *pretrained_on = true;
1296  }
1297  if (ev->command_id == IDA_ADAPTIVE || shape_table_ == nullptr) {
1298  *shape_id = -1;
1299  return unichar_id;
1300  }
1301  for (int s = 0; s < shape_table_->NumShapes(); ++s) {
1302  if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1303  tprintf("%s\n", shape_table_->DebugStr(s).string());
1304  }
1305  }
1306  } else {
1307  tprintf("Char class '%s' not found in unicharset",
1308  ev->parameter);
1309  }
1310  }
1311  }
1312  delete ev;
1313  } while (ev_type != SVET_CLICK);
1314  return 0;
1315 } /* GetClassToDebug */
1316 
1317 } // namespace tesseract
1318 #endif
1319 
1331 void GetCPPadsForLevel(int Level,
1332  float *EndPad,
1333  float *SidePad,
1334  float *AnglePad) {
1335  switch (Level) {
1336  case 0:
1337  *EndPad = classify_cp_end_pad_loose * GetPicoFeatureLength ();
1338  *SidePad = classify_cp_side_pad_loose * GetPicoFeatureLength ();
1339  *AnglePad = classify_cp_angle_pad_loose / 360.0;
1340  break;
1341 
1342  case 1:
1343  *EndPad = classify_cp_end_pad_medium * GetPicoFeatureLength ();
1344  *SidePad = classify_cp_side_pad_medium * GetPicoFeatureLength ();
1345  *AnglePad = classify_cp_angle_pad_medium / 360.0;
1346  break;
1347 
1348  case 2:
1349  *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
1350  *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
1351  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1352  break;
1353 
1354  default:
1355  *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
1356  *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
1357  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1358  break;
1359  }
1360  if (*AnglePad > 0.5)
1361  *AnglePad = 0.5;
1362 
1363 } /* GetCPPadsForLevel */
1364 
1371  assert (Evidence >= 0.0);
1372  assert (Evidence <= 1.0);
1373 
1374  if (Evidence >= 0.90)
1375  return ScrollView::WHITE;
1376  else if (Evidence >= 0.75)
1377  return ScrollView::GREEN;
1378  else if (Evidence >= 0.50)
1379  return ScrollView::RED;
1380  else
1381  return ScrollView::BLUE;
1382 } /* GetMatchColorFor */
1383 
1392 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {
1393  FILL_SWITCH *Next;
1394 
1395  /* compute the fill assuming no switches will be encountered */
1396  Fill->AngleStart = Filler->AngleStart;
1397  Fill->AngleEnd = Filler->AngleEnd;
1398  Fill->X = Filler->X;
1399  Fill->YStart = Filler->YStart >> 8;
1400  Fill->YEnd = Filler->YEnd >> 8;
1401 
1402  /* update the fill info and the filler for ALL switches at this X value */
1403  Next = &(Filler->Switch[Filler->NextSwitch]);
1404  while (Filler->X >= Next->X) {
1405  Fill->X = Filler->X = Next->X;
1406  if (Next->Type == StartSwitch) {
1407  Fill->YStart = Next->Y;
1408  Filler->StartDelta = Next->Delta;
1409  Filler->YStart = Next->YInit;
1410  }
1411  else if (Next->Type == EndSwitch) {
1412  Fill->YEnd = Next->Y;
1413  Filler->EndDelta = Next->Delta;
1414  Filler->YEnd = Next->YInit;
1415  }
1416  else { /* Type must be LastSwitch */
1417  break;
1418  }
1419  Filler->NextSwitch++;
1420  Next = &(Filler->Switch[Filler->NextSwitch]);
1421  }
1422 
1423  /* prepare the filler for the next call to this routine */
1424  Filler->X++;
1425  Filler->YStart += Filler->StartDelta;
1426  Filler->YEnd += Filler->EndDelta;
1427 
1428 } /* GetNextFill */
1429 
1439 void InitTableFiller (float EndPad, float SidePad,
1440  float AnglePad, PROTO Proto, TABLE_FILLER * Filler)
1441 #define XS X_SHIFT
1442 #define YS Y_SHIFT
1443 #define AS ANGLE_SHIFT
1444 #define NB NUM_CP_BUCKETS
1445 {
1446  float Angle;
1447  float X, Y, HalfLength;
1448  float Cos, Sin;
1449  float XAdjust, YAdjust;
1450  FPOINT Start, Switch1, Switch2, End;
1451  int S1 = 0;
1452  int S2 = 1;
1453 
1454  Angle = Proto->Angle;
1455  X = Proto->X;
1456  Y = Proto->Y;
1457  HalfLength = Proto->Length / 2.0;
1458 
1459  Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
1460  Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
1461  Filler->NextSwitch = 0;
1462 
1463  if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
1464  /* horizontal proto - handle as special case */
1465  Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
1466  Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
1467  Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
1468  Filler->StartDelta = 0;
1469  Filler->EndDelta = 0;
1470  Filler->Switch[0].Type = LastSwitch;
1471  Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
1472  } else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
1473  fabs(Angle - 0.75) < HV_TOLERANCE) {
1474  /* vertical proto - handle as special case */
1475  Filler->X = Bucket8For(X - SidePad, XS, NB);
1476  Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
1477  Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
1478  Filler->StartDelta = 0;
1479  Filler->EndDelta = 0;
1480  Filler->Switch[0].Type = LastSwitch;
1481  Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
1482  } else {
1483  /* diagonal proto */
1484 
1485  if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1486  /* rising diagonal proto */
1487  Angle *= 2.0 * M_PI;
1488  Cos = fabs(cos(Angle));
1489  Sin = fabs(sin(Angle));
1490 
1491  /* compute the positions of the corners of the acceptance region */
1492  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1493  Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1494  End.x = 2.0 * X - Start.x;
1495  End.y = 2.0 * Y - Start.y;
1496  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1497  Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1498  Switch2.x = 2.0 * X - Switch1.x;
1499  Switch2.y = 2.0 * Y - Switch1.y;
1500 
1501  if (Switch1.x > Switch2.x) {
1502  S1 = 1;
1503  S2 = 0;
1504  }
1505 
1506  /* translate into bucket positions and deltas */
1507  Filler->X = Bucket8For(Start.x, XS, NB);
1508  Filler->StartDelta = -static_cast<int16_t>((Cos / Sin) * 256);
1509  Filler->EndDelta = static_cast<int16_t>((Sin / Cos) * 256);
1510 
1511  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1512  YAdjust = XAdjust * Cos / Sin;
1513  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1514  YAdjust = XAdjust * Sin / Cos;
1515  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1516 
1517  Filler->Switch[S1].Type = StartSwitch;
1518  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1519  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1520  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1521  YAdjust = XAdjust * Sin / Cos;
1522  Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
1523  Filler->Switch[S1].Delta = Filler->EndDelta;
1524 
1525  Filler->Switch[S2].Type = EndSwitch;
1526  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1527  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1528  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1529  YAdjust = XAdjust * Cos / Sin;
1530  Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
1531  Filler->Switch[S2].Delta = Filler->StartDelta;
1532 
1533  Filler->Switch[2].Type = LastSwitch;
1534  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1535  } else {
1536  /* falling diagonal proto */
1537  Angle *= 2.0 * M_PI;
1538  Cos = fabs(cos(Angle));
1539  Sin = fabs(sin(Angle));
1540 
1541  /* compute the positions of the corners of the acceptance region */
1542  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1543  Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1544  End.x = 2.0 * X - Start.x;
1545  End.y = 2.0 * Y - Start.y;
1546  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1547  Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1548  Switch2.x = 2.0 * X - Switch1.x;
1549  Switch2.y = 2.0 * Y - Switch1.y;
1550 
1551  if (Switch1.x > Switch2.x) {
1552  S1 = 1;
1553  S2 = 0;
1554  }
1555 
1556  /* translate into bucket positions and deltas */
1557  Filler->X = Bucket8For(Start.x, XS, NB);
1558  Filler->StartDelta = static_cast<int16_t>(ClipToRange<int>(
1559  -IntCastRounded((Sin / Cos) * 256), INT16_MIN, INT16_MAX));
1560  Filler->EndDelta = static_cast<int16_t>(ClipToRange<int>(
1561  IntCastRounded((Cos / Sin) * 256), INT16_MIN, INT16_MAX));
1562 
1563  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1564  YAdjust = XAdjust * Sin / Cos;
1565  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1566  YAdjust = XAdjust * Cos / Sin;
1567  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1568 
1569  Filler->Switch[S1].Type = EndSwitch;
1570  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1571  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1572  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1573  YAdjust = XAdjust * Sin / Cos;
1574  Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
1575  Filler->Switch[S1].Delta = Filler->StartDelta;
1576 
1577  Filler->Switch[S2].Type = StartSwitch;
1578  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1579  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1580  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1581  YAdjust = XAdjust * Cos / Sin;
1582  Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
1583  Filler->Switch[S2].Delta = Filler->EndDelta;
1584 
1585  Filler->Switch[2].Type = LastSwitch;
1586  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1587  }
1588  }
1589 } /* InitTableFiller */
1590 
1591 
1592 /*---------------------------------------------------------------------------*/
1593 #ifndef GRAPHICS_DISABLED
1594 
1602 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
1603  ScrollView::Color color) {
1604  float X, Y, Dx, Dy, Length;
1605 
1606  window->Pen(color);
1607  assert(Feature != nullptr);
1608  assert(color != 0);
1609 
1610  X = Feature->X;
1611  Y = Feature->Y;
1612  Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
1613  // The -PI has no significant effect here, but the value of Theta is computed
1614  // using BinaryAnglePlusPi in intfx.cpp.
1615  Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1616  Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1617 
1618  window->SetCursor(X, Y);
1619  window->DrawTo(X + Dx, Y + Dy);
1620 } /* RenderIntFeature */
1621 
1637  INT_CLASS Class,
1638  PROTO_ID ProtoId,
1639  ScrollView::Color color) {
1640  PROTO_SET ProtoSet;
1641  INT_PROTO Proto;
1642  int ProtoSetIndex;
1643  int ProtoWordIndex;
1644  float Length;
1645  int Xmin, Xmax, Ymin, Ymax;
1646  float X, Y, Dx, Dy;
1647  uint32_t ProtoMask;
1648  int Bucket;
1649 
1650  assert(ProtoId >= 0);
1651  assert(Class != nullptr);
1652  assert(ProtoId < Class->NumProtos);
1653  assert(color != 0);
1654  window->Pen(color);
1655 
1656  ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
1657  ProtoSetIndex = IndexForProto(ProtoId);
1658  Proto = &(ProtoSet->Protos[ProtoSetIndex]);
1659  Length = (Class->ProtoLengths[ProtoId] *
1661  ProtoMask = PPrunerMaskFor(ProtoId);
1662  ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
1663 
1664  // find the x and y extent of the proto from the proto pruning table
1665  Xmin = Ymin = NUM_PP_BUCKETS;
1666  Xmax = Ymax = 0;
1667  for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
1668  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
1669  UpdateRange(Bucket, &Xmin, &Xmax);
1670  }
1671 
1672  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
1673  UpdateRange(Bucket, &Ymin, &Ymax);
1674  }
1675  }
1676  X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1677  Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1678  // The -PI has no significant effect here, but the value of Theta is computed
1679  // using BinaryAnglePlusPi in intfx.cpp.
1680  Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1681  Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1682 
1683  window->SetCursor(X - Dx, Y - Dy);
1684  window->DrawTo(X + Dx, Y + Dy);
1685 } /* RenderIntProto */
1686 #endif
1687 
1701 int TruncateParam(float Param, int Min, int Max, char *Id) {
1702  if (Param < Min) {
1703  if (Id)
1704  cprintf("Warning: Param %s truncated from %f to %d!\n",
1705  Id, Param, Min);
1706  Param = Min;
1707  } else if (Param > Max) {
1708  if (Id)
1709  cprintf("Warning: Param %s truncated from %f to %d!\n",
1710  Id, Param, Max);
1711  Param = Max;
1712  }
1713  return static_cast<int>(std::floor(Param));
1714 } /* TruncateParam */
1715 
1716 
1717 #ifndef GRAPHICS_DISABLED
1718 
1723  if (IntMatchWindow == nullptr) {
1724  IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
1725  auto* popup_menu = new SVMenuNode();
1726 
1727  popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
1728  "x", "Class to debug");
1729  popup_menu->AddChild("Debug Static classes", IDA_STATIC,
1730  "x", "Class to debug");
1731  popup_menu->AddChild("Debug Both", IDA_BOTH,
1732  "x", "Class to debug");
1733  popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
1734  "0", "Index to debug");
1735  popup_menu->BuildMenu(IntMatchWindow, false);
1736  }
1737 }
1738 
1744  if (ProtoDisplayWindow == nullptr) {
1745  ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
1746  550, 200);
1747  }
1748 }
1749 
1755  if (FeatureDisplayWindow == nullptr) {
1756  FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
1757  50, 700);
1758  }
1759 }
1760 
1763 ScrollView* CreateFeatureSpaceWindow(const char* name, int xpos, int ypos) {
1764  return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
1765 }
1766 #endif // GRAPHICS_DISABLED
IntCastRounded
int IntCastRounded(double x)
Definition: helpers.h:175
test_bit
#define test_bit(array, bit)
Definition: bitvec.h:59
FCOORD
Definition: points.h:189
PROTO_STRUCT::C
float C
Definition: protos.h:39
tesseract::Classify::shape_table_
ShapeTable * shape_table_
Definition: classify.h:546
FILL_SPEC::AngleEnd
uint8_t AngleEnd
Definition: intproto.cpp:100
tesseract::read_set
bool read_set(TFile *f, FontSet *fs)
Definition: fontinfo.cpp:226
TABLE_FILLER::YEnd
int16_t YEnd
Definition: intproto.cpp:88
PROTOS_PER_PROTO_SET
#define PROTOS_PER_PROTO_SET
Definition: intproto.h:49
BucketStart
float BucketStart(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1092
FILL_SPEC
Definition: intproto.cpp:97
shapetable.h
INT_CLASS_STRUCT::font_set_id
int font_set_id
Definition: intproto.h:112
ProtoIn
#define ProtoIn(Class, Pid)
Definition: protos.h:84
UNICHARSET::size
int size() const
Definition: unicharset.h:341
tesseract::write_set
bool write_set(FILE *f, const FontSet &fs)
Definition: fontinfo.cpp:232
TruncateParam
int TruncateParam(float Param, int Min, int Max, char *Id)
Definition: intproto.cpp:1701
INT_CLASS_STRUCT::ConfigLengths
uint16_t ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:111
FILL_SPEC::AngleStart
uint8_t AngleStart
Definition: intproto.cpp:100
MAX_NUM_CLASSES
#define MAX_NUM_CLASSES
Definition: matchdefs.h:30
MAX_NUM_CONFIGS
#define MAX_NUM_CONFIGS
Definition: intproto.h:47
tesseract::Classify::GetClassToDebug
CLASS_ID GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on, int *shape_id)
Definition: intproto.cpp:1255
STRING::string
const char * string() const
Definition: strngs.cpp:194
emalloc.h
INT_CLASS_STRUCT::ProtoSets
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
Definition: intproto.h:109
InitProtoDisplayWindowIfReqd
void InitProtoDisplayWindowIfReqd()
Definition: intproto.cpp:1743
Efree
void Efree(void *ptr)
Definition: emalloc.cpp:45
MaxNumIntProtosIn
#define MaxNumIntProtosIn(C)
Definition: intproto.h:165
AddProtoToClassPruner
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
Definition: intproto.cpp:328
EndSwitch
@ EndSwitch
Definition: intproto.cpp:68
GetPicoFeatureLength
#define GetPicoFeatureLength()
Definition: picofeat.h:57
MAX_LEVEL
#define MAX_LEVEL
callcpp.h
INT_XRADIUS
#define INT_XRADIUS
Definition: intproto.cpp:57
TABLE_FILLER::AngleEnd
uint8_t AngleEnd
Definition: intproto.cpp:86
INT_TEMPLATES_STRUCT::ClassPruners
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
Definition: intproto.h:122
INT_PROTO_STRUCT::C
int8_t C
Definition: intproto.h:84
PRUNER_ANGLE
#define PRUNER_ANGLE
Definition: intproto.h:37
INT_MAX_X
#define INT_MAX_X
Definition: intproto.cpp:61
NB
#define NB
INT_CLASS_STRUCT::NumProtos
uint16_t NumProtos
Definition: intproto.h:106
DisplayIntProto
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, float Evidence)
Definition: intproto.cpp:608
FillPPCircularBits
void FillPPCircularBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1184
MAX_NUM_CLASS_PRUNERS
#define MAX_NUM_CLASS_PRUNERS
Definition: intproto.h:60
IDA_STATIC
@ IDA_STATIC
Definition: intproto.h:156
UnusedClassIdIn
#define UnusedClassIdIn(T, c)
Definition: intproto.h:177
BIT_VECTOR
uint32_t * BIT_VECTOR
Definition: bitvec.h:28
TABLE_FILLER::AngleStart
uint8_t AngleStart
Definition: intproto.cpp:86
NUM_PP_PARAMS
#define NUM_PP_PARAMS
Definition: intproto.h:51
INT_YRADIUS
#define INT_YRADIUS
Definition: intproto.cpp:58
picofeat.h
TABLE_FILLER::StartDelta
int16_t StartDelta
Definition: intproto.cpp:89
ScrollView::Pen
void Pen(Color color)
Definition: scrollview.cpp:719
AddIntProto
int AddIntProto(INT_CLASS Class)
Definition: intproto.cpp:282
AddIntConfig
int AddIntConfig(INT_CLASS Class)
Definition: intproto.cpp:261
tesseract::Param
Definition: params.h:125
tesseract::write_spacing_info
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:198
CPrunerMaskFor
#define CPrunerMaskFor(L, c)
Definition: intproto.h:184
FPOINT::x
float x
Definition: fpoint.h:46
tesseract::write_info
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:163
INT_DESCENDER
#define INT_DESCENDER
Definition: intproto.cpp:50
UNICHARSET::id_to_unichar
const char * id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:291
SVEventType
SVEventType
Definition: scrollview.h:45
INT_CLASS_STRUCT
Definition: intproto.h:105
TABLE_FILLER::YStart
int16_t YStart
Definition: intproto.cpp:88
INT_MAX_Y
#define INT_MAX_Y
Definition: intproto.cpp:62
MAX_NUM_PROTOS
#define MAX_NUM_PROTOS
Definition: intproto.h:48
tesseract
Definition: altorenderer.cpp:25
tesseract::File
Definition: fileio.h:57
SVEvent::parameter
char * parameter
Definition: scrollview.h:66
TABLE_FILLER::X
int8_t X
Definition: intproto.cpp:87
NUM_BITS_PER_CLASS
#define NUM_BITS_PER_CLASS
Definition: intproto.h:55
tesseract::Shape::ContainsUnichar
bool ContainsUnichar(int unichar_id) const
Definition: shapetable.cpp:147
SVMenuNode
Definition: svmnode.h:35
INT_TEMPLATES_STRUCT::NumClasses
int NumClasses
Definition: intproto.h:119
SVEvent::type
SVEventType type
Definition: scrollview.h:64
FILL_SWITCH::YInit
int16_t YInit
Definition: intproto.cpp:76
ScrollView::AwaitEvent
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:443
cprintf
void cprintf(const char *format,...)
Definition: callcpp.cpp:32
LegalClassId
#define LegalClassId(c)
Definition: intproto.h:176
HV_TOLERANCE
#define HV_TOLERANCE
Definition: intproto.cpp:65
PRUNER_X
#define PRUNER_X
Definition: intproto.h:35
Bucket16For
uint16_t Bucket16For(float param, float offset, int num_buckets)
Definition: intproto.cpp:422
ProtoForProtoId
#define ProtoForProtoId(C, P)
Definition: intproto.h:168
INT_PROTO_STRUCT
Definition: intproto.h:81
tesseract::read_spacing_info
bool read_spacing_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:170
YS
#define YS
OLD_MAX_NUM_CONFIGS
#define OLD_MAX_NUM_CONFIGS
Definition: intproto.cpp:108
tesseract::Classify::classify_norm_method
int classify_norm_method
Definition: classify.h:434
NO_PROTO
#define NO_PROTO
Definition: matchdefs.h:41
DisplayIntFeature
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, float Evidence)
Definition: intproto.cpp:590
INT_PROTO_STRUCT::Configs
uint32_t Configs[WERDS_PER_CONFIG_VEC]
Definition: intproto.h:86
StartSwitch
@ StartSwitch
Definition: intproto.cpp:68
ClipToRange
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:108
PROTO_SET_STRUCT::Protos
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
Definition: intproto.h:97
CPrunerBitIndexFor
#define CPrunerBitIndexFor(c)
Definition: intproto.h:183
TABLE_FILLER
Definition: intproto.cpp:84
INT_TEMPLATES_STRUCT::NumClassPruners
int NumClassPruners
Definition: intproto.h:120
PROTO_STRUCT::Y
float Y
Definition: protos.h:41
INT_CLASS_STRUCT::NumProtoSets
uint8_t NumProtoSets
Definition: intproto.h:107
INT_PROTO_STRUCT::A
int8_t A
Definition: intproto.h:82
genericvector.h
tesseract::Classify::fontset_table_
UnicityTable< FontSet > fontset_table_
Definition: classify.h:537
INT_FEATURE_STRUCT
Definition: intproto.h:132
tprintf
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:35
UnicityTable::get
const T & get(int id) const
Return the object from an id.
Definition: unicity_table.h:132
tesseract::FontSet::configs
int * configs
Definition: fontinfo.h:139
INT_PROTO_STRUCT::B
uint8_t B
Definition: intproto.h:83
PROTO_SET_STRUCT
Definition: intproto.h:95
IDA_BOTH
@ IDA_BOTH
Definition: intproto.h:158
UNICHARSET::unichar_to_id
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:210
UNICHARSET::contains_unichar
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:671
XS
#define XS
ASSERT_HOST
#define ASSERT_HOST(x)
Definition: errcode.h:88
PROTO_STRUCT::Length
float Length
Definition: protos.h:43
ScrollView
Definition: scrollview.h:98
ScrollView::ZoomToRectangle
void ZoomToRectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:757
AddIntClass
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
Definition: intproto.cpp:231
WERDS_PER_CP_VECTOR
#define WERDS_PER_CP_VECTOR
Definition: intproto.h:62
PPrunerMaskFor
#define PPrunerMaskFor(I)
Definition: intproto.h:173
TABLE_FILLER::Switch
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
Definition: intproto.cpp:90
ScrollView::Update
static void Update()
Definition: scrollview.cpp:709
INT_FEATURE_STRUCT::Theta
uint8_t Theta
Definition: intproto.h:142
CLASS_STRUCT::Configurations
CONFIGS Configurations
Definition: protos.h:60
INT_PROTO_STRUCT::Angle
uint8_t Angle
Definition: intproto.h:85
PROTO_STRUCT::B
float B
Definition: protos.h:38
Erealloc
void * Erealloc(void *ptr, int size)
Definition: emalloc.cpp:38
INT_MIN_X
#define INT_MIN_X
Definition: intproto.cpp:59
INT_CHAR_NORM_RANGE
#define INT_CHAR_NORM_RANGE
Definition: intproto.h:130
CLASS_PRUNER_STRUCT
Definition: intproto.h:76
UpdateRange
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:120
INT_CLASS_STRUCT::NumConfigs
uint8_t NumConfigs
Definition: intproto.h:108
MapParam
#define MapParam(P, O, N)
Definition: intproto.cpp:119
WERDS_PER_PP_VECTOR
#define WERDS_PER_PP_VECTOR
Definition: intproto.h:63
AS
#define AS
SVET_CLICK
@ SVET_CLICK
Definition: scrollview.h:48
FILL_SWITCH
Definition: intproto.cpp:73
IDA_ADAPTIVE
@ IDA_ADAPTIVE
Definition: intproto.h:155
tesstrain_utils.int
int
Definition: tesstrain_utils.py:154
LastSwitch
@ LastSwitch
Definition: intproto.cpp:68
SVEvent
Definition: scrollview.h:61
helpers.h
CLASS_STRUCT::font_set
UnicityTableEqEq< int > font_set
Definition: protos.h:61
NewIntTemplates
INT_TEMPLATES NewIntTemplates()
Definition: intproto.cpp:682
tesseract::Classify::ShowMatchDisplay
void ShowMatchDisplay()
Definition: intproto.cpp:962
ScrollView::GREY
@ GREY
Definition: scrollview.h:134
tesseract::FontSet::size
int size
Definition: fontinfo.h:138
PROTO_SET_STRUCT::ProtoPruner
PROTO_PRUNER ProtoPruner
Definition: intproto.h:96
FILL_SPEC::X
int8_t X
Definition: intproto.cpp:98
GetCPPadsForLevel
void GetCPPadsForLevel(int Level, float *EndPad, float *SidePad, float *AnglePad)
Definition: intproto.cpp:1331
FillPPLinearBits
void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1223
PROTO_STRUCT::X
float X
Definition: protos.h:40
NewPermanentTessCallback
_ConstTessMemberResultCallback_5_0< false, R, T1, P1, P2, P3, P4, P5 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)(P1, P2, P3, P4, P5) const, typename Identity< P1 >::type p1, typename Identity< P2 >::type p2, typename Identity< P3 >::type p3, typename Identity< P4 >::type p4, typename Identity< P5 >::type p5)
Definition: tesscallback.h:258
CPrunerIdFor
#define CPrunerIdFor(c)
Definition: intproto.h:180
tesseract::Classify::ReadIntTemplates
INT_TEMPLATES ReadIntTemplates(TFile *fp)
Definition: intproto.cpp:718
CircBucketFor
uint8_t CircBucketFor(float param, float offset, int num_buckets)
Definition: intproto.cpp:432
InitIntMatchWindowIfReqd
void InitIntMatchWindowIfReqd()
Definition: intproto.cpp:1722
ScrollView::Color
Color
Definition: scrollview.h:101
ScrollView::Rectangle
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:600
tesseract::FontSet
Definition: fontinfo.h:137
IDA_SHAPE_INDEX
@ IDA_SHAPE_INDEX
Definition: intproto.h:157
tesseract::CCUtil::unicharset
UNICHARSET unicharset
Definition: ccutil.h:73
SWITCH_TYPE
SWITCH_TYPE
Definition: intproto.cpp:68
tesseract::TFile::FRead
int FRead(void *buffer, size_t size, int count)
Definition: serialis.cpp:288
Y_SHIFT
#define Y_SHIFT
Definition: intproto.h:42
tesseract::ShapeTable::NumShapes
int NumShapes() const
Definition: shapetable.h:274
FillerDone
bool FillerDone(TABLE_FILLER *Filler)
Definition: intproto.cpp:1162
NewIntClass
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
Definition: intproto.cpp:626
CircularIncrement
#define CircularIncrement(i, r)
Definition: intproto.cpp:116
INT_XHEIGHT
#define INT_XHEIGHT
Definition: intproto.cpp:52
ScrollView::BLUE
@ BLUE
Definition: scrollview.h:109
CreateFeatureSpaceWindow
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1763
IndexForProto
#define IndexForProto(P)
Definition: intproto.h:167
tesseract::ShapeTable::DebugStr
STRING DebugStr(int shape_id) const
Definition: shapetable.cpp:281
RenderIntProto
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
Definition: intproto.cpp:1636
NUM_CP_BUCKETS
#define NUM_CP_BUCKETS
Definition: intproto.h:53
BITS_PER_CP_VECTOR
#define BITS_PER_CP_VECTOR
Definition: intproto.h:59
INT_FEATURE_STRUCT::X
uint8_t X
Definition: intproto.h:140
BITS_PER_WERD
#define BITS_PER_WERD
Definition: intproto.h:45
intproto.h
InitTableFiller
void InitTableFiller(float EndPad, float SidePad, float AnglePad, PROTO Proto, TABLE_FILLER *Filler)
Definition: intproto.cpp:1439
NORM_METHOD
NORM_METHOD
Definition: mfoutline.h:63
FILL_SPEC::YStart
int8_t YStart
Definition: intproto.cpp:99
tesseract::Classify::CreateIntTemplates
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:527
FILL_SWITCH::Type
SWITCH_TYPE Type
Definition: intproto.cpp:74
svmnode.h
INT_XCENTER
#define INT_XCENTER
Definition: intproto.cpp:55
CLASS_STRUCT
Definition: protos.h:47
SET_BIT
#define SET_BIT(array, bit)
Definition: bitvec.h:55
ANGLE_SHIFT
#define ANGLE_SHIFT
Definition: intproto.h:40
FILL_SWITCH::Y
int8_t Y
Definition: intproto.cpp:75
GetMatchColorFor
ScrollView::Color GetMatchColorFor(float Evidence)
Definition: intproto.cpp:1370
FPOINT::y
float y
Definition: fpoint.h:46
baseline
@ baseline
Definition: mfoutline.h:63
INT_FEATURE_STRUCT::Y
uint8_t Y
Definition: intproto.h:141
Bucket8For
uint8_t Bucket8For(float param, float offset, int num_buckets)
Definition: intproto.cpp:418
tesseract::ShapeTable::GetShape
const Shape & GetShape(int shape_id) const
Definition: shapetable.h:319
INT_CLASS_STRUCT::ProtoLengths
uint8_t * ProtoLengths
Definition: intproto.h:110
CPrunerWordIndexFor
#define CPrunerWordIndexFor(c)
Definition: intproto.h:182
fontinfo.h
PROTO_STRUCT::A
float A
Definition: protos.h:37
AddProtoToProtoPruner
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
Definition: intproto.cpp:367
classify.h
BucketEnd
float BucketEnd(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1108
FILL_SPEC::YEnd
int8_t YEnd
Definition: intproto.cpp:99
OLD_WERDS_PER_CONFIG_VEC
#define OLD_WERDS_PER_CONFIG_VEC
Definition: intproto.cpp:109
UpdateMatchDisplay
void UpdateMatchDisplay()
Definition: intproto.cpp:447
Emalloc
void * Emalloc(int Size)
Definition: emalloc.cpp:31
SVET_POPUP
@ SVET_POPUP
Definition: scrollview.h:54
FPOINT
Definition: fpoint.h:29
UnicityTable::size
int size() const
Return the size used.
Definition: unicity_table.h:119
tesseract::Classify::ConvertProto
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class)
Definition: intproto.cpp:488
PROTO_ID
int16_t PROTO_ID
Definition: matchdefs.h:40
TABLE_FILLER::NextSwitch
uint8_t NextSwitch
Definition: intproto.cpp:85
CLASS_STRUCT::NumConfigs
int16_t NumConfigs
Definition: protos.h:58
INT_BASELINE
#define INT_BASELINE
Definition: intproto.cpp:51
free_int_templates
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:698
ConvertConfig
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
Definition: intproto.cpp:463
X_SHIFT
#define X_SHIFT
Definition: intproto.h:41
Modulo
int Modulo(int a, int b)
Definition: helpers.h:158
ScrollView::GREEN
@ GREEN
Definition: scrollview.h:107
WERDS_PER_CONFIG_VEC
#define WERDS_PER_CONFIG_VEC
Definition: intproto.h:68
tesseract::read_info
bool read_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:153
PROTO_PRUNER_SCALE
#define PROTO_PRUNER_SCALE
Definition: intproto.cpp:48
MaxNumClassesIn
#define MaxNumClassesIn(T)
Definition: intproto.h:175
tesseract::ShapeTable::GetFirstUnicharAndFont
void GetFirstUnicharAndFont(int shape_id, int *unichar_id, int *font_id) const
Definition: shapetable.cpp:404
TABLE_FILLER::EndDelta
int16_t EndDelta
Definition: intproto.cpp:89
tesseract::TFile::FReadEndian
int FReadEndian(void *buffer, size_t size, int count)
Definition: serialis.cpp:277
SVEvent::command_id
int command_id
Definition: scrollview.h:71
mfoutline.h
PROTO_STRUCT
Definition: protos.h:36
DoFill
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, uint32_t ClassMask, uint32_t ClassCount, uint32_t WordIndex)
Definition: intproto.cpp:1122
PPrunerWordIndexFor
#define PPrunerWordIndexFor(I)
Definition: intproto.h:170
tesseract::Classify::WriteIntTemplates
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:1017
FILL_SWITCH::X
int8_t X
Definition: intproto.cpp:75
FILL_SWITCH::Delta
int16_t Delta
Definition: intproto.cpp:77
NUM_PP_BUCKETS
#define NUM_PP_BUCKETS
Definition: intproto.h:52
CLASS_STRUCT::NumProtos
int16_t NumProtos
Definition: protos.h:55
MAX_NUM_PROTO_SETS
#define MAX_NUM_PROTO_SETS
Definition: intproto.h:50
ScrollView::DrawTo
void DrawTo(int x, int y)
Definition: scrollview.cpp:525
points.h
INT_CAPHEIGHT
#define INT_CAPHEIGHT
Definition: intproto.cpp:53
CLASS_ID
UNICHAR_ID CLASS_ID
Definition: matchdefs.h:34
INT_MIN_Y
#define INT_MIN_Y
Definition: intproto.cpp:60
GetNextFill
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
Definition: intproto.cpp:1392
PRUNER_Y
#define PRUNER_Y
Definition: intproto.h:36
SetForProto
#define SetForProto(P)
Definition: intproto.h:166
tesseract::Classify::fontinfo_table_
UnicityTable< FontInfo > fontinfo_table_
Definition: classify.h:529
MAX_NUM_SWITCHES
#define MAX_NUM_SWITCHES
Definition: intproto.cpp:70
ClassForClassId
#define ClassForClassId(T, c)
Definition: intproto.h:178
INT_YCENTER
#define INT_YCENTER
Definition: intproto.cpp:56
tesseract::ClearFeatureSpaceWindow
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:987
RenderIntFeature
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1602
double_VAR
#define double_VAR(name, val, comment)
Definition: params.h:312
ScrollView::Clear
void Clear()
Definition: scrollview.cpp:589
INT_FEATURE_STRUCT::INT_FEATURE_STRUCT
INT_FEATURE_STRUCT()
Definition: intproto.h:133
INT_TEMPLATES_STRUCT
Definition: intproto.h:118
SVET_ANY
@ SVET_ANY
Definition: scrollview.h:56
tesseract::TFile
Definition: serialis.h:76
ScrollView::SetCursor
void SetCursor(int x, int y)
Definition: scrollview.cpp:519
UNICHARSET
Definition: unicharset.h:145
CLASS_PRUNER_STRUCT::p
uint32_t p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
Definition: intproto.h:78
ScrollView::WHITE
@ WHITE
Definition: scrollview.h:104
tesseract::Classify::classify_learning_debug_level
int classify_learning_debug_level
Definition: classify.h:455
CPrunerFor
#define CPrunerFor(T, c)
Definition: intproto.h:181
InitFeatureDisplayWindowIfReqd
void InitFeatureDisplayWindowIfReqd()
Definition: intproto.cpp:1754
PROTO_STRUCT::Angle
float Angle
Definition: protos.h:42
INT_TEMPLATES_STRUCT::Class
INT_CLASS Class[MAX_NUM_CLASSES]
Definition: intproto.h:121
Config
CLUSTERCONFIG Config
Definition: commontraining.cpp:88
ScrollView::RED
@ RED
Definition: scrollview.h:105
INT_VAR
#define INT_VAR(name, val, comment)
Definition: params.h:303