46 #include "config_auto.h" 52 #define PROTO_PRUNER_SCALE (4.0) 54 #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE) 55 #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE) 56 #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE) 57 #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE) 59 #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE) 60 #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE) 61 #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE) 62 #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE) 65 #define INT_MAX_X INT_CHAR_NORM_RANGE 66 #define INT_MAX_Y INT_CHAR_NORM_RANGE 69 #define HV_TOLERANCE (0.0025) 74 #define MAX_NUM_SWITCHES 3 112 #define OLD_MAX_NUM_CONFIGS 32 113 #define OLD_WERDS_PER_CONFIG_VEC ((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\ 120 #define CircularIncrement(i,r) (((i) < (r) - 1)?((i)++):((i) = 0)) 123 #define MapParam(P,O,N) (floor (((P) + (O)) * (N))) 134 register uinT32 ClassMask,
135 register uinT32 ClassCount,
136 register uinT32 WordIndex);
162 #ifndef GRAPHICS_DISABLED 170 #endif // GRAPHICS_DISABLED 190 "Class Pruner Angle Pad Loose");
192 "Class Pruner Angle Pad Medium");
194 "CLass Pruner Angle Pad Tight");
243 fprintf(stderr,
"Please make sure that classes are added to templates");
244 fprintf(stderr,
" in increasing order of ClassIds\n");
310 memset(ProtoSet, 0,
sizeof(*ProtoSet));
351 FLOAT32 EndPad, SidePad, AnglePad;
366 DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
392 cprintf(
"AddProtoToProtoPruner:assert failed: %d < %d",
394 assert(ProtoId < Class->NumProtos);
399 Angle = Proto->
Angle;
401 assert(!
isnan(Angle));
412 Pad =
MAX (fabs (cos (Angle)) * (Length / 2.0 +
421 Pad =
MAX (fabs (sin (Angle)) * (Length / 2.0 +
451 return static_cast<uinT8>(
Modulo(bucket, num_buckets));
455 #ifndef GRAPHICS_DISABLED 468 if (IntMatchWindow != NULL)
492 for (ProtoId = 0, TotalLength = 0;
520 assert(ProtoId < Class->NumProtos);
524 Param = Proto->
A * 128;
527 Param = -Proto->
B * 256;
530 Param = Proto->
C * 128;
533 Param = Proto->
Angle * 256;
542 if (classify_learning_debug_level >= 2)
543 cprintf(
"Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
569 for (ClassId = 0; ClassId < target_unicharset.
size(); ClassId++) {
570 FClass = &(FloatProtos[ClassId]);
572 strcmp(target_unicharset.
id_to_unichar(ClassId),
" ") != 0) {
573 cprintf(
"Warning: no protos/configs for %s in CreateIntTemplates()\n",
581 for (
int i = 0; i < fs.
size; ++i) {
584 if (this->fontset_table_.contains(fs)) {
585 IClass->
font_set_id = this->fontset_table_.get_id(fs);
588 IClass->
font_set_id = this->fontset_table_.push_back(fs);
592 for (ProtoId = 0; ProtoId < FClass->
NumProtos; ProtoId++) {
594 ConvertProto(
ProtoIn(FClass, ProtoId), ProtoId, IClass);
596 classify_learning_debug_level >= 2);
600 for (ConfigId = 0; ConfigId < FClass->
NumConfigs; ConfigId++) {
605 return (IntTemplates);
610 #ifndef GRAPHICS_DISABLED 626 if (FeatureDisplayWindow) {
647 if (ProtoDisplayWindow) {
683 memset(ProtoSet, 0,
sizeof(*ProtoSet));
762 int i, j, w, x, y, z;
772 int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
780 uinT32 Mask, NewMask, ClassBits;
787 if (fp->
FReadEndian(&unicharset_size,
sizeof(unicharset_size), 1) != 1)
788 tprintf(
"Bad read of inttemp!\n");
793 tprintf(
"Bad read of inttemp!\n");
799 tprintf(
"Bad read of inttemp!\n");
802 if (version_id < 3) {
807 if (version_id < 2) {
808 if (fp->
FReadEndian(IndexFor,
sizeof(IndexFor[0]), unicharset_size) !=
810 tprintf(
"Bad read of inttemp!\n");
812 if (fp->
FReadEndian(ClassIdFor,
sizeof(ClassIdFor[0]),
814 tprintf(
"Bad read of inttemp!\n");
819 const int kNumBuckets =
823 if (fp->
FReadEndian(Pruner,
sizeof(Pruner->
p[0][0][0][0]), kNumBuckets) !=
825 tprintf(
"Bad read of inttemp!\n");
827 if (version_id < 2) {
828 TempClassPruner[i] = Pruner;
835 if (version_id < 2) {
839 if (ClassIdFor[i] > max_class_id)
840 max_class_id = ClassIdFor[i];
853 if (TempClassPruner[i]->p[x][y][z][w] == 0)
857 if (bit_number > last_cp_bit_number)
861 Mask = SetBitsForMask << b;
862 ClassBits = TempClassPruner[i]->
p[x][y][z][w] & Mask;
869 ClassBits <<= (new_b - b);
871 ClassBits >>= (b - new_b);
875 NewMask = SetBitsForMask << new_b;
876 Templates->
ClassPruners[new_i]->
p[x][y][z][new_w] &= ~NewMask;
877 Templates->
ClassPruners[new_i]->
p[x][y][z][new_w] |= ClassBits;
882 delete TempClassPruner[i];
893 tprintf(
"Bad read of inttemp!\n");
894 if (version_id == 0) {
896 for (j = 0; j < 5; ++j) {
898 if (fp->
FRead(&junk,
sizeof(junk), 1) != 1)
899 tprintf(
"Bad read of inttemp!\n");
902 int num_configs = version_id < 4 ? MaxNumConfigs : Class->
NumConfigs;
906 tprintf(
"Bad read of inttemp!\n");
908 if (version_id < 2) {
920 tprintf(
"Bad read of inttemp!\n");
930 num_buckets) != num_buckets)
931 tprintf(
"Bad read of inttemp!\n");
941 tprintf(
"Bad read of inttemp!\n");
944 WerdsPerConfigVec) != WerdsPerConfigVec)
945 cprintf(
"Bad read of inttemp!\n");
949 if (version_id < 4) {
956 if (version_id < 2) {
964 if (i < Templates->NumClasses) {
966 fprintf(stderr,
"Non-contiguous class ids in inttemp\n");
971 fprintf(stderr,
"Class id %d exceeds NumClassesIn (Templates) %d\n",
978 if (version_id >= 4) {
980 if (version_id >= 5) {
981 this->fontinfo_table_.read(fp,
990 delete[] TempClassPruner;
996 #ifndef GRAPHICS_DISABLED 1010 if (ProtoDisplayWindow) {
1011 ProtoDisplayWindow->
Clear();
1013 if (FeatureDisplayWindow) {
1014 FeatureDisplayWindow->
Clear();
1017 static_cast<NORM_METHOD>(static_cast<int>(classify_norm_method)),
1021 if (ProtoDisplayWindow) {
1025 if (FeatureDisplayWindow) {
1071 int unicharset_size = target_unicharset.
size();
1072 int version_id = -5;
1074 if (Templates->
NumClasses != unicharset_size) {
1075 cprintf(
"Warning: executing WriteIntTemplates() with %d classes in" 1076 " Templates, while target_unicharset size is %d\n",
1081 fwrite(&unicharset_size,
sizeof(unicharset_size), 1, File);
1082 fwrite(&version_id,
sizeof(version_id), 1, File);
1093 for (i = 0; i < Templates->
NumClasses; i++) {
1094 Class = Templates->
Class[i];
1117 fwrite(&Class->
font_set_id,
sizeof(
int), 1, File);
1122 this->fontinfo_table_.write(File,
1146 return (((
FLOAT32) Bucket / NumBuckets) - Offset);
1164 return (((
FLOAT32) (Bucket + 1) / NumBuckets) - Offset);
1183 register uinT32 ClassMask,
1184 register uinT32 ClassCount,
1185 register uinT32 WordIndex) {
1195 if (FillSpec->
YStart < 0)
1200 for (Y = FillSpec->
YStart; Y <= FillSpec->YEnd; Y++)
1203 OldWord = Pruner->
p[
X][
Y][Angle][WordIndex];
1204 if (ClassCount > (OldWord & ClassMask)) {
1205 OldWord &= ~ClassMask;
1206 OldWord |= ClassCount;
1207 Pruner->
p[
X][
Y][Angle][WordIndex] = OldWord;
1254 int i, FirstBucket, LastBucket;
1260 if (FirstBucket < 0)
1266 if (debug)
tprintf(
"Circular fill from %d to %d", FirstBucket, LastBucket);
1271 if (i == LastBucket)
1297 int i, FirstBucket, LastBucket;
1300 if (FirstBucket < 0)
1307 if (debug)
tprintf(
"Linear fill from %d to %d", FirstBucket, LastBucket);
1308 for (i = FirstBucket; i <= LastBucket; i++)
1315 #ifndef GRAPHICS_DISABLED 1329 CLASS_ID Classify::GetClassToDebug(
const char *Prompt,
bool* adaptive_on,
1330 bool* pretrained_on,
int* shape_id) {
1334 int unichar_id = INVALID_UNICHAR_ID;
1341 if (shape_table_ != NULL) {
1343 *adaptive_on =
false;
1344 *pretrained_on =
true;
1345 if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1347 shape_table_->GetFirstUnicharAndFont(*shape_id, &unichar_id,
1349 tprintf(
"Shape %d, first unichar=%d, font=%d\n",
1350 *shape_id, unichar_id, font_id);
1355 tprintf(
"No shape table loaded!\n");
1358 if (unicharset.contains_unichar(ev->
parameter)) {
1359 unichar_id = unicharset.unichar_to_id(ev->
parameter);
1361 *adaptive_on =
true;
1362 *pretrained_on =
false;
1365 *adaptive_on =
false;
1366 *pretrained_on =
true;
1368 *adaptive_on =
true;
1369 *pretrained_on =
true;
1375 for (
int s = 0; s < shape_table_->NumShapes(); ++s) {
1376 if (shape_table_->GetShape(s).ContainsUnichar(unichar_id)) {
1377 tprintf(
"%s\n", shape_table_->DebugStr(s).string());
1381 tprintf(
"Char class '%s' not found in unicharset",
1438 if (*AnglePad > 0.5)
1451 assert (Evidence >= 0.0);
1452 assert (Evidence <= 1.0);
1454 if (Evidence >= 0.90)
1456 else if (Evidence >= 0.75)
1458 else if (Evidence >= 0.50)
1482 Fill->
X = Filler->
X;
1488 while (Filler->
X >= Next->
X) {
1489 Fill->
X = Filler->
X = Next->
X;
1496 Fill->
YEnd = Next->
Y;
1532 #define AS ANGLE_SHIFT 1533 #define NB NUM_CP_BUCKETS 1539 FPOINT Start, Switch1, Switch2, End;
1543 Angle = Proto->
Angle;
1546 HalfLength = Proto->
Length / 2.0;
1574 if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1577 Cos = fabs(cos(Angle));
1578 Sin = fabs(sin(Angle));
1581 Start.
x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1582 Start.
y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1583 End.
x = 2.0 * X - Start.
x;
1584 End.
y = 2.0 * Y - Start.
y;
1585 Switch1.
x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1586 Switch1.
y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1587 Switch2.
x = 2.0 * X - Switch1.
x;
1588 Switch2.
y = 2.0 * Y - Switch1.
y;
1590 if (Switch1.
x > Switch2.
x) {
1601 YAdjust = XAdjust * Cos / Sin;
1603 YAdjust = XAdjust * Sin / Cos;
1610 YAdjust = XAdjust * Sin / Cos;
1618 YAdjust = XAdjust * Cos / Sin;
1627 Cos = fabs(cos(Angle));
1628 Sin = fabs(sin(Angle));
1631 Start.
x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1632 Start.
y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1633 End.
x = 2.0 * X - Start.
x;
1634 End.
y = 2.0 * Y - Start.
y;
1635 Switch1.
x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1636 Switch1.
y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1637 Switch2.
x = 2.0 * X - Switch1.
x;
1638 Switch2.
y = 2.0 * Y - Switch1.
y;
1640 if (Switch1.
x > Switch2.
x) {
1653 YAdjust = XAdjust * Sin / Cos;
1655 YAdjust = XAdjust * Cos / Sin;
1662 YAdjust = XAdjust * Sin / Cos;
1670 YAdjust = XAdjust * Cos / Sin;
1682 #ifndef GRAPHICS_DISABLED 1698 assert(Feature != NULL);
1706 Dx = (Length / 2.0) * cos((Feature->
Theta / 256.0) * 2.0 *
PI -
PI);
1707 Dy = (Length / 2.0) * sin((Feature->
Theta / 256.0) * 2.0 *
PI -
PI);
1710 window->
DrawTo(X + Dx, Y + Dy);
1738 int Xmin, Xmax, Ymin, Ymax;
1743 assert(ProtoId >= 0);
1744 assert(Class != NULL);
1745 assert(ProtoId < Class->NumProtos);
1751 Proto = &(ProtoSet->
Protos[ProtoSetIndex]);
1773 Dx = (Length / 2.0) * cos((Proto->
Angle / 256.0) * 2.0 *
PI -
PI);
1774 Dy = (Length / 2.0) * sin((Proto->
Angle / 256.0) * 2.0 *
PI -
PI);
1777 window->
DrawTo(X + Dx, Y + Dy);
1799 cprintf(
"Warning: Param %s truncated from %f to %d!\n",
1802 }
else if (Param > Max) {
1804 cprintf(
"Warning: Param %s truncated from %f to %d!\n",
1808 return static_cast<int>(floor(Param));
1812 #ifndef GRAPHICS_DISABLED 1818 if (IntMatchWindow == NULL) {
1823 "x",
"Class to debug");
1825 "x",
"Class to debug");
1827 "x",
"Class to debug");
1829 "0",
"Index to debug");
1830 popup_menu->
BuildMenu(IntMatchWindow,
false);
1839 if (ProtoDisplayWindow == NULL) {
1850 if (FeatureDisplayWindow == NULL) {
1859 return new ScrollView(name, xpos, ypos, 520, 520, 260, 260,
true);
1861 #endif // GRAPHICS_DISABLED void InitFeatureDisplayWindowIfReqd()
#define CircularIncrement(i, r)
#define NUM_BITS_PER_CLASS
void AddProtoToClassPruner(PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates)
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS]
uinT8 Bucket8For(FLOAT32 param, FLOAT32 offset, int num_buckets)
#define BITS_PER_CP_VECTOR
bool read_spacing_info(TFile *f, FontInfo *fi)
#define CPrunerBitIndexFor(c)
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET]
#define PPrunerWordIndexFor(I)
double classify_cp_angle_pad_loose
CLASS_PRUNER_STRUCT * ClassPruners[MAX_NUM_CLASS_PRUNERS]
bool read_set(TFile *f, FontSet *fs)
_ConstTessMemberResultCallback_0_0< false, R, T1 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)() const)
void free_int_class(INT_CLASS int_class)
bool write_set(FILE *f, const FontSet &fs)
#define WERDS_PER_CP_VECTOR
#define MAX_NUM_CLASS_PRUNERS
#define UnusedClassIdIn(T, c)
void DisplayIntFeature(const INT_FEATURE_STRUCT *Feature, FLOAT32 Evidence)
struct PROTO_SET_STRUCT * PROTO_SET
int size() const
Return the size used.
ScrollView * IntMatchWindow
double classify_cp_angle_pad_tight
void InitTableFiller(FLOAT32 EndPad, FLOAT32 SidePad, FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER *Filler)
double classify_cp_side_pad_loose
void DoFill(FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, register uinT32 ClassMask, register uinT32 ClassCount, register uinT32 WordIndex)
void FillPPCircularBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
int FReadEndian(void *buffer, int size, int count)
#define MapParam(P, O, N)
#define CPrunerWordIndexFor(c)
int IntCastRounded(double x)
double classify_cp_end_pad_medium
int classify_num_cp_levels
double classify_cp_side_pad_medium
uinT32 p[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR]
double classify_pp_side_pad
void SetCursor(int x, int y)
uinT16 Bucket16For(FLOAT32 param, FLOAT32 offset, int num_buckets)
const char * id_to_unichar(UNICHAR_ID id) const
#define ProtoForProtoId(C, P)
FILL_SWITCH Switch[MAX_NUM_SWITCHES]
#define double_VAR(name, val, comment)
#define ClassForClassId(T, c)
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
void Rectangle(int x1, int y1, int x2, int y2)
void RenderIntProto(ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color)
int AddIntConfig(INT_CLASS Class)
double classify_cp_end_pad_tight
#define OLD_MAX_NUM_CONFIGS
bool write_info(FILE *f, const FontInfo &fi)
bool read_info(TFile *f, FontInfo *fi)
uinT16 ConfigLengths[MAX_NUM_CONFIGS]
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
#define INT_VAR(name, val, comment)
#define INT_CHAR_NORM_RANGE
void ZoomToRectangle(int x1, int y1, int x2, int y2)
INT_TEMPLATES NewIntTemplates()
INT_CLASS Class[MAX_NUM_CLASSES]
uinT32 Configs[WERDS_PER_CONFIG_VEC]
int TruncateParam(FLOAT32 Param, int Min, int Max, char *Id)
int AddIntProto(INT_CLASS Class)
FLOAT32 BucketEnd(int Bucket, FLOAT32 Offset, int NumBuckets)
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class)
#define MAX_NUM_PROTO_SETS
void AddProtoToProtoPruner(PROTO Proto, int ProtoId, INT_CLASS Class, bool debug)
struct INT_CLASS_STRUCT * INT_CLASS
void InitIntMatchWindowIfReqd()
uinT8 CircBucketFor(FLOAT32 param, FLOAT32 offset, int num_buckets)
void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class)
#define PROTO_PRUNER_SCALE
bool write_spacing_info(FILE *f, const FontInfo &fi)
void GetCPPadsForLevel(int Level, FLOAT32 *EndPad, FLOAT32 *SidePad, FLOAT32 *AnglePad)
#define PROTOS_PER_PROTO_SET
UnicityTableEqEq< int > font_set
#define test_bit(array, bit)
void * Erealloc(void *ptr, int size)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
void InitProtoDisplayWindowIfReqd()
#define WERDS_PER_PP_VECTOR
void cprintf(const char *format,...)
ScrollView * FeatureDisplayWindow
#define SET_BIT(array, bit)
void GetNextFill(TABLE_FILLER *Filler, FILL_SPEC *Fill)
double classify_pp_angle_pad
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence)
SVMenuNode * AddChild(const char *txt)
void FillPPLinearBits(uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug)
#define MaxNumIntProtosIn(C)
const T & get(int id) const
Return the object from an id.
#define GetPicoFeatureLength()
double classify_pp_end_pad
struct INT_TEMPLATES_STRUCT * INT_TEMPLATES
void free_int_templates(INT_TEMPLATES templates)
#define CPrunerMaskFor(L, c)
double classify_cp_angle_pad_medium
void UpdateRange(const T1 &x, T2 *lower_bound, T2 *upper_bound)
#define ProtoIn(Class, Pid)
double classify_cp_side_pad_tight
void UpdateMatchDisplay()
void BuildMenu(ScrollView *sv, bool menu_bar=true)
#define WERDS_PER_CONFIG_VEC
BOOL8 FillerDone(TABLE_FILLER *Filler)
#define MaxNumClassesIn(T)
double classify_cp_end_pad_loose
#define PPrunerMaskFor(I)
void DrawTo(int x, int y)
SVEvent * AwaitEvent(SVEventType type)
ScrollView::Color GetMatchColorFor(FLOAT32 Evidence)
FLOAT32 BucketStart(int Bucket, FLOAT32 Offset, int NumBuckets)
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs)
int FRead(void *buffer, int size, int count)
#define OLD_WERDS_PER_CONFIG_VEC
ScrollView * ProtoDisplayWindow