tesseract 4.1.1
Loading...
Searching...
No Matches
intproto.cpp
Go to the documentation of this file.
1/******************************************************************************
2 ** Filename: intproto.c
3 ** Purpose: Definition of data structures for integer protos.
4 ** Author: Dan Johnson
5 **
6 ** (c) Copyright Hewlett-Packard Company, 1988.
7 ** Licensed under the Apache License, Version 2.0 (the "License");
8 ** you may not use this file except in compliance with the License.
9 ** You may obtain a copy of the License at
10 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 ******************************************************************************/
17/*-----------------------------------------------------------------------------
18 Include Files and Type Defines
19-----------------------------------------------------------------------------*/
20
21#define _USE_MATH_DEFINES // for M_PI
22#include <algorithm>
23#include <cmath> // for M_PI, std::floor
24#include <cstdio>
25#include <cassert>
26
27#include "classify.h"
28#include "callcpp.h" // for cprintf
29#include "emalloc.h"
30#include "fontinfo.h"
31#include "genericvector.h"
32#include "helpers.h"
33#include "intproto.h"
34#include "mfoutline.h"
35#include "picofeat.h"
36#include "points.h"
37#include "shapetable.h"
38#include "svmnode.h"
39
40// Include automatically generated configuration file if running autoconf.
41#ifdef HAVE_CONFIG_H
42#include "config_auto.h"
43#endif
44
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
67typedef enum
70#define MAX_NUM_SWITCHES 3
71
72typedef struct
73{
75 int8_t X, Y;
76 int16_t YInit;
77 int16_t Delta;
78}
79
80
82
83typedef 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
96typedef struct
97{
98 int8_t X;
99 int8_t YStart, YEnd;
100 uint8_t AngleStart, AngleEnd;
101}
102
103
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----------------------------------------------------------------------------*/
124float BucketStart(int Bucket, float Offset, int NumBuckets);
125
126float BucketEnd(int Bucket, float Offset, int NumBuckets);
127
128void DoFill(FILL_SPEC *FillSpec,
129 CLASS_PRUNER_STRUCT* Pruner,
130 uint32_t ClassMask,
131 uint32_t ClassCount,
132 uint32_t WordIndex);
133
134bool FillerDone(TABLE_FILLER* Filler);
135
136void FillPPCircularBits(uint32_t
138 int Bit, float Center, float Spread, bool debug);
139
140void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
141 int Bit, float Center, float Spread, bool debug);
142
143void GetCPPadsForLevel(int Level,
144 float *EndPad,
145 float *SidePad,
146 float *AnglePad);
147
148ScrollView::Color GetMatchColorFor(float Evidence);
149
150void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill);
151
152void InitTableFiller(float EndPad,
153 float SidePad,
154 float AnglePad,
155 PROTO Proto,
156 TABLE_FILLER *Filler);
157
158#ifndef GRAPHICS_DISABLED
159void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT* Feature,
160 ScrollView::Color color);
161
162void RenderIntProto(ScrollView *window,
163 INT_CLASS Class,
164 PROTO_ID ProtoId,
165 ScrollView::Color color);
166#endif // GRAPHICS_DISABLED
167
168int 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*/
175static ScrollView* IntMatchWindow = nullptr;
176static ScrollView* FeatureDisplayWindow = nullptr;
177static ScrollView* ProtoDisplayWindow = nullptr;
178
179/*-----------------------------------------------------------------------------
180 Variables
181-----------------------------------------------------------------------------*/
182
183/* control knobs */
184static INT_VAR(classify_num_cp_levels, 3, "Number of Class Pruner Levels");
185static double_VAR(classify_cp_angle_pad_loose, 45.0,
186 "Class Pruner Angle Pad Loose");
187static double_VAR(classify_cp_angle_pad_medium, 20.0,
188 "Class Pruner Angle Pad Medium");
189static double_VAR(classify_cp_angle_pad_tight, 10.0,
190 "CLass Pruner Angle Pad Tight");
191static double_VAR(classify_cp_end_pad_loose, 0.5, "Class Pruner End Pad Loose");
192static double_VAR(classify_cp_end_pad_medium, 0.5, "Class Pruner End Pad Medium");
193static double_VAR(classify_cp_end_pad_tight, 0.5, "Class Pruner End Pad Tight");
194static double_VAR(classify_cp_side_pad_loose, 2.5, "Class Pruner Side Pad Loose");
195static double_VAR(classify_cp_side_pad_medium, 1.2, "Class Pruner Side Pad Medium");
196static double_VAR(classify_cp_side_pad_tight, 0.6, "Class Pruner Side Pad Tight");
197static double_VAR(classify_pp_angle_pad, 45.0, "Proto Pruner Angle Pad");
198static double_VAR(classify_pp_end_pad, 0.5, "Proto Prune End Pad");
199static double_VAR(classify_pp_side_pad, 2.5, "Proto Pruner Side Pad");
200
201/*-----------------------------------------------------------------------------
202 Public Code
203-----------------------------------------------------------------------------*/
207 : X(ClipToRange<int16_t>(static_cast<int16_t>(pos.x() + 0.5), 0, 255)),
208 Y(ClipToRange<int16_t>(static_cast<int16_t>(pos.y() + 0.5), 0, 255)),
209 Theta(theta),
210 CP_misses(0) {
211}
214 : X(static_cast<uint8_t>(ClipToRange<int>(x, 0, UINT8_MAX))),
215 Y(static_cast<uint8_t>(ClipToRange<int>(y, 0, UINT8_MAX))),
216 Theta(static_cast<uint8_t>(ClipToRange<int>(theta, 0, UINT8_MAX))),
217 CP_misses(0) {
218}
219
231void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) {
232 int Pruner;
233
234 assert (LegalClassId (ClassId));
235 if (ClassId != Templates->NumClasses) {
236 fprintf(stderr, "Please make sure that classes are added to templates");
237 fprintf(stderr, " in increasing order of ClassIds\n");
238 exit(1);
239 }
240 ClassForClassId (Templates, ClassId) = Class;
241 Templates->NumClasses++;
242
243 if (Templates->NumClasses > MaxNumClassesIn (Templates)) {
244 Pruner = Templates->NumClassPruners++;
245 Templates->ClassPruners[Pruner] = new CLASS_PRUNER_STRUCT;
246 memset(Templates->ClassPruners[Pruner], 0, sizeof(CLASS_PRUNER_STRUCT));
247 }
248} /* AddIntClass */
249
250
262 int Index;
263
264 assert(Class->NumConfigs < MAX_NUM_CONFIGS);
265
266 Index = Class->NumConfigs++;
267 Class->ConfigLengths[Index] = 0;
268 return Index;
269} /* AddIntConfig */
270
271
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
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
367void 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
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
418uint8_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}
422uint16_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
432uint8_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
448 if (IntMatchWindow != nullptr)
449 IntMatchWindow->Update();
450} /* ClearMatchDisplay */
451#endif
452
463void 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
480namespace tesseract {
488void 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
590void 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
608void 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
626INT_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
664static 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
684 int i;
685
686 T = static_cast<INT_TEMPLATES>(Emalloc (sizeof (INT_TEMPLATES_STRUCT)));
687 T->NumClasses = 0;
688 T->NumClassPruners = 0;
689
690 for (i = 0; i < MAX_NUM_CLASSES; i++)
691 ClassForClassId (T, i) = nullptr;
692
693 return (T);
694} /* NewIntTemplates */
695
696
697/*---------------------------------------------------------------------------*/
699 int i;
700
701 for (i = 0; i < templates->NumClasses; i++)
702 free_int_class(templates->Class[i]);
703 for (i = 0; i < templates->NumClassPruners; i++)
704 delete templates->ClassPruners[i];
705 Efree(templates);
706}
707
708
709namespace 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)));
885 if (fp->FReadEndian(&ProtoSet->ProtoPruner,
886 sizeof(ProtoSet->ProtoPruner[0][0][0]),
887 num_buckets) != num_buckets)
888 tprintf("Bad read of inttemp!\n");
889 for (x = 0; x < PROTOS_PER_PROTO_SET; x++) {
890 if (fp->FRead(&ProtoSet->Protos[x].A, sizeof(ProtoSet->Protos[x].A),
891 1) != 1 ||
892 fp->FRead(&ProtoSet->Protos[x].B, sizeof(ProtoSet->Protos[x].B),
893 1) != 1 ||
894 fp->FRead(&ProtoSet->Protos[x].C, sizeof(ProtoSet->Protos[x].C),
895 1) != 1 ||
896 fp->FRead(&ProtoSet->Protos[x].Angle,
897 sizeof(ProtoSet->Protos[x].Angle), 1) != 1)
898 tprintf("Bad read of inttemp!\n");
899 if (fp->FReadEndian(&ProtoSet->Protos[x].Configs,
900 sizeof(ProtoSet->Protos[x].Configs[0]),
901 WerdsPerConfigVec) != WerdsPerConfigVec)
902 cprintf("Bad read of inttemp!\n");
903 }
904 Class->ProtoSets[j] = ProtoSet;
905 }
906 if (version_id < 4) {
907 Class->font_set_id = -1;
908 } else {
909 fp->FReadEndian(&Class->font_set_id, sizeof(Class->font_set_id), 1);
910 }
911 }
912
913 if (version_id < 2) {
914 /* add an empty nullptr class with class id 0 */
915 assert(UnusedClassIdIn (Templates, 0));
916 ClassForClassId (Templates, 0) = NewIntClass (1, 1);
917 ClassForClassId (Templates, 0)->font_set_id = -1;
918 Templates->NumClasses++;
919 /* make sure the classes are contiguous */
920 for (i = 0; i < MAX_NUM_CLASSES; i++) {
921 if (i < Templates->NumClasses) {
922 if (ClassForClassId (Templates, i) == nullptr) {
923 fprintf(stderr, "Non-contiguous class ids in inttemp\n");
924 exit(1);
925 }
926 } else {
927 if (ClassForClassId (Templates, i) != nullptr) {
928 fprintf(stderr, "Class id %d exceeds NumClassesIn (Templates) %d\n",
929 i, Templates->NumClasses);
930 exit(1);
931 }
932 }
933 }
934 }
935 if (version_id >= 4) {
937 if (version_id >= 5) {
938 this->fontinfo_table_.read(fp,
940 }
942 }
943
944 // Clean up.
945 delete[] IndexFor;
946 delete[] ClassIdFor;
947 delete[] TempClassPruner;
948
949 return (Templates);
950} /* ReadIntTemplates */
951
952
953#ifndef GRAPHICS_DISABLED
964 if (ProtoDisplayWindow) {
965 ProtoDisplayWindow->Clear();
966 }
967 if (FeatureDisplayWindow) {
968 FeatureDisplayWindow->Clear();
969 }
971 static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
972 IntMatchWindow);
973 IntMatchWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
975 if (ProtoDisplayWindow) {
976 ProtoDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
978 }
979 if (FeatureDisplayWindow) {
980 FeatureDisplayWindow->ZoomToRectangle(INT_MIN_X, INT_MIN_Y,
982 }
983} /* ShowMatchDisplay */
984
988 window->Clear();
989
990 window->Pen(ScrollView::GREY);
991 // Draw the feature space limit rectangle.
992 window->Rectangle(0, 0, INT_MAX_X, INT_MAX_Y);
993 if (norm_method == baseline) {
994 window->SetCursor(0, INT_DESCENDER);
996 window->SetCursor(0, INT_BASELINE);
997 window->DrawTo(INT_MAX_X, INT_BASELINE);
998 window->SetCursor(0, INT_XHEIGHT);
999 window->DrawTo(INT_MAX_X, INT_XHEIGHT);
1000 window->SetCursor(0, INT_CAPHEIGHT);
1001 window->DrawTo(INT_MAX_X, INT_CAPHEIGHT);
1002 } else {
1005 }
1006}
1007#endif
1008
1018 const UNICHARSET& target_unicharset) {
1019 int i, j;
1020 INT_CLASS Class;
1021 int unicharset_size = target_unicharset.size();
1022 int version_id = -5; // When negated by the reader -1 becomes +1 etc.
1023
1024 if (Templates->NumClasses != unicharset_size) {
1025 cprintf("Warning: executing WriteIntTemplates() with %d classes in"
1026 " Templates, while target_unicharset size is %d\n",
1027 Templates->NumClasses, unicharset_size);
1028 }
1029
1030 /* first write the high level template struct */
1031 fwrite(&unicharset_size, sizeof(unicharset_size), 1, File);
1032 fwrite(&version_id, sizeof(version_id), 1, File);
1033 fwrite(&Templates->NumClassPruners, sizeof(Templates->NumClassPruners),
1034 1, File);
1035 fwrite(&Templates->NumClasses, sizeof(Templates->NumClasses), 1, File);
1036
1037 /* then write out the class pruners */
1038 for (i = 0; i < Templates->NumClassPruners; i++)
1039 fwrite(Templates->ClassPruners[i],
1040 sizeof(CLASS_PRUNER_STRUCT), 1, File);
1041
1042 /* then write out each class */
1043 for (i = 0; i < Templates->NumClasses; i++) {
1044 Class = Templates->Class[i];
1045
1046 /* first write out the high level struct for the class */
1047 fwrite(&Class->NumProtos, sizeof(Class->NumProtos), 1, File);
1048 fwrite(&Class->NumProtoSets, sizeof(Class->NumProtoSets), 1, File);
1049 ASSERT_HOST(Class->NumConfigs == this->fontset_table_.get(Class->font_set_id).size);
1050 fwrite(&Class->NumConfigs, sizeof(Class->NumConfigs), 1, File);
1051 for (j = 0; j < Class->NumConfigs; ++j) {
1052 fwrite(&Class->ConfigLengths[j], sizeof(uint16_t), 1, File);
1053 }
1054
1055 /* then write out the proto lengths */
1056 if (MaxNumIntProtosIn (Class) > 0) {
1057 fwrite(Class->ProtoLengths, sizeof(uint8_t),
1058 MaxNumIntProtosIn(Class), File);
1059 }
1060
1061 /* then write out the proto sets */
1062 for (j = 0; j < Class->NumProtoSets; j++)
1063 fwrite(Class->ProtoSets[j], sizeof(PROTO_SET_STRUCT), 1, File);
1064
1065 /* then write the fonts info */
1066 fwrite(&Class->font_set_id, sizeof(int), 1, File);
1067 }
1068
1069 /* Write the fonts info tables */
1071 this->fontinfo_table_.write(File,
1074} /* WriteIntTemplates */
1075} // namespace tesseract
1076
1077
1078/*-----------------------------------------------------------------------------
1079 Private Code
1080-----------------------------------------------------------------------------*/
1092float BucketStart(int Bucket, float Offset, int NumBuckets) {
1093 return ((static_cast<float>(Bucket) / NumBuckets) - Offset);
1094
1095} /* BucketStart */
1096
1108float BucketEnd(int Bucket, float Offset, int NumBuckets) {
1109 return ((static_cast<float>(Bucket + 1) / NumBuckets) - Offset);
1110} /* BucketEnd */
1111
1122void DoFill(FILL_SPEC *FillSpec,
1123 CLASS_PRUNER_STRUCT* Pruner,
1124 uint32_t ClassMask,
1125 uint32_t ClassCount,
1126 uint32_t WordIndex) {
1127 int X, Y, Angle;
1128 uint32_t OldWord;
1129
1130 X = FillSpec->X;
1131 if (X < 0)
1132 X = 0;
1133 if (X >= NUM_CP_BUCKETS)
1134 X = NUM_CP_BUCKETS - 1;
1135
1136 if (FillSpec->YStart < 0)
1137 FillSpec->YStart = 0;
1138 if (FillSpec->YEnd >= NUM_CP_BUCKETS)
1139 FillSpec->YEnd = NUM_CP_BUCKETS - 1;
1140
1141 for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
1142 for (Angle = FillSpec->AngleStart; ;
1144 OldWord = Pruner->p[X][Y][Angle][WordIndex];
1145 if (ClassCount > (OldWord & ClassMask)) {
1146 OldWord &= ~ClassMask;
1147 OldWord |= ClassCount;
1148 Pruner->p[X][Y][Angle][WordIndex] = OldWord;
1149 }
1150 if (Angle == FillSpec->AngleEnd)
1151 break;
1152 }
1153} /* DoFill */
1154
1163 FILL_SWITCH *Next;
1164
1165 Next = &(Filler->Switch[Filler->NextSwitch]);
1166
1167 return Filler->X > Next->X && Next->Type == LastSwitch;
1168
1169} /* FillerDone */
1170
1185 int Bit, float Center, float Spread, bool debug) {
1186 int i, FirstBucket, LastBucket;
1187
1188 if (Spread > 0.5)
1189 Spread = 0.5;
1190
1191 FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1192 if (FirstBucket < 0)
1193 FirstBucket += NUM_PP_BUCKETS;
1194
1195 LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1196 if (LastBucket >= NUM_PP_BUCKETS)
1197 LastBucket -= NUM_PP_BUCKETS;
1198 if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
1199 for (i = FirstBucket; true; CircularIncrement (i, NUM_PP_BUCKETS)) {
1200 SET_BIT (ParamTable[i], Bit);
1201
1202 /* exit loop after we have set the bit for the last bucket */
1203 if (i == LastBucket)
1204 break;
1205 }
1206
1207} /* FillPPCircularBits */
1208
1224 int Bit, float Center, float Spread, bool debug) {
1225 int i, FirstBucket, LastBucket;
1226
1227 FirstBucket = static_cast<int>(std::floor((Center - Spread) * NUM_PP_BUCKETS));
1228 if (FirstBucket < 0)
1229 FirstBucket = 0;
1230
1231 LastBucket = static_cast<int>(std::floor((Center + Spread) * NUM_PP_BUCKETS));
1232 if (LastBucket >= NUM_PP_BUCKETS)
1233 LastBucket = NUM_PP_BUCKETS - 1;
1234
1235 if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
1236 for (i = FirstBucket; i <= LastBucket; i++)
1237 SET_BIT (ParamTable[i], Bit);
1238
1239} /* FillPPLinearBits */
1240
1241
1242/*---------------------------------------------------------------------------*/
1243#ifndef GRAPHICS_DISABLED
1244namespace tesseract {
1255CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool* adaptive_on,
1256 bool* pretrained_on, int* shape_id) {
1257 tprintf("%s\n", Prompt);
1258 SVEvent* ev;
1259 SVEventType ev_type;
1260 int unichar_id = INVALID_UNICHAR_ID;
1261 // Wait until a click or popup event.
1262 do {
1263 ev = IntMatchWindow->AwaitEvent(SVET_ANY);
1264 ev_type = ev->type;
1265 if (ev_type == SVET_POPUP) {
1266 if (ev->command_id == IDA_SHAPE_INDEX) {
1267 if (shape_table_ != nullptr) {
1268 *shape_id = atoi(ev->parameter);
1269 *adaptive_on = false;
1270 *pretrained_on = true;
1271 if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1272 int font_id;
1273 shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1274 &font_id);
1275 tprintf("Shape %d, first unichar=%d, font=%d\n",
1276 *shape_id, unichar_id, font_id);
1277 return unichar_id;
1278 }
1279 tprintf("Shape index '%s' not found in shape table\n", ev->parameter);
1280 } else {
1281 tprintf("No shape table loaded!\n");
1282 }
1283 } else {
1285 unichar_id = unicharset.unichar_to_id(ev->parameter);
1286 if (ev->command_id == IDA_ADAPTIVE) {
1287 *adaptive_on = true;
1288 *pretrained_on = false;
1289 *shape_id = -1;
1290 } else if (ev->command_id == IDA_STATIC) {
1291 *adaptive_on = false;
1292 *pretrained_on = true;
1293 } else {
1294 *adaptive_on = true;
1295 *pretrained_on = true;
1296 }
1297 if (ev->command_id == IDA_ADAPTIVE || shape_table_ == nullptr) {
1298 *shape_id = -1;
1299 return unichar_id;
1300 }
1301 for (int s = 0; s < shape_table_->NumShapes(); ++s) {
1302 if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1303 tprintf("%s\n", shape_table_->DebugStr(s).string());
1304 }
1305 }
1306 } else {
1307 tprintf("Char class '%s' not found in unicharset",
1308 ev->parameter);
1309 }
1310 }
1311 }
1312 delete ev;
1313 } while (ev_type != SVET_CLICK);
1314 return 0;
1315} /* GetClassToDebug */
1316
1317} // namespace tesseract
1318#endif
1319
1331void GetCPPadsForLevel(int Level,
1332 float *EndPad,
1333 float *SidePad,
1334 float *AnglePad) {
1335 switch (Level) {
1336 case 0:
1337 *EndPad = classify_cp_end_pad_loose * GetPicoFeatureLength ();
1338 *SidePad = classify_cp_side_pad_loose * GetPicoFeatureLength ();
1339 *AnglePad = classify_cp_angle_pad_loose / 360.0;
1340 break;
1341
1342 case 1:
1343 *EndPad = classify_cp_end_pad_medium * GetPicoFeatureLength ();
1344 *SidePad = classify_cp_side_pad_medium * GetPicoFeatureLength ();
1345 *AnglePad = classify_cp_angle_pad_medium / 360.0;
1346 break;
1347
1348 case 2:
1349 *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
1350 *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
1351 *AnglePad = classify_cp_angle_pad_tight / 360.0;
1352 break;
1353
1354 default:
1355 *EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
1356 *SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
1357 *AnglePad = classify_cp_angle_pad_tight / 360.0;
1358 break;
1359 }
1360 if (*AnglePad > 0.5)
1361 *AnglePad = 0.5;
1362
1363} /* GetCPPadsForLevel */
1364
1371 assert (Evidence >= 0.0);
1372 assert (Evidence <= 1.0);
1373
1374 if (Evidence >= 0.90)
1375 return ScrollView::WHITE;
1376 else if (Evidence >= 0.75)
1377 return ScrollView::GREEN;
1378 else if (Evidence >= 0.50)
1379 return ScrollView::RED;
1380 else
1381 return ScrollView::BLUE;
1382} /* GetMatchColorFor */
1383
1392void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill) {
1393 FILL_SWITCH *Next;
1394
1395 /* compute the fill assuming no switches will be encountered */
1396 Fill->AngleStart = Filler->AngleStart;
1397 Fill->AngleEnd = Filler->AngleEnd;
1398 Fill->X = Filler->X;
1399 Fill->YStart = Filler->YStart >> 8;
1400 Fill->YEnd = Filler->YEnd >> 8;
1401
1402 /* update the fill info and the filler for ALL switches at this X value */
1403 Next = &(Filler->Switch[Filler->NextSwitch]);
1404 while (Filler->X >= Next->X) {
1405 Fill->X = Filler->X = Next->X;
1406 if (Next->Type == StartSwitch) {
1407 Fill->YStart = Next->Y;
1408 Filler->StartDelta = Next->Delta;
1409 Filler->YStart = Next->YInit;
1410 }
1411 else if (Next->Type == EndSwitch) {
1412 Fill->YEnd = Next->Y;
1413 Filler->EndDelta = Next->Delta;
1414 Filler->YEnd = Next->YInit;
1415 }
1416 else { /* Type must be LastSwitch */
1417 break;
1418 }
1419 Filler->NextSwitch++;
1420 Next = &(Filler->Switch[Filler->NextSwitch]);
1421 }
1422
1423 /* prepare the filler for the next call to this routine */
1424 Filler->X++;
1425 Filler->YStart += Filler->StartDelta;
1426 Filler->YEnd += Filler->EndDelta;
1427
1428} /* GetNextFill */
1429
1439void InitTableFiller (float EndPad, float SidePad,
1440 float AnglePad, PROTO Proto, TABLE_FILLER * Filler)
1441#define XS X_SHIFT
1442#define YS Y_SHIFT
1443#define AS ANGLE_SHIFT
1444#define NB NUM_CP_BUCKETS
1445{
1446 float Angle;
1447 float X, Y, HalfLength;
1448 float Cos, Sin;
1449 float XAdjust, YAdjust;
1450 FPOINT Start, Switch1, Switch2, End;
1451 int S1 = 0;
1452 int S2 = 1;
1453
1454 Angle = Proto->Angle;
1455 X = Proto->X;
1456 Y = Proto->Y;
1457 HalfLength = Proto->Length / 2.0;
1458
1459 Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
1460 Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
1461 Filler->NextSwitch = 0;
1462
1463 if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
1464 /* horizontal proto - handle as special case */
1465 Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
1466 Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
1467 Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
1468 Filler->StartDelta = 0;
1469 Filler->EndDelta = 0;
1470 Filler->Switch[0].Type = LastSwitch;
1471 Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
1472 } else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
1473 fabs(Angle - 0.75) < HV_TOLERANCE) {
1474 /* vertical proto - handle as special case */
1475 Filler->X = Bucket8For(X - SidePad, XS, NB);
1476 Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
1477 Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
1478 Filler->StartDelta = 0;
1479 Filler->EndDelta = 0;
1480 Filler->Switch[0].Type = LastSwitch;
1481 Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
1482 } else {
1483 /* diagonal proto */
1484
1485 if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1486 /* rising diagonal proto */
1487 Angle *= 2.0 * M_PI;
1488 Cos = fabs(cos(Angle));
1489 Sin = fabs(sin(Angle));
1490
1491 /* compute the positions of the corners of the acceptance region */
1492 Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1493 Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1494 End.x = 2.0 * X - Start.x;
1495 End.y = 2.0 * Y - Start.y;
1496 Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1497 Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1498 Switch2.x = 2.0 * X - Switch1.x;
1499 Switch2.y = 2.0 * Y - Switch1.y;
1500
1501 if (Switch1.x > Switch2.x) {
1502 S1 = 1;
1503 S2 = 0;
1504 }
1505
1506 /* translate into bucket positions and deltas */
1507 Filler->X = Bucket8For(Start.x, XS, NB);
1508 Filler->StartDelta = -static_cast<int16_t>((Cos / Sin) * 256);
1509 Filler->EndDelta = static_cast<int16_t>((Sin / Cos) * 256);
1510
1511 XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1512 YAdjust = XAdjust * Cos / Sin;
1513 Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1514 YAdjust = XAdjust * Sin / Cos;
1515 Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1516
1517 Filler->Switch[S1].Type = StartSwitch;
1518 Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1519 Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1520 XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1521 YAdjust = XAdjust * Sin / Cos;
1522 Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
1523 Filler->Switch[S1].Delta = Filler->EndDelta;
1524
1525 Filler->Switch[S2].Type = EndSwitch;
1526 Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1527 Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1528 XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1529 YAdjust = XAdjust * Cos / Sin;
1530 Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
1531 Filler->Switch[S2].Delta = Filler->StartDelta;
1532
1533 Filler->Switch[2].Type = LastSwitch;
1534 Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1535 } else {
1536 /* falling diagonal proto */
1537 Angle *= 2.0 * M_PI;
1538 Cos = fabs(cos(Angle));
1539 Sin = fabs(sin(Angle));
1540
1541 /* compute the positions of the corners of the acceptance region */
1542 Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1543 Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1544 End.x = 2.0 * X - Start.x;
1545 End.y = 2.0 * Y - Start.y;
1546 Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1547 Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1548 Switch2.x = 2.0 * X - Switch1.x;
1549 Switch2.y = 2.0 * Y - Switch1.y;
1550
1551 if (Switch1.x > Switch2.x) {
1552 S1 = 1;
1553 S2 = 0;
1554 }
1555
1556 /* translate into bucket positions and deltas */
1557 Filler->X = Bucket8For(Start.x, XS, NB);
1558 Filler->StartDelta = static_cast<int16_t>(ClipToRange<int>(
1559 -IntCastRounded((Sin / Cos) * 256), INT16_MIN, INT16_MAX));
1560 Filler->EndDelta = static_cast<int16_t>(ClipToRange<int>(
1561 IntCastRounded((Cos / Sin) * 256), INT16_MIN, INT16_MAX));
1562
1563 XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
1564 YAdjust = XAdjust * Sin / Cos;
1565 Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
1566 YAdjust = XAdjust * Cos / Sin;
1567 Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
1568
1569 Filler->Switch[S1].Type = EndSwitch;
1570 Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
1571 Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
1572 XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
1573 YAdjust = XAdjust * Sin / Cos;
1574 Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
1575 Filler->Switch[S1].Delta = Filler->StartDelta;
1576
1577 Filler->Switch[S2].Type = StartSwitch;
1578 Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
1579 Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
1580 XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
1581 YAdjust = XAdjust * Cos / Sin;
1582 Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
1583 Filler->Switch[S2].Delta = Filler->EndDelta;
1584
1585 Filler->Switch[2].Type = LastSwitch;
1586 Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
1587 }
1588 }
1589} /* InitTableFiller */
1590
1591
1592/*---------------------------------------------------------------------------*/
1593#ifndef GRAPHICS_DISABLED
1603 ScrollView::Color color) {
1604 float X, Y, Dx, Dy, Length;
1605
1606 window->Pen(color);
1607 assert(Feature != nullptr);
1608 assert(color != 0);
1609
1610 X = Feature->X;
1611 Y = Feature->Y;
1612 Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
1613 // The -PI has no significant effect here, but the value of Theta is computed
1614 // using BinaryAnglePlusPi in intfx.cpp.
1615 Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1616 Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * M_PI - M_PI);
1617
1618 window->SetCursor(X, Y);
1619 window->DrawTo(X + Dx, Y + Dy);
1620} /* RenderIntFeature */
1621
1637 INT_CLASS Class,
1638 PROTO_ID ProtoId,
1639 ScrollView::Color color) {
1640 PROTO_SET ProtoSet;
1641 INT_PROTO Proto;
1642 int ProtoSetIndex;
1643 int ProtoWordIndex;
1644 float Length;
1645 int Xmin, Xmax, Ymin, Ymax;
1646 float X, Y, Dx, Dy;
1647 uint32_t ProtoMask;
1648 int Bucket;
1649
1650 assert(ProtoId >= 0);
1651 assert(Class != nullptr);
1652 assert(ProtoId < Class->NumProtos);
1653 assert(color != 0);
1654 window->Pen(color);
1655
1656 ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
1657 ProtoSetIndex = IndexForProto(ProtoId);
1658 Proto = &(ProtoSet->Protos[ProtoSetIndex]);
1659 Length = (Class->ProtoLengths[ProtoId] *
1661 ProtoMask = PPrunerMaskFor(ProtoId);
1662 ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
1663
1664 // find the x and y extent of the proto from the proto pruning table
1665 Xmin = Ymin = NUM_PP_BUCKETS;
1666 Xmax = Ymax = 0;
1667 for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
1668 if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
1669 UpdateRange(Bucket, &Xmin, &Xmax);
1670 }
1671
1672 if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
1673 UpdateRange(Bucket, &Ymin, &Ymax);
1674 }
1675 }
1676 X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1677 Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
1678 // The -PI has no significant effect here, but the value of Theta is computed
1679 // using BinaryAnglePlusPi in intfx.cpp.
1680 Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1681 Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * M_PI - M_PI);
1682
1683 window->SetCursor(X - Dx, Y - Dy);
1684 window->DrawTo(X + Dx, Y + Dy);
1685} /* RenderIntProto */
1686#endif
1687
1701int TruncateParam(float Param, int Min, int Max, char *Id) {
1702 if (Param < Min) {
1703 if (Id)
1704 cprintf("Warning: Param %s truncated from %f to %d!\n",
1705 Id, Param, Min);
1706 Param = Min;
1707 } else if (Param > Max) {
1708 if (Id)
1709 cprintf("Warning: Param %s truncated from %f to %d!\n",
1710 Id, Param, Max);
1711 Param = Max;
1712 }
1713 return static_cast<int>(std::floor(Param));
1714} /* TruncateParam */
1715
1716
1717#ifndef GRAPHICS_DISABLED
1723 if (IntMatchWindow == nullptr) {
1724 IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
1725 auto* popup_menu = new SVMenuNode();
1726
1727 popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
1728 "x", "Class to debug");
1729 popup_menu->AddChild("Debug Static classes", IDA_STATIC,
1730 "x", "Class to debug");
1731 popup_menu->AddChild("Debug Both", IDA_BOTH,
1732 "x", "Class to debug");
1733 popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
1734 "0", "Index to debug");
1735 popup_menu->BuildMenu(IntMatchWindow, false);
1736 }
1737}
1738
1744 if (ProtoDisplayWindow == nullptr) {
1745 ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
1746 550, 200);
1747 }
1748}
1749
1755 if (FeatureDisplayWindow == nullptr) {
1756 FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
1757 50, 700);
1758 }
1759}
1760
1763ScrollView* CreateFeatureSpaceWindow(const char* name, int xpos, int ypos) {
1764 return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
1765}
1766#endif // GRAPHICS_DISABLED
#define ASSERT_HOST(x)
Definition: errcode.h:88
int Modulo(int a, int b)
Definition: helpers.h:158
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
Definition: helpers.h:120
int IntCastRounded(double x)
Definition: helpers.h:175
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
Definition: helpers.h:108
#define INT_VAR(name, val, comment)
Definition: params.h:303
#define double_VAR(name, val, comment)
Definition: params.h:312
_ConstTessMemberResultCallback_5_0< false, R, T1, P1, P2, P3, P4, P5 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)(P1, P2, P3, P4, P5) const, typename Identity< P1 >::type p1, typename Identity< P2 >::type p2, typename Identity< P3 >::type p3, typename Identity< P4 >::type p4, typename Identity< P5 >::type p5)
Definition: tesscallback.h:258
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:35
INT_TEMPLATES NewIntTemplates()
Definition: intproto.cpp:682
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, float Evidence)
Definition: intproto.cpp:590
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
Definition: intproto.cpp:328
#define OLD_MAX_NUM_CONFIGS
Definition: intproto.cpp:108
void InitIntMatchWindowIfReqd()
Definition: intproto.cpp:1722
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1763
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
Definition: intproto.cpp:1392
#define CircularIncrement(i, r)
Definition: intproto.cpp:116
void UpdateMatchDisplay()
Definition: intproto.cpp:447
#define INT_YRADIUS
Definition: intproto.cpp:58
uint8_t Bucket8For(float param, float offset, int num_buckets)
Definition: intproto.cpp:418
SWITCH_TYPE
Definition: intproto.cpp:68
@ StartSwitch
Definition: intproto.cpp:68
@ EndSwitch
Definition: intproto.cpp:68
@ LastSwitch
Definition: intproto.cpp:68
#define XS
float BucketStart(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1092
void InitFeatureDisplayWindowIfReqd()
Definition: intproto.cpp:1754
#define INT_MAX_Y
Definition: intproto.cpp:62
int AddIntProto(INT_CLASS Class)
Definition: intproto.cpp:282
int AddIntConfig(INT_CLASS Class)
Definition: intproto.cpp:261
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
Definition: intproto.cpp:463
#define NB
void GetCPPadsForLevel(int Level, float *EndPad, float *SidePad, float *AnglePad)
Definition: intproto.cpp:1331
#define MAX_LEVEL
#define INT_DESCENDER
Definition: intproto.cpp:50
float BucketEnd(int Bucket, float Offset, int NumBuckets)
Definition: intproto.cpp:1108
#define INT_MIN_Y
Definition: intproto.cpp:60
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
Definition: intproto.cpp:231
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, float Evidence)
Definition: intproto.cpp:608
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
Definition: intproto.cpp:1636
#define INT_YCENTER
Definition: intproto.cpp:56
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, uint32_t ClassMask, uint32_t ClassCount, uint32_t WordIndex)
Definition: intproto.cpp:1122
#define HV_TOLERANCE
Definition: intproto.cpp:65
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1602
#define INT_XHEIGHT
Definition: intproto.cpp:52
uint8_t CircBucketFor(float param, float offset, int num_buckets)
Definition: intproto.cpp:432
#define MapParam(P, O, N)
Definition: intproto.cpp:119
int TruncateParam(float Param, int Min, int Max, char *Id)
Definition: intproto.cpp:1701
uint16_t Bucket16For(float param, float offset, int num_buckets)
Definition: intproto.cpp:422
#define INT_XCENTER
Definition: intproto.cpp:55
#define AS
void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1223
void FillPPCircularBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
Definition: intproto.cpp:1184
void InitTableFiller(float EndPad, float SidePad, float AnglePad, PROTO Proto, TABLE_FILLER *Filler)
Definition: intproto.cpp:1439
#define INT_MIN_X
Definition: intproto.cpp:59
ScrollView::Color GetMatchColorFor(float Evidence)
Definition: intproto.cpp:1370
#define YS
#define PROTO_PRUNER_SCALE
Definition: intproto.cpp:48
void InitProtoDisplayWindowIfReqd()
Definition: intproto.cpp:1743
#define INT_MAX_X
Definition: intproto.cpp:61
#define MAX_NUM_SWITCHES
Definition: intproto.cpp:70
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
Definition: intproto.cpp:367
#define OLD_WERDS_PER_CONFIG_VEC
Definition: intproto.cpp:109
void free_int_templates(INT_TEMPLATES templates)
Definition: intproto.cpp:698
#define INT_BASELINE
Definition: intproto.cpp:51
#define INT_XRADIUS
Definition: intproto.cpp:57
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
Definition: intproto.cpp:626
#define INT_CAPHEIGHT
Definition: intproto.cpp:53
bool FillerDone(TABLE_FILLER *Filler)
Definition: intproto.cpp:1162
#define PPrunerWordIndexFor(I)
Definition: intproto.h:170
#define ANGLE_SHIFT
Definition: intproto.h:40
#define BITS_PER_CP_VECTOR
Definition: intproto.h:59
#define MaxNumIntProtosIn(C)
Definition: intproto.h:165
#define MAX_NUM_PROTO_SETS
Definition: intproto.h:50
#define NUM_PP_PARAMS
Definition: intproto.h:51
#define UnusedClassIdIn(T, c)
Definition: intproto.h:177
#define MAX_NUM_PROTOS
Definition: intproto.h:48
#define IndexForProto(P)
Definition: intproto.h:167
#define WERDS_PER_PP_VECTOR
Definition: intproto.h:63
#define INT_CHAR_NORM_RANGE
Definition: intproto.h:130
#define MAX_NUM_CONFIGS
Definition: intproto.h:47
#define BITS_PER_WERD
Definition: intproto.h:45
#define ClassForClassId(T, c)
Definition: intproto.h:178
#define LegalClassId(c)
Definition: intproto.h:176
#define X_SHIFT
Definition: intproto.h:41
#define PRUNER_Y
Definition: intproto.h:36
#define MaxNumClassesIn(T)
Definition: intproto.h:175
#define WERDS_PER_CONFIG_VEC
Definition: intproto.h:68
#define CPrunerWordIndexFor(c)
Definition: intproto.h:182
#define CPrunerIdFor(c)
Definition: intproto.h:180
#define PRUNER_ANGLE
Definition: intproto.h:37
#define SetForProto(P)
Definition: intproto.h:166
#define CPrunerBitIndexFor(c)
Definition: intproto.h:183
#define PPrunerMaskFor(I)
Definition: intproto.h:173
#define NUM_CP_BUCKETS
Definition: intproto.h:53
#define MAX_NUM_CLASS_PRUNERS
Definition: intproto.h:60
@ IDA_BOTH
Definition: intproto.h:158
@ IDA_STATIC
Definition: intproto.h:156
@ IDA_SHAPE_INDEX
Definition: intproto.h:157
@ IDA_ADAPTIVE
Definition: intproto.h:155
#define WERDS_PER_CP_VECTOR
Definition: intproto.h:62
#define Y_SHIFT
Definition: intproto.h:42
#define PROTOS_PER_PROTO_SET
Definition: intproto.h:49
#define NUM_PP_BUCKETS
Definition: intproto.h:52
#define NUM_BITS_PER_CLASS
Definition: intproto.h:55
#define CPrunerMaskFor(L, c)
Definition: intproto.h:184
#define CPrunerFor(T, c)
Definition: intproto.h:181
#define PRUNER_X
Definition: intproto.h:35
#define ProtoForProtoId(C, P)
Definition: intproto.h:168
NORM_METHOD
Definition: mfoutline.h:63
@ baseline
Definition: mfoutline.h:63
#define GetPicoFeatureLength()
Definition: picofeat.h:57
#define ProtoIn(Class, Pid)
Definition: protos.h:84
uint32_t * BIT_VECTOR
Definition: bitvec.h:28
#define test_bit(array, bit)
Definition: bitvec.h:59
#define SET_BIT(array, bit)
Definition: bitvec.h:55
void cprintf(const char *format,...)
Definition: callcpp.cpp:32
void * Erealloc(void *ptr, int size)
Definition: emalloc.cpp:38
void * Emalloc(int Size)
Definition: emalloc.cpp:31
void Efree(void *ptr)
Definition: emalloc.cpp:45
UNICHAR_ID CLASS_ID
Definition: matchdefs.h:34
#define NO_PROTO
Definition: matchdefs.h:41
int16_t PROTO_ID
Definition: matchdefs.h:40
#define MAX_NUM_CLASSES
Definition: matchdefs.h:30
CLUSTERCONFIG Config
SVEventType
Definition: scrollview.h:45
@ SVET_CLICK
Definition: scrollview.h:48
@ SVET_POPUP
Definition: scrollview.h:54
@ SVET_ANY
Definition: scrollview.h:56
bool write_set(FILE *f, const FontSet &fs)
Definition: fontinfo.cpp:232
bool write_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:163
bool write_spacing_info(FILE *f, const FontInfo &fi)
Definition: fontinfo.cpp:198
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:987
bool read_set(TFile *f, FontSet *fs)
Definition: fontinfo.cpp:226
bool read_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:153
bool read_spacing_info(TFile *f, FontInfo *fi)
Definition: fontinfo.cpp:170
int size() const
Return the size used.
const T & get(int id) const
Return the object from an id.
Definition: points.h:189
UNICHARSET unicharset
Definition: ccutil.h:73
int FReadEndian(void *buffer, size_t size, int count)
Definition: serialis.cpp:260
int FRead(void *buffer, size_t size, int count)
Definition: serialis.cpp:271
const char * string() const
Definition: strngs.cpp:194
bool contains_unichar(const char *const unichar_repr) const
Definition: unicharset.cpp:671
const char * id_to_unichar(UNICHAR_ID id) const
Definition: unicharset.cpp:291
int size() const
Definition: unicharset.h:341
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
Definition: unicharset.cpp:210
ShapeTable * shape_table_
Definition: classify.h:546
UnicityTable< FontSet > fontset_table_
Definition: classify.h:537
CLASS_ID GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on, int *shape_id)
Definition: intproto.cpp:1255
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:1017
INT_TEMPLATES ReadIntTemplates(TFile *fp)
Definition: intproto.cpp:718
UnicityTable< FontInfo > fontinfo_table_
Definition: classify.h:529
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class)
Definition: intproto.cpp:488
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
Definition: intproto.cpp:527
int classify_learning_debug_level
Definition: classify.h:455
Definition: fpoint.h:29
float y
Definition: fpoint.h:30
float x
Definition: fpoint.h:30
int16_t Delta
Definition: intproto.cpp:77
int8_t X
Definition: intproto.cpp:75
int16_t YInit
Definition: intproto.cpp:76
int8_t Y
Definition: intproto.cpp:75
SWITCH_TYPE Type
Definition: intproto.cpp:74
int16_t StartDelta
Definition: intproto.cpp:89
int8_t X
Definition: intproto.cpp:87
uint8_t AngleEnd
Definition: intproto.cpp:86
uint8_t NextSwitch
Definition: intproto.cpp:85
uint8_t AngleStart
Definition: intproto.cpp:86
int16_t YStart
Definition: intproto.cpp:88
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
Definition: intproto.cpp:90
int16_t YEnd
Definition: intproto.cpp:88
int16_t EndDelta
Definition: intproto.cpp:89
uint8_t AngleEnd
Definition: intproto.cpp:100
int8_t X
Definition: intproto.cpp:98
int8_t YEnd
Definition: intproto.cpp:99
uint8_t AngleStart
Definition: intproto.cpp:100
int8_t YStart
Definition: intproto.cpp:99
uint32_t p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
Definition: intproto.h:78
uint8_t Angle
Definition: intproto.h:85
uint32_t Configs[WERDS_PER_CONFIG_VEC]
Definition: intproto.h:86
PROTO_PRUNER ProtoPruner
Definition: intproto.h:96
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
Definition: intproto.h:97
uint8_t NumProtoSets
Definition: intproto.h:107
uint16_t NumProtos
Definition: intproto.h:106
uint8_t * ProtoLengths
Definition: intproto.h:110
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
Definition: intproto.h:109
uint16_t ConfigLengths[MAX_NUM_CONFIGS]
Definition: intproto.h:111
uint8_t NumConfigs
Definition: intproto.h:108
INT_CLASS Class[MAX_NUM_CLASSES]
Definition: intproto.h:121
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
Definition: intproto.h:122
float Angle
Definition: protos.h:42
float Length
Definition: protos.h:43
float Y
Definition: protos.h:41
float B
Definition: protos.h:38
float A
Definition: protos.h:37
float C
Definition: protos.h:39
float X
Definition: protos.h:40
int16_t NumConfigs
Definition: protos.h:58
int16_t NumProtos
Definition: protos.h:55
UnicityTableEqEq< int > font_set
Definition: protos.h:61
CONFIGS Configurations
Definition: protos.h:60
bool ContainsUnichar(int unichar_id) const
Definition: shapetable.cpp:147
int NumShapes() const
Definition: shapetable.h:274
void GetFirstUnicharAndFont(int shape_id, int *unichar_id, int *font_id) const
Definition: shapetable.cpp:404
STRING DebugStr(int shape_id) const
Definition: shapetable.cpp:281
const Shape & GetShape(int shape_id) const
Definition: shapetable.h:319
SVEventType type
Definition: scrollview.h:64
char * parameter
Definition: scrollview.h:66
int command_id
Definition: scrollview.h:71
static void Update()
Definition: scrollview.cpp:709
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:443
void DrawTo(int x, int y)
Definition: scrollview.cpp:525
void Clear()
Definition: scrollview.cpp:589
void ZoomToRectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:757
void SetCursor(int x, int y)
Definition: scrollview.cpp:519
void Pen(Color color)
Definition: scrollview.cpp:719
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:600