tesseract  5.0.0-alpha-619-ge9db
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"
32 #include <tesseract/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 -----------------------------------------------------------------------------*/
206 INT_FEATURE_STRUCT::INT_FEATURE_STRUCT(const FCOORD& pos, uint8_t theta)
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 }
213 INT_FEATURE_STRUCT::INT_FEATURE_STRUCT(int x, int y, int theta)
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 
261 int AddIntConfig(INT_CLASS Class) {
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 
447 void UpdateMatchDisplay() {
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 /*---------------------------------------------------------------------------*/
698 void free_int_templates(INT_TEMPLATES templates) {
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) {
936  using namespace std::placeholders; // for _1, _2
937  this->fontinfo_table_.read(fp, std::bind(read_info, _1, _2));
938  if (version_id >= 5) {
939  this->fontinfo_table_.read(fp,
940  std::bind(read_spacing_info, _1, _2));
941  }
942  this->fontset_table_.read(fp, std::bind(read_set, _1, _2));
943  }
944 
945  // Clean up.
946  delete[] IndexFor;
947  delete[] ClassIdFor;
948  delete[] TempClassPruner;
949 
950  return (Templates);
951 } /* ReadIntTemplates */
952 
953 
954 #ifndef GRAPHICS_DISABLED
955 
965  if (ProtoDisplayWindow) {
966  ProtoDisplayWindow->Clear();
967  }
968  if (FeatureDisplayWindow) {
969  FeatureDisplayWindow->Clear();
970  }
972  static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
973  IntMatchWindow);
974  IntMatchWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
976  if (ProtoDisplayWindow) {
977  ProtoDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
979  }
980  if (FeatureDisplayWindow) {
981  FeatureDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
983  }
984 } /* ShowMatchDisplay */
985 
988 void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView* window) {
989  window->Clear();
990 
991  window->Pen(ScrollView::GREY);
992  // Draw the feature space limit rectangle.
993  window->Rectangle(0, 0, INT_MAX_X, INT_MAX_Y);
994  if (norm_method == baseline) {
995  window->SetCursor(0, INT_DESCENDER);
996  window->DrawTo(INT_MAX_X, INT_DESCENDER);
997  window->SetCursor(0, INT_BASELINE);
998  window->DrawTo(INT_MAX_X, INT_BASELINE);
999  window->SetCursor(0, INT_XHEIGHT);
1000  window->DrawTo(INT_MAX_X, INT_XHEIGHT);
1001  window->SetCursor(0, INT_CAPHEIGHT);
1002  window->DrawTo(INT_MAX_X, INT_CAPHEIGHT);
1003  } else {
1006  }
1007 }
1008 #endif
1009 
1018 void Classify::WriteIntTemplates(FILE *File, INT_TEMPLATES Templates,
1019  const UNICHARSET& target_unicharset) {
1020  int i, j;
1021  INT_CLASS Class;
1022  int unicharset_size = target_unicharset.size();
1023  int version_id = -5; // When negated by the reader -1 becomes +1 etc.
1024 
1025  if (Templates->NumClasses != unicharset_size) {
1026  cprintf("Warning: executing WriteIntTemplates() with %d classes in"
1027  " Templates, while target_unicharset size is %d\n",
1028  Templates->NumClasses, unicharset_size);
1029  }
1030 
1031  /* first write the high level template struct */
1032  fwrite(&unicharset_size, sizeof(unicharset_size), 1, File);
1033  fwrite(&version_id, sizeof(version_id), 1, File);
1034  fwrite(&Templates->NumClassPruners, sizeof(Templates->NumClassPruners),
1035  1, File);
1036  fwrite(&Templates->NumClasses, sizeof(Templates->NumClasses), 1, File);
1037 
1038  /* then write out the class pruners */
1039  for (i = 0; i < Templates->NumClassPruners; i++)
1040  fwrite(Templates->ClassPruners[i],
1041  sizeof(CLASS_PRUNER_STRUCT), 1, File);
1042 
1043  /* then write out each class */
1044  for (i = 0; i < Templates->NumClasses; i++) {
1045  Class = Templates->Class[i];
1046 
1047  /* first write out the high level struct for the class */
1048  fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
1049  fwrite(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File);
1050  ASSERT_HOST(Class->NumConfigs == this->fontset_table_.get(Class->font_set_id).size);
1051  fwrite(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File);
1052  for (j = 0; j < Class->NumConfigs; ++j) {
1053  fwrite(&Class->ConfigLengths[j], sizeof(uint16_t), 1, File);
1054  }
1055 
1056  /* then write out the proto lengths */
1057  if (MaxNumIntProtosIn (Class) > 0) {
1058  fwrite(Class->ProtoLengths, sizeof(uint8_t),
1059  MaxNumIntProtosIn(Class), File);
1060  }
1061 
1062  /* then write out the proto sets */
1063  for (j = 0; j < Class->NumProtoSets; j++)
1064  fwrite(Class->ProtoSets[j], sizeof(PROTO_SET_STRUCT), 1, File);
1065 
1066  /* then write the fonts info */
1067  fwrite(&Class->font_set_id, sizeof(int), 1, File);
1068  }
1069 
1070  /* Write the fonts info tables */
1071  using namespace std::placeholders; // for _1, _2
1072  this->fontinfo_table_.write(File, std::bind(write_info, _1, _2));
1073  this->fontinfo_table_.write(File,
1074  std::bind(write_spacing_info, _1, _2));
1075  this->fontset_table_.write(File, std::bind(write_set, _1, _2));
1076 } /* WriteIntTemplates */
1077 } // namespace tesseract
1078 
1079 
1080 /*-----------------------------------------------------------------------------
1081  Private Code
1082 -----------------------------------------------------------------------------*/
1094 float BucketStart(int Bucket, float Offset, int NumBuckets) {
1095  return ((static_cast<float>(Bucket) / NumBuckets) - Offset);
1096 
1097 } /* BucketStart */
1098 
1110 float BucketEnd(int Bucket, float Offset, int NumBuckets) {
1111  return ((static_cast<float>(Bucket + 1) / NumBuckets) - Offset);
1112 } /* BucketEnd */
1113 
1124 void DoFill(FILL_SPEC *FillSpec,
1125  CLASS_PRUNER_STRUCT* Pruner,
1126  uint32_t ClassMask,
1127  uint32_t ClassCount,
1128  uint32_t WordIndex) {
1129  int X, Y, Angle;
1130  uint32_t OldWord;
1131 
1132  X = FillSpec->X;
1133  if (X < 0)
1134  X = 0;
1135  if (X >= NUM_CP_BUCKETS)
1136  X = NUM_CP_BUCKETS - 1;
1137 
1138  if (FillSpec->YStart < 0)
1139  FillSpec->YStart = 0;
1140  if (FillSpec->YEnd >= NUM_CP_BUCKETS)
1141  FillSpec->YEnd = NUM_CP_BUCKETS - 1;
1142 
1143  for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
1144  for (Angle = FillSpec->AngleStart; ;
1146  OldWord = Pruner->p[X][Y][Angle][WordIndex];
1147  if (ClassCount > (OldWord & ClassMask)) {
1148  OldWord &= ~ClassMask;
1149  OldWord |= ClassCount;
1150  Pruner->p[X][Y][Angle][WordIndex] = OldWord;
1151  }
1152  if (Angle == FillSpec->AngleEnd)
1153  break;
1154  }
1155 } /* DoFill */
1156 
1164 bool FillerDone(TABLE_FILLER* Filler) {
1165  FILL_SWITCH *Next;
1166 
1167  Next = &(Filler->Switch[Filler->NextSwitch]);
1168 
1169  return Filler->X > Next->X && Next->Type == LastSwitch;
1170 
1171 } /* FillerDone */
1172 
1186 void FillPPCircularBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
1187  int Bit, float Center, float Spread, bool debug) {
1188  int i, FirstBucket, LastBucket;
1189 
1190  if (Spread > 0.5)
1191  Spread = 0.5;
1192 
1193  FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1194  if (FirstBucket < 0)
1195  FirstBucket += NUM_PP_BUCKETS;
1196 
1197  LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1198  if (LastBucket >= NUM_PP_BUCKETS)
1199  LastBucket -= NUM_PP_BUCKETS;
1200  if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
1201  for (i = FirstBucket; true; CircularIncrement (i, NUM_PP_BUCKETS)) {
1202  SET_BIT (ParamTable[i], Bit);
1203 
1204  /* exit loop after we have set the bit for the last bucket */
1205  if (i == LastBucket)
1206  break;
1207  }
1208 
1209 } /* FillPPCircularBits */
1210 
1225 void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
1226  int Bit, float Center, float Spread, bool debug) {
1227  int i, FirstBucket, LastBucket;
1228 
1229  FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1230  if (FirstBucket < 0)
1231  FirstBucket = 0;
1232 
1233  LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1234  if (LastBucket >= NUM_PP_BUCKETS)
1235  LastBucket = NUM_PP_BUCKETS - 1;
1236 
1237  if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
1238  for (i = FirstBucket; i <= LastBucket; i++)
1239  SET_BIT (ParamTable[i], Bit);
1240 
1241 } /* FillPPLinearBits */
1242 
1243 
1244 /*---------------------------------------------------------------------------*/
1245 #ifndef GRAPHICS_DISABLED
1246 namespace tesseract {
1257 CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool* adaptive_on,
1258  bool* pretrained_on, int* shape_id) {
1259  tprintf("%s\n", Prompt);
1260  SVEvent* ev;
1261  SVEventType ev_type;
1262  int unichar_id = INVALID_UNICHAR_ID;
1263  // Wait until a click or popup event.
1264  do {
1265  ev = IntMatchWindow->AwaitEvent(SVET_ANY);
1266  ev_type = ev->type;
1267  if (ev_type == SVET_POPUP) {
1268  if (ev->command_id == IDA_SHAPE_INDEX) {
1269  if (shape_table_ != nullptr) {
1270  *shape_id = atoi(ev->parameter);
1271  *adaptive_on = false;
1272  *pretrained_on = true;
1273  if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1274  int font_id;
1275  shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1276  &font_id);
1277  tprintf("Shape %d, first unichar=%d, font=%d\n",
1278  *shape_id, unichar_id, font_id);
1279  return unichar_id;
1280  }
1281  tprintf("Shape index '%s' not found in shape table\n", ev->parameter);
1282  } else {
1283  tprintf("No shape table loaded!\n");
1284  }
1285  } else {
1287  unichar_id = unicharset.unichar_to_id(ev->parameter);
1288  if (ev->command_id == IDA_ADAPTIVE) {
1289  *adaptive_on = true;
1290  *pretrained_on = false;
1291  *shape_id = -1;
1292  } else if (ev->command_id == IDA_STATIC) {
1293  *adaptive_on = false;
1294  *pretrained_on = true;
1295  } else {
1296  *adaptive_on = true;
1297  *pretrained_on = true;
1298  }
1299  if (ev->command_id == IDA_ADAPTIVE || shape_table_ == nullptr) {
1300  *shape_id = -1;
1301  return unichar_id;
1302  }
1303  for (int s = 0; s < shape_table_->NumShapes(); ++s) {
1304  if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1305  tprintf("%s\n", shape_table_->DebugStr(s).c_str());
1306  }
1307  }
1308  } else {
1309  tprintf("Char class '%s' not found in unicharset",
1310  ev->parameter);
1311  }
1312  }
1313  }
1314  delete ev;
1315  } while (ev_type != SVET_CLICK);
1316  return 0;
1317 } /* GetClassToDebug */
1318 
1319 } // namespace tesseract
1320 #endif
1321 
1333 void GetCPPadsForLevel(int Level,
1334  float *EndPad,
1335  float *SidePad,
1336  float *AnglePad) {
1337  switch (Level) {
1338  case 0:
1339  *EndPad = classify_cp_end_pad_loose * GetPicoFeatureLength ();
1340  *SidePad = classify_cp_side_pad_loose * GetPicoFeatureLength ();
1341  *AnglePad = classify_cp_angle_pad_loose / 360.0;
1342  break;
1343 
1344  case 1:
1345  *EndPad = classify_cp_end_pad_medium * GetPicoFeatureLength ();
1346  *SidePad = classify_cp_side_pad_medium * GetPicoFeatureLength ();
1347  *AnglePad = classify_cp_angle_pad_medium / 360.0;
1348  break;
1349 
1350  case 2:
1351  *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
1352  *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
1353  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1354  break;
1355 
1356  default:
1357  *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
1358  *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
1359  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1360  break;
1361  }
1362  if (*AnglePad > 0.5)
1363  *AnglePad = 0.5;
1364 
1365 } /* GetCPPadsForLevel */
1366 
1372 ScrollView::Color GetMatchColorFor(float Evidence) {
1373  assert (Evidence >= 0.0);
1374  assert (Evidence <= 1.0);
1375 
1376  if (Evidence >= 0.90)
1377  return ScrollView::WHITE;
1378  else if (Evidence >= 0.75)
1379  return ScrollView::GREEN;
1380  else if (Evidence >= 0.50)
1381  return ScrollView::RED;
1382  else
1383  return ScrollView::BLUE;
1384 } /* GetMatchColorFor */
1385 
1394 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {
1395  FILL_SWITCH *Next;
1396 
1397  /* compute the fill assuming no switches will be encountered */
1398  Fill->AngleStart = Filler->AngleStart;
1399  Fill->AngleEnd = Filler->AngleEnd;
1400  Fill->X = Filler->X;
1401  Fill->YStart = Filler->YStart >> 8;
1402  Fill->YEnd = Filler->YEnd >> 8;
1403 
1404  /* update the fill info and the filler for ALL switches at this X value */
1405  Next = &(Filler->Switch[Filler->NextSwitch]);
1406  while (Filler->X >= Next->X) {
1407  Fill->X = Filler->X = Next->X;
1408  if (Next->Type == StartSwitch) {
1409  Fill->YStart = Next->Y;
1410  Filler->StartDelta = Next->Delta;
1411  Filler->YStart = Next->YInit;
1412  }
1413  else if (Next->Type == EndSwitch) {
1414  Fill->YEnd = Next->Y;
1415  Filler->EndDelta = Next->Delta;
1416  Filler->YEnd = Next->YInit;
1417  }
1418  else { /* Type must be LastSwitch */
1419  break;
1420  }
1421  Filler->NextSwitch++;
1422  Next = &(Filler->Switch[Filler->NextSwitch]);
1423  }
1424 
1425  /* prepare the filler for the next call to this routine */
1426  Filler->X++;
1427  Filler->YStart += Filler->StartDelta;
1428  Filler->YEnd += Filler->EndDelta;
1429 
1430 } /* GetNextFill */
1431 
1441 void InitTableFiller (float EndPad, float SidePad,
1442  float AnglePad, PROTO Proto, TABLE_FILLER * Filler)
1443 #define XS X_SHIFT
1444 #define YS Y_SHIFT
1445 #define AS ANGLE_SHIFT
1446 #define NB NUM_CP_BUCKETS
1447 {
1448  float Angle;
1449  float X, Y, HalfLength;
1450  float Cos, Sin;
1451  float XAdjust, YAdjust;
1452  FPOINT Start, Switch1, Switch2, End;
1453  int S1 = 0;
1454  int S2 = 1;
1455 
1456  Angle = Proto->Angle;
1457  X = Proto->X;
1458  Y = Proto->Y;
1459  HalfLength = Proto->Length / 2.0;
1460 
1461  Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
1462  Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
1463  Filler->NextSwitch = 0;
1464 
1465  if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
1466  /* horizontal proto - handle as special case */
1467  Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
1468  Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
1469  Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
1470  Filler->StartDelta = 0;
1471  Filler->EndDelta = 0;
1472  Filler->Switch[0].Type = LastSwitch;
1473  Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
1474  } else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
1475  fabs(Angle - 0.75) < HV_TOLERANCE) {
1476  /* vertical proto - handle as special case */
1477  Filler->X = Bucket8For(X - SidePad, XS, NB);
1478  Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
1479  Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
1480  Filler->StartDelta = 0;
1481  Filler->EndDelta = 0;
1482  Filler->Switch[0].Type = LastSwitch;
1483  Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
1484  } else {
1485  /* diagonal proto */
1486 
1487  if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1488  /* rising diagonal proto */
1489  Angle *= 2.0 * M_PI;
1490  Cos = fabs(cos(Angle));
1491  Sin = fabs(sin(Angle));
1492 
1493  /* compute the positions of the corners of the acceptance region */
1494  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1495  Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1496  End.x = 2.0 * X - Start.x;
1497  End.y = 2.0 * Y - Start.y;
1498  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1499  Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1500  Switch2.x = 2.0 * X - Switch1.x;
1501  Switch2.y = 2.0 * Y - Switch1.y;
1502 
1503  if (Switch1.x > Switch2.x) {
1504  S1 = 1;
1505  S2 = 0;
1506  }
1507 
1508  /* translate into bucket positions and deltas */
1509  Filler->X = Bucket8For(Start.x, XS, NB);
1510  Filler->StartDelta = -static_cast<int16_t>((Cos / Sin) * 256);
1511  Filler->EndDelta = static_cast<int16_t>((Sin / Cos) * 256);
1512 
1513  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1514  YAdjust = XAdjust * Cos / Sin;
1515  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1516  YAdjust = XAdjust * Sin / Cos;
1517  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1518 
1519  Filler->Switch[S1].Type = StartSwitch;
1520  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1521  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1522  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1523  YAdjust = XAdjust * Sin / Cos;
1524  Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
1525  Filler->Switch[S1].Delta = Filler->EndDelta;
1526 
1527  Filler->Switch[S2].Type = EndSwitch;
1528  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1529  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1530  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1531  YAdjust = XAdjust * Cos / Sin;
1532  Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
1533  Filler->Switch[S2].Delta = Filler->StartDelta;
1534 
1535  Filler->Switch[2].Type = LastSwitch;
1536  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1537  } else {
1538  /* falling diagonal proto */
1539  Angle *= 2.0 * M_PI;
1540  Cos = fabs(cos(Angle));
1541  Sin = fabs(sin(Angle));
1542 
1543  /* compute the positions of the corners of the acceptance region */
1544  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1545  Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1546  End.x = 2.0 * X - Start.x;
1547  End.y = 2.0 * Y - Start.y;
1548  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1549  Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1550  Switch2.x = 2.0 * X - Switch1.x;
1551  Switch2.y = 2.0 * Y - Switch1.y;
1552 
1553  if (Switch1.x > Switch2.x) {
1554  S1 = 1;
1555  S2 = 0;
1556  }
1557 
1558  /* translate into bucket positions and deltas */
1559  Filler->X = Bucket8For(Start.x, XS, NB);
1560  Filler->StartDelta = static_cast<int16_t>(ClipToRange<int>(
1561  -IntCastRounded((Sin / Cos) * 256), INT16_MIN, INT16_MAX));
1562  Filler->EndDelta = static_cast<int16_t>(ClipToRange<int>(
1563  IntCastRounded((Cos / Sin) * 256), INT16_MIN, INT16_MAX));
1564 
1565  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1566  YAdjust = XAdjust * Sin / Cos;
1567  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1568  YAdjust = XAdjust * Cos / Sin;
1569  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1570 
1571  Filler->Switch[S1].Type = EndSwitch;
1572  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1573  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1574  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1575  YAdjust = XAdjust * Sin / Cos;
1576  Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
1577  Filler->Switch[S1].Delta = Filler->StartDelta;
1578 
1579  Filler->Switch[S2].Type = StartSwitch;
1580  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1581  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1582  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1583  YAdjust = XAdjust * Cos / Sin;
1584  Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
1585  Filler->Switch[S2].Delta = Filler->EndDelta;
1586 
1587  Filler->Switch[2].Type = LastSwitch;
1588  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1589  }
1590  }
1591 } /* InitTableFiller */
1592 
1593 
1594 /*---------------------------------------------------------------------------*/
1595 #ifndef GRAPHICS_DISABLED
1596 
1604 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
1605  ScrollView::Color color) {
1606  float X, Y, Dx, Dy, Length;
1607 
1608  window->Pen(color);
1609  assert(Feature != nullptr);
1610  assert(color != 0);
1611 
1612  X = Feature->X;
1613  Y = Feature->Y;
1614  Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
1615  // The -PI has no significant effect here, but the value of Theta is computed
1616  // using BinaryAnglePlusPi in intfx.cpp.
1617  Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1618  Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1619 
1620  window->SetCursor(X, Y);
1621  window->DrawTo(X + Dx, Y + Dy);
1622 } /* RenderIntFeature */
1623 
1638 void RenderIntProto(ScrollView *window,
1639  INT_CLASS Class,
1640  PROTO_ID ProtoId,
1641  ScrollView::Color color) {
1642  PROTO_SET ProtoSet;
1643  INT_PROTO Proto;
1644  int ProtoSetIndex;
1645  int ProtoWordIndex;
1646  float Length;
1647  int Xmin, Xmax, Ymin, Ymax;
1648  float X, Y, Dx, Dy;
1649  uint32_t ProtoMask;
1650  int Bucket;
1651 
1652  assert(ProtoId >= 0);
1653  assert(Class != nullptr);
1654  assert(ProtoId < Class->NumProtos);
1655  assert(color != 0);
1656  window->Pen(color);
1657 
1658  ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
1659  ProtoSetIndex = IndexForProto(ProtoId);
1660  Proto = &(ProtoSet->Protos[ProtoSetIndex]);
1661  Length = (Class->ProtoLengths[ProtoId] *
1663  ProtoMask = PPrunerMaskFor(ProtoId);
1664  ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
1665 
1666  // find the x and y extent of the proto from the proto pruning table
1667  Xmin = Ymin = NUM_PP_BUCKETS;
1668  Xmax = Ymax = 0;
1669  for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
1670  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
1671  UpdateRange(Bucket, &Xmin, &Xmax);
1672  }
1673 
1674  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
1675  UpdateRange(Bucket, &Ymin, &Ymax);
1676  }
1677  }
1678  X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1679  Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1680  // The -PI has no significant effect here, but the value of Theta is computed
1681  // using BinaryAnglePlusPi in intfx.cpp.
1682  Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1683  Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1684 
1685  window->SetCursor(X - Dx, Y - Dy);
1686  window->DrawTo(X + Dx, Y + Dy);
1687 } /* RenderIntProto */
1688 #endif
1689 
1703 int TruncateParam(float Param, int Min, int Max, char *Id) {
1704  if (Param < Min) {
1705  if (Id)
1706  cprintf("Warning: Param %s truncated from %f to %d!\n",
1707  Id, Param, Min);
1708  Param = Min;
1709  } else if (Param > Max) {
1710  if (Id)
1711  cprintf("Warning: Param %s truncated from %f to %d!\n",
1712  Id, Param, Max);
1713  Param = Max;
1714  }
1715  return static_cast<int>(std::floor(Param));
1716 } /* TruncateParam */
1717 
1718 
1719 #ifndef GRAPHICS_DISABLED
1720 
1724 void InitIntMatchWindowIfReqd() {
1725  if (IntMatchWindow == nullptr) {
1726  IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
1727  auto* popup_menu = new SVMenuNode();
1728 
1729  popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
1730  "x", "Class to debug");
1731  popup_menu->AddChild("Debug Static classes", IDA_STATIC,
1732  "x", "Class to debug");
1733  popup_menu->AddChild("Debug Both", IDA_BOTH,
1734  "x", "Class to debug");
1735  popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
1736  "0", "Index to debug");
1737  popup_menu->BuildMenu(IntMatchWindow, false);
1738  }
1739 }
1740 
1746  if (ProtoDisplayWindow == nullptr) {
1747  ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
1748  550, 200);
1749  }
1750 }
1751 
1757  if (FeatureDisplayWindow == nullptr) {
1758  FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
1759  50, 700);
1760  }
1761 }
1762 
1765 ScrollView* CreateFeatureSpaceWindow(const char* name, int xpos, int ypos) {
1766  return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
1767 }
1768 #endif // GRAPHICS_DISABLED
ScrollView::GREY
Definition: scrollview.h:133
FILL_SPEC::X
int8_t X
Definition: intproto.cpp:97
INT_TEMPLATES_STRUCT
Definition: intproto.h:117
INT_CLASS_STRUCT::font_set_id
int font_set_id
Definition: intproto.h:111
tesseract::Shape::ContainsUnichar
bool ContainsUnichar(int unichar_id) const
Definition: shapetable.cpp:147
ClipToRange
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:106
PROTO_STRUCT::Length
float Length
Definition: protos.h:41
emalloc.h
INT_CLASS_STRUCT::ConfigLengths
uint16_t ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:110
ScrollView
Definition: scrollview.h:97
INT_VAR
#define INT_VAR(name, val, comment)
Definition: params.h:300
PROTOS_PER_PROTO_SET
#define PROTOS_PER_PROTO_SET
Definition: intproto.h:48
picofeat.h
BITS_PER_CP_VECTOR
#define BITS_PER_CP_VECTOR
Definition: intproto.h:58
PROTO_PRUNER_SCALE
#define PROTO_PRUNER_SCALE
Definition: intproto.cpp:47
CLASS_ID
UNICHAR_ID CLASS_ID
Definition: matchdefs.h:33
NewIntTemplates
INT_TEMPLATES NewIntTemplates()
Definition: intproto.cpp:681
SVEventType
SVEventType
Definition: scrollview.h:44
TABLE_FILLER::Switch
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
Definition: intproto.cpp:89
PRUNER_ANGLE
#define PRUNER_ANGLE
Definition: intproto.h:36
IDA_SHAPE_INDEX
Definition: intproto.h:156
PROTO_SET_STRUCT::Protos
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
Definition: intproto.h:96
tesseract::Classify::classify_norm_method
int classify_norm_method
Definition: classify.h:434
SVET_CLICK
Definition: scrollview.h:47
FILL_SPEC
Definition: intproto.cpp:95
GetMatchColorFor
ScrollView::Color GetMatchColorFor(float Evidence)
Definition: intproto.cpp:1371
FillPPLinearBits
void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1224
CLASS_STRUCT::Configurations
CONFIGS Configurations
Definition: protos.h:58
FPOINT::y
float y
Definition: fpoint.h:44
Emalloc
void * Emalloc(int Size)
Definition: emalloc.cpp:31
FILL_SWITCH::YInit
int16_t YInit
Definition: intproto.cpp:75
Bucket8For
uint8_t Bucket8For(float param, float offset, int num_buckets)
Definition: intproto.cpp:417
NUM_PP_PARAMS
#define NUM_PP_PARAMS
Definition: intproto.h:50
tesseract::Classify::fontinfo_table_
UnicityTable< FontInfo > fontinfo_table_
Definition: classify.h:529
MAX_LEVEL
#define MAX_LEVEL
ASSERT_HOST
#define ASSERT_HOST(x)
Definition: errcode.h:87
SVET_POPUP
Definition: scrollview.h:53
INT_CLASS_STRUCT
Definition: intproto.h:104
tesseract::write_set
bool write_set(FILE *f, const FontSet &fs)
Definition: fontinfo.cpp:235
INT_DESCENDER
#define INT_DESCENDER
Definition: intproto.cpp:49
PROTO_STRUCT
Definition: protos.h:34
baseline
Definition: mfoutline.h:62
mfoutline.h
FILL_SPEC::YEnd
int8_t YEnd
Definition: intproto.cpp:98
NewIntClass
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
Definition: intproto.cpp:625
BucketEnd
float BucketEnd(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1109
tesseract::ShapeTable::NumShapes
int NumShapes() const
Definition: shapetable.h:274
INT_FEATURE_STRUCT::Theta
uint8_t Theta
Definition: intproto.h:141
INT_FEATURE_STRUCT::INT_FEATURE_STRUCT
INT_FEATURE_STRUCT()
Definition: intproto.h:132
tesseract::Classify::GetClassToDebug
CLASS_ID GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on, int *shape_id)
Definition: intproto.cpp:1256
tesseract::write_info
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:166
CLASS_STRUCT::NumProtos
int16_t NumProtos
Definition: protos.h:53
PROTO_ID
int16_t PROTO_ID
Definition: matchdefs.h:39
INT_PROTO_STRUCT
Definition: intproto.h:80
FILL_SPEC::AngleEnd
uint8_t AngleEnd
Definition: intproto.cpp:99
Config
CLUSTERCONFIG Config
Definition: commontraining.cpp:88
test_bit
#define test_bit(array, bit)
Definition: bitvec.h:58
INT_CHAR_NORM_RANGE
#define INT_CHAR_NORM_RANGE
Definition: intproto.h:129
ScrollView::Clear
void Clear()
Definition: scrollview.cpp:588
INT_PROTO_STRUCT::Configs
uint32_t Configs[WERDS_PER_CONFIG_VEC]
Definition: intproto.h:85
FPOINT
Definition: fpoint.h:28
cprintf
void cprintf(const char *format,...)
Definition: callcpp.cpp:32
TABLE_FILLER
Definition: intproto.cpp:82
tesseract::Classify::ConvertProto
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class)
Definition: intproto.cpp:487
ScrollView::Pen
void Pen(Color color)
Definition: scrollview.cpp:717
ScrollView::DrawTo
void DrawTo(int x, int y)
Definition: scrollview.cpp:524
PRUNER_X
#define PRUNER_X
Definition: intproto.h:34
INT_MIN_X
#define INT_MIN_X
Definition: intproto.cpp:58
Bucket16For
uint16_t Bucket16For(float param, float offset, int num_buckets)
Definition: intproto.cpp:421
NUM_PP_BUCKETS
#define NUM_PP_BUCKETS
Definition: intproto.h:51
tesseract::Classify::classify_learning_debug_level
int classify_learning_debug_level
Definition: classify.h:455
InitTableFiller
void InitTableFiller(float EndPad, float SidePad, float AnglePad, PROTO Proto, TABLE_FILLER *Filler)
Definition: intproto.cpp:1440
IntCastRounded
int IntCastRounded(double x)
Definition: helpers.h:173
MAX_NUM_SWITCHES
#define MAX_NUM_SWITCHES
Definition: intproto.cpp:69
CircBucketFor
uint8_t CircBucketFor(float param, float offset, int num_buckets)
Definition: intproto.cpp:431
tesseract::read_spacing_info
bool read_spacing_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:173
FPOINT::x
float x
Definition: fpoint.h:44
MAX_NUM_PROTO_SETS
#define MAX_NUM_PROTO_SETS
Definition: intproto.h:49
PROTO_SET_STRUCT::ProtoPruner
PROTO_PRUNER ProtoPruner
Definition: intproto.h:95
INT_CLASS_STRUCT::NumProtos
uint16_t NumProtos
Definition: intproto.h:105
INT_XRADIUS
#define INT_XRADIUS
Definition: intproto.cpp:56
CPrunerBitIndexFor
#define CPrunerBitIndexFor(c)
Definition: intproto.h:182
GetNextFill
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
Definition: intproto.cpp:1393
PRUNER_Y
#define PRUNER_Y
Definition: intproto.h:35
FILL_SWITCH::Type
SWITCH_TYPE Type
Definition: intproto.cpp:73
ScrollView::ZoomToRectangle
void ZoomToRectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:755
tesseract::Classify::CreateIntTemplates
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:526
FCOORD
Definition: points.h:187
INT_TEMPLATES_STRUCT::NumClassPruners
int NumClassPruners
Definition: intproto.h:119
tesseract::write_spacing_info
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:201
ScrollView::BLUE
Definition: scrollview.h:108
PROTO_STRUCT::B
float B
Definition: protos.h:36
MAX_NUM_CLASS_PRUNERS
#define MAX_NUM_CLASS_PRUNERS
Definition: intproto.h:59
FILL_SPEC::AngleStart
uint8_t AngleStart
Definition: intproto.cpp:99
tesseract::CCUtil::unicharset
UNICHARSET unicharset
Definition: ccutil.h:57
CPrunerWordIndexFor
#define CPrunerWordIndexFor(c)
Definition: intproto.h:181
ProtoIn
#define ProtoIn(Class, Pid)
Definition: protos.h:82
Y_SHIFT
#define Y_SHIFT
Definition: intproto.h:41
AddIntProto
int AddIntProto(INT_CLASS Class)
Definition: intproto.cpp:281
INT_CLASS_STRUCT::NumProtoSets
uint8_t NumProtoSets
Definition: intproto.h:106
INT_PROTO_STRUCT::B
uint8_t B
Definition: intproto.h:82
AddIntClass
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
Definition: intproto.cpp:230
FILL_SPEC::YStart
int8_t YStart
Definition: intproto.cpp:98
AddProtoToProtoPruner
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
Definition: intproto.cpp:366
IndexForProto
#define IndexForProto(P)
Definition: intproto.h:166
TABLE_FILLER::NextSwitch
uint8_t NextSwitch
Definition: intproto.cpp:84
genericvector.h
INT_PROTO_STRUCT::Angle
uint8_t Angle
Definition: intproto.h:84
svmnode.h
TABLE_FILLER::YStart
int16_t YStart
Definition: intproto.cpp:87
tesseract::ShapeTable::GetFirstUnicharAndFont
void GetFirstUnicharAndFont(int shape_id, int *unichar_id, int *font_id) const
Definition: shapetable.cpp:404
ConvertConfig
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
Definition: intproto.cpp:462
SVEvent::parameter
char * parameter
Definition: scrollview.h:65
BucketStart
float BucketStart(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1093
CPrunerMaskFor
#define CPrunerMaskFor(L, c)
Definition: intproto.h:183
TABLE_FILLER::X
int8_t X
Definition: intproto.cpp:86
BITS_PER_WERD
#define BITS_PER_WERD
Definition: intproto.h:44
tesseract::Classify::ShowMatchDisplay
void ShowMatchDisplay()
Definition: intproto.cpp:962
STRING::c_str
const char * c_str() const
Definition: strngs.cpp:192
INT_MAX_Y
#define INT_MAX_Y
Definition: intproto.cpp:61
LegalClassId
#define LegalClassId(c)
Definition: intproto.h:175
INT_CAPHEIGHT
#define INT_CAPHEIGHT
Definition: intproto.cpp:52
MAX_NUM_CONFIGS
#define MAX_NUM_CONFIGS
Definition: intproto.h:46
MAX_NUM_PROTOS
#define MAX_NUM_PROTOS
Definition: intproto.h:47
MAX_NUM_CLASSES
#define MAX_NUM_CLASSES
Definition: matchdefs.h:29
TABLE_FILLER::AngleStart
uint8_t AngleStart
Definition: intproto.cpp:85
tesseract::Classify::shape_table_
ShapeTable * shape_table_
Definition: classify.h:546
tesstrain_utils.int
int
Definition: tesstrain_utils.py:154
EndSwitch
Definition: intproto.cpp:67
GetCPPadsForLevel
void GetCPPadsForLevel(int Level, float *EndPad, float *SidePad, float *AnglePad)
Definition: intproto.cpp:1332
NO_PROTO
#define NO_PROTO
Definition: matchdefs.h:40
INT_CLASS_STRUCT::ProtoLengths
uint8_t * ProtoLengths
Definition: intproto.h:109
PROTO_STRUCT::Y
float Y
Definition: protos.h:39
INT_MAX_X
#define INT_MAX_X
Definition: intproto.cpp:60
MaxNumIntProtosIn
#define MaxNumIntProtosIn(C)
Definition: intproto.h:164
InitIntMatchWindowIfReqd
void InitIntMatchWindowIfReqd()
Definition: intproto.cpp:1723
MapParam
#define MapParam(P, O, N)
Definition: intproto.cpp:118
UNICHARSET::unichar_to_id
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:209
DisplayIntFeature
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, float Evidence)
Definition: intproto.cpp:589
ANGLE_SHIFT
#define ANGLE_SHIFT
Definition: intproto.h:39
HV_TOLERANCE
#define HV_TOLERANCE
Definition: intproto.cpp:64
PROTO_STRUCT::C
float C
Definition: protos.h:37
shapetable.h
CLASS_STRUCT::NumConfigs
int16_t NumConfigs
Definition: protos.h:56
FillerDone
bool FillerDone(TABLE_FILLER *Filler)
Definition: intproto.cpp:1163
UNICHARSET
Definition: unicharset.h:145
tesseract::ShapeTable::DebugStr
STRING DebugStr(int shape_id) const
Definition: shapetable.cpp:281
PROTO_STRUCT::X
float X
Definition: protos.h:38
CircularIncrement
#define CircularIncrement(i, r)
Definition: intproto.cpp:115
INT_TEMPLATES_STRUCT::NumClasses
int NumClasses
Definition: intproto.h:118
NORM_METHOD
NORM_METHOD
Definition: mfoutline.h:62
CLASS_STRUCT::font_set
UnicityTableEqEq< int > font_set
Definition: protos.h:59
tesseract::ShapeTable::GetShape
const Shape & GetShape(int shape_id) const
Definition: shapetable.h:319
CreateFeatureSpaceWindow
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1764
ScrollView::WHITE
Definition: scrollview.h:103
AddIntConfig
int AddIntConfig(INT_CLASS Class)
Definition: intproto.cpp:260
CLASS_STRUCT
Definition: protos.h:45
PROTO_STRUCT::Angle
float Angle
Definition: protos.h:40
UnicityTable::get
const T & get(int id) const
Return the object from an id.
Definition: unicity_table.h:140
INT_FEATURE_STRUCT::Y
uint8_t Y
Definition: intproto.h:140
BIT_VECTOR
uint32_t * BIT_VECTOR
Definition: bitvec.h:27
helpers.h
tesseract
Definition: baseapi.h:65
WERDS_PER_CONFIG_VEC
#define WERDS_PER_CONFIG_VEC
Definition: intproto.h:67
fontinfo.h
tesseract::Classify::WriteIntTemplates
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:1017
DoFill
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, uint32_t ClassMask, uint32_t ClassCount, uint32_t WordIndex)
Definition: intproto.cpp:1123
double_VAR
#define double_VAR(name, val, comment)
Definition: params.h:309
SVEvent::type
SVEventType type
Definition: scrollview.h:63
NUM_CP_BUCKETS
#define NUM_CP_BUCKETS
Definition: intproto.h:52
ScrollView::RED
Definition: scrollview.h:104
IDA_STATIC
Definition: intproto.h:155
MaxNumClassesIn
#define MaxNumClassesIn(T)
Definition: intproto.h:174
callcpp.h
INT_CLASS_STRUCT::ProtoSets
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
Definition: intproto.h:108
Erealloc
void * Erealloc(void *ptr, int size)
Definition: emalloc.cpp:38
INT_BASELINE
#define INT_BASELINE
Definition: intproto.cpp:50
PPrunerWordIndexFor
#define PPrunerWordIndexFor(I)
Definition: intproto.h:169
AS
#define AS
TruncateParam
int TruncateParam(float Param, int Min, int Max, char *Id)
Definition: intproto.cpp:1702
INT_YCENTER
#define INT_YCENTER
Definition: intproto.cpp:55
SVET_ANY
Definition: scrollview.h:55
UnicityTable::size
int size() const
Return the size used.
Definition: unicity_table.h:127
RenderIntProto
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
Definition: intproto.cpp:1637
ScrollView::AwaitEvent
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:443
SET_BIT
#define SET_BIT(array, bit)
Definition: bitvec.h:54
TABLE_FILLER::AngleEnd
uint8_t AngleEnd
Definition: intproto.cpp:85
InitProtoDisplayWindowIfReqd
void InitProtoDisplayWindowIfReqd()
Definition: intproto.cpp:1744
SetForProto
#define SetForProto(P)
Definition: intproto.h:165
SWITCH_TYPE
SWITCH_TYPE
Definition: intproto.cpp:66
PROTO_STRUCT::A
float A
Definition: protos.h:35
CPrunerIdFor
#define CPrunerIdFor(c)
Definition: intproto.h:179
tesseract::read_info
bool read_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:156
INT_XCENTER
#define INT_XCENTER
Definition: intproto.cpp:54
INT_TEMPLATES_STRUCT::Class
INT_CLASS Class[MAX_NUM_CLASSES]
Definition: intproto.h:120
StartSwitch
Definition: intproto.cpp:67
DisplayIntProto
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, float Evidence)
Definition: intproto.cpp:607
INT_FEATURE_STRUCT
Definition: intproto.h:131
SVMenuNode
Definition: svmnode.h:35
PROTO_SET_STRUCT
Definition: intproto.h:94
FillPPCircularBits
void FillPPCircularBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1185
tesseract::FontSet::size
int size
Definition: fontinfo.h:138
INT_YRADIUS
#define INT_YRADIUS
Definition: intproto.cpp:57
SVEvent
Definition: scrollview.h:60
UNICHARSET::contains_unichar
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:670
Efree
void Efree(void *ptr)
Definition: emalloc.cpp:45
ScrollView::GREEN
Definition: scrollview.h:106
CPrunerFor
#define CPrunerFor(T, c)
Definition: intproto.h:180
FILL_SWITCH::Y
int8_t Y
Definition: intproto.cpp:74
UpdateMatchDisplay
void UpdateMatchDisplay()
Definition: intproto.cpp:446
SVEvent::command_id
int command_id
Definition: scrollview.h:70
TABLE_FILLER::YEnd
int16_t YEnd
Definition: intproto.cpp:87
XS
#define XS
tesseract::FontSet::configs
int * configs
Definition: fontinfo.h:139
X_SHIFT
#define X_SHIFT
Definition: intproto.h:40
INT_TEMPLATES_STRUCT::ClassPruners
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
Definition: intproto.h:121
Modulo
int Modulo(int a, int b)
Definition: helpers.h:156
WERDS_PER_CP_VECTOR
#define WERDS_PER_CP_VECTOR
Definition: intproto.h:61
tprintf
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:34
CLASS_PRUNER_STRUCT
Definition: intproto.h:75
tesseract::Classify::ReadIntTemplates
INT_TEMPLATES ReadIntTemplates(TFile *fp)
Definition: intproto.cpp:717
CLASS_PRUNER_STRUCT::p
uint32_t p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
Definition: intproto.h:77
free_int_templates
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:697
INT_XHEIGHT
#define INT_XHEIGHT
Definition: intproto.cpp:51
ScrollView::Update
static void Update()
Definition: scrollview.cpp:708
NUM_BITS_PER_CLASS
#define NUM_BITS_PER_CLASS
Definition: intproto.h:54
FILL_SWITCH
Definition: intproto.cpp:71
ScrollView::SetCursor
void SetCursor(int x, int y)
Definition: scrollview.cpp:518
intproto.h
AddProtoToClassPruner
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
Definition: intproto.cpp:327
IDA_BOTH
Definition: intproto.h:157
classify.h
UNICHARSET::id_to_unichar
const char * id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:290
WERDS_PER_PP_VECTOR
#define WERDS_PER_PP_VECTOR
Definition: intproto.h:62
ProtoForProtoId
#define ProtoForProtoId(C, P)
Definition: intproto.h:167
INT_CLASS_STRUCT::NumConfigs
uint8_t NumConfigs
Definition: intproto.h:107
ScrollView::Color
Color
Definition: scrollview.h:100
UpdateRange
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:118
TABLE_FILLER::StartDelta
int16_t StartDelta
Definition: intproto.cpp:88
tesseract::Classify::fontset_table_
UnicityTable< FontSet > fontset_table_
Definition: classify.h:537
INT_PROTO_STRUCT::C
int8_t C
Definition: intproto.h:83
FILL_SWITCH::X
int8_t X
Definition: intproto.cpp:74
INT_FEATURE_STRUCT::X
uint8_t X
Definition: intproto.h:139
OLD_MAX_NUM_CONFIGS
#define OLD_MAX_NUM_CONFIGS
Definition: intproto.cpp:107
ScrollView::Rectangle
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:599
FILL_SWITCH::Delta
int16_t Delta
Definition: intproto.cpp:76
UnusedClassIdIn
#define UnusedClassIdIn(T, c)
Definition: intproto.h:176
ClassForClassId
#define ClassForClassId(T, c)
Definition: intproto.h:177
tesseract::FontSet
Definition: fontinfo.h:137
YS
#define YS
IDA_ADAPTIVE
Definition: intproto.h:154
LastSwitch
Definition: intproto.cpp:67
tesseract::ClearFeatureSpaceWindow
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:987
INT_MIN_Y
#define INT_MIN_Y
Definition: intproto.cpp:59
INT_PROTO_STRUCT::A
int8_t A
Definition: intproto.h:81
OLD_WERDS_PER_CONFIG_VEC
#define OLD_WERDS_PER_CONFIG_VEC
Definition: intproto.cpp:108
InitFeatureDisplayWindowIfReqd
void InitFeatureDisplayWindowIfReqd()
Definition: intproto.cpp:1755
NB
#define NB
UNICHARSET::size
int size() const
Definition: unicharset.h:341
RenderIntFeature
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1603
TABLE_FILLER::EndDelta
int16_t EndDelta
Definition: intproto.cpp:88
PPrunerMaskFor
#define PPrunerMaskFor(I)
Definition: intproto.h:172
tesseract::read_set
bool read_set(TFile *f, FontSet *fs)
Definition: fontinfo.cpp:229
points.h
GetPicoFeatureLength
#define GetPicoFeatureLength()
Definition: picofeat.h:56