43 #include "config_auto.h" 49 #define PROTO_PRUNER_SCALE (4.0) 51 #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE) 52 #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE) 53 #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE) 54 #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE) 56 #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE) 57 #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE) 58 #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE) 59 #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE) 62 #define INT_MAX_X INT_CHAR_NORM_RANGE 63 #define INT_MAX_Y INT_CHAR_NORM_RANGE 66 #define HV_TOLERANCE (0.0025) 71 #define MAX_NUM_SWITCHES 3 109 #define OLD_MAX_NUM_CONFIGS 32 110 #define OLD_WERDS_PER_CONFIG_VEC ((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\ 117 #define CircularIncrement(i,r) (((i) < (r) - 1)?((i)++):((i) = 0)) 120 #define MapParam(P,O,N) (std::floor(((P) + (O)) * (N))) 125 float BucketStart(
int Bucket,
float Offset,
int NumBuckets);
127 float BucketEnd(
int Bucket,
float Offset,
int NumBuckets);
139 int Bit,
float Center,
float Spread,
bool debug);
142 int Bit,
float Center,
float Spread,
bool debug);
159 #ifndef GRAPHICS_DISABLED 167 #endif // GRAPHICS_DISABLED 187 "Class Pruner Angle Pad Loose");
189 "Class Pruner Angle Pad Medium");
191 "CLass Pruner Angle Pad Tight");
208 : X(
ClipToRange<int16_t>(static_cast<int16_t>(pos.x() + 0.5), 0, 255)),
209 Y(
ClipToRange<int16_t>(static_cast<int16_t>(pos.y() + 0.5), 0, 255)),
215 : X(static_cast<uint8_t>(
ClipToRange<int>(x, 0, UINT8_MAX))),
216 Y(static_cast<uint8_t>(
ClipToRange<int>(y, 0, UINT8_MAX))),
217 Theta(static_cast<uint8_t>(
ClipToRange<int>(theta, 0, UINT8_MAX))),
237 fprintf(stderr,
"Please make sure that classes are added to templates");
238 fprintf(stderr,
" in increasing order of ClassIds\n");
300 memset(ProtoSet, 0,
sizeof(*ProtoSet));
339 float EndPad, SidePad, AnglePad;
354 DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
372 float Angle, X, Y, Length;
378 cprintf(
"AddProtoToProtoPruner:assert failed: %d < %d",
380 assert(ProtoId < Class->NumProtos);
385 Angle = Proto->
Angle;
387 assert(!std::isnan(Angle));
398 Pad = std::max(fabs (cos (Angle)) * (Length / 2.0 +
407 Pad = std::max(fabs (sin (Angle)) * (Length / 2.0 +
421 uint8_t
Bucket8For(
float param,
float offset,
int num_buckets) {
423 return static_cast<uint8_t
>(ClipToRange<int>(bucket, 0, num_buckets - 1));
425 uint16_t
Bucket16For(
float param,
float offset,
int num_buckets) {
427 return static_cast<uint16_t
>(ClipToRange<int>(bucket, 0, num_buckets - 1));
437 return static_cast<uint8_t
>(
Modulo(bucket, num_buckets));
441 #ifndef GRAPHICS_DISABLED 474 for (ProtoId = 0, TotalLength = 0;
500 assert(ProtoId < Class->NumProtos);
523 cprintf(
"Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
547 for (ClassId = 0; ClassId < target_unicharset.
size(); ClassId++) {
548 FClass = &(FloatProtos[ClassId]);
550 strcmp(target_unicharset.
id_to_unichar(ClassId),
" ") != 0) {
551 cprintf(
"Warning: no protos/configs for %s in CreateIntTemplates()\n",
559 for (
int i = 0; i < fs.
size; ++i) {
570 for (ProtoId = 0; ProtoId < FClass->
NumProtos; ProtoId++) {
578 for (ConfigId = 0; ConfigId < FClass->
NumConfigs; ConfigId++) {
583 return (IntTemplates);
588 #ifndef GRAPHICS_DISABLED 655 memset(ProtoSet, 0,
sizeof(*ProtoSet));
674 static void free_int_class(
INT_CLASS int_class) {
712 free_int_class(templates->
Class[i]);
729 int i, j, w, x, y, z;
739 int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
745 uint32_t SetBitsForMask =
747 uint32_t Mask, NewMask, ClassBits;
754 if (fp->
FReadEndian(&unicharset_size,
sizeof(unicharset_size), 1) != 1)
755 tprintf(
"Bad read of inttemp!\n");
760 tprintf(
"Bad read of inttemp!\n");
766 tprintf(
"Bad read of inttemp!\n");
769 if (version_id < 3) {
774 if (version_id < 2) {
775 if (fp->
FReadEndian(IndexFor,
sizeof(IndexFor[0]), unicharset_size) !=
777 tprintf(
"Bad read of inttemp!\n");
779 if (fp->
FReadEndian(ClassIdFor,
sizeof(ClassIdFor[0]),
781 tprintf(
"Bad read of inttemp!\n");
786 const int kNumBuckets =
790 if (fp->
FReadEndian(Pruner,
sizeof(Pruner->
p[0][0][0][0]), kNumBuckets) !=
792 tprintf(
"Bad read of inttemp!\n");
794 if (version_id < 2) {
795 TempClassPruner[i] = Pruner;
802 if (version_id < 2) {
806 if (ClassIdFor[i] > max_class_id)
807 max_class_id = ClassIdFor[i];
820 if (TempClassPruner[i]->p[x][y][z][w] == 0)
824 if (bit_number > last_cp_bit_number)
828 Mask = SetBitsForMask << b;
829 ClassBits = TempClassPruner[i]->
p[x][y][z][w] & Mask;
836 ClassBits <<= (new_b - b);
838 ClassBits >>= (b - new_b);
842 NewMask = SetBitsForMask << new_b;
843 Templates->
ClassPruners[new_i]->
p[x][y][z][new_w] &= ~NewMask;
844 Templates->
ClassPruners[new_i]->
p[x][y][z][new_w] |= ClassBits;
849 delete TempClassPruner[i];
860 tprintf(
"Bad read of inttemp!\n");
861 if (version_id == 0) {
863 for (j = 0; j < 5; ++j) {
865 if (fp->
FRead(&junk,
sizeof(junk), 1) != 1)
866 tprintf(
"Bad read of inttemp!\n");
869 int num_configs = version_id < 4 ? MaxNumConfigs : Class->
NumConfigs;
873 tprintf(
"Bad read of inttemp!\n");
875 if (version_id < 2) {
887 tprintf(
"Bad read of inttemp!\n");
897 num_buckets) != num_buckets)
898 tprintf(
"Bad read of inttemp!\n");
908 tprintf(
"Bad read of inttemp!\n");
911 WerdsPerConfigVec) != WerdsPerConfigVec)
912 cprintf(
"Bad read of inttemp!\n");
916 if (version_id < 4) {
923 if (version_id < 2) {
931 if (i < Templates->NumClasses) {
933 fprintf(stderr,
"Non-contiguous class ids in inttemp\n");
938 fprintf(stderr,
"Class id %d exceeds NumClassesIn (Templates) %d\n",
945 if (version_id >= 4) {
947 if (version_id >= 5) {
957 delete[] TempClassPruner;
963 #ifndef GRAPHICS_DISABLED 1034 int unicharset_size = target_unicharset.
size();
1035 int version_id = -5;
1037 if (Templates->
NumClasses != unicharset_size) {
1038 cprintf(
"Warning: executing WriteIntTemplates() with %d classes in" 1039 " Templates, while target_unicharset size is %d\n",
1044 fwrite(&unicharset_size,
sizeof(unicharset_size), 1,
File);
1045 fwrite(&version_id,
sizeof(version_id), 1,
File);
1056 for (i = 0; i < Templates->
NumClasses; i++) {
1057 Class = Templates->
Class[i];
1106 return (((
float) Bucket / NumBuckets) - Offset);
1122 return (((
float) (Bucket + 1) / NumBuckets) - Offset);
1140 uint32_t ClassCount,
1141 uint32_t WordIndex) {
1151 if (FillSpec->
YStart < 0)
1156 for (Y = FillSpec->
YStart; Y <= FillSpec->YEnd; Y++)
1159 OldWord = Pruner->
p[X][Y][Angle][WordIndex];
1160 if (ClassCount > (OldWord & ClassMask)) {
1161 OldWord &= ~ClassMask;
1162 OldWord |= ClassCount;
1163 Pruner->
p[X][Y][Angle][WordIndex] = OldWord;
1202 int Bit,
float Center,
float Spread,
bool debug) {
1203 int i, FirstBucket, LastBucket;
1208 FirstBucket =
static_cast<int>(std::floor((Center - Spread) *
NUM_PP_BUCKETS));
1209 if (FirstBucket < 0)
1212 LastBucket =
static_cast<int>(std::floor((Center + Spread) *
NUM_PP_BUCKETS));
1215 if (debug)
tprintf(
"Circular fill from %d to %d", FirstBucket, LastBucket);
1220 if (i == LastBucket)
1243 int Bit,
float Center,
float Spread,
bool debug) {
1244 int i, FirstBucket, LastBucket;
1246 FirstBucket =
static_cast<int>(std::floor((Center - Spread) *
NUM_PP_BUCKETS));
1247 if (FirstBucket < 0)
1250 LastBucket =
static_cast<int>(std::floor((Center + Spread) *
NUM_PP_BUCKETS));
1254 if (debug)
tprintf(
"Linear fill from %d to %d", FirstBucket, LastBucket);
1255 for (i = FirstBucket; i <= LastBucket; i++)
1262 #ifndef GRAPHICS_DISABLED 1275 bool* pretrained_on,
int* shape_id) {
1279 int unichar_id = INVALID_UNICHAR_ID;
1288 *adaptive_on =
false;
1289 *pretrained_on =
true;
1290 if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1294 tprintf(
"Shape %d, first unichar=%d, font=%d\n",
1295 *shape_id, unichar_id, font_id);
1300 tprintf(
"No shape table loaded!\n");
1306 *adaptive_on =
true;
1307 *pretrained_on =
false;
1310 *adaptive_on =
false;
1311 *pretrained_on =
true;
1313 *adaptive_on =
true;
1314 *pretrained_on =
true;
1326 tprintf(
"Char class '%s' not found in unicharset",
1381 if (*AnglePad > 0.5)
1392 assert (Evidence >= 0.0);
1393 assert (Evidence <= 1.0);
1395 if (Evidence >= 0.90)
1397 else if (Evidence >= 0.75)
1399 else if (Evidence >= 0.50)
1421 Fill->
X = Filler->
X;
1427 while (Filler->
X >= Next->
X) {
1428 Fill->
X = Filler->
X = Next->
X;
1435 Fill->
YEnd = Next->
Y;
1469 #define AS ANGLE_SHIFT 1470 #define NB NUM_CP_BUCKETS 1473 float X, Y, HalfLength;
1475 float XAdjust, YAdjust;
1476 FPOINT Start, Switch1, Switch2, End;
1480 Angle = Proto->
Angle;
1483 HalfLength = Proto->
Length / 2.0;
1511 if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1513 Angle *= 2.0 * M_PI;
1514 Cos = fabs(cos(Angle));
1515 Sin = fabs(sin(Angle));
1518 Start.
x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1519 Start.
y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1520 End.
x = 2.0 * X - Start.
x;
1521 End.
y = 2.0 * Y - Start.
y;
1522 Switch1.
x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1523 Switch1.
y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1524 Switch2.
x = 2.0 * X - Switch1.
x;
1525 Switch2.
y = 2.0 * Y - Switch1.
y;
1527 if (Switch1.
x > Switch2.
x) {
1534 Filler->
StartDelta = -(int16_t) ((Cos / Sin) * 256);
1535 Filler->
EndDelta = (int16_t) ((Sin / Cos) * 256);
1538 YAdjust = XAdjust * Cos / Sin;
1540 YAdjust = XAdjust * Sin / Cos;
1547 YAdjust = XAdjust * Sin / Cos;
1555 YAdjust = XAdjust * Cos / Sin;
1563 Angle *= 2.0 * M_PI;
1564 Cos = fabs(cos(Angle));
1565 Sin = fabs(sin(Angle));
1568 Start.
x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1569 Start.
y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1570 End.
x = 2.0 * X - Start.
x;
1571 End.
y = 2.0 * Y - Start.
y;
1572 Switch1.
x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1573 Switch1.
y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1574 Switch2.
x = 2.0 * X - Switch1.
x;
1575 Switch2.
y = 2.0 * Y - Switch1.
y;
1577 if (Switch1.
x > Switch2.
x) {
1584 Filler->
StartDelta =
static_cast<int16_t
>(ClipToRange<int>(
1586 Filler->
EndDelta =
static_cast<int16_t
>(ClipToRange<int>(
1590 YAdjust = XAdjust * Sin / Cos;
1592 YAdjust = XAdjust * Cos / Sin;
1599 YAdjust = XAdjust * Sin / Cos;
1607 YAdjust = XAdjust * Cos / Sin;
1619 #ifndef GRAPHICS_DISABLED 1630 float X, Y, Dx, Dy, Length;
1633 assert(Feature !=
nullptr);
1641 Dx = (Length / 2.0) * cos((Feature->
Theta / 256.0) * 2.0 * M_PI - M_PI);
1642 Dy = (Length / 2.0) * sin((Feature->
Theta / 256.0) * 2.0 * M_PI - M_PI);
1645 window->
DrawTo(X + Dx, Y + Dy);
1671 int Xmin, Xmax, Ymin, Ymax;
1676 assert(ProtoId >= 0);
1677 assert(Class !=
nullptr);
1678 assert(ProtoId < Class->NumProtos);
1684 Proto = &(ProtoSet->
Protos[ProtoSetIndex]);
1706 Dx = (Length / 2.0) * cos((Proto->
Angle / 256.0) * 2.0 * M_PI - M_PI);
1707 Dy = (Length / 2.0) * sin((Proto->
Angle / 256.0) * 2.0 * M_PI - M_PI);
1710 window->
DrawTo(X + Dx, Y + Dy);
1730 cprintf(
"Warning: Param %s truncated from %f to %d!\n",
1733 }
else if (Param > Max) {
1735 cprintf(
"Warning: Param %s truncated from %f to %d!\n",
1739 return static_cast<int>(std::floor(Param));
1743 #ifndef GRAPHICS_DISABLED 1754 "x",
"Class to debug");
1756 "x",
"Class to debug");
1758 "x",
"Class to debug");
1760 "0",
"Index to debug");
1790 return new ScrollView(name, xpos, ypos, 520, 520, 260, 260,
true);
1792 #endif // GRAPHICS_DISABLED double classify_cp_angle_pad_loose
bool write_spacing_info(FILE *f, const FontInfo &fi)
ScrollView::Color GetMatchColorFor(float Evidence)
bool write_info(FILE *f, const FontInfo &fi)
#define BITS_PER_CP_VECTOR
uint16_t Bucket16For(float param, float offset, int num_buckets)
void DrawTo(int x, int y)
int FRead(void *buffer, size_t size, int count)
double classify_cp_angle_pad_medium
void InitTableFiller(float EndPad, float SidePad, float AnglePad, PROTO Proto, TABLE_FILLER *Filler)
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
void UpdateMatchDisplay()
void cprintf(const char *format,...)
void free_int_templates(INT_TEMPLATES templates)
INT_CLASS Class[MAX_NUM_CLASSES]
uint32_t Configs[WERDS_PER_CONFIG_VEC]
int classify_num_cp_levels
#define double_VAR(name, val, comment)
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, float Evidence)
STRING DebugStr(int shape_id) const
bool FillerDone(TABLE_FILLER *Filler)
uint8_t CircBucketFor(float param, float offset, int num_buckets)
void ZoomToRectangle(int x1, int y1, int x2, int y2)
struct INT_CLASS_STRUCT * INT_CLASS
const char * string() const
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class)
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
#define NUM_BITS_PER_CLASS
#define INT_CHAR_NORM_RANGE
#define MAX_NUM_PROTO_SETS
ScrollView * FeatureDisplayWindow
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
#define ProtoForProtoId(C, P)
double classify_pp_angle_pad
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
void InitProtoDisplayWindowIfReqd()
void SetCursor(int x, int y)
#define UnusedClassIdIn(T, c)
double classify_pp_end_pad
uint32_t p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
int AddIntProto(INT_CLASS Class)
double classify_cp_angle_pad_tight
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos, const UNICHARSET &target_unicharset)
UnicityTableEqEq< int > font_set
#define ProtoIn(Class, Pid)
#define CPrunerWordIndexFor(c)
#define GetPicoFeatureLength()
#define MapParam(P, O, N)
int FReadEndian(void *buffer, size_t size, int count)
#define CPrunerMaskFor(L, c)
double classify_cp_end_pad_tight
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
double classify_cp_end_pad_medium
void GetCPPadsForLevel(int Level, float *EndPad, float *SidePad, float *AnglePad)
double classify_cp_side_pad_loose
#define WERDS_PER_PP_VECTOR
#define MaxNumIntProtosIn(C)
bool read_spacing_info(TFile *f, FontInfo *fi)
SVEvent * AwaitEvent(SVEventType type)
int classify_learning_debug_level
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
bool contains_unichar(const char *const unichar_repr) const
double classify_cp_end_pad_loose
int TruncateParam(float Param, int Min, int Max, char *Id)
int size() const
Return the size used.
SVMenuNode * AddChild(const char *txt)
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates, const UNICHARSET &target_unicharset)
int IntCastRounded(double x)
uint16_t ConfigLengths[MAX_NUM_CONFIGS]
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
struct PROTO_SET_STRUCT * PROTO_SET
ShapeTable * shape_table_
float BucketEnd(int Bucket, float Offset, int NumBuckets)
DLLSYM void tprintf(const char *format,...)
#define PROTOS_PER_PROTO_SET
double classify_pp_side_pad
bool read_info(TFile *f, FontInfo *fi)
#define MaxNumClassesIn(T)
#define PPrunerWordIndexFor(I)
const Shape & GetShape(int shape_id) const
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, uint32_t ClassMask, uint32_t ClassCount, uint32_t WordIndex)
uint8_t Bucket8For(float param, float offset, int num_buckets)
int AddIntConfig(INT_CLASS Class)
#define CPrunerBitIndexFor(c)
float BucketStart(int Bucket, float Offset, int NumBuckets)
void FillPPCircularBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
UnicityTable< FontInfo > fontinfo_table_
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
const T & get(int id) const
Return the object from an id.
#define OLD_WERDS_PER_CONFIG_VEC
ScrollView * ProtoDisplayWindow
void InitFeatureDisplayWindowIfReqd()
double classify_cp_side_pad_tight
void * Erealloc(void *ptr, int size)
INT_TEMPLATES ReadIntTemplates(TFile *fp)
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
const char * id_to_unichar(UNICHAR_ID id) const
INT_TEMPLATES NewIntTemplates()
#define PROTO_PRUNER_SCALE
#define WERDS_PER_CP_VECTOR
ScrollView * IntMatchWindow
bool ContainsUnichar(int unichar_id) const
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, float Evidence)
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
void GetFirstUnicharAndFont(int shape_id, int *unichar_id, int *font_id) const
void InitIntMatchWindowIfReqd()
bool read_set(TFile *f, FontSet *fs)
void Rectangle(int x1, int y1, int x2, int y2)
bool write_set(FILE *f, const FontSet &fs)
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
void BuildMenu(ScrollView *sv, bool menu_bar=true)
#define ClassForClassId(T, c)
double classify_cp_side_pad_medium
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
#define MAX_NUM_CLASS_PRUNERS
#define CircularIncrement(i, r)
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
#define test_bit(array, bit)
UnicityTable< FontSet > fontset_table_
#define SET_BIT(array, bit)
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
CLASS_ID GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on, int *shape_id)
#define INT_VAR(name, val, comment)
struct INT_TEMPLATES_STRUCT * INT_TEMPLATES
#define OLD_MAX_NUM_CONFIGS
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
#define PPrunerMaskFor(I)
void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, float Center, float Spread, bool debug)
#define WERDS_PER_CONFIG_VEC