All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
intproto.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  ** Filename: intproto.c
3  ** Purpose: Definition of data structures for integer protos.
4  ** Author: Dan Johnson
5  ** History: Thu Feb 7 14:38:16 1991, DSJ, Created.
6  **
7  ** (c) Copyright Hewlett-Packard Company, 1988.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  ******************************************************************************/
18 /*-----------------------------------------------------------------------------
19  Include Files and Type Defines
20 -----------------------------------------------------------------------------*/
21 
22 #include <math.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #ifdef __UNIX__
26 #include <unistd.h>
27 #endif
28 
29 #include "classify.h"
30 #include "const.h"
31 #include "emalloc.h"
32 #include "fontinfo.h"
33 #include "genericvector.h"
34 #include "globals.h"
35 #include "helpers.h"
36 #include "intproto.h"
37 #include "mfoutline.h"
38 #include "ndminx.h"
39 #include "picofeat.h"
40 #include "points.h"
41 #include "shapetable.h"
42 #include "svmnode.h"
43 
44 // Include automatically generated configuration file if running autoconf.
45 #ifdef HAVE_CONFIG_H
46 #include "config_auto.h"
47 #endif
48 
50 using tesseract::FontSet;
52 
53 /* match debug display constants*/
54 #define PROTO_PRUNER_SCALE (4.0)
55 
56 #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE)
57 #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE)
58 #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE)
59 #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE)
60 
61 #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE)
62 #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE)
63 #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE)
64 #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE)
65 #define INT_MIN_X 0
66 #define INT_MIN_Y 0
67 #define INT_MAX_X INT_CHAR_NORM_RANGE
68 #define INT_MAX_Y INT_CHAR_NORM_RANGE
69 
71 #define HV_TOLERANCE (0.0025) /* approx 0.9 degrees */
72 
73 typedef enum
76 #define MAX_NUM_SWITCHES 3
77 
78 typedef struct
79 {
81  inT8 X, Y;
84 }
85 
86 
88 
89 typedef struct
90 {
92  uinT8 AngleStart, AngleEnd;
94  inT16 YStart, YEnd;
95  inT16 StartDelta, EndDelta;
97 }
98 
99 
101 
102 typedef struct
103 {
105  inT8 YStart, YEnd;
106  uinT8 AngleStart, AngleEnd;
107 }
108 
109 
110 FILL_SPEC;
111 
112 
113 /* constants for conversion from old inttemp format */
114 #define OLD_MAX_NUM_CONFIGS 32
115 #define OLD_WERDS_PER_CONFIG_VEC ((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\
116  BITS_PER_WERD)
117 
118 /*-----------------------------------------------------------------------------
119  Macros
120 -----------------------------------------------------------------------------*/
122 #define CircularIncrement(i,r) (((i) < (r) - 1)?((i)++):((i) = 0))
123 
125 #define MapParam(P,O,N) (floor (((P) + (O)) * (N)))
126 
127 /*---------------------------------------------------------------------------
128  Private Function Prototypes
129 ----------------------------------------------------------------------------*/
130 FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets);
131 
132 FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets);
133 
134 void DoFill(FILL_SPEC *FillSpec,
135  CLASS_PRUNER_STRUCT* Pruner,
136  register uinT32 ClassMask,
137  register uinT32 ClassCount,
138  register uinT32 WordIndex);
139 
140 BOOL8 FillerDone(TABLE_FILLER *Filler);
141 
143  ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
144  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug);
145 
147  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug);
148 
149 void GetCPPadsForLevel(int Level,
150  FLOAT32 *EndPad,
151  FLOAT32 *SidePad,
152  FLOAT32 *AnglePad);
153 
155 
156 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill);
157 
158 void InitTableFiller(FLOAT32 EndPad,
159  FLOAT32 SidePad,
160  FLOAT32 AnglePad,
161  PROTO Proto,
162  TABLE_FILLER *Filler);
163 
164 #ifndef GRAPHICS_DISABLED
165 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
166  ScrollView::Color color);
167 
168 void RenderIntProto(ScrollView *window,
169  INT_CLASS Class,
170  PROTO_ID ProtoId,
171  ScrollView::Color color);
172 #endif // GRAPHICS_DISABLED
173 
174 int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id);
175 
176 /*-----------------------------------------------------------------------------
177  Global Data Definitions and Declarations
178 -----------------------------------------------------------------------------*/
179 
180 /* global display lists used to display proto and feature match information*/
184 
185 /*-----------------------------------------------------------------------------
186  Variables
187 -----------------------------------------------------------------------------*/
188 
189 /* control knobs */
190 INT_VAR(classify_num_cp_levels, 3, "Number of Class Pruner Levels");
192  "Class Pruner Angle Pad Loose");
194  "Class Pruner Angle Pad Medium");
196  "CLass Pruner Angle Pad Tight");
197 double_VAR(classify_cp_end_pad_loose, 0.5, "Class Pruner End Pad Loose");
198 double_VAR(classify_cp_end_pad_medium, 0.5, "Class Pruner End Pad Medium");
199 double_VAR(classify_cp_end_pad_tight, 0.5, "Class Pruner End Pad Tight");
200 double_VAR(classify_cp_side_pad_loose, 2.5, "Class Pruner Side Pad Loose");
201 double_VAR(classify_cp_side_pad_medium, 1.2, "Class Pruner Side Pad Medium");
202 double_VAR(classify_cp_side_pad_tight, 0.6, "Class Pruner Side Pad Tight");
203 double_VAR(classify_pp_angle_pad, 45.0, "Proto Pruner Angle Pad");
204 double_VAR(classify_pp_end_pad, 0.5, "Proto Prune End Pad");
205 double_VAR(classify_pp_side_pad, 2.5, "Proto Pruner Side Pad");
206 
207 /*-----------------------------------------------------------------------------
208  Public Code
209 -----------------------------------------------------------------------------*/
213  : X(ClipToRange<inT16>(static_cast<inT16>(pos.x() + 0.5), 0, 255)),
214  Y(ClipToRange<inT16>(static_cast<inT16>(pos.y() + 0.5), 0, 255)),
215  Theta(theta),
216  CP_misses(0) {
217 }
220  : X(static_cast<uinT8>(ClipToRange(x, 0, MAX_UINT8))),
221  Y(static_cast<uinT8>(ClipToRange(y, 0, MAX_UINT8))),
222  Theta(static_cast<uinT8>(ClipToRange(theta, 0, MAX_UINT8))),
223  CP_misses(0) {
224 }
225 
240 void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) {
241  int Pruner;
242 
243  assert (LegalClassId (ClassId));
244  if (ClassId != Templates->NumClasses) {
245  fprintf(stderr, "Please make sure that classes are added to templates");
246  fprintf(stderr, " in increasing order of ClassIds\n");
247  exit(1);
248  }
249  ClassForClassId (Templates, ClassId) = Class;
250  Templates->NumClasses++;
251 
252  if (Templates->NumClasses > MaxNumClassesIn (Templates)) {
253  Pruner = Templates->NumClassPruners++;
254  Templates->ClassPruners[Pruner] = new CLASS_PRUNER_STRUCT;
255  memset(Templates->ClassPruners[Pruner], 0, sizeof(CLASS_PRUNER_STRUCT));
256  }
257 } /* AddIntClass */
258 
259 
273  int Index;
274 
275  assert(Class->NumConfigs < MAX_NUM_CONFIGS);
276 
277  Index = Class->NumConfigs++;
278  Class->ConfigLengths[Index] = 0;
279  return Index;
280 } /* AddIntConfig */
281 
282 
295 int AddIntProto(INT_CLASS Class) {
296  int Index;
297  int ProtoSetId;
298  PROTO_SET ProtoSet;
299  INT_PROTO Proto;
300  register uinT32 *Word;
301 
302  if (Class->NumProtos >= MAX_NUM_PROTOS)
303  return (NO_PROTO);
304 
305  Index = Class->NumProtos++;
306 
307  if (Class->NumProtos > MaxNumIntProtosIn(Class)) {
308  ProtoSetId = Class->NumProtoSets++;
309 
310  ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
311  Class->ProtoSets[ProtoSetId] = ProtoSet;
312  memset(ProtoSet, 0, sizeof(*ProtoSet));
313 
314  /* reallocate space for the proto lengths and install in class */
315  Class->ProtoLengths =
316  (uinT8 *)Erealloc(Class->ProtoLengths,
317  MaxNumIntProtosIn(Class) * sizeof(uinT8));
318  memset(&Class->ProtoLengths[Index], 0,
319  sizeof(*Class->ProtoLengths) * (MaxNumIntProtosIn(Class) - Index));
320  }
321 
322  /* initialize proto so its length is zero and it isn't in any configs */
323  Class->ProtoLengths[Index] = 0;
324  Proto = ProtoForProtoId (Class, Index);
325  for (Word = Proto->Configs;
326  Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0);
327 
328  return (Index);
329 
330 }
331 
332 
346 void AddProtoToClassPruner (PROTO Proto, CLASS_ID ClassId,
347  INT_TEMPLATES Templates)
348 #define MAX_LEVEL 2
349 {
350  CLASS_PRUNER_STRUCT* Pruner;
351  uinT32 ClassMask;
352  uinT32 ClassCount;
353  uinT32 WordIndex;
354  int Level;
355  FLOAT32 EndPad, SidePad, AnglePad;
356  TABLE_FILLER TableFiller;
357  FILL_SPEC FillSpec;
358 
359  Pruner = CPrunerFor (Templates, ClassId);
360  WordIndex = CPrunerWordIndexFor (ClassId);
361  ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassId);
362 
363  for (Level = classify_num_cp_levels - 1; Level >= 0; Level--) {
364  GetCPPadsForLevel(Level, &EndPad, &SidePad, &AnglePad);
365  ClassCount = CPrunerMaskFor (Level, ClassId);
366  InitTableFiller(EndPad, SidePad, AnglePad, Proto, &TableFiller);
367 
368  while (!FillerDone (&TableFiller)) {
369  GetNextFill(&TableFiller, &FillSpec);
370  DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
371  }
372  }
373 } /* AddProtoToClassPruner */
374 
375 
389 void AddProtoToProtoPruner(PROTO Proto, int ProtoId,
390  INT_CLASS Class, bool debug) {
391  FLOAT32 Angle, X, Y, Length;
392  FLOAT32 Pad;
393  int Index;
394  PROTO_SET ProtoSet;
395 
396  if (ProtoId >= Class->NumProtos)
397  cprintf("AddProtoToProtoPruner:assert failed: %d < %d",
398  ProtoId, Class->NumProtos);
399  assert(ProtoId < Class->NumProtos);
400 
401  Index = IndexForProto (ProtoId);
402  ProtoSet = Class->ProtoSets[SetForProto (ProtoId)];
403 
404  Angle = Proto->Angle;
405 #ifndef _WIN32
406  assert(!isnan(Angle));
407 #endif
408 
409  FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index,
410  Angle + ANGLE_SHIFT, classify_pp_angle_pad / 360.0,
411  debug);
412 
413  Angle *= 2.0 * PI;
414  Length = Proto->Length;
415 
416  X = Proto->X + X_SHIFT;
417  Pad = MAX (fabs (cos (Angle)) * (Length / 2.0 +
420  fabs (sin (Angle)) * (classify_pp_side_pad *
422 
423  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad, debug);
424 
425  Y = Proto->Y + Y_SHIFT;
426  Pad = MAX (fabs (sin (Angle)) * (Length / 2.0 +
429  fabs (cos (Angle)) * (classify_pp_side_pad *
431 
432  FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_Y], Index, Y, Pad, debug);
433 } /* AddProtoToProtoPruner */
434 
435 
441 uinT8 Bucket8For(FLOAT32 param, FLOAT32 offset, int num_buckets) {
442  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
443  return static_cast<uinT8>(ClipToRange(bucket, 0, num_buckets - 1));
444 }
445 uinT16 Bucket16For(FLOAT32 param, FLOAT32 offset, int num_buckets) {
446  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
447  return static_cast<uinT16>(ClipToRange(bucket, 0, num_buckets - 1));
448 }
449 
455 uinT8 CircBucketFor(FLOAT32 param, FLOAT32 offset, int num_buckets) {
456  int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
457  return static_cast<uinT8>(Modulo(bucket, num_buckets));
458 } /* CircBucketFor */
459 
460 
461 #ifndef GRAPHICS_DISABLED
462 
474  if (IntMatchWindow != NULL)
475  IntMatchWindow->Update();
476 } /* ClearMatchDisplay */
477 #endif
478 
493 void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class) {
494  int ProtoId;
495  INT_PROTO Proto;
496  int TotalLength;
497 
498  for (ProtoId = 0, TotalLength = 0;
499  ProtoId < Class->NumProtos; ProtoId++) {
500  if (test_bit(Config, ProtoId)) {
501  Proto = ProtoForProtoId(Class, ProtoId);
502  SET_BIT(Proto->Configs, ConfigId);
503  TotalLength += Class->ProtoLengths[ProtoId];
504  }
505  }
506  Class->ConfigLengths[ConfigId] = TotalLength;
507 } /* ConvertConfig */
508 
509 
510 namespace tesseract {
522 void Classify::ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class) {
523  INT_PROTO P;
524  FLOAT32 Param;
525 
526  assert(ProtoId < Class->NumProtos);
527 
528  P = ProtoForProtoId(Class, ProtoId);
529 
530  Param = Proto->A * 128;
531  P->A = TruncateParam(Param, -128, 127, NULL);
532 
533  Param = -Proto->B * 256;
534  P->B = TruncateParam(Param, 0, 255, NULL);
535 
536  Param = Proto->C * 128;
537  P->C = TruncateParam(Param, -128, 127, NULL);
538 
539  Param = Proto->Angle * 256;
540  if (Param < 0 || Param >= 256)
541  P->Angle = 0;
542  else
543  P->Angle = (uinT8) Param;
544 
545  /* round proto length to nearest integer number of pico-features */
546  Param = (Proto->Length / GetPicoFeatureLength()) + 0.5;
547  Class->ProtoLengths[ProtoId] = TruncateParam(Param, 1, 255, NULL);
549  cprintf("Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
550  P->A, P->B, P->C, Class->ProtoLengths[ProtoId]);
551 } /* ConvertProto */
552 
553 
565  const UNICHARSET&
566  target_unicharset) {
567  INT_TEMPLATES IntTemplates;
568  CLASS_TYPE FClass;
569  INT_CLASS IClass;
570  int ClassId;
571  int ProtoId;
572  int ConfigId;
573 
574  IntTemplates = NewIntTemplates();
575 
576  for (ClassId = 0; ClassId < target_unicharset.size(); ClassId++) {
577  FClass = &(FloatProtos[ClassId]);
578  if (FClass->NumProtos == 0 && FClass->NumConfigs == 0 &&
579  strcmp(target_unicharset.id_to_unichar(ClassId), " ") != 0) {
580  cprintf("Warning: no protos/configs for %s in CreateIntTemplates()\n",
581  target_unicharset.id_to_unichar(ClassId));
582  }
583  assert(UnusedClassIdIn(IntTemplates, ClassId));
584  IClass = NewIntClass(FClass->NumProtos, FClass->NumConfigs);
585  FontSet fs;
586  fs.size = FClass->font_set.size();
587  fs.configs = new int[fs.size];
588  for (int i = 0; i < fs.size; ++i) {
589  fs.configs[i] = FClass->font_set.get(i);
590  }
591  if (this->fontset_table_.contains(fs)) {
592  IClass->font_set_id = this->fontset_table_.get_id(fs);
593  delete[] fs.configs;
594  } else {
595  IClass->font_set_id = this->fontset_table_.push_back(fs);
596  }
597  AddIntClass(IntTemplates, ClassId, IClass);
598 
599  for (ProtoId = 0; ProtoId < FClass->NumProtos; ProtoId++) {
600  AddIntProto(IClass);
601  ConvertProto(ProtoIn(FClass, ProtoId), ProtoId, IClass);
602  AddProtoToProtoPruner(ProtoIn(FClass, ProtoId), ProtoId, IClass,
604  AddProtoToClassPruner(ProtoIn(FClass, ProtoId), ClassId, IntTemplates);
605  }
606 
607  for (ConfigId = 0; ConfigId < FClass->NumConfigs; ConfigId++) {
608  AddIntConfig(IClass);
609  ConvertConfig(FClass->Configurations[ConfigId], ConfigId, IClass);
610  }
611  }
612  return (IntTemplates);
613 } /* CreateIntTemplates */
614 } // namespace tesseract
615 
616 
617 #ifndef GRAPHICS_DISABLED
618 
630 void DisplayIntFeature(const INT_FEATURE_STRUCT* Feature, FLOAT32 Evidence) {
631  ScrollView::Color color = GetMatchColorFor(Evidence);
632  RenderIntFeature(IntMatchWindow, Feature, color);
633  if (FeatureDisplayWindow) {
634  RenderIntFeature(FeatureDisplayWindow, Feature, color);
635  }
636 } /* DisplayIntFeature */
637 
638 
652 void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence) {
653  ScrollView::Color color = GetMatchColorFor(Evidence);
654  RenderIntProto(IntMatchWindow, Class, ProtoId, color);
655  if (ProtoDisplayWindow) {
656  RenderIntProto(ProtoDisplayWindow, Class, ProtoId, color);
657  }
658 } /* DisplayIntProto */
659 #endif
660 
672 INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs) {
673  INT_CLASS Class;
674  PROTO_SET ProtoSet;
675  int i;
676 
677  assert(MaxNumConfigs <= MAX_NUM_CONFIGS);
678 
679  Class = (INT_CLASS) Emalloc(sizeof(INT_CLASS_STRUCT));
680  Class->NumProtoSets = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) /
682 
683  assert(Class->NumProtoSets <= MAX_NUM_PROTO_SETS);
684 
685  Class->NumProtos = 0;
686  Class->NumConfigs = 0;
687 
688  for (i = 0; i < Class->NumProtoSets; i++) {
689  /* allocate space for a proto set, install in class, and initialize */
690  ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
691  memset(ProtoSet, 0, sizeof(*ProtoSet));
692  Class->ProtoSets[i] = ProtoSet;
693 
694  /* allocate space for the proto lengths and install in class */
695  }
696  if (MaxNumIntProtosIn (Class) > 0) {
697  Class->ProtoLengths =
698  (uinT8 *)Emalloc(MaxNumIntProtosIn (Class) * sizeof (uinT8));
699  memset(Class->ProtoLengths, 0,
700  MaxNumIntProtosIn(Class) * sizeof(*Class->ProtoLengths));
701  } else {
702  Class->ProtoLengths = NULL;
703  }
704  memset(Class->ConfigLengths, 0, sizeof(Class->ConfigLengths));
705 
706  return (Class);
707 
708 } /* NewIntClass */
709 
710 
711 void free_int_class(INT_CLASS int_class) {
712  int i;
713 
714  for (i = 0; i < int_class->NumProtoSets; i++) {
715  Efree (int_class->ProtoSets[i]);
716  }
717  if (int_class->ProtoLengths != NULL) {
718  Efree (int_class->ProtoLengths);
719  }
720  Efree(int_class);
721 }
722 
723 
733  INT_TEMPLATES T;
734  int i;
735 
736  T = (INT_TEMPLATES) Emalloc (sizeof (INT_TEMPLATES_STRUCT));
737  T->NumClasses = 0;
738  T->NumClassPruners = 0;
739 
740  for (i = 0; i < MAX_NUM_CLASSES; i++)
741  ClassForClassId (T, i) = NULL;
742 
743  return (T);
744 } /* NewIntTemplates */
745 
746 
747 /*---------------------------------------------------------------------------*/
749  int i;
750 
751  for (i = 0; i < templates->NumClasses; i++)
752  free_int_class(templates->Class[i]);
753  for (i = 0; i < templates->NumClassPruners; i++)
754  delete templates->ClassPruners[i];
755  Efree(templates);
756 }
757 
758 
759 namespace tesseract {
771  int i, j, w, x, y, z;
772  BOOL8 swap;
773  int nread;
774  int unicharset_size;
775  int version_id = 0;
776  INT_TEMPLATES Templates;
777  CLASS_PRUNER_STRUCT* Pruner;
778  INT_CLASS Class;
779  uinT8 *Lengths;
780  PROTO_SET ProtoSet;
781 
782  /* variables for conversion from older inttemp formats */
783  int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
784  CLASS_ID class_id, max_class_id;
785  inT16 *IndexFor = new inT16[MAX_NUM_CLASSES];
786  CLASS_ID *ClassIdFor = new CLASS_ID[MAX_NUM_CLASSES];
787  CLASS_PRUNER_STRUCT **TempClassPruner =
789  uinT32 SetBitsForMask = // word with NUM_BITS_PER_CLASS
790  (1 << NUM_BITS_PER_CLASS) - 1; // set starting at bit 0
791  uinT32 Mask, NewMask, ClassBits;
792  int MaxNumConfigs = MAX_NUM_CONFIGS;
793  int WerdsPerConfigVec = WERDS_PER_CONFIG_VEC;
794 
795  /* first read the high level template struct */
796  Templates = NewIntTemplates();
797  // Read Templates in parts for 64 bit compatibility.
798  if (fread(&unicharset_size, sizeof(int), 1, File) != 1)
799  cprintf("Bad read of inttemp!\n");
800  if (fread(&Templates->NumClasses,
801  sizeof(Templates->NumClasses), 1, File) != 1 ||
802  fread(&Templates->NumClassPruners,
803  sizeof(Templates->NumClassPruners), 1, File) != 1)
804  cprintf("Bad read of inttemp!\n");
805  // Swap status is determined automatically.
806  swap = Templates->NumClassPruners < 0 ||
808  if (swap) {
809  Reverse32(&Templates->NumClassPruners);
810  Reverse32(&Templates->NumClasses);
811  Reverse32(&unicharset_size);
812  }
813  if (Templates->NumClasses < 0) {
814  // This file has a version id!
815  version_id = -Templates->NumClasses;
816  if (fread(&Templates->NumClasses, sizeof(Templates->NumClasses),
817  1, File) != 1)
818  cprintf("Bad read of inttemp!\n");
819  if (swap)
820  Reverse32(&Templates->NumClasses);
821  }
822 
823  if (version_id < 3) {
824  MaxNumConfigs = OLD_MAX_NUM_CONFIGS;
825  WerdsPerConfigVec = OLD_WERDS_PER_CONFIG_VEC;
826  }
827 
828  if (version_id < 2) {
829  for (i = 0; i < unicharset_size; ++i) {
830  if (fread(&IndexFor[i], sizeof(inT16), 1, File) != 1)
831  cprintf("Bad read of inttemp!\n");
832  }
833  for (i = 0; i < Templates->NumClasses; ++i) {
834  if (fread(&ClassIdFor[i], sizeof(CLASS_ID), 1, File) != 1)
835  cprintf("Bad read of inttemp!\n");
836  }
837  if (swap) {
838  for (i = 0; i < Templates->NumClasses; i++)
839  Reverse16(&IndexFor[i]);
840  for (i = 0; i < Templates->NumClasses; i++)
841  Reverse32(&ClassIdFor[i]);
842  }
843  }
844 
845  /* then read in the class pruners */
846  for (i = 0; i < Templates->NumClassPruners; i++) {
847  Pruner = new CLASS_PRUNER_STRUCT;
848  if ((nread =
849  fread(Pruner, 1, sizeof(CLASS_PRUNER_STRUCT),
850  File)) != sizeof(CLASS_PRUNER_STRUCT))
851  cprintf("Bad read of inttemp!\n");
852  if (swap) {
853  for (x = 0; x < NUM_CP_BUCKETS; x++) {
854  for (y = 0; y < NUM_CP_BUCKETS; y++) {
855  for (z = 0; z < NUM_CP_BUCKETS; z++) {
856  for (w = 0; w < WERDS_PER_CP_VECTOR; w++) {
857  Reverse32(&Pruner->p[x][y][z][w]);
858  }
859  }
860  }
861  }
862  }
863  if (version_id < 2) {
864  TempClassPruner[i] = Pruner;
865  } else {
866  Templates->ClassPruners[i] = Pruner;
867  }
868  }
869 
870  /* fix class pruners if they came from an old version of inttemp */
871  if (version_id < 2) {
872  // Allocate enough class pruners to cover all the class ids.
873  max_class_id = 0;
874  for (i = 0; i < Templates->NumClasses; i++)
875  if (ClassIdFor[i] > max_class_id)
876  max_class_id = ClassIdFor[i];
877  for (i = 0; i <= CPrunerIdFor(max_class_id); i++) {
878  Templates->ClassPruners[i] = new CLASS_PRUNER_STRUCT;
879  memset(Templates->ClassPruners[i], 0, sizeof(CLASS_PRUNER_STRUCT));
880  }
881  // Convert class pruners from the old format (indexed by class index)
882  // to the new format (indexed by class id).
883  last_cp_bit_number = NUM_BITS_PER_CLASS * Templates->NumClasses - 1;
884  for (i = 0; i < Templates->NumClassPruners; i++) {
885  for (x = 0; x < NUM_CP_BUCKETS; x++)
886  for (y = 0; y < NUM_CP_BUCKETS; y++)
887  for (z = 0; z < NUM_CP_BUCKETS; z++)
888  for (w = 0; w < WERDS_PER_CP_VECTOR; w++) {
889  if (TempClassPruner[i]->p[x][y][z][w] == 0)
890  continue;
891  for (b = 0; b < BITS_PER_WERD; b += NUM_BITS_PER_CLASS) {
892  bit_number = i * BITS_PER_CP_VECTOR + w * BITS_PER_WERD + b;
893  if (bit_number > last_cp_bit_number)
894  break; // the rest of the bits in this word are not used
895  class_id = ClassIdFor[bit_number / NUM_BITS_PER_CLASS];
896  // Single out NUM_BITS_PER_CLASS bits relating to class_id.
897  Mask = SetBitsForMask << b;
898  ClassBits = TempClassPruner[i]->p[x][y][z][w] & Mask;
899  // Move these bits to the new position in which they should
900  // appear (indexed corresponding to the class_id).
901  new_i = CPrunerIdFor(class_id);
902  new_w = CPrunerWordIndexFor(class_id);
903  new_b = CPrunerBitIndexFor(class_id) * NUM_BITS_PER_CLASS;
904  if (new_b > b) {
905  ClassBits <<= (new_b - b);
906  } else {
907  ClassBits >>= (b - new_b);
908  }
909  // Copy bits relating to class_id to the correct position
910  // in Templates->ClassPruner.
911  NewMask = SetBitsForMask << new_b;
912  Templates->ClassPruners[new_i]->p[x][y][z][new_w] &= ~NewMask;
913  Templates->ClassPruners[new_i]->p[x][y][z][new_w] |= ClassBits;
914  }
915  }
916  }
917  for (i = 0; i < Templates->NumClassPruners; i++) {
918  delete TempClassPruner[i];
919  }
920  }
921 
922  /* then read in each class */
923  for (i = 0; i < Templates->NumClasses; i++) {
924  /* first read in the high level struct for the class */
925  Class = (INT_CLASS) Emalloc (sizeof (INT_CLASS_STRUCT));
926  if (fread(&Class->NumProtos, sizeof(Class->NumProtos), 1, File) != 1 ||
927  fread(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File) != 1 ||
928  fread(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File) != 1)
929  cprintf ("Bad read of inttemp!\n");
930  if (version_id == 0) {
931  // Only version 0 writes 5 pointless pointers to the file.
932  for (j = 0; j < 5; ++j) {
933  int junk;
934  if (fread(&junk, sizeof(junk), 1, File) != 1)
935  cprintf ("Bad read of inttemp!\n");
936  }
937  }
938  if (version_id < 4) {
939  for (j = 0; j < MaxNumConfigs; ++j) {
940  if (fread(&Class->ConfigLengths[j], sizeof(uinT16), 1, File) != 1)
941  cprintf ("Bad read of inttemp!\n");
942  }
943  if (swap) {
944  Reverse16(&Class->NumProtos);
945  for (j = 0; j < MaxNumConfigs; j++)
946  Reverse16(&Class->ConfigLengths[j]);
947  }
948  } else {
949  ASSERT_HOST(Class->NumConfigs < MaxNumConfigs);
950  for (j = 0; j < Class->NumConfigs; ++j) {
951  if (fread(&Class->ConfigLengths[j], sizeof(uinT16), 1, File) != 1)
952  cprintf ("Bad read of inttemp!\n");
953  }
954  if (swap) {
955  Reverse16(&Class->NumProtos);
956  for (j = 0; j < MaxNumConfigs; j++)
957  Reverse16(&Class->ConfigLengths[j]);
958  }
959  }
960  if (version_id < 2) {
961  ClassForClassId (Templates, ClassIdFor[i]) = Class;
962  } else {
963  ClassForClassId (Templates, i) = Class;
964  }
965 
966  /* then read in the proto lengths */
967  Lengths = NULL;
968  if (MaxNumIntProtosIn (Class) > 0) {
969  Lengths = (uinT8 *)Emalloc(sizeof(uinT8) * MaxNumIntProtosIn(Class));
970  if ((nread =
971  fread((char *)Lengths, sizeof(uinT8),
972  MaxNumIntProtosIn(Class), File)) != MaxNumIntProtosIn (Class))
973  cprintf ("Bad read of inttemp!\n");
974  }
975  Class->ProtoLengths = Lengths;
976 
977  /* then read in the proto sets */
978  for (j = 0; j < Class->NumProtoSets; j++) {
979  ProtoSet = (PROTO_SET)Emalloc(sizeof(PROTO_SET_STRUCT));
980  if (version_id < 3) {
981  if ((nread =
982  fread((char *) &ProtoSet->ProtoPruner, 1,
983  sizeof(PROTO_PRUNER), File)) != sizeof(PROTO_PRUNER))
984  cprintf("Bad read of inttemp!\n");
985  for (x = 0; x < PROTOS_PER_PROTO_SET; x++) {
986  if ((nread = fread((char *) &ProtoSet->Protos[x].A, 1,
987  sizeof(inT8), File)) != sizeof(inT8) ||
988  (nread = fread((char *) &ProtoSet->Protos[x].B, 1,
989  sizeof(uinT8), File)) != sizeof(uinT8) ||
990  (nread = fread((char *) &ProtoSet->Protos[x].C, 1,
991  sizeof(inT8), File)) != sizeof(inT8) ||
992  (nread = fread((char *) &ProtoSet->Protos[x].Angle, 1,
993  sizeof(uinT8), File)) != sizeof(uinT8))
994  cprintf("Bad read of inttemp!\n");
995  for (y = 0; y < WerdsPerConfigVec; y++)
996  if ((nread = fread((char *) &ProtoSet->Protos[x].Configs[y], 1,
997  sizeof(uinT32), File)) != sizeof(uinT32))
998  cprintf("Bad read of inttemp!\n");
999  }
1000  } else {
1001  if ((nread =
1002  fread((char *) ProtoSet, 1, sizeof(PROTO_SET_STRUCT),
1003  File)) != sizeof(PROTO_SET_STRUCT))
1004  cprintf("Bad read of inttemp!\n");
1005  }
1006  if (swap) {
1007  for (x = 0; x < NUM_PP_PARAMS; x++)
1008  for (y = 0; y < NUM_PP_BUCKETS; y++)
1009  for (z = 0; z < WERDS_PER_PP_VECTOR; z++)
1010  Reverse32(&ProtoSet->ProtoPruner[x][y][z]);
1011  for (x = 0; x < PROTOS_PER_PROTO_SET; x++)
1012  for (y = 0; y < WerdsPerConfigVec; y++)
1013  Reverse32(&ProtoSet->Protos[x].Configs[y]);
1014  }
1015  Class->ProtoSets[j] = ProtoSet;
1016  }
1017  if (version_id < 4)
1018  Class->font_set_id = -1;
1019  else {
1020  fread(&Class->font_set_id, sizeof(int), 1, File);
1021  if (swap)
1022  Reverse32(&Class->font_set_id);
1023  }
1024  }
1025 
1026  if (version_id < 2) {
1027  /* add an empty NULL class with class id 0 */
1028  assert(UnusedClassIdIn (Templates, 0));
1029  ClassForClassId (Templates, 0) = NewIntClass (1, 1);
1030  ClassForClassId (Templates, 0)->font_set_id = -1;
1031  Templates->NumClasses++;
1032  /* make sure the classes are contiguous */
1033  for (i = 0; i < MAX_NUM_CLASSES; i++) {
1034  if (i < Templates->NumClasses) {
1035  if (ClassForClassId (Templates, i) == NULL) {
1036  fprintf(stderr, "Non-contiguous class ids in inttemp\n");
1037  exit(1);
1038  }
1039  } else {
1040  if (ClassForClassId (Templates, i) != NULL) {
1041  fprintf(stderr, "Class id %d exceeds NumClassesIn (Templates) %d\n",
1042  i, Templates->NumClasses);
1043  exit(1);
1044  }
1045  }
1046  }
1047  }
1048  if (version_id >= 4) {
1049  this->fontinfo_table_.read(File, NewPermanentTessCallback(read_info), swap);
1050  if (version_id >= 5) {
1051  this->fontinfo_table_.read(File,
1053  swap);
1054  }
1055  this->fontset_table_.read(File, NewPermanentTessCallback(read_set), swap);
1056  }
1057 
1058  // Clean up.
1059  delete[] IndexFor;
1060  delete[] ClassIdFor;
1061  delete[] TempClassPruner;
1062 
1063  return (Templates);
1064 } /* ReadIntTemplates */
1065 
1066 
1067 #ifndef GRAPHICS_DISABLED
1068 
1081  if (ProtoDisplayWindow) {
1082  ProtoDisplayWindow->Clear();
1083  }
1084  if (FeatureDisplayWindow) {
1085  FeatureDisplayWindow->Clear();
1086  }
1088  static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
1089  IntMatchWindow);
1090  IntMatchWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
1091  INT_MAX_X, INT_MAX_Y);
1092  if (ProtoDisplayWindow) {
1093  ProtoDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
1094  INT_MAX_X, INT_MAX_Y);
1095  }
1096  if (FeatureDisplayWindow) {
1097  FeatureDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
1098  INT_MAX_X, INT_MAX_Y);
1099  }
1100 } /* ShowMatchDisplay */
1101 
1104 void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView* window) {
1105  window->Clear();
1106 
1107  window->Pen(ScrollView::GREY);
1108  // Draw the feature space limit rectangle.
1109  window->Rectangle(0, 0, INT_MAX_X, INT_MAX_Y);
1110  if (norm_method == baseline) {
1111  window->SetCursor(0, INT_DESCENDER);
1112  window->DrawTo(INT_MAX_X, INT_DESCENDER);
1113  window->SetCursor(0, INT_BASELINE);
1114  window->DrawTo(INT_MAX_X, INT_BASELINE);
1115  window->SetCursor(0, INT_XHEIGHT);
1116  window->DrawTo(INT_MAX_X, INT_XHEIGHT);
1117  window->SetCursor(0, INT_CAPHEIGHT);
1118  window->DrawTo(INT_MAX_X, INT_CAPHEIGHT);
1119  } else {
1122  }
1123 }
1124 #endif
1125 
1139  const UNICHARSET& target_unicharset) {
1140  int i, j;
1141  INT_CLASS Class;
1142  int unicharset_size = target_unicharset.size();
1143  int version_id = -5; // When negated by the reader -1 becomes +1 etc.
1144 
1145  if (Templates->NumClasses != unicharset_size) {
1146  cprintf("Warning: executing WriteIntTemplates() with %d classes in"
1147  " Templates, while target_unicharset size is %d\n",
1148  Templates->NumClasses, unicharset_size);
1149  }
1150 
1151  /* first write the high level template struct */
1152  fwrite(&unicharset_size, sizeof(unicharset_size), 1, File);
1153  fwrite(&version_id, sizeof(version_id), 1, File);
1154  fwrite(&Templates->NumClassPruners, sizeof(Templates->NumClassPruners),
1155  1, File);
1156  fwrite(&Templates->NumClasses, sizeof(Templates->NumClasses), 1, File);
1157 
1158  /* then write out the class pruners */
1159  for (i = 0; i < Templates->NumClassPruners; i++)
1160  fwrite(Templates->ClassPruners[i],
1161  sizeof(CLASS_PRUNER_STRUCT), 1, File);
1162 
1163  /* then write out each class */
1164  for (i = 0; i < Templates->NumClasses; i++) {
1165  Class = Templates->Class[i];
1166 
1167  /* first write out the high level struct for the class */
1168  fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
1169  fwrite(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File);
1170  ASSERT_HOST(Class->NumConfigs == this->fontset_table_.get(Class->font_set_id).size);
1171  fwrite(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File);
1172  for (j = 0; j < Class->NumConfigs; ++j) {
1173  fwrite(&Class->ConfigLengths[j], sizeof(uinT16), 1, File);
1174  }
1175 
1176  /* then write out the proto lengths */
1177  if (MaxNumIntProtosIn (Class) > 0) {
1178  fwrite ((char *) (Class->ProtoLengths), sizeof (uinT8),
1179  MaxNumIntProtosIn (Class), File);
1180  }
1181 
1182  /* then write out the proto sets */
1183  for (j = 0; j < Class->NumProtoSets; j++)
1184  fwrite ((char *) Class->ProtoSets[j],
1185  sizeof (PROTO_SET_STRUCT), 1, File);
1186 
1187  /* then write the fonts info */
1188  fwrite(&Class->font_set_id, sizeof(int), 1, File);
1189  }
1190 
1191  /* Write the fonts info tables */
1193  this->fontinfo_table_.write(File,
1196 } /* WriteIntTemplates */
1197 } // namespace tesseract
1198 
1199 
1200 /*-----------------------------------------------------------------------------
1201  Private Code
1202 -----------------------------------------------------------------------------*/
1216 FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets) {
1217  return (((FLOAT32) Bucket / NumBuckets) - Offset);
1218 
1219 } /* BucketStart */
1220 
1221 
1235 FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets) {
1236  return (((FLOAT32) (Bucket + 1) / NumBuckets) - Offset);
1237 } /* BucketEnd */
1238 
1239 
1254 void DoFill(FILL_SPEC *FillSpec,
1255  CLASS_PRUNER_STRUCT* Pruner,
1256  register uinT32 ClassMask,
1257  register uinT32 ClassCount,
1258  register uinT32 WordIndex) {
1259  register int X, Y, Angle;
1260  register uinT32 OldWord;
1261 
1262  X = FillSpec->X;
1263  if (X < 0)
1264  X = 0;
1265  if (X >= NUM_CP_BUCKETS)
1266  X = NUM_CP_BUCKETS - 1;
1267 
1268  if (FillSpec->YStart < 0)
1269  FillSpec->YStart = 0;
1270  if (FillSpec->YEnd >= NUM_CP_BUCKETS)
1271  FillSpec->YEnd = NUM_CP_BUCKETS - 1;
1272 
1273  for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
1274  for (Angle = FillSpec->AngleStart;
1276  OldWord = Pruner->p[X][Y][Angle][WordIndex];
1277  if (ClassCount > (OldWord & ClassMask)) {
1278  OldWord &= ~ClassMask;
1279  OldWord |= ClassCount;
1280  Pruner->p[X][Y][Angle][WordIndex] = OldWord;
1281  }
1282  if (Angle == FillSpec->AngleEnd)
1283  break;
1284  }
1285 } /* DoFill */
1286 
1287 
1298  FILL_SWITCH *Next;
1299 
1300  Next = &(Filler->Switch[Filler->NextSwitch]);
1301 
1302  if (Filler->X > Next->X && Next->Type == LastSwitch)
1303  return (TRUE);
1304  else
1305  return (FALSE);
1306 
1307 } /* FillerDone */
1308 
1309 
1328  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) {
1329  int i, FirstBucket, LastBucket;
1330 
1331  if (Spread > 0.5)
1332  Spread = 0.5;
1333 
1334  FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
1335  if (FirstBucket < 0)
1336  FirstBucket += NUM_PP_BUCKETS;
1337 
1338  LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
1339  if (LastBucket >= NUM_PP_BUCKETS)
1340  LastBucket -= NUM_PP_BUCKETS;
1341  if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
1342  for (i = FirstBucket; TRUE; CircularIncrement (i, NUM_PP_BUCKETS)) {
1343  SET_BIT (ParamTable[i], Bit);
1344 
1345  /* exit loop after we have set the bit for the last bucket */
1346  if (i == LastBucket)
1347  break;
1348  }
1349 
1350 } /* FillPPCircularBits */
1351 
1352 
1372  int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) {
1373  int i, FirstBucket, LastBucket;
1374 
1375  FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
1376  if (FirstBucket < 0)
1377  FirstBucket = 0;
1378 
1379  LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
1380  if (LastBucket >= NUM_PP_BUCKETS)
1381  LastBucket = NUM_PP_BUCKETS - 1;
1382 
1383  if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
1384  for (i = FirstBucket; i <= LastBucket; i++)
1385  SET_BIT (ParamTable[i], Bit);
1386 
1387 } /* FillPPLinearBits */
1388 
1389 
1390 /*---------------------------------------------------------------------------*/
1391 #ifndef GRAPHICS_DISABLED
1392 namespace tesseract {
1405 CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool* adaptive_on,
1406  bool* pretrained_on, int* shape_id) {
1407  tprintf("%s\n", Prompt);
1408  SVEvent* ev;
1409  SVEventType ev_type;
1410  int unichar_id = INVALID_UNICHAR_ID;
1411  // Wait until a click or popup event.
1412  do {
1413  ev = IntMatchWindow->AwaitEvent(SVET_ANY);
1414  ev_type = ev->type;
1415  if (ev_type == SVET_POPUP) {
1416  if (ev->command_id == IDA_SHAPE_INDEX) {
1417  if (shape_table_ != NULL) {
1418  *shape_id = atoi(ev->parameter);
1419  *adaptive_on = false;
1420  *pretrained_on = true;
1421  if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1422  int font_id;
1423  shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1424  &font_id);
1425  tprintf("Shape %d, first unichar=%d, font=%d\n",
1426  *shape_id, unichar_id, font_id);
1427  return unichar_id;
1428  }
1429  tprintf("Shape index '%s' not found in shape table\n", ev->parameter);
1430  } else {
1431  tprintf("No shape table loaded!\n");
1432  }
1433  } else {
1435  unichar_id = unicharset.unichar_to_id(ev->parameter);
1436  if (ev->command_id == IDA_ADAPTIVE) {
1437  *adaptive_on = true;
1438  *pretrained_on = false;
1439  *shape_id = -1;
1440  } else if (ev->command_id == IDA_STATIC) {
1441  *adaptive_on = false;
1442  *pretrained_on = true;
1443  } else {
1444  *adaptive_on = true;
1445  *pretrained_on = true;
1446  }
1447  if (ev->command_id == IDA_ADAPTIVE || shape_table_ == NULL) {
1448  *shape_id = -1;
1449  return unichar_id;
1450  }
1451  for (int s = 0; s < shape_table_->NumShapes(); ++s) {
1452  if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1453  tprintf("%s\n", shape_table_->DebugStr(s).string());
1454  }
1455  }
1456  } else {
1457  tprintf("Char class '%s' not found in unicharset",
1458  ev->parameter);
1459  }
1460  }
1461  }
1462  delete ev;
1463  } while (ev_type != SVET_CLICK);
1464  return 0;
1465 } /* GetClassToDebug */
1466 
1467 } // namespace tesseract
1468 #endif
1469 
1485 void GetCPPadsForLevel(int Level,
1486  FLOAT32 *EndPad,
1487  FLOAT32 *SidePad,
1488  FLOAT32 *AnglePad) {
1489  switch (Level) {
1490  case 0:
1493  *AnglePad = classify_cp_angle_pad_loose / 360.0;
1494  break;
1495 
1496  case 1:
1499  *AnglePad = classify_cp_angle_pad_medium / 360.0;
1500  break;
1501 
1502  case 2:
1505  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1506  break;
1507 
1508  default:
1511  *AnglePad = classify_cp_angle_pad_tight / 360.0;
1512  break;
1513  }
1514  if (*AnglePad > 0.5)
1515  *AnglePad = 0.5;
1516 
1517 } /* GetCPPadsForLevel */
1518 
1519 
1528  assert (Evidence >= 0.0);
1529  assert (Evidence <= 1.0);
1530 
1531  if (Evidence >= 0.90)
1532  return ScrollView::WHITE;
1533  else if (Evidence >= 0.75)
1534  return ScrollView::GREEN;
1535  else if (Evidence >= 0.50)
1536  return ScrollView::RED;
1537  else
1538  return ScrollView::BLUE;
1539 } /* GetMatchColorFor */
1540 
1541 
1554 void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {
1555  FILL_SWITCH *Next;
1556 
1557  /* compute the fill assuming no switches will be encountered */
1558  Fill->AngleStart = Filler->AngleStart;
1559  Fill->AngleEnd = Filler->AngleEnd;
1560  Fill->X = Filler->X;
1561  Fill->YStart = Filler->YStart >> 8;
1562  Fill->YEnd = Filler->YEnd >> 8;
1563 
1564  /* update the fill info and the filler for ALL switches at this X value */
1565  Next = &(Filler->Switch[Filler->NextSwitch]);
1566  while (Filler->X >= Next->X) {
1567  Fill->X = Filler->X = Next->X;
1568  if (Next->Type == StartSwitch) {
1569  Fill->YStart = Next->Y;
1570  Filler->StartDelta = Next->Delta;
1571  Filler->YStart = Next->YInit;
1572  }
1573  else if (Next->Type == EndSwitch) {
1574  Fill->YEnd = Next->Y;
1575  Filler->EndDelta = Next->Delta;
1576  Filler->YEnd = Next->YInit;
1577  }
1578  else { /* Type must be LastSwitch */
1579  break;
1580  }
1581  Filler->NextSwitch++;
1582  Next = &(Filler->Switch[Filler->NextSwitch]);
1583  }
1584 
1585  /* prepare the filler for the next call to this routine */
1586  Filler->X++;
1587  Filler->YStart += Filler->StartDelta;
1588  Filler->YEnd += Filler->EndDelta;
1589 
1590 } /* GetNextFill */
1591 
1592 
1607 void InitTableFiller (FLOAT32 EndPad, FLOAT32 SidePad,
1608  FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER * Filler)
1609 #define XS X_SHIFT
1610 #define YS Y_SHIFT
1611 #define AS ANGLE_SHIFT
1612 #define NB NUM_CP_BUCKETS
1613 {
1614  FLOAT32 Angle;
1615  FLOAT32 X, Y, HalfLength;
1616  FLOAT32 Cos, Sin;
1617  FLOAT32 XAdjust, YAdjust;
1618  FPOINT Start, Switch1, Switch2, End;
1619  int S1 = 0;
1620  int S2 = 1;
1621 
1622  Angle = Proto->Angle;
1623  X = Proto->X;
1624  Y = Proto->Y;
1625  HalfLength = Proto->Length / 2.0;
1626 
1627  Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
1628  Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
1629  Filler->NextSwitch = 0;
1630 
1631  if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
1632  /* horizontal proto - handle as special case */
1633  Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
1634  Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
1635  Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
1636  Filler->StartDelta = 0;
1637  Filler->EndDelta = 0;
1638  Filler->Switch[0].Type = LastSwitch;
1639  Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
1640  } else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
1641  fabs(Angle - 0.75) < HV_TOLERANCE) {
1642  /* vertical proto - handle as special case */
1643  Filler->X = Bucket8For(X - SidePad, XS, NB);
1644  Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
1645  Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
1646  Filler->StartDelta = 0;
1647  Filler->EndDelta = 0;
1648  Filler->Switch[0].Type = LastSwitch;
1649  Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
1650  } else {
1651  /* diagonal proto */
1652 
1653  if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1654  /* rising diagonal proto */
1655  Angle *= 2.0 * PI;
1656  Cos = fabs(cos(Angle));
1657  Sin = fabs(sin(Angle));
1658 
1659  /* compute the positions of the corners of the acceptance region */
1660  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1661  Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1662  End.x = 2.0 * X - Start.x;
1663  End.y = 2.0 * Y - Start.y;
1664  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1665  Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1666  Switch2.x = 2.0 * X - Switch1.x;
1667  Switch2.y = 2.0 * Y - Switch1.y;
1668 
1669  if (Switch1.x > Switch2.x) {
1670  S1 = 1;
1671  S2 = 0;
1672  }
1673 
1674  /* translate into bucket positions and deltas */
1675  Filler->X = Bucket8For(Start.x, XS, NB);
1676  Filler->StartDelta = -(inT16) ((Cos / Sin) * 256);
1677  Filler->EndDelta = (inT16) ((Sin / Cos) * 256);
1678 
1679  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1680  YAdjust = XAdjust * Cos / Sin;
1681  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1682  YAdjust = XAdjust * Sin / Cos;
1683  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1684 
1685  Filler->Switch[S1].Type = StartSwitch;
1686  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1687  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1688  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1689  YAdjust = XAdjust * Sin / Cos;
1690  Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
1691  Filler->Switch[S1].Delta = Filler->EndDelta;
1692 
1693  Filler->Switch[S2].Type = EndSwitch;
1694  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1695  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1696  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1697  YAdjust = XAdjust * Cos / Sin;
1698  Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
1699  Filler->Switch[S2].Delta = Filler->StartDelta;
1700 
1701  Filler->Switch[2].Type = LastSwitch;
1702  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1703  } else {
1704  /* falling diagonal proto */
1705  Angle *= 2.0 * PI;
1706  Cos = fabs(cos(Angle));
1707  Sin = fabs(sin(Angle));
1708 
1709  /* compute the positions of the corners of the acceptance region */
1710  Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1711  Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1712  End.x = 2.0 * X - Start.x;
1713  End.y = 2.0 * Y - Start.y;
1714  Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1715  Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1716  Switch2.x = 2.0 * X - Switch1.x;
1717  Switch2.y = 2.0 * Y - Switch1.y;
1718 
1719  if (Switch1.x > Switch2.x) {
1720  S1 = 1;
1721  S2 = 0;
1722  }
1723 
1724  /* translate into bucket positions and deltas */
1725  Filler->X = Bucket8For(Start.x, XS, NB);
1726  Filler->StartDelta = -(inT16) ((Sin / Cos) * 256);
1727  Filler->EndDelta = (inT16) ((Cos / Sin) * 256);
1728 
1729  XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1730  YAdjust = XAdjust * Sin / Cos;
1731  Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1732  YAdjust = XAdjust * Cos / Sin;
1733  Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1734 
1735  Filler->Switch[S1].Type = EndSwitch;
1736  Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1737  Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1738  XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1739  YAdjust = XAdjust * Sin / Cos;
1740  Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
1741  Filler->Switch[S1].Delta = Filler->StartDelta;
1742 
1743  Filler->Switch[S2].Type = StartSwitch;
1744  Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1745  Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1746  XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1747  YAdjust = XAdjust * Cos / Sin;
1748  Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
1749  Filler->Switch[S2].Delta = Filler->EndDelta;
1750 
1751  Filler->Switch[2].Type = LastSwitch;
1752  Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1753  }
1754  }
1755 } /* InitTableFiller */
1756 
1757 
1758 /*---------------------------------------------------------------------------*/
1759 #ifndef GRAPHICS_DISABLED
1760 
1770 void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
1771  ScrollView::Color color) {
1772  FLOAT32 X, Y, Dx, Dy, Length;
1773 
1774  window->Pen(color);
1775  assert(Feature != NULL);
1776  assert(color != 0);
1777 
1778  X = Feature->X;
1779  Y = Feature->Y;
1780  Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
1781  // The -PI has no significant effect here, but the value of Theta is computed
1782  // using BinaryAnglePlusPi in intfx.cpp.
1783  Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * PI - PI);
1784  Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * PI - PI);
1785 
1786  window->SetCursor(X, Y);
1787  window->DrawTo(X + Dx, Y + Dy);
1788 } /* RenderIntFeature */
1789 
1790 
1808  INT_CLASS Class,
1809  PROTO_ID ProtoId,
1810  ScrollView::Color color) {
1811  PROTO_SET ProtoSet;
1812  INT_PROTO Proto;
1813  int ProtoSetIndex;
1814  int ProtoWordIndex;
1815  FLOAT32 Length;
1816  int Xmin, Xmax, Ymin, Ymax;
1817  FLOAT32 X, Y, Dx, Dy;
1818  uinT32 ProtoMask;
1819  int Bucket;
1820 
1821  assert(ProtoId >= 0);
1822  assert(Class != NULL);
1823  assert(ProtoId < Class->NumProtos);
1824  assert(color != 0);
1825  window->Pen(color);
1826 
1827  ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
1828  ProtoSetIndex = IndexForProto(ProtoId);
1829  Proto = &(ProtoSet->Protos[ProtoSetIndex]);
1830  Length = (Class->ProtoLengths[ProtoId] *
1832  ProtoMask = PPrunerMaskFor(ProtoId);
1833  ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
1834 
1835  // find the x and y extent of the proto from the proto pruning table
1836  Xmin = Ymin = NUM_PP_BUCKETS;
1837  Xmax = Ymax = 0;
1838  for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
1839  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
1840  UpdateRange(Bucket, &Xmin, &Xmax);
1841  }
1842 
1843  if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
1844  UpdateRange(Bucket, &Ymin, &Ymax);
1845  }
1846  }
1847  X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1848  Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1849  // The -PI has no significant effect here, but the value of Theta is computed
1850  // using BinaryAnglePlusPi in intfx.cpp.
1851  Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * PI - PI);
1852  Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * PI - PI);
1853 
1854  window->SetCursor(X - Dx, Y - Dy);
1855  window->DrawTo(X + Dx, Y + Dy);
1856 } /* RenderIntProto */
1857 #endif
1858 
1874 int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id) {
1875  if (Param < Min) {
1876  if (Id)
1877  cprintf("Warning: Param %s truncated from %f to %d!\n",
1878  Id, Param, Min);
1879  Param = Min;
1880  } else if (Param > Max) {
1881  if (Id)
1882  cprintf("Warning: Param %s truncated from %f to %d!\n",
1883  Id, Param, Max);
1884  Param = Max;
1885  }
1886  return static_cast<int>(floor(Param));
1887 } /* TruncateParam */
1888 
1889 
1890 #ifndef GRAPHICS_DISABLED
1891 
1896  if (IntMatchWindow == NULL) {
1897  IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
1898  SVMenuNode* popup_menu = new SVMenuNode();
1899 
1900  popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
1901  "x", "Class to debug");
1902  popup_menu->AddChild("Debug Static classes", IDA_STATIC,
1903  "x", "Class to debug");
1904  popup_menu->AddChild("Debug Both", IDA_BOTH,
1905  "x", "Class to debug");
1906  popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
1907  "0", "Index to debug");
1908  popup_menu->BuildMenu(IntMatchWindow, false);
1909  }
1910 }
1911 
1917  if (ProtoDisplayWindow == NULL) {
1918  ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
1919  550, 200);
1920  }
1921 }
1922 
1928  if (FeatureDisplayWindow == NULL) {
1929  FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
1930  50, 700);
1931  }
1932 }
1933 
1936 ScrollView* CreateFeatureSpaceWindow(const char* name, int xpos, int ypos) {
1937  return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
1938 }
1939 #endif // GRAPHICS_DISABLED
uinT8 AngleEnd
Definition: intproto.cpp:106
uinT16 Bucket16For(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:445
#define isnan(x)
Definition: mathfix.h:31
#define MAX_LEVEL
#define PPrunerMaskFor(I)
Definition: intproto.h:176
void Pen(Color color)
Definition: scrollview.cpp:726
#define INT_YCENTER
Definition: intproto.cpp:62
#define NUM_CP_BUCKETS
Definition: intproto.h:52
#define X_SHIFT
Definition: intproto.h:40
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
Definition: intproto.cpp:389
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
Definition: intproto.h:125
const UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:194
#define XS
#define ANGLE_SHIFT
Definition: intproto.h:39
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, FLOAT32 Evidence)
Definition: intproto.cpp:630
#define INT_CHAR_NORM_RANGE
Definition: intproto.h:133
FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets)
Definition: intproto.cpp:1235
float FLOAT32
Definition: host.h:111
#define MAX(x, y)
Definition: ndminx.h:24
inT16 PROTO_ID
Definition: matchdefs.h:41
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:168
void * Erealloc(void *ptr, int size)
Definition: emalloc.cpp:64
double classify_cp_angle_pad_tight
Definition: intproto.cpp:196
double classify_cp_side_pad_loose
Definition: intproto.cpp:200
bool read_info(FILE *f, FontInfo *fi, bool swap)
Definition: fontinfo.cpp:152
INT_CLASS Class[MAX_NUM_CLASSES]
Definition: intproto.h:124
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:1104
#define MAX_NUM_CLASSES
Definition: matchdefs.h:31
#define double_VAR(name, val, comment)
Definition: params.h:286
#define ProtoIn(Class, Pid)
Definition: protos.h:123
double classify_cp_end_pad_tight
Definition: intproto.cpp:199
#define INT_MIN_Y
Definition: intproto.cpp:66
#define MaxNumIntProtosIn(C)
Definition: intproto.h:168
#define MAX_NUM_SWITCHES
Definition: intproto.cpp:76
#define WERDS_PER_PP_VECTOR
Definition: intproto.h:62
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
Definition: intproto.h:97
#define MAX_NUM_CONFIGS
Definition: intproto.h:46
static void Update()
Definition: scrollview.cpp:715
#define PRUNER_ANGLE
Definition: intproto.h:36
#define IndexForProto(P)
Definition: intproto.h:170
uinT8 Bucket8For(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:441
uinT32 * BIT_VECTOR
Definition: bitvec.h:28
#define tprintf(...)
Definition: tprintf.h:31
int classify_num_cp_levels
Definition: intproto.cpp:190
void DrawTo(int x, int y)
Definition: scrollview.cpp:531
inT8 YStart
Definition: intproto.cpp:105
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:121
struct INT_CLASS_STRUCT * INT_CLASS
inT16 NumConfigs
Definition: protos.h:62
void Reverse32(void *ptr)
Definition: helpers.h:193
UNICHARSET unicharset
Definition: ccutil.h:72
#define INT_YRADIUS
Definition: intproto.cpp:64
void InitIntMatchWindowIfReqd()
Definition: intproto.cpp:1895
ScrollView * ProtoDisplayWindow
Definition: intproto.cpp:183
inT16 YStart
Definition: intproto.cpp:94
void InitFeatureDisplayWindowIfReqd()
Definition: intproto.cpp:1927
#define Y_SHIFT
Definition: intproto.h:41
int command_id
Definition: scrollview.h:70
unsigned char BOOL8
Definition: host.h:113
uinT32 PROTO_PRUNER[NUM_PP_PARAMS][NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR]
Definition: intproto.h:92
#define CPrunerIdFor(c)
Definition: intproto.h:183
double classify_cp_side_pad_tight
Definition: intproto.cpp:202
#define INT_MAX_X
Definition: intproto.cpp:67
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class)
Definition: intproto.cpp:522
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence)
Definition: intproto.cpp:652
bool read_set(FILE *f, FontSet *fs, bool swap)
Definition: fontinfo.cpp:240
#define CPrunerWordIndexFor(c)
Definition: intproto.h:185
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
Definition: intproto.cpp:346
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:125
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
Definition: intproto.cpp:672
#define test_bit(array, bit)
Definition: bitvec.h:61
UnicityTableEqEq< int > font_set
Definition: protos.h:65
UNICHAR_ID CLASS_ID
Definition: matchdefs.h:35
inT16 NumProtos
Definition: protos.h:59
UnicityTable< FontInfo > fontinfo_table_
Definition: classify.h:488
int Modulo(int a, int b)
Definition: helpers.h:157
uinT16 ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:113
bool ContainsUnichar(int unichar_id) const
Definition: shapetable.cpp:156
double classify_pp_end_pad
Definition: intproto.cpp:204
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:564
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, register uinT32 ClassMask, register uinT32 ClassCount, register uinT32 WordIndex)
Definition: intproto.cpp:1254
int AddIntConfig(INT_CLASS Class)
Definition: intproto.cpp:272
#define INT_XRADIUS
Definition: intproto.cpp:63
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:115
int classify_learning_debug_level
Definition: classify.h:419
#define ASSERT_HOST(x)
Definition: errcode.h:84
#define WERDS_PER_CP_VECTOR
Definition: intproto.h:61
#define PRUNER_Y
Definition: intproto.h:35
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
Definition: intproto.h:111
#define MapParam(P, O, N)
Definition: intproto.cpp:125
SVEventType
Definition: scrollview.h:45
#define MAX_NUM_PROTO_SETS
Definition: intproto.h:49
inT16 YEnd
Definition: intproto.cpp:94
#define ProtoForProtoId(C, P)
Definition: intproto.h:171
double classify_cp_end_pad_medium
Definition: intproto.cpp:198
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:211
FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets)
Definition: intproto.cpp:1216
double classify_cp_angle_pad_medium
Definition: intproto.cpp:194
#define HV_TOLERANCE
Definition: intproto.cpp:71
#define MAX_NUM_CLASS_PRUNERS
Definition: intproto.h:59
Definition: fpoint.h:29
void Clear()
Definition: scrollview.cpp:595
double classify_pp_side_pad
Definition: intproto.cpp:205
uinT8 AngleEnd
Definition: intproto.cpp:92
#define BITS_PER_WERD
Definition: intproto.h:44
#define INT_XCENTER
Definition: intproto.cpp:61
ShapeTable * shape_table_
Definition: classify.h:512
ScrollView * IntMatchWindow
Definition: intproto.cpp:181
inT16 YInit
Definition: intproto.cpp:82
int AddIntProto(INT_CLASS Class)
Definition: intproto.cpp:295
void InitProtoDisplayWindowIfReqd()
Definition: intproto.cpp:1916
FLOAT32 X
Definition: protos.h:47
#define LegalClassId(c)
Definition: intproto.h:179
SWITCH_TYPE
Definition: intproto.cpp:73
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
Definition: intproto.cpp:1807
#define INT_CAPHEIGHT
Definition: intproto.cpp:59
uinT8 AngleStart
Definition: intproto.cpp:106
unsigned int uinT32
Definition: host.h:103
void free_int_class(INT_CLASS int_class)
Definition: intproto.cpp:711
void ZoomToRectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:765
#define INT_DESCENDER
Definition: intproto.cpp:56
FLOAT32 Angle
Definition: protos.h:49
void SetCursor(int x, int y)
Definition: scrollview.cpp:525
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
Definition: intproto.cpp:493
#define CPrunerFor(T, c)
Definition: intproto.h:184
name_table name
const char *const id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:266
INT_TEMPLATES NewIntTemplates()
Definition: intproto.cpp:732
double classify_pp_angle_pad
Definition: intproto.cpp:203
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
Definition: intproto.cpp:240
#define SetForProto(P)
Definition: intproto.h:169
inT16 StartDelta
Definition: intproto.cpp:95
#define YS
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:449
void FillPPCircularBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
Definition: intproto.cpp:1327
void * Emalloc(int Size)
Definition: emalloc.cpp:47
INT_TEMPLATES ReadIntTemplates(FILE *File)
Definition: intproto.cpp:770
#define NO_PROTO
Definition: matchdefs.h:42
#define OLD_WERDS_PER_CONFIG_VEC
Definition: intproto.cpp:115
#define GetPicoFeatureLength()
Definition: picofeat.h:59
#define SET_BIT(array, bit)
Definition: bitvec.h:57
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
Definition: tesscallback.h:116
char * parameter
Definition: scrollview.h:71
#define AS
#define INT_BASELINE
Definition: intproto.cpp:57
uinT8 CircBucketFor(FLOAT32 param, FLOAT32 offset, int num_buckets)
Definition: intproto.cpp:455
#define MAX_UINT8
Definition: host.h:121
#define PRUNER_X
Definition: intproto.h:34
uinT8 AngleStart
Definition: intproto.cpp:92
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1770
double classify_cp_end_pad_loose
Definition: intproto.cpp:197
#define INT_MAX_Y
Definition: intproto.cpp:68
#define NUM_PP_PARAMS
Definition: intproto.h:50
void GetCPPadsForLevel(int Level, FLOAT32 *EndPad, FLOAT32 *SidePad, FLOAT32 *AnglePad)
Definition: intproto.cpp:1485
void UpdateMatchDisplay()
Definition: intproto.cpp:473
inT8 YEnd
Definition: intproto.cpp:105
#define PPrunerWordIndexFor(I)
Definition: intproto.h:173
void Reverse16(void *ptr)
Definition: helpers.h:188
#define INT_VAR(name, val, comment)
Definition: params.h:277
void InitTableFiller(FLOAT32 EndPad, FLOAT32 SidePad, FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER *Filler)
Definition: intproto.cpp:1607
struct INT_TEMPLATES_STRUCT * INT_TEMPLATES
#define NUM_PP_BUCKETS
Definition: intproto.h:51
#define UnusedClassIdIn(T, c)
Definition: intproto.h:180
inT16 EndDelta
Definition: intproto.cpp:95
#define MaxNumClassesIn(T)
Definition: intproto.h:178
FLOAT32 B
Definition: protos.h:45
FLOAT32 y
Definition: fpoint.h:31
int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id)
Definition: intproto.cpp:1874
#define PROTO_PRUNER_SCALE
Definition: intproto.cpp:54
#define ClassForClassId(T, c)
Definition: intproto.h:181
CLUSTERCONFIG Config
ScrollView::Color GetMatchColorFor(FLOAT32 Evidence)
Definition: intproto.cpp:1527
STRING DebugStr(int shape_id) const
Definition: shapetable.cpp:291
const T & get(int id) const
Return the object from an id.
#define INT_MIN_X
Definition: intproto.cpp:65
uinT8 NextSwitch
Definition: intproto.cpp:91
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
Definition: intproto.cpp:1554
#define CPrunerMaskFor(L, c)
Definition: intproto.h:187
#define CPrunerBitIndexFor(c)
Definition: intproto.h:186
SWITCH_TYPE Type
Definition: intproto.cpp:80
uinT8 NumProtoSets
Definition: intproto.h:109
FLOAT32 Length
Definition: protos.h:50
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:748
#define FALSE
Definition: capi.h:29
void Efree(void *ptr)
Definition: emalloc.cpp:79
int size() const
Return the size used.
inT16 Delta
Definition: intproto.cpp:83
PROTO_PRUNER ProtoPruner
Definition: intproto.h:96
#define PROTOS_PER_PROTO_SET
Definition: intproto.h:48
int IntCastRounded(double x)
Definition: helpers.h:172
double classify_cp_side_pad_medium
Definition: intproto.cpp:201
#define PI
Definition: const.h:19
BOOL8 FillerDone(TABLE_FILLER *Filler)
Definition: intproto.cpp:1297
#define INT_XHEIGHT
Definition: intproto.cpp:58
#define BITS_PER_CP_VECTOR
Definition: intproto.h:58
#define TRUE
Definition: capi.h:28
#define NUM_BITS_PER_CLASS
Definition: intproto.h:54
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
Definition: intproto.cpp:96
SVEventType type
Definition: scrollview.h:64
void FillPPLinearBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
Definition: intproto.cpp:1371
uinT8 NumConfigs
Definition: intproto.h:110
CLASS_ID GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on, int *shape_id)
Definition: intproto.cpp:1405
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
USHORT Offset
Definition: GlyphLessFont.h:26
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:1138
UnicityTable< FontSet > fontset_table_
Definition: classify.h:496
FLOAT32 C
Definition: protos.h:46
uinT32 p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
Definition: intproto.h:77
double classify_cp_angle_pad_loose
Definition: intproto.cpp:192
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:644
void cprintf(const char *format,...)
Definition: callcpp.cpp:40
#define NULL
Definition: host.h:144
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1936
SIGNED char inT8
Definition: host.h:98
void GetFirstUnicharAndFont(int shape_id, int *unichar_id, int *font_id) const
Definition: shapetable.cpp:414
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:59
#define MAX_NUM_PROTOS
Definition: intproto.h:47
uinT8 * ProtoLengths
Definition: intproto.h:112
int size() const
Definition: unicharset.h:297
bool read_spacing_info(FILE *f, FontInfo *fi, bool swap)
Definition: fontinfo.cpp:177
const char * string() const
Definition: strngs.cpp:193
FLOAT32 A
Definition: protos.h:44
const Shape & GetShape(int shape_id) const
Definition: shapetable.h:323
#define WERDS_PER_CONFIG_VEC
Definition: intproto.h:68
NORM_METHOD
Definition: mfoutline.h:53
Definition: points.h:189
uinT16 NumProtos
Definition: intproto.h:108
CONFIGS Configurations
Definition: protos.h:64
#define NB
int NumShapes() const
Definition: shapetable.h:278
ScrollView * FeatureDisplayWindow
Definition: intproto.cpp:182
struct PROTO_SET_STRUCT * PROTO_SET
uinT32 Configs[WERDS_PER_CONFIG_VEC]
Definition: intproto.h:86
bool write_set(FILE *f, const FontSet &fs)
Definition: fontinfo.cpp:253
FLOAT32 x
Definition: fpoint.h:31
#define CircularIncrement(i, r)
Definition: intproto.cpp:122
unsigned short uinT16
Definition: host.h:101
short inT16
Definition: host.h:100
FLOAT32 Y
Definition: protos.h:48
unsigned char uinT8
Definition: host.h:99
#define OLD_MAX_NUM_CONFIGS
Definition: intproto.cpp:114