45 #include "config_auto.h"
53 #define PROTO_PRUNER_SCALE (4.0)
55 #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE)
56 #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE)
57 #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE)
58 #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE)
60 #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE)
61 #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE)
62 #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE)
63 #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE)
66 #define INT_MAX_X INT_CHAR_NORM_RANGE
67 #define INT_MAX_Y INT_CHAR_NORM_RANGE
70 #define HV_TOLERANCE (0.0025)
75 #define MAX_NUM_SWITCHES 3
113 #define OLD_MAX_NUM_CONFIGS 32
114 #define OLD_WERDS_PER_CONFIG_VEC ((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\
121 #define CircularIncrement(i,r) (((i) < (r) - 1)?((i)++):((i) = 0))
124 #define MapParam(P,O,N) (floor (((P) + (O)) * (N)))
135 register uinT32 ClassMask,
136 register uinT32 ClassCount,
137 register uinT32 WordIndex);
163 #ifndef GRAPHICS_DISABLED
171 #endif // GRAPHICS_DISABLED
191 "Class Pruner Angle Pad Loose");
193 "Class Pruner Angle Pad Medium");
195 "CLass Pruner Angle Pad Tight");
229 fprintf(stderr,
"Please make sure that classes are added to templates");
230 fprintf(stderr,
" in increasing order of ClassIds\n");
298 memset(ProtoSet, 0,
sizeof(*ProtoSet));
342 FLOAT32 EndPad, SidePad, AnglePad;
357 DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
385 cprintf(
"AddProtoToProtoPruner:assert failed: %d < %d",
387 assert(ProtoId < Class->NumProtos);
392 Angle = Proto->
Angle;
394 assert(!isnan(Angle));
405 Pad =
MAX (fabs (cos (Angle)) * (Length / 2.0 +
414 Pad =
MAX (fabs (sin (Angle)) * (Length / 2.0 +
465 Bucket =
static_cast<int>(
MapParam(Param, Offset, NumBuckets));
467 Bucket += NumBuckets;
468 else if (Bucket >= NumBuckets)
469 Bucket -= NumBuckets;
475 #ifndef GRAPHICS_DISABLED
488 if (IntMatchWindow !=
NULL)
514 for (ProtoId = 0, TotalLength = 0;
544 assert(ProtoId < Class->NumProtos);
548 Param = Proto->
A * 128;
551 Param = -Proto->
B * 256;
554 Param = Proto->
C * 128;
557 Param = Proto->
Angle * 256;
567 cprintf(
"Converted ffeat to (A=%d,B=%d,C=%d,L=%d)",
595 for (ClassId = 0; ClassId < target_unicharset.
size(); ClassId++) {
596 FClass = &(FloatProtos[ClassId]);
598 strcmp(target_unicharset.
id_to_unichar(ClassId),
" ") != 0) {
599 cprintf(
"Warning: no protos/configs for %s in CreateIntTemplates()\n",
607 for (
int i = 0; i < fs.
size; ++i) {
618 for (ProtoId = 0; ProtoId < FClass->
NumProtos; ProtoId++) {
626 for (ConfigId = 0; ConfigId < FClass->
NumConfigs; ConfigId++) {
631 return (IntTemplates);
637 #ifndef GRAPHICS_DISABLED
653 if (FeatureDisplayWindow) {
676 if (ProtoDisplayWindow) {
714 memset(ProtoSet, 0,
sizeof(*ProtoSet));
798 int i, j, w, x, y, z;
810 int b, bit_number, last_cp_bit_number, new_b, new_i, new_w;
818 uinT32 Mask, NewMask, ClassBits;
825 if (fread(&unicharset_size,
sizeof(
int), 1, File) != 1)
826 cprintf(
"Bad read of inttemp!\n");
828 sizeof(Templates->
NumClasses), 1, File) != 1 ||
831 cprintf(
"Bad read of inttemp!\n");
845 cprintf(
"Bad read of inttemp!\n");
850 if (version_id < 3) {
855 if (version_id < 2) {
856 for (i = 0; i < unicharset_size; ++i) {
857 if (fread(&IndexFor[i],
sizeof(
inT16), 1, File) != 1)
858 cprintf(
"Bad read of inttemp!\n");
861 if (fread(&ClassIdFor[i],
sizeof(
CLASS_ID), 1, File) != 1)
862 cprintf(
"Bad read of inttemp!\n");
878 cprintf(
"Bad read of inttemp!\n");
890 if (version_id < 2) {
891 TempClassPruner[i] = Pruner;
898 if (version_id < 2) {
902 if (ClassIdFor[i] > max_class_id)
903 max_class_id = ClassIdFor[i];
916 if (TempClassPruner[i]->p[x][y][z][w] == 0)
920 if (bit_number > last_cp_bit_number)
924 Mask = SetBitsForMask << b;
925 ClassBits = TempClassPruner[i]->
p[x][y][z][w] & Mask;
932 ClassBits <<= (new_b - b);
934 ClassBits >>= (b - new_b);
938 NewMask = SetBitsForMask << new_b;
939 Templates->
ClassPruners[new_i]->
p[x][y][z][new_w] &= ~NewMask;
940 Templates->
ClassPruners[new_i]->
p[x][y][z][new_w] |= ClassBits;
945 delete TempClassPruner[i];
956 cprintf (
"Bad read of inttemp!\n");
957 if (version_id == 0) {
959 for (j = 0; j < 5; ++j) {
961 if (fread(&junk,
sizeof(junk), 1, File) != 1)
962 cprintf (
"Bad read of inttemp!\n");
965 if (version_id < 4) {
966 for (j = 0; j < MaxNumConfigs; ++j) {
968 cprintf (
"Bad read of inttemp!\n");
972 for (j = 0; j < MaxNumConfigs; j++)
979 cprintf (
"Bad read of inttemp!\n");
983 for (j = 0; j < MaxNumConfigs; j++)
987 if (version_id < 2) {
998 fread((
char *)Lengths,
sizeof(
uinT8),
1000 cprintf (
"Bad read of inttemp!\n");
1007 if (version_id < 3) {
1011 cprintf(
"Bad read of inttemp!\n");
1013 if ((nread = fread((
char *) &ProtoSet->
Protos[x].
A, 1,
1014 sizeof(
inT8), File)) !=
sizeof(
inT8) ||
1015 (nread = fread((
char *) &ProtoSet->
Protos[x].
B, 1,
1017 (nread = fread((
char *) &ProtoSet->
Protos[x].
C, 1,
1018 sizeof(
inT8), File)) !=
sizeof(
inT8) ||
1019 (nread = fread((
char *) &ProtoSet->
Protos[x].
Angle, 1,
1021 cprintf(
"Bad read of inttemp!\n");
1022 for (y = 0; y < WerdsPerConfigVec; y++)
1023 if ((nread = fread((
char *) &ProtoSet->
Protos[x].
Configs[y], 1,
1025 cprintf(
"Bad read of inttemp!\n");
1031 cprintf(
"Bad read of inttemp!\n");
1039 for (y = 0; y < WerdsPerConfigVec; y++)
1053 if (version_id < 2) {
1061 if (i < Templates->NumClasses) {
1063 fprintf(stderr,
"Non-contiguous class ids in inttemp\n");
1068 fprintf(stderr,
"Class id %d exceeds NumClassesIn (Templates) %d\n",
1075 if (version_id >= 4) {
1077 if (version_id >= 5) {
1087 delete[] ClassIdFor;
1088 delete[] TempClassPruner;
1095 #ifndef GRAPHICS_DISABLED
1109 if (ProtoDisplayWindow) {
1110 ProtoDisplayWindow->
Clear();
1112 if (FeatureDisplayWindow) {
1113 FeatureDisplayWindow->
Clear();
1120 if (ProtoDisplayWindow) {
1124 if (FeatureDisplayWindow) {
1171 int unicharset_size = target_unicharset.
size();
1172 int version_id = -5;
1174 if (Templates->
NumClasses != unicharset_size) {
1175 cprintf(
"Warning: executing WriteIntTemplates() with %d classes in"
1176 " Templates, while target_unicharset size is %d\n",
1181 fwrite(&unicharset_size,
sizeof(unicharset_size), 1, File);
1182 fwrite(&version_id,
sizeof(version_id), 1, File);
1193 for (i = 0; i < Templates->
NumClasses; i++) {
1194 Class = Templates->
Class[i];
1217 fwrite(&Class->
font_set_id,
sizeof(
int), 1, File);
1248 return (((
FLOAT32) Bucket / NumBuckets) - Offset);
1269 return (((
FLOAT32) (Bucket + 1) / NumBuckets) - Offset);
1276 register uinT32 ClassMask,
1277 register uinT32 ClassCount,
1278 register uinT32 WordIndex) {
1294 register int X, Y, Angle;
1303 if (FillSpec->
YStart < 0)
1308 for (Y = FillSpec->
YStart; Y <= FillSpec->YEnd; Y++)
1311 OldWord = Pruner->
p[X][Y][Angle][WordIndex];
1312 if (ClassCount > (OldWord & ClassMask)) {
1313 OldWord &= ~ClassMask;
1314 OldWord |= ClassCount;
1315 Pruner->
p[X][Y][Angle][WordIndex] = OldWord;
1367 int i, FirstBucket, LastBucket;
1373 if (FirstBucket < 0)
1379 if (debug)
tprintf(
"Circular fill from %d to %d", FirstBucket, LastBucket);
1384 if (i == LastBucket)
1412 int i, FirstBucket, LastBucket;
1415 if (FirstBucket < 0)
1422 if (debug)
tprintf(
"Linear fill from %d to %d", FirstBucket, LastBucket);
1423 for (i = FirstBucket; i <= LastBucket; i++)
1430 #ifndef GRAPHICS_DISABLED
1433 bool* pretrained_on,
int* shape_id) {
1447 int unichar_id = INVALID_UNICHAR_ID;
1456 *adaptive_on =
false;
1457 *pretrained_on =
true;
1458 if (*shape_id >= 0 && *shape_id < shape_table_->NumShapes()) {
1462 tprintf(
"Shape %d, first unichar=%d, font=%d\n",
1463 *shape_id, unichar_id, font_id);
1468 tprintf(
"No shape table loaded!\n");
1474 *adaptive_on =
true;
1475 *pretrained_on =
false;
1478 *adaptive_on =
false;
1479 *pretrained_on =
true;
1481 *adaptive_on =
true;
1482 *pretrained_on =
true;
1494 tprintf(
"Char class '%s' not found in unicharset",
1553 if (*AnglePad > 0.5)
1571 assert (Evidence >= 0.0);
1572 assert (Evidence <= 1.0);
1574 if (Evidence >= 0.90)
1576 else if (Evidence >= 0.75)
1578 else if (Evidence >= 0.50)
1605 Fill->
X = Filler->
X;
1611 while (Filler->
X >= Next->
X) {
1612 Fill->
X = Filler->
X = Next->
X;
1619 Fill->
YEnd = Next->
Y;
1658 #define AS ANGLE_SHIFT
1659 #define NB NUM_CP_BUCKETS
1665 FPOINT Start, Switch1, Switch2, End;
1669 Angle = Proto->
Angle;
1672 HalfLength = Proto->
Length / 2.0;
1700 if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
1703 Cos = fabs(cos(Angle));
1704 Sin = fabs(sin(Angle));
1707 Start.
x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1708 Start.
y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
1709 End.
x = 2.0 * X - Start.
x;
1710 End.
y = 2.0 * Y - Start.
y;
1711 Switch1.
x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1712 Switch1.
y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
1713 Switch2.
x = 2.0 * X - Switch1.
x;
1714 Switch2.
y = 2.0 * Y - Switch1.
y;
1716 if (Switch1.
x > Switch2.
x) {
1727 YAdjust = XAdjust * Cos / Sin;
1729 YAdjust = XAdjust * Sin / Cos;
1736 YAdjust = XAdjust * Sin / Cos;
1745 YAdjust = XAdjust * Cos / Sin;
1755 Cos = fabs(cos(Angle));
1756 Sin = fabs(sin(Angle));
1759 Start.
x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
1760 Start.
y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
1761 End.
x = 2.0 * X - Start.
x;
1762 End.
y = 2.0 * Y - Start.
y;
1763 Switch1.
x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
1764 Switch1.
y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
1765 Switch2.
x = 2.0 * X - Switch1.
x;
1766 Switch2.
y = 2.0 * Y - Switch1.
y;
1768 if (Switch1.
x > Switch2.
x) {
1779 YAdjust = XAdjust * Sin / Cos;
1781 YAdjust = XAdjust * Cos / Sin;
1788 YAdjust = XAdjust * Sin / Cos;
1797 YAdjust = XAdjust * Cos / Sin;
1810 #ifndef GRAPHICS_DISABLED
1827 assert(Feature !=
NULL);
1835 Dx = (Length / 2.0) * cos((Feature->
Theta / 256.0) * 2.0 *
PI -
PI);
1836 Dy = (Length / 2.0) * sin((Feature->
Theta / 256.0) * 2.0 *
PI -
PI);
1839 window->
DrawTo(X + Dx, Y + Dy);
1868 int Xmin, Xmax, Ymin, Ymax;
1873 assert(ProtoId >= 0);
1874 assert(Class !=
NULL);
1875 assert(ProtoId < Class->NumProtos);
1881 Proto = &(ProtoSet->
Protos[ProtoSetIndex]);
1903 Dx = (Length / 2.0) * cos((Proto->
Angle / 256.0) * 2.0 *
PI -
PI);
1904 Dy = (Length / 2.0) * sin((Proto->
Angle / 256.0) * 2.0 *
PI -
PI);
1907 window->
DrawTo(X + Dx, Y + Dy);
1930 cprintf(
"Warning: Param %s truncated from %f to %d!\n",
1933 }
else if (Param > Max) {
1935 cprintf(
"Warning: Param %s truncated from %f to %d!\n",
1939 return static_cast<int>(floor(Param));
1944 #ifndef GRAPHICS_DISABLED
1950 if (IntMatchWindow ==
NULL) {
1955 "x",
"Class to debug");
1957 "x",
"Class to debug");
1959 "x",
"Class to debug");
1961 "0",
"Index to debug");
1962 popup_menu->
BuildMenu(IntMatchWindow,
false);
1971 if (ProtoDisplayWindow ==
NULL) {
1982 if (FeatureDisplayWindow ==
NULL) {
1991 return new ScrollView(name, xpos, ypos, 520, 520, 260, 260,
true);
1993 #endif // GRAPHICS_DISABLED